Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #89099 > unrolled thread
| Started by | Paddy <paddy3118@gmail.com> |
|---|---|
| First post | 2015-04-17 18:19 -0700 |
| Last post | 2015-04-18 01:08 -0700 |
| Articles | 5 — 3 participants |
Back to article view | Back to comp.lang.python
Need opinions on P vs NP Paddy <paddy3118@gmail.com> - 2015-04-17 18:19 -0700
Re: Need opinions on P vs NP Ian Kelly <ian.g.kelly@gmail.com> - 2015-04-17 20:33 -0600
Re: Need opinions on P vs NP Paddy <paddy3118@gmail.com> - 2015-04-17 22:11 -0700
Re: Need opinions on P vs NP wxjmfauth@gmail.com - 2015-04-18 00:08 -0700
Re: Need opinions on P vs NP Paddy <paddy3118@gmail.com> - 2015-04-18 01:08 -0700
| From | Paddy <paddy3118@gmail.com> |
|---|---|
| Date | 2015-04-17 18:19 -0700 |
| Subject | Need opinions on P vs NP |
| Message-ID | <f2e51cb7-dbcf-4679-baf3-9b006b82e08c@googlegroups.com> |
Having just seen Raymond's talk on Beyond PEP-8 here: https://www.youtube.com/watch?v=wf-BqAjZb8M, it reminded me of my own recent post where I am soliciting opinions from non-newbies on the relative Pythonicity of different versions of a routine that has non-simple array manipulations.
The blog post: http://paddy3118.blogspot.co.uk/2015/04/pythonic-matrix-manipulation.html
The first, (and original), code sample:
def cholesky(A):
L = [[0.0] * len(A) for _ in range(len(A))]
for i in range(len(A)):
for j in range(i+1):
s = sum(L[i][k] * L[j][k] for k in range(j))
L[i][j] = sqrt(A[i][i] - s) if (i == j) else \
(1.0 / L[j][j] * (A[i][j] - s))
return L
The second equivalent code sample:
def cholesky2(A):
L = [[0.0] * len(A) for _ in range(len(A))]
for i, (Ai, Li) in enumerate(zip(A, L)):
for j, Lj in enumerate(L[:i+1]):
s = sum(Li[k] * Lj[k] for k in range(j))
Li[j] = sqrt(Ai[i] - s) if (i == j) else \
(1.0 / Lj[j] * (Ai[j] - s))
return L
The third:
def cholesky3(A):
L = [[0.0] * len(A) for _ in range(len(A))]
for i, (Ai, Li) in enumerate(zip(A, L)):
for j, Lj in enumerate(L[:i]):
#s = fsum(Li[k] * Lj[k] for k in range(j))
s = fsum(Lik * Ljk for Lik, Ljk in zip(Li, Lj[:j]))
Li[j] = (1.0 / Lj[j] * (Ai[j] - s))
s = fsum(Lik * Lik for Lik in Li[:i])
Li[i] = sqrt(Ai[i] - s)
return L
My blog post gives a little more explanation, but I have yet to receive any comments on relative Pythonicity.
[toc] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-04-17 20:33 -0600 |
| Message-ID | <mailman.389.1429324454.12925.python-list@python.org> |
| In reply to | #89099 |
On Fri, Apr 17, 2015 at 7:19 PM, Paddy <paddy3118@gmail.com> wrote: > Having just seen Raymond's talk on Beyond PEP-8 here: https://www.youtube.com/watch?v=wf-BqAjZb8M, it reminded me of my own recent post where I am soliciting opinions from non-newbies on the relative Pythonicity of different versions of a routine that has non-simple array manipulations. > > The blog post: http://paddy3118.blogspot.co.uk/2015/04/pythonic-matrix-manipulation.html > > The first, (and original), code sample: > > def cholesky(A): > L = [[0.0] * len(A) for _ in range(len(A))] > for i in range(len(A)): > for j in range(i+1): > s = sum(L[i][k] * L[j][k] for k in range(j)) > L[i][j] = sqrt(A[i][i] - s) if (i == j) else \ > (1.0 / L[j][j] * (A[i][j] - s)) > return L > > > The second equivalent code sample: > > def cholesky2(A): > L = [[0.0] * len(A) for _ in range(len(A))] > for i, (Ai, Li) in enumerate(zip(A, L)): > for j, Lj in enumerate(L[:i+1]): > s = sum(Li[k] * Lj[k] for k in range(j)) > Li[j] = sqrt(Ai[i] - s) if (i == j) else \ > (1.0 / Lj[j] * (Ai[j] - s)) > return L > > > The third: > > def cholesky3(A): > L = [[0.0] * len(A) for _ in range(len(A))] > for i, (Ai, Li) in enumerate(zip(A, L)): > for j, Lj in enumerate(L[:i]): > #s = fsum(Li[k] * Lj[k] for k in range(j)) > s = fsum(Lik * Ljk for Lik, Ljk in zip(Li, Lj[:j])) > Li[j] = (1.0 / Lj[j] * (Ai[j] - s)) > s = fsum(Lik * Lik for Lik in Li[:i]) > Li[i] = sqrt(Ai[i] - s) > return L > > My blog post gives a little more explanation, but I have yet to receive any comments on relative Pythonicity. I prefer the first version. You're dealing with mathematical formulas involving matrices here, so subscripting seems appropriate, and enumerating out rows and columns just feels weird to me. That said, I also prefer how the third version pulls the last column of each row out of the inner loop instead of using a verbose conditional expression that you already know will be false for every column except the last one. Do that in the first version, and I think you've got it.
[toc] | [prev] | [next] | [standalone]
| From | Paddy <paddy3118@gmail.com> |
|---|---|
| Date | 2015-04-17 22:11 -0700 |
| Message-ID | <43f7a201-5b3e-48f9-b216-feeea306dac6@googlegroups.com> |
| In reply to | #89105 |
On Saturday, 18 April 2015 03:34:57 UTC+1, Ian wrote: > On Fri, Apr 17, 2015 at 7:19 PM, Paddy <paddy3118@..l.com> wrote: > > Having just seen Raymond's talk on Beyond PEP-8 here: https://www.youtube.com/watch?v=wf-BqAjZb8M, it reminded me of my own recent post where I am soliciting opinions from non-newbies on the relative Pythonicity of different versions of a routine that has non-simple array manipulations. > > > > The blog post: http://paddy3118.blogspot.co.uk/2015/04/pythonic-matrix-manipulation.html > > > > The first, (and original), code sample: > > > > def cholesky(A): > > L = [[0.0] * len(A) for _ in range(len(A))] > > for i in range(len(A)): > > for j in range(i+1): > > s = sum(L[i][k] * L[j][k] for k in range(j)) > > L[i][j] = sqrt(A[i][i] - s) if (i == j) else \ > > (1.0 / L[j][j] * (A[i][j] - s)) > > return L > > > > > > The second equivalent code sample: > > > > def cholesky2(A): > > L = [[0.0] * len(A) for _ in range(len(A))] > > for i, (Ai, Li) in enumerate(zip(A, L)): > > for j, Lj in enumerate(L[:i+1]): > > s = sum(Li[k] * Lj[k] for k in range(j)) > > Li[j] = sqrt(Ai[i] - s) if (i == j) else \ > > (1.0 / Lj[j] * (Ai[j] - s)) > > return L > > > > > > The third: > > > > def cholesky3(A): > > L = [[0.0] * len(A) for _ in range(len(A))] > > for i, (Ai, Li) in enumerate(zip(A, L)): > > for j, Lj in enumerate(L[:i]): > > #s = fsum(Li[k] * Lj[k] for k in range(j)) > > s = fsum(Lik * Ljk for Lik, Ljk in zip(Li, Lj[:j])) > > Li[j] = (1.0 / Lj[j] * (Ai[j] - s)) > > s = fsum(Lik * Lik for Lik in Li[:i]) > > Li[i] = sqrt(Ai[i] - s) > > return L > > > > My blog post gives a little more explanation, but I have yet to receive any comments on relative Pythonicity. > > I prefer the first version. You're dealing with mathematical formulas > involving matrices here, so subscripting seems appropriate, and > enumerating out rows and columns just feels weird to me. > > That said, I also prefer how the third version pulls the last column > of each row out of the inner loop instead of using a verbose > conditional expression that you already know will be false for every > column except the last one. Do that in the first version, and I think > you've got it. But shouldn't the maths transcend the slight change in representation? A programmer in the J language might have a conceptually neater representation of the same thing due to its grounding in arrays (maybe) and for a J representation it would become J-thonic. In Python, it is usual to iterate over collections and also to use enumerate where we must have indices. Could it be that there is a also a strong pull in the direction of using indices because that is what is predominantly given in the way matrix maths is likely to be expressed mathematically? A case of "TeX likes indices so we should too"?
[toc] | [prev] | [next] | [standalone]
| From | wxjmfauth@gmail.com |
|---|---|
| Date | 2015-04-18 00:08 -0700 |
| Message-ID | <734ce510-16d7-4ccb-9fd1-8e0db646114b@googlegroups.com> |
| In reply to | #89099 |
Le samedi 18 avril 2015 03:19:40 UTC+2, Paddy a écrit :
> Having just seen Raymond's talk on Beyond PEP-8 here: https://www.youtube.com/watch?v=wf-BqAjZb8M, it reminded me of my own recent post where I am soliciting opinions from non-newbies on the relative Pythonicity of different versions of a routine that has non-simple array manipulations.
>
> The blog post: http://paddy3118.blogspot.co.uk/2015/04/pythonic-matrix-manipulation.html
>
> The first, (and original), code sample:
>
> def cholesky(A):
> L = [[0.0] * len(A) for _ in range(len(A))]
> for i in range(len(A)):
> for j in range(i+1):
> s = sum(L[i][k] * L[j][k] for k in range(j))
> L[i][j] = sqrt(A[i][i] - s) if (i == j) else \
> (1.0 / L[j][j] * (A[i][j] - s))
> return L
>
>
> The second equivalent code sample:
>
> def cholesky2(A):
> L = [[0.0] * len(A) for _ in range(len(A))]
> for i, (Ai, Li) in enumerate(zip(A, L)):
> for j, Lj in enumerate(L[:i+1]):
> s = sum(Li[k] * Lj[k] for k in range(j))
> Li[j] = sqrt(Ai[i] - s) if (i == j) else \
> (1.0 / Lj[j] * (Ai[j] - s))
> return L
>
>
> The third:
>
> def cholesky3(A):
> L = [[0.0] * len(A) for _ in range(len(A))]
> for i, (Ai, Li) in enumerate(zip(A, L)):
> for j, Lj in enumerate(L[:i]):
> #s = fsum(Li[k] * Lj[k] for k in range(j))
> s = fsum(Lik * Ljk for Lik, Ljk in zip(Li, Lj[:j]))
> Li[j] = (1.0 / Lj[j] * (Ai[j] - s))
> s = fsum(Lik * Lik for Lik in Li[:i])
> Li[i] = sqrt(Ai[i] - s)
> return L
>
> My blog post gives a little more explanation, but I have yet to receive any comments on relative Pythonicity.
========
def cholesky999(A):
n = len(A)
L = [[0.0] * n for i in range(n)]
for i in range(n):
for j in range(i+1):
s = 0.0
for k in range(j):
s += L[i][k] * L[j][k]
if i == j:
L[i][j] = sqrt(A[i][i] - s)
else:
L[i][j] = (1.0 / L[j][j] * (A[i][j] - s))
return L
Simple, clear, logical, consistant.
[toc] | [prev] | [next] | [standalone]
| From | Paddy <paddy3118@gmail.com> |
|---|---|
| Date | 2015-04-18 01:08 -0700 |
| Message-ID | <23cb60d6-1cdf-4b77-a523-f0b187a49be0@googlegroups.com> |
| In reply to | #89114 |
On Saturday, 18 April 2015 08:09:06 UTC+1, wxjm...@gmail.com wrote: > Le samedi 18 avril 2015 03:19:40 UTC+2, Paddy a écrit : > > Having just seen Raymond's talk on Beyond PEP-8 here: https://www.youtube.com/watch?v=wf-BqAjZb8M, it reminded me of my own recent post where I am soliciting opinions from non-newbies on the relative Pythonicity of different versions of a routine that has non-simple array manipulations. > > > > The blog post: http://paddy3118.blogspot.co.uk/2015/04/pythonic-matrix-manipulation.html > > > > The first, (and original), code sample: > > > > def cholesky(A): > > L = [[0.0] * len(A) for _ in range(len(A))] > > for i in range(len(A)): > > for j in range(i+1): > > s = sum(L[i][k] * L[j][k] for k in range(j)) > > L[i][j] = sqrt(A[i][i] - s) if (i == j) else \ > > (1.0 / L[j][j] * (A[i][j] - s)) > > return L > > > > > > The second equivalent code sample: > > > > def cholesky2(A): > > L = [[0.0] * len(A) for _ in range(len(A))] > > for i, (Ai, Li) in enumerate(zip(A, L)): > > for j, Lj in enumerate(L[:i+1]): > > s = sum(Li[k] * Lj[k] for k in range(j)) > > Li[j] = sqrt(Ai[i] - s) if (i == j) else \ > > (1.0 / Lj[j] * (Ai[j] - s)) > > return L > > > > > > The third: > > > > def cholesky3(A): > > L = [[0.0] * len(A) for _ in range(len(A))] > > for i, (Ai, Li) in enumerate(zip(A, L)): > > for j, Lj in enumerate(L[:i]): > > #s = fsum(Li[k] * Lj[k] for k in range(j)) > > s = fsum(Lik * Ljk for Lik, Ljk in zip(Li, Lj[:j])) > > Li[j] = (1.0 / Lj[j] * (Ai[j] - s)) > > s = fsum(Lik * Lik for Lik in Li[:i]) > > Li[i] = sqrt(Ai[i] - s) > > return L > > > > My blog post gives a little more explanation, but I have yet to receive any comments on relative Pythonicity. > > ======== > > def cholesky999(A): > n = len(A) > L = [[0.0] * n for i in range(n)] > for i in range(n): > for j in range(i+1): > s = 0.0 > for k in range(j): > s += L[i][k] * L[j][k] > if i == j: > L[i][j] = sqrt(A[i][i] - s) > else: > L[i][j] = (1.0 / L[j][j] * (A[i][j] - s)) > return L > > Simple, clear, logical, consistant. And so most Pythonic? Maybe so.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web