* I wrote fluid advection code: How to make this more elegant? @ 2016-01-23 10:00 Arne Babenhauserheide 2016-01-23 11:33 ` Panicz Maciej Godek 2016-01-23 12:42 ` Taylan Ulrich Bayırlı/Kammer 0 siblings, 2 replies; 7+ messages in thread From: Arne Babenhauserheide @ 2016-01-23 10:00 UTC (permalink / raw) To: guile-devel [-- Attachment #1: Type: text/plain, Size: 4745 bytes --] Hi, I just recreated a fluid advection exercise in Guile Scheme and I’m not quite happy with its readability. Can you help me improve it? My main gripe is that the math does not look instantly accessible. The original version was in Python: psi[i] - c1*(psi[i+1] - psi[i-1]) + c2*(psi[i+1] - 2.0*psi[i] + psi[i-1]) My port to Scheme looks like this: (let ((newvalue (+ (- (psir i) (* c1 (- (psir (+ i 1)) (psir (- i 1))))) (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) (psir (- i 1))))))) (array-set! psinew newvalue i)) Liebe Grüße, Arne Here’s the full code: #!/bin/sh # -*- scheme -*- exec guile -e '(@@ (advection) main)' -s "$0" "$@" !# ; Copyright (c) 2015 John Burkardt (original Python), 2016 Corinna ; Hoose (adaption) and 2016 Arne Babenhauserheide (pep8 + Scheme ; version). ; License: LGPL, built on the Python version from 2015 John Burkardt ; and Corinna Hoose. License LGPL. (define-module (advection) #:use-module (ice-9 optargs) ; define* #:use-module (srfi srfi-1) ; iota #:use-module (ice-9 format) #:use-module (ice-9 popen)) (define* (fd1d-advection-lax-wendroff #:key (nx 101) (nt 1000) (c 1)) (let* ((dx (/ 1 (- nx 1))) (x (iota nx 0 (/ 1 nx))) (dt (/ 1 nt)) (c1 (* #e0.5 (* c (/ dt dx)))) (c2 (* 0.5 (expt (* c (/ dt dx)) 2)))) (format #t "CFL condition: dt (~g) ≤ (~g) dx/c\n" dt (/ dx c)) (let ((psi (make-array 0 nx)) (X (make-array 0 nx (+ nt 1))) (Y (make-array 0 nx (+ nt 1))) (Z (make-array 0 nx (+ nt 1)))) (let ((psinew (let ((pn (make-array 0 nx))) (let loop ((i 0)) (cond ((= i nx) pn) (else (let ((xi (list-ref x i))) (when (and (<= 0.4 xi) (<= xi 0.6)) (array-set! pn (* (expt (- (* 10 xi) 4) 2) (expt (- 6 (* 10 xi)) 2)) i)) (loop (+ 1 i))))))))) (define (psir i) (array-ref psi i)) (let loop ((j 0)) (cond ((> j nt) #t) ; done (else (let ((t (/ j nt))) (when (>= j 1) (let ((newvalue (+ (- (psir 0) (* c1 (- (psir 1) (psir (- nx 1))))) (* c2 (+ (- (psir 1) (* 2 (psir 0))) (psir (- nx 1))))))) (array-set! psinew newvalue 0)) (let loop ((i 1)) (when (< i (- nx 1)) (let ((newvalue (+ (- (psir i) (* c1 (- (psir (+ i 1)) (psir (- i 1))))) (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) (psir (- i 1))))))) (array-set! psinew newvalue i)) (loop (+ i 1)))) (let ((newvalue (+ (- (psir (- nx 1)) (* c1 (- (psir 0) (psir (- nx 2))))) (* c2 (+ (- (psir 0) (* 2 (psir (- nx 1)))) (psir (- nx 2))))))) (array-set! psinew newvalue (- nx 1)))) (let loop ((i 0)) (when (< i nx) (array-set! psi (array-ref psinew i) i) (array-set! X (list-ref x i) i j) (array-set! Y t i j) (array-set! Z (psir i) i j) (loop (+ i 1))))) (loop (+ j 1))))) (list X Y Z))))) (define (main args) (display "Hello World!\n") (let ((res (fd1d-advection-lax-wendroff))) (let ((X (list-ref res 0)) (Y (list-ref res 1)) (Z (list-ref res 2))) ; (display Z) (let ((port (open-output-pipe "python"))) (format port "import pylab as pl\n") (format port "y = [[float(j) for j in i] for i in eval('~A'[2:].replace(' ',', '))]\n" Z) (format port "pl.imshow(y)\n") (format port "pl.colorbar()\n") (format port "pl.show()\n") (close-pipe port)))) (newline)) -- Unpolitisch sein heißt politisch sein ohne es zu merken [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 298 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: I wrote fluid advection code: How to make this more elegant? 2016-01-23 10:00 I wrote fluid advection code: How to make this more elegant? Arne Babenhauserheide @ 2016-01-23 11:33 ` Panicz Maciej Godek 2016-01-24 15:04 ` Arne Babenhauserheide 2016-01-23 12:42 ` Taylan Ulrich Bayırlı/Kammer 1 sibling, 1 reply; 7+ messages in thread From: Panicz Maciej Godek @ 2016-01-23 11:33 UTC (permalink / raw) To: Arne Babenhauserheide; +Cc: guile-devel [-- Attachment #1: Type: text/plain, Size: 6568 bytes --] Hi, although I cannot be of immediate help with the topic, because I don't know anything about advection, I think that the main problem with your code is that it is imperative. While Python's stylistics handles the imperative code quite nicely, it looks rather strange in Scheme. From my experience, the proper Scheme solution should resemble the mathematical formulation of a problem (except that it should be more descriptive), rather than a list of steps for solving it. Also, it should be more readable to use patern matching instead of list indexing, so most likely your expression (let ((newvalue (+ (- (psir i) (* c1 (- (psir (+ i 1)) (psir (- i 1))))) (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) (psir (- i 1))))))) (array-set! psinew newvalue i)) should look like this (map (lambda (prev this next) (- this (* c1 (- next prev)) (* (- c2) (+ next (* -2 this) prev)))) `(0 ,@(drop psir 1)) psir `(,@(drop-right psir 1) 0)) While this may also look slightly difficult to read (and write), this isn't solely because of the expression's structure, but because the factors of the expression have no name, and therefore the source code doesn't explain their role (this is the problem of the Python code either, but Python doesn't prompt to fix that) HTH PS I think that this subject fits better to guile-user 2016-01-23 11:00 GMT+01:00 Arne Babenhauserheide <arne_bab@web.de>: > Hi, > > I just recreated a fluid advection exercise in Guile Scheme and I’m not > quite happy with its readability. Can you help me improve it? > > My main gripe is that the math does not look instantly accessible. > > The original version was in Python: > > psi[i] - c1*(psi[i+1] - psi[i-1]) + c2*(psi[i+1] - 2.0*psi[i] + > psi[i-1]) > > My port to Scheme looks like this: > > (let ((newvalue (+ (- (psir i) > (* c1 (- (psir (+ i 1)) (psir (- i 1))))) > (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) > (psir (- i 1))))))) > (array-set! psinew newvalue i)) > > > Liebe Grüße, > Arne > > Here’s the full code: > > #!/bin/sh > # -*- scheme -*- > exec guile -e '(@@ (advection) main)' -s "$0" "$@" > !# > > ; Copyright (c) 2015 John Burkardt (original Python), 2016 Corinna > ; Hoose (adaption) and 2016 Arne Babenhauserheide (pep8 + Scheme > ; version). > > ; License: LGPL, built on the Python version from 2015 John Burkardt > ; and Corinna Hoose. License LGPL. > > (define-module (advection) > #:use-module (ice-9 optargs) ; define* > #:use-module (srfi srfi-1) ; iota > #:use-module (ice-9 format) > #:use-module (ice-9 popen)) > > > (define* (fd1d-advection-lax-wendroff #:key (nx 101) (nt 1000) (c 1)) > (let* ((dx (/ 1 (- nx 1))) > (x (iota nx 0 (/ 1 nx))) > (dt (/ 1 nt)) > (c1 (* #e0.5 (* c (/ dt dx)))) > (c2 (* 0.5 (expt (* c (/ dt dx)) 2)))) > (format #t "CFL condition: dt (~g) ≤ (~g) dx/c\n" dt (/ dx c)) > (let ((psi (make-array 0 nx)) > (X (make-array 0 nx (+ nt 1))) > (Y (make-array 0 nx (+ nt 1))) > (Z (make-array 0 nx (+ nt 1)))) > (let ((psinew (let ((pn (make-array 0 nx))) > (let loop ((i 0)) > (cond ((= i nx) > pn) > (else > (let ((xi (list-ref x i))) > (when (and (<= 0.4 xi) (<= xi 0.6)) > (array-set! pn > (* (expt (- (* 10 xi) 4) 2) > (expt (- 6 (* 10 xi)) 2)) > i)) > (loop (+ 1 i))))))))) > (define (psir i) (array-ref psi i)) > (let loop ((j 0)) > (cond > ((> j nt) #t) ; done > (else > (let ((t (/ j nt))) > (when (>= j 1) > (let ((newvalue (+ (- (psir 0) > (* c1 (- (psir 1) > (psir (- nx 1))))) > (* c2 (+ (- (psir 1) > (* 2 (psir 0))) > (psir (- nx 1))))))) > (array-set! psinew newvalue 0)) > (let loop ((i 1)) > (when (< i (- nx 1)) > (let ((newvalue (+ (- (psir i) > (* c1 (- (psir (+ i 1)) (psir (- > i 1))))) > (* c2 (+ (- (psir (+ i 1)) (* 2 > (psir i))) > (psir (- i 1))))))) > (array-set! psinew newvalue i)) > (loop (+ i 1)))) > (let ((newvalue (+ (- (psir (- nx 1)) > (* c1 (- (psir 0) (psir (- nx 2))))) > (* c2 (+ (- (psir 0) (* 2 (psir (- nx > 1)))) > (psir (- nx 2))))))) > (array-set! psinew newvalue (- nx 1)))) > (let loop ((i 0)) > (when (< i nx) > (array-set! psi (array-ref psinew i) i) > (array-set! X (list-ref x i) i j) > (array-set! Y t i j) > (array-set! Z (psir i) i j) > (loop (+ i 1))))) > (loop (+ j 1))))) > (list X Y Z))))) > > (define (main args) > (display "Hello World!\n") > (let ((res (fd1d-advection-lax-wendroff))) > (let ((X (list-ref res 0)) > (Y (list-ref res 1)) > (Z (list-ref res 2))) > ; (display Z) > (let ((port (open-output-pipe "python"))) > (format port "import pylab as pl\n") > (format port "y = [[float(j) for j in i] for i in > eval('~A'[2:].replace(' ',', '))]\n" Z) > (format port "pl.imshow(y)\n") > (format port "pl.colorbar()\n") > (format port "pl.show()\n") > (close-pipe port)))) > (newline)) > > > -- > Unpolitisch sein > heißt politisch sein > ohne es zu merken > [-- Attachment #2: Type: text/html, Size: 8430 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: I wrote fluid advection code: How to make this more elegant? 2016-01-23 11:33 ` Panicz Maciej Godek @ 2016-01-24 15:04 ` Arne Babenhauserheide 0 siblings, 0 replies; 7+ messages in thread From: Arne Babenhauserheide @ 2016-01-24 15:04 UTC (permalink / raw) To: Panicz Maciej Godek; +Cc: Arne Babenhauserheide, guile-devel [-- Attachment #1: Type: text/plain, Size: 2363 bytes --] Panicz Maciej Godek writes: > although I cannot be of immediate help with the topic, because I don't know > anything about advection, I think that the main problem with your code is > that it is imperative. While Python's stylistics handles the imperative > code quite nicely, it looks rather strange in Scheme. > > From my experience, the proper Scheme solution should resemble the > mathematical formulation of a problem (except that it should be more > descriptive), rather than a list of steps for solving it. That’s a good point — I should have given the mathematical formulation along with the code. The advection equation this implements is: (φ_j,n+1 - φ_j,n)/Δt + c(φ_j+1,n - φ_j-1,n)/2Δx - (c² Δt/Δx) * (φ_j+1,n - 2φ_j,n + φ_j-1,n) / 2Δx = 0 [sadly this isn’t easy to read, either, but it’s the math which needs implementation] > Also, it should be more readable to use pattern matching instead of list > indexing, so most likely your expression > > (let ((newvalue (+ (- (psir i) > (* c1 (- (psir (+ i 1)) (psir (- i 1))))) > (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) > (psir (- i 1))))))) > (array-set! psinew newvalue i)) > > should look like this > > (map (lambda (prev this next) > (- this > (* c1 (- next prev)) > (* (- c2) (+ next (* -2 this) prev)))) > `(0 ,@(drop psir 1)) > psir > `(,@(drop-right psir 1) 0)) > > While this may also look slightly difficult to read (and write), I think it already helps a lot, that this is shorter (prev this next clearly wins against (+/- i 1)). > this isn't solely because of the expression's structure, but because > the factors of the expression have no name, and therefore the source > code doesn't explain their role (this is the problem of the Python > code either, but Python doesn't prompt to fix that) that part is already in the math, but using variables with better names sounds like an improvement. Thank you! > PS I think that this subject fits better to guile-user You’re right — sorry. I’m still spoiled by projects where exactly one mailing list is active… Best wishes, Arne -- Unpolitisch sein heißt politisch sein ohne es zu merken [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 298 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: I wrote fluid advection code: How to make this more elegant? 2016-01-23 10:00 I wrote fluid advection code: How to make this more elegant? Arne Babenhauserheide 2016-01-23 11:33 ` Panicz Maciej Godek @ 2016-01-23 12:42 ` Taylan Ulrich Bayırlı/Kammer 2016-01-24 17:21 ` Nala Ginrut 2016-01-24 17:24 ` Arne Babenhauserheide 1 sibling, 2 replies; 7+ messages in thread From: Taylan Ulrich Bayırlı/Kammer @ 2016-01-23 12:42 UTC (permalink / raw) To: Arne Babenhauserheide; +Cc: guile-devel Arne Babenhauserheide <arne_bab@web.de> writes: > Hi, > > I just recreated a fluid advection exercise in Guile Scheme and I’m not > quite happy with its readability. Can you help me improve it? > > My main gripe is that the math does not look instantly accessible. > > The original version was in Python: > > psi[i] - c1*(psi[i+1] - psi[i-1]) + c2*(psi[i+1] - 2.0*psi[i] + psi[i-1]) > > My port to Scheme looks like this: > > (let ((newvalue (+ (- (psir i) > (* c1 (- (psir (+ i 1)) (psir (- i 1))))) > (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) > (psir (- i 1))))))) > (array-set! psinew newvalue i)) Guile supports SRFI-105, so that could be: {{psi[i] - {c1 * {psi[{i + 1}] - psi[{i - 1}]}}} + {c2 * {{psi[{i + 1}] - {2 * psi[i]}} + psi[{i - 1}]}}} which is less readable than the Python version because there's no first-hand support for operator precedence so we {} group all binary operations, plus we need to use {} within [], plus we must separate operators with whitespace, but maybe it's acceptable. You can put "#!curly-infix" at the start of your Scheme file to enable SRFI-105 syntax. Note that all those 'psi[x]' expressions will expand to ($bracket-apply$ psi x) and you can implement a macro of that name to turn that into whatever is suitable at compile-time. (If performance is not an issue, SRFI-123 provides a run-time polymorphic procedure for $bracket-access$.) With a smart definition of $bracket-apply$, you could also cut down those psi[{i + 1}] to psi[i + 1]. The latter will expand to ($bracket-apply$ psi i + 1) which could be accommodated for in a special-purpose definition of $bracket-apply$ such as: (syntax-rules () ((_ obj index) (obj index)) ((_ obj x operator y) (obj (operator x y)))) That would *not* support e.g. psi[i + j - 1], which would instead need to be written e.g. psi[{i + j} - 1], i.e. we only save one pair of {}, but maybe that's good enough. By the way, e.g. {x - y + z} will turn into ($nfx$ x - y + z), and maybe there's a definition for $nfx$ out in the wild (or you can create one) that does operator precedence. (That could then also be used in $bracket-apply$.) So optimally, the whole thing could become: {psi[i] - c1 * {psi[i + 1] - psi[i - 1]} + c2 * {psi[i + 1] - 2 * psi[i] + psi[i - 1]}} Taylan ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: I wrote fluid advection code: How to make this more elegant? 2016-01-23 12:42 ` Taylan Ulrich Bayırlı/Kammer @ 2016-01-24 17:21 ` Nala Ginrut 2016-01-24 17:24 ` Arne Babenhauserheide 1 sibling, 0 replies; 7+ messages in thread From: Nala Ginrut @ 2016-01-24 17:21 UTC (permalink / raw) To: Taylan Ulrich Bayırlı/Kammer; +Cc: Arne Babenhauserheide, guile-devel The math formula may take advantage of sweet expression which is contained in the current Guile reader, IIRC. One may give it a try? On Sat, 2016-01-23 at 13:42 +0100, Taylan Ulrich Bayırlı/Kammer wrote: > Arne Babenhauserheide <arne_bab@web.de> writes: > > > Hi, > > > > I just recreated a fluid advection exercise in Guile Scheme and I’m not > > quite happy with its readability. Can you help me improve it? > > > > My main gripe is that the math does not look instantly accessible. > > > > The original version was in Python: > > > > psi[i] - c1*(psi[i+1] - psi[i-1]) + c2*(psi[i+1] - 2.0*psi[i] + psi[i-1]) > > > > My port to Scheme looks like this: > > > > (let ((newvalue (+ (- (psir i) > > (* c1 (- (psir (+ i 1)) (psir (- i 1))))) > > (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) > > (psir (- i 1))))))) > > (array-set! psinew newvalue i)) > > Guile supports SRFI-105, so that could be: > > {{psi[i] - {c1 * {psi[{i + 1}] - psi[{i - 1}]}}} + {c2 * {{psi[{i + 1}] - {2 * psi[i]}} + psi[{i - 1}]}}} > > which is less readable than the Python version because there's no > first-hand support for operator precedence so we {} group all binary > operations, plus we need to use {} within [], plus we must separate > operators with whitespace, but maybe it's acceptable. > > You can put "#!curly-infix" at the start of your Scheme file to enable > SRFI-105 syntax. > > Note that all those 'psi[x]' expressions will expand to > > ($bracket-apply$ psi x) > > and you can implement a macro of that name to turn that into whatever is > suitable at compile-time. (If performance is not an issue, SRFI-123 > provides a run-time polymorphic procedure for $bracket-access$.) > > With a smart definition of $bracket-apply$, you could also cut down > those psi[{i + 1}] to psi[i + 1]. The latter will expand to > > ($bracket-apply$ psi i + 1) > > which could be accommodated for in a special-purpose definition of > $bracket-apply$ such as: > > (syntax-rules () > ((_ obj index) > (obj index)) > ((_ obj x operator y) > (obj (operator x y)))) > > That would *not* support e.g. psi[i + j - 1], which would instead need > to be written e.g. psi[{i + j} - 1], i.e. we only save one pair of {}, > but maybe that's good enough. > > By the way, e.g. {x - y + z} will turn into ($nfx$ x - y + z), and maybe > there's a definition for $nfx$ out in the wild (or you can create one) > that does operator precedence. (That could then also be used in > $bracket-apply$.) So optimally, the whole thing could become: > > {psi[i] - c1 * {psi[i + 1] - psi[i - 1]} + c2 * {psi[i + 1] - 2 * psi[i] + psi[i - 1]}} > > Taylan > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: I wrote fluid advection code: How to make this more elegant? 2016-01-23 12:42 ` Taylan Ulrich Bayırlı/Kammer 2016-01-24 17:21 ` Nala Ginrut @ 2016-01-24 17:24 ` Arne Babenhauserheide 2016-01-24 17:46 ` Taylan Ulrich Bayırlı/Kammer 1 sibling, 1 reply; 7+ messages in thread From: Arne Babenhauserheide @ 2016-01-24 17:24 UTC (permalink / raw) To: Taylan Ulrich Bayırlı/Kammer Cc: Arne Babenhauserheide, David A Wheeler, guile-devel [-- Attachment #1: Type: text/plain, Size: 2347 bytes --] Taylan Ulrich Bayırlı/Kammer writes: > Arne Babenhauserheide <arne_bab@web.de> writes: >> The original version was in Python: >> >> psi[i] - c1*(psi[i+1] - psi[i-1]) + c2*(psi[i+1] - 2.0*psi[i] + psi[i-1]) >> >> My port to Scheme looks like this: >> >> (let ((newvalue (+ (- (psir i) >> (* c1 (- (psir (+ i 1)) (psir (- i 1))))) >> (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) >> (psir (- i 1))))))) >> (array-set! psinew newvalue i)) > > Guile supports SRFI-105, so that could be: > > {{psi[i] - {c1 * {psi[{i + 1}] - psi[{i - 1}]}}} + {c2 * {{psi[{i + 1}] - {2 * psi[i]}} + psi[{i - 1}]}}} That’s already pretty close — I wonder why I didn’t think of the psi[i] form. I think a + around the equation would actually help here: (+ psi[i] (* -1 c1 {psi[{i + 1}] - psi[{i - 1}]}) (* c2 {{psi[{i + 1}] - {2 * psi[i]}} + psi[{i - 1}]})) Though neoteric expressions combined with curly infix make this even easier: p{i + 1} → (p (+ i 1)) (though this did not work for me in the REPL right now — did I miss something?) So the function psir could be used to have elegant access to elements: (+ psi[i] (* -1 c1 {psi[{i + 1}] - psi[{i - 1}]}) (* c2 {{psi[{i + 1}] - {2 * psi[i]}} + psi[{i - 1}]})) > {psi[i] - c1 * {psi[i + 1] - psi[i - 1]} + c2 * {psi[i + 1] - 2 * psi[i] + psi[i - 1]}} That looks roughly as readable as the Python version. With the + around I think it becomes better: (+ psi[i] (* -1 c1 {psi[i + 1] - psi[i - 1]}) (* c2 {{psi[i + 1] - {2 * psi[i]}} + psi[i - 1]})) And I don’t think it’s worse than the Python version, because in Python I also need to first import numpy which changes some semantics (the [] operator changes and arrays have some special properties which can sometimes bite). Besides: when working on the Python, I was tempted to bracket the expression to make it easier to split the lines and make the boundary between sub-expressions clearer: (psi[i] - c1*(psi[i+1] - psi[i-1]) + c2*(psi[i+1] - 2.0*psi[i] + psi[i-1])) Best wishes, Arne PS: CCed to David A. Wheeler who wrote SRFI-105. -- Unpolitisch sein heißt politisch sein ohne es zu merken [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 298 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: I wrote fluid advection code: How to make this more elegant? 2016-01-24 17:24 ` Arne Babenhauserheide @ 2016-01-24 17:46 ` Taylan Ulrich Bayırlı/Kammer 0 siblings, 0 replies; 7+ messages in thread From: Taylan Ulrich Bayırlı/Kammer @ 2016-01-24 17:46 UTC (permalink / raw) To: Arne Babenhauserheide; +Cc: guile-devel Arne Babenhauserheide <arne_bab@web.de> writes: > Taylan Ulrich Bayırlı/Kammer writes: >> Arne Babenhauserheide <arne_bab@web.de> writes: >>> The original version was in Python: >>> >>> psi[i] - c1*(psi[i+1] - psi[i-1]) + c2*(psi[i+1] - 2.0*psi[i] + psi[i-1]) >>> >>> My port to Scheme looks like this: >>> >>> (let ((newvalue (+ (- (psir i) >>> (* c1 (- (psir (+ i 1)) (psir (- i 1))))) >>> (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) >>> (psir (- i 1))))))) >>> (array-set! psinew newvalue i)) >> >> Guile supports SRFI-105, so that could be: >> >> {{psi[i] - {c1 * {psi[{i + 1}] - psi[{i - 1}]}}} + {c2 * {{psi[{i + 1}] - {2 * psi[i]}} + psi[{i - 1}]}}} > > That’s already pretty close — I wonder why I didn’t think of the psi[i] > form. > > I think a + around the equation would actually help here: > > (+ psi[i] > (* -1 c1 {psi[{i + 1}] - psi[{i - 1}]}) > (* c2 {{psi[{i + 1}] - {2 * psi[i]}} + psi[{i - 1}]})) > > Though neoteric expressions combined with curly infix make this even > easier: p{i + 1} → (p (+ i 1)) Good call, I had forgotten that's included in SRFI 105. (Thought it was just for x[y].) > (though this did not work for me in the REPL right now — did I miss something?) Any SRFI 105 syntax must appear within {}, so that would have to be e.g. {p{i + 1}}, although if it appears within a larger {} block then it won't have that annoyance. > So the function psir could be used to have elegant access to elements: > > (+ psi[i] > (* -1 c1 {psi[{i + 1}] - psi[{i - 1}]}) > (* c2 {{psi[{i + 1}] - {2 * psi[i]}} + psi[{i - 1}]})) > >> {psi[i] - c1 * {psi[i + 1] - psi[i - 1]} + c2 * {psi[i + 1] - 2 * psi[i] + psi[i - 1]}} > > That looks roughly as readable as the Python version. With the + around > I think it becomes better: > > (+ psi[i] > (* -1 c1 {psi[i + 1] - psi[i - 1]}) > (* c2 {{psi[i + 1] - {2 * psi[i]}} + psi[i - 1]})) I agree mixing in some prefix notation actually makes things more readable here. Taylan ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-01-24 17:46 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-01-23 10:00 I wrote fluid advection code: How to make this more elegant? Arne Babenhauserheide 2016-01-23 11:33 ` Panicz Maciej Godek 2016-01-24 15:04 ` Arne Babenhauserheide 2016-01-23 12:42 ` Taylan Ulrich Bayırlı/Kammer 2016-01-24 17:21 ` Nala Ginrut 2016-01-24 17:24 ` Arne Babenhauserheide 2016-01-24 17:46 ` Taylan Ulrich Bayırlı/Kammer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).