Vector Normalize Function in Mathematica, APL, Haskell, Ruby, Python, Perl, Lisp, JavaScript, Java, …

, , …,

This pages demonstrates the power of Mathematica language, by a example of writing a math vector normalize function, together with implementation in other languages.

Let's say for example, we want to write a function that takes a vector (of linear algebra), and return a vector in the same direction but with length 1. In linear algebra terminology, the new vector is called the “normalized” vector of the original.

Let's say we are working with 3-dimensional vectors. This means, we want a function whose input is a list of 3 elements say {x,y,z}, and output is also a list of 3 elements, say {a,b,c}, with the condition that:

a = x/Sqrt[x^2+y^2+z^2]
b = y/Sqrt[x^2+y^2+z^2]
c = z/Sqrt[x^2+y^2+z^2]

Example:

In[1]:= Normalize[{1, 1, 1}]

Out[1]= {1/Sqrt[3], 1/Sqrt[3], 1/Sqrt[3]}

In[2]:= Normalize[{1, 1, 1, 1}]

Out[2]= {1/2, 1/2, 1/2, 1/2}

In Mathematica, this can be defined like this:

normalize = Function[#/Sqrt@(Plus@@(#^2))]

The beauty of this line is that it works for vectors of any dimension, i.e. list of any length.

Here's a sample call and output:

In[2]:= normalize[{1, 1, 1}]

Out[2]= {1/Sqrt[3], 1/Sqrt[3], 1/Sqrt[3]}

In[3]:= normalize[{1, 1, 1.}]

Out[3]= {0.57735, 0.57735, 0.57735}

How Does it Work?

Here i explain how it is so succinct.

In normalize = Function[#/Sqrt@(Plus@@(#^2))], the “Function” is lisper's “lambda”. The # is the first formal parameter (the first argument). We assign a function to the variable “normalize” in normalize = Function[…].

The # in Function[…] is like the x in lisp's (lambda (x) …). The # is shorthand for #1. The second argument would be #2, third is #3, etc. This way, when defininig a function, you don't have to explicitly name your arguments. You just use the symbols {#1, #2, #3, …} (but you can if you want, ⁖ Function[{x, y}, …] is lisp's (lambda (x y) …)) .

Mathematica support array programing concepts. This means, when a operation is applied to a list, it automatically maps over the list. For example, 1 + {3, 4, 5} is semantically equivalent to {1 + 3, 1 + 4, 1 + 5}, and {3, 4, 5}^2 is semantically equivalent to {3^2, 4^2, 5^2}, and {3, 4, 5}/b is semantically equivalent to {3/b, 4/b, 5/b}.

In typical languages such as Python, including lisp, you would have to explicitly map the operation into each list elements instead.

The Sqrt@… is a syntax shortcut for Sqrt[…]. In general, the a@b is syntactically equivalent to a[b] for any expressions a and b.

The Plus@@… is a syntax shortcut for Apply[Plus, …], which is lisp's “funcall”. In general, a@@b is syntactically equivalent to Apply[a,b].

So, taking the above all together, the code for “normalize” given above is SYNTACTICALLY EQUIVALENT to this:

normalize = Function[ #/Sqrt[ Apply[Plus, #^2] ]]

The above means: square the vector, add the components together, square root it, then have the vector divide the result.

Mathematica's expression has a 100% regular fully nested form, called FullForm. In FullForm, no operators are used, only functions and nesting syntax. (similar to lisp) So, when written in FullForm, all Mathematica code are of form f[ f[… ], f[…], …].

The = in a = b is a operator syntax for Set[a, b]. The ^ in a ^ b is a operator syntax for Power[a, b], and the / in a/b is a shortcut for Times[a, Power[b, -1]]. And the # is a syntax shortcut for the FullForm Slot[1].

Here, by steps, we rewrite a short Mathematica expression in FullForm. Each of the following line are syntactically equivalent:

normalize = #/Sqrt@(Plus@@(#^2)) &

normalize = Function[#/Sqrt@(Plus@@(#^2))]

normalize = Function[#/Sqrt@(Plus@@(Power[#, 2]))]

normalize = Function[#/Sqrt@( Apply[Plus, Power[#, 2]] )]

normalize = Function[ #/Sqrt[Apply[Plus, Power[#, 2]]] ]

normalize = Function[ Times[#, Power[ Sqrt[Apply[Plus, Power[#, 2]]], -1]] ]

normalize = Function[ Times[Slot[1], Power[ Sqrt[Apply[Plus, Power[Slot[1], 2]]], -1]] ]

Set[normalize, Function[ Times[Slot[1], Power[ Sqrt[Apply[Plus, Power[Slot[1], 2]]], -1]] ] ]

For advanced Mathematica programers, the form #/Sqrt@(Plus@@(#^2)) & is common. But most users will probably write Function[ #/Sqrt[Apply[Plus, #^2]] ]. Nobody really write using the fully nested FullForm. But understanding FullForm is vital for any serious Mathematica programing.

Note: Normalize function is now a built-in function in Mathematica v6, released sometimes in 2007. See: http://reference.wolfram.com/mathematica/ref/Normalize.html.

Normalize Function in Haskell, Ruby, Python, Perl, Scheme Lisp, JavaScript, Java, C

Thanks to “comp.lang.*” newsgroups, various people have given code for different languages.

APL

APL and Mathematica can both be categorized into a so-called Array programming language. The APL implementation here is very similar to Mathematica.

normalize←{⍵÷((+/⍵⋆2)⋆0.5)}

normalize 3 4 5 6
⍝ Output: 0.3234983196103152 0.43133109281375365 0.539163866017192 0.6469966392206304

Code by Tom Novelli. APL code can be run here: http://ngn.github.com/apl/web/index.html

〔☛ How to Create a APL or Math Symbols Keyboard Layout ⌨

Haskell

-- Haskell. By the.brown.dragon…@gmail.com
let normalize vec = map (/ (sqrt $ sum (map (^2) vec))) vec in normalize [3,4]

Ruby

# -*- coding: utf-8 -*-
# Ruby 1.8.7. By w_a_x…@yahoo.com
def normalize vec
  s = Math.sqrt(vec.map{|x|x*x}.inject{|x,y|x+y})
  vec.map{|x| x/s}
end

p normalize([3,4,5,6])
# [0.323498319610315, 0.431331092813754, 0.539163866017192, 0.64699663922063]

Python

# Python 2.6.5 By Roberto Bonvallet
def normalize(vec):
    return (lambda norm: [x/norm for x in vec])(sum(x**2 for x in vec) **0.5)

print normalize([3,4,5,6])
# [0.32349831961031522, 0.43133109281375365, 0.53916386601719202, 0.64699663922063044]

〔☛ Python: List Comprehension

Perl

# Perl v5.10.1. By Jim Gibson
sub normalize {
  my $sum = 0;
  $sum += $_ ** 2 for @_;
  return map { $_ / sqrt($sum) } @_;
}

use Data::Dumper;
print Dumper([normalize(3,4,5,6)]);
# [ '0.323498319610315', '0.431331092813754', '0.539163866017192', '0.64699663922063' ]

Scheme Lisp

;; Scheme Lisp. (scsh 0.6.7 (R6RS))  By Bakul Shah
(define (normalize vec)
   (let ((d (sqrt (apply + (map (lambda (x) (* x x)) vec)))))
     (map (lambda (x) (/ x d)) vec)))

(normalize '(3 4 5 6))
;; '(0.323498 0.431331 0.539164 0.646997)

JavaScript

// JavaScript. By William James. Modified by Xah Lee
function normalize( vec ) {
var div = Math.sqrt(vec.map(function(x) {return x*x}).reduce(function(a,b) {return a+b}));
return vec.map(function(x) {return x/div});
}

console.log(normalize([3,4,5,6]));
// [ 0.3234983196103152, 0.43133109281375365, 0.539163866017192, 0.6469966392206304 ]

〔☛ JavaScript Array Methods

// JavaScript. By Gerard Flanagan
var map = function(fn, v) {
     var b = new Array(v.length);
     for (i = 0; i < v.length; i++) {
         b[i] = fn(v[i]);
     }
     return b
};

var reduce = function(fn, v, init) {
     var s = init;
     for (i = 0; i < v.length; i++) {
         s = fn(s, v[i]);
     }
     return s
};

var sum = function(v) {
     return reduce(function(x, y) { return x + y }, v, 0.0)
};

var vectorLength = function(v) {
     var pow = Math.pow;
     return Math.sqrt(sum(map(function(x) { return pow(x, 2) }, v)))
};

var normalize = function(vec) {
     var N = vectorLength(vec);
     return map(function(x) { return x/N }, vec)
}

console.log(normalize([3,4,5,6]));
// [ 0.3234983196103152, 0.43133109281375365, 0.539163866017192, 0.6469966392206304 ]

Java

// Java. By John W Kennedy. Class wrapper and printing code added by Xah Lee.
class Test {
    static float[] normalize(final float[] vec) {
        float sum = 0.0f;
        for (int i = 0; i < vec.length; ++i) sum += vec[i] * vec[i];
        final float divisor = (float) Math.sqrt(sum);
        float[] a = new float[vec.length];
        for (int i = 0; i < vec.length; ++i) a[i] = vec[i]/divisor;
        return a;
    }

    public static void main(String[] args) {
        float[] inputVector = {3,4};
        float[] resultVector = normalize(inputVector);

        for (int i = 0; i < resultVector.length; i++) {
            System.out.print(resultVector[i] + " ");
        }
    }
}

〔☛ Java Tutorial: Defining a Function

Other

The following C code is not qualified. It needs to be a full stand alone program that takes vector of any dimension and prints the result. Due to C's low-level nature, the program perhaps needs include code to parse command line input of arbitrary vector such as a list of numbers separated by space, and print the result in output.

// C. By John W Kennedy
#include <stdlib.h>
#include <math.h>
void normalize(int dim, float* x, float* a) {
    float sum = 0.0f;
    int i;
    float divisor;
    for (i = 0; i < dim; ++i) sum += x[i] * x[i];
    divisor = sqrt(sum);
    for (i = 0; i < dim; ++i) a[i] = x[i]/divisor;
}
blog comments powered by Disqus