[plt-scheme] random walk

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Fri May 29 12:23:15 EDT 2009

Do you want this function? I don't see the need for a macro.

#lang scheme

;; Nat Nat -> Nat
;; compute L2 distance for all random walks of depth dpt in n-space
(define (walk n depth)
   (define O (make-vector n 0))
   (define Ds (deltas n))
   (let step ((ld 0) (p O))
     (if (>= ld depth)
         (L2 p)
         (apply + (map (lambda (d) (step (+ ld 1) (v+ p d))) Ds)))))

;; (Vectorof Nat) -> Nat
(define (L2 p)
   (apply + (map sqr (vector->list p))))

;; Nat -> (Listof (Vectorof {0|+1|-1}))
(define (deltas n)
   (define (mk+1 i) (lambda (j) (if (= i j) +1 0)))
   (define (mk-1 i) (lambda (j) (if (= i j) -1 0)))
   (apply append
          (build-list n (lambda (i)
                          (list (build-vector n (mk+1 i))
                                (build-vector n (mk-1 i)))))))

;; (Vectorof Nat) (Vector Nat) -> (Vector Nat)
(define (v+ u v)
   ;; I am sure there's some for/vector somewhere, I can't find it
   (list->vector (for/list ((x u) (y v)) (+ x y))))

;;  
------------------------------------------------------------------------ 
-----
(require test-engine/scheme-tests)

;; deltas
(check-expect (deltas 0) '())
(check-expect (deltas 1) (list (vector +1) (vector -1)))
(check-expect
  (deltas 2) (list (vector +1 0) (vector -1 0) (vector 0 +1) (vector  
0 -1)))

;; v+
(check-expect (v+ #3(2 3 0) #3(-1 0 0)) #3(1 3 0))

;; L2
(check-expect (L2 #3(2 3 0)) 13)

;; walk:
;; add your favorite test here

(test)




On May 29, 2009, at 11:08 AM, Marijn Schouten (hkBst) wrote:

> Hi,
>
> I'm trying to write a macro that writes a function that sums the L2- 
> lengths of
> all (random) walks of depth d on a square grid of dimension DIM. In  
> dimension 2
> that function should look like this:
>
>
> (define (walk depth)
>   (let step ((d 0) (x 0) (y 0) #;(z 0))
>     (cond ((< d depth)
> 	   (let ((d+1 (+ d 1)))
> 	     (+
> 	      (step d+1 (+ x 1) y)
> 	      (+
> 	       (step d+1 (- x 1) y)
> 	       (+ (step d+1 x (+ y 1))
> 	          (step d+1 x (- y 1))) ))))
> 	  (else
> 	   (+ (* x x) (* y y)) ) )))
>
>
> (walk d) starts at the origin, (x,y) = (0,0), and recursively walks  
> a step in
> all 2DIM directions, returning the L2-length when depth d is  
> reached and summing
> all those lengths. It is not hard to prove that (walk depth) is  
> equal to (expt
> (* 2 (DIM)) depth) but this random walk length summer is only the  
> starting point
> for doing more interesting things.
>
> I'm looking for a macro that will write the `walk' function given  
> the dimension.
>
> Attached is an attempt that I cannot seem to get working.
>
> Thanks,
>
> Marijn
>
>
> -- 
> If you cannot read my mind, then listen to what I say.
>
> Marijn Schouten (hkBst), Gentoo Lisp project, Gentoo ML
> <http://www.gentoo.org/proj/en/lisp/>, #gentoo-{lisp,ml} on FreeNode
> ; $ gsi -:s stripped-randomwalk -e "(main 10)"
> ; $ mzscheme -e '(require (rename-in scheme (syntax->datum syntax- 
> object->datum)))' -f stripped-randomwalk.scm -e "(main 10)"
>
> (define-syntax DIM
>   (syntax-rules ()
>     ((DIM) 2)))
> ;    ((DIM) 3)))
>
> ;;; (reduce-map unit reducer mapper list)
> ;;; (reduce-map u r m '()) |-> u
> ;;; (reduce-map u r m l) |-> (reduce u r (map m l))
> (define-syntax macro-reduce-map
>   (syntax-rules ()
>     ((_ u r m) u)
>     ((_ u r m a b ...)
>      (r (m a)
> 	(macro-reduce-map u r m b ...)))))
>
> (define-syntax L2-norm
>   (syntax-rules ()
>     ((_ a ...) (macro-reduce-map 0 + (lambda (e) (* e e)) a ...))))
>
> (define (main depth)
> ;  (pp (/ (walk-f depth) (expt (* 2 (DIM)) depth)))
>   (pp (/ (walk depth) (expt (* 2 (DIM)) depth)))
> )
>
> (define (walk depth)
>   (let-syntax
>       ((step
> 	(lambda (x)
> 	  (syntax-case x ()
> 	    ((_)
> 	     (letrec ((vector-map (lambda (f v)
> 				    (let* ((l (vector-length v))
> 					   (ret (make-vector l)))
> 				      (let loop ((i 0))
> 					(cond ((= i l) ret)
> 					      (else (vector-set! ret i (f (vector-ref v i) i))
> 						    (loop (+ i 1))))))))
> 		      (make-next-coords (lambda (names pos inc)
> 					  (if (= pos 0)
> 					      (cons `(,+ ,(car names) ,inc) (cdr names))
> 					      (cons (car names) (make-next-coords (cdr names) (- pos  
> 1) inc))))))
> 	       (with-syntax (((d) (generate-temporaries (list 'd)))
> 			      (coords (generate-temporaries (vector->list (make-vector  
> (DIM))))))
> 	         (with-syntax ((next #'(vector->list (let ((next-v (make- 
> vector (* 2 (DIM)))))
> 						   (vector-map (lambda (e i) (make-next-coords #'coords  
> (modulo i (DIM)) (if (< i (DIM)) +1 -1))) next-v)))))
> 		   (with-syntax ((bindings #'(map (lambda (e) (list e 0)) (cons d  
> coords)))
> 				 ((d+1) (generate-temporaries (list 'd+1)))
> 				 ((%step) (generate-temporaries (list '%step))) )
> 		     #`(let %step bindings
> 			 (cond ((< d depth)
> 				(let* ((d+1 (fx+ d 1)))
> 				  #,(with-syntax ((d+1&next (map (lambda (l) (cons #'d+1 l))  
> #'next)))
> 				      (macro-reduce-map 0 + #'%step #'d+1&next))))
> 			       (else (L2-norm coords)) ))  )))))))))
>     (step)))
>
> ;;; what walk should look like for dimension 2
> (define (walk-f depth)
>   (let step ((d 0) (x 0) (y 0) #;(z 0))
>     (cond ((< d depth)
> 	   (let ((d+1 (+ d 1)))
> 	     (+
> 	      (step d+1 (+ x 1) y)
> 	      (+
> 	       (step d+1 (- x 1) y)
> 	       (+ (step d+1 x (+ y 1))
> 		       (step d+1 x (- y 1))) ))))
> 	  (else
> 	   (L2-norm x y)))))
>
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme



Posted on the users mailing list.