Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Scheme code for getting unit vector

4 views
Skip to first unread message

Xah Lee

unread,
Dec 11, 2008, 2:38:17 PM12/11/08
to
recently there's a fun implementation for a function that returns the
unit vector of a given vector in any dimension.

Various people has given code in Mathematica, scheme, java, c,
javascript, python, ruby...

One of them is:

;; Chicken Scheme. By the.brown.dragon...@gmail.com
(require 'srfi-1)
(define (normalize vec)
(map (cute / <> (sqrt (reduce + 0 (map (cute expt <> 2) vec))))
vec))

i don't have experience coding Scheme lisp. Is it possible to make
this work in scsh? (i'm running scsh 0.6.4) Also, what kinda lib is
srfi-1? I imagine it is possible to do without it and still having
elegant code?

Thanks.

The various code can be seen at bottom of:
http://xahlee.org/UnixResource_dir/writ/Mathematica_expressiveness.html

Xah
http://xahlee.org/


Jens Axel Soegaard

unread,
Dec 11, 2008, 3:26:58 PM12/11/08
to
Xah Lee skrev:

> ;; Chicken Scheme. By the.brown.dragon...@gmail.com
> (require 'srfi-1)
> (define (normalize vec)
> (map (cute / <> (sqrt (reduce + 0 (map (cute expt <> 2) vec))))
> vec))

A few solutions in PLT Scheme. The last one is the prettiest.


#lang scheme
(require srfi/26 srfi/42)

(define v '(1 0 -1))

; the solution from c.l.s
(map (cute / <> (sqrt (foldl + 0 (map sqr v)))) v)

; without cute
(map (λ (x) (/ x (sqrt (foldl + 0 (map sqr v))))) v)


; without foldl
(map (λ (x) (/ x (sqrt (sum-ec (: x v) (sqr x))))) v)


; add spice
(define (swap f) (λ (x y) (f y x)))
(map ((curry (swap /)) (sqrt (foldl + 0 (map sqr v)))) v)
(map ((curry (swap /)) (sqrt (sum-ec (: x v) (sqr x)))) v)


; better primitives
(define (sum v) (foldl + 0 v))
(define (scale c v) (map (λ (x) (* c x)) v))
(define (inv x) (/ x))

; final result
(scale (inv (sqrt (sum (map sqr v)))) v)

; well, even better
(define (norm x) (sqrt (sum (map sqr v))))
(scale (inv (norm v)) v)


--
Jens Axel Søgaard

Bakul Shah

unread,
Dec 11, 2008, 3:35:57 PM12/11/08
to

In standard Scheme:

(define (normalize vec)
(let ((d (sqrt (apply + (map (lambda (x) (* x x)) vec)))))
(map (lambda (x) (/ x d)) vec)))
; test in gambit v4
> (normalize '(1 1 1 1))
(1/2 1/2 1/2 1/2)
> (normalize '(20 20 20 20))
(1/2 1/2 1/2 1/2)

BTW, Xah, you seem to have missed my post where I show a
Q implementation! Here it is again (this time I name the
function and its argument):

normalize:{[vec] vec%sqrt sum vec*vec}

Test:
q)normalize 1 1 1 1
0.5 0.5 0.5 0.5
q)normalize 20 20 20 20
0.5 0.5 0.5 0.5

Andrew Reilly

unread,
Dec 11, 2008, 4:15:00 PM12/11/08
to
On Thu, 11 Dec 2008 11:38:17 -0800, Xah Lee wrote:

> recently there's a fun implementation for a function that returns the
> unit vector of a given vector in any dimension.
>
> Various people has given code in Mathematica, scheme, java, c,
> javascript, python, ruby...

Here's an easy one in matlab (actually octave):
function u = unit(a)
u = a./norm(a)
end

Using a domain-specific language intended for numerical computation is
probably cheating, though.

Cheers,

--
Andrew

Tamas K Papp

unread,
Dec 11, 2008, 4:25:21 PM12/11/08
to
On Thu, 11 Dec 2008 21:15:00 +0000, Andrew Reilly wrote:

> Here's an easy one in matlab (actually octave): function u = unit(a)
> u = a./norm(a)
> end
>
> Using a domain-specific language intended for numerical computation is
> probably cheating, though.

Given that the whole exercise of collecting variants of this extremely
simple function in many languages is pretty pointless, I don't see how
this is cheating.

Tamas

Jussi Piitulainen

unread,
Dec 11, 2008, 4:44:24 PM12/11/08
to
Bakul Shah writes:

> In standard Scheme:
>
> (define (normalize vec)
> (let ((d (sqrt (apply + (map (lambda (x) (* x x)) vec)))))
> (map (lambda (x) (/ x d)) vec)))

I tend to write (map * vec vec) for the squares.

aug...@darksim.com

unread,
Dec 12, 2008, 4:03:44 PM12/12/08
to
On Dec 11, 2:44 pm, Jussi Piitulainen <jpiit...@ling.helsinki.fi>
wrote:

> I tend to write (map * vec vec) for the squares.

As a newbie checking out CL for possible use in future product
development, I'm interested in seeing the fastest possible version of
normalizing a 3 element float vector. I'm loving CL so far but still
don't have a good handle on optimization techniques.

Xah Lee

unread,
Dec 25, 2008, 6:10:25 AM12/25/08
to
Xah Lee wrote:
> recently there's a fun implementation for a function that returns the
> unit vector of a given vector in any dimension.

On Dec 11, 12:35 pm, Bakul Shah wrote:
> In standard Scheme:
>
> (define (normalize vec)
> (let ((d (sqrt (apply + (map (lambda (x) (* x x)) vec)))))
> (map (lambda (x) (/ x d)) vec)))
> ; test in gambit v4
> > (normalize '(1 1 1 1))
> (1/2 1/2 1/2 1/2)
> > (normalize '(20 20 20 20))
> (1/2 1/2 1/2 1/2)

Thanks. I tested it in scsh and it works.
I've put your code up.

> BTW, Xah, you seem to have missed my post where I show a
> Q implementation! Here it is again (this time I name the
> function and its argument):
>
> normalize:{[vec] vec%sqrt sum vec*vec}

Q? is that the term rewriting lang?
http://en.wikipedia.org/wiki/Q_(programming_language)

not sure i want to include langs where only few people heard of.

currently, the javascript example there is considered broken by me.
(it is syntax error in SpiderMonkey engine “JavaScript-C 1.7.0
2007-10-03”)

The C code by John W Kennedy there also considered broken. It needs to
be a full, runnable program that print result.

Xah
http://xahlee.org/


William James

unread,
Feb 24, 2009, 4:02:21 AM2/24/09
to
Xah Lee wrote:

> > In standard Scheme:
> >
> > (define (normalize vec)
> > (let ((d (sqrt (apply + (map (lambda (x) (* x x)) vec)))))
> > (map (lambda (x) (/ x d)) vec)))
> > ; test in gambit v4
> > > (normalize '(1 1 1 1))
> > (1/2 1/2 1/2 1/2)
> > > (normalize '(20 20 20 20))
> > (1/2 1/2 1/2 1/2)

Clojure:

(defn normalize [vec]
(let [div (Math/sqrt (reduce + (map * vec vec)))]
(map #(/ % div) vec)))

0 new messages