Paste: n-dimensional gradient

Author: triliyn
Mode: factor
Date: Mon, 16 Jul 2012 07:14:30
Plain Text |
! return a dim-dimensional basis vector corresponding to the nth dimension
: (basis) ( n dim -- v ) [ 0 ] replicate [ 1 ] 2dip [ set-nth ] keep ;

! return a list of all basis vectors
: (bases) ( dim -- {v} ) [ iota ] keep [ (basis) ] curry map ;

! compute the gradient of a scalar field at a point
: (grad) ( quot: ( loc -- field ) step loc -- v )
  [ dup ] dip 
  [ length (bases) swap [ v*n ] curry map ] [ [ v+ ] curry map ] [ ] tri
  [ swap ] 2dip pick call [ swap map ] dip [ - ] curry map swap v/n ; inline

: grad ( quot: ( loc -- field ) loc -- v ) 0.01 swap (grad) ; inline

Annotation: haskellised

Author: lukeworth
Mode: haskell
Date: Mon, 16 Jul 2012 09:52:04
Plain Text |
The same code in haskell

basis' dim n = replicate n 0 ++ [1] ++ replicate (dim - n - 1) 0
bases' dim = map (basis' dim) [0..dim-1]
grad' step quot loc = (/ step) <$> subtract (quot loc) <$> quot <$> zipWith (+) loc <$> fmap (* step) <$> bases' (length loc)
grad = grad' 0.01
   

Annotation: re-factored (heh, get it?)

Author: lukeworth
Mode: factor
Date: Mon, 16 Jul 2012 11:52:50
Plain Text |
Sorry for wrong language, I saw a challenge and took it. Here is the code converted back to factor, and much easier to read than the original IMO. (Concatenative programming is hard to read).

:: (basis) ( dim n -- v )
   [ 1 ]
   n
   dim [ 0 ] replicate
   [ set-nth ] keep ;

:: (bases) ( dim -- {v} )
   dim iota
   [ dim basis ] map ;

:: (grad) ( quot: ( loc -- field ) step loc -- v )
   loc length (bases)
   [ step v*n ] map
   [ loc v+ ] map
   quot
   loc quot -
   step / ;

:: grad ( quot: ( loc -- field ) loc -- v ) quot 0.01 loc (grad) ;

Annotation: Thanks!

Author: triliyn
Mode: factor
Date: Mon, 16 Jul 2012 16:28:48
Plain Text |
I should have thought of using local variables. I am trying to avoid them because it's more fun to read and write that way, but (grad) kinda needs them if not the others.

I think you made a couple minor mistakes: in (bases) you call basis instead of (basis), and in (grad) I think you need to call the quotes (i.e. "loc quot call" instead of "loc quot").

After that correction though I will definitely be using your (grad) code. Thanks!

New Annotation

Summary:
Author:
Mode:
Body: