Mathematica 7 compares to other languages

S

Stef Mientki

Lest anyone doubt that problem size is important for comparing program
run times, consider ...

just in case there's any doubt:

Simply change these lines in Jon's program:

Main[9, 512, 4] to Main[9, 512, 4.]

and it will run faster.
Who said Mathematica was a high level language ?
cheers,
Stef
 
W

w_a_x_man

For those of you who don't know linear algebra but knows coding, 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]
In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

Ruby:

def norm a
s = Math.sqrt(a.map{|x|x*x}.inject{|x,y|x+y})
a.map{|x| x/s}
end
 
K

Kaz Kylheku

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 algebar terminology, the new vector is called
the “normalized†vector of the original.

For those of you who don't know linear algebra but knows coding, this

If I were to guess who that would be ...
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]

In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

Really? ``50 or hundreds'' of lines in C?

#include <math.h> /* for sqrt */

void normalize(double *out, double *in)
{
double denom = sqrt(in[0] * in[0] + in[1] * in[1] + in[2] * in[2]);

out[0] = in[0]/denom;
out[1] = in[1]/denom;
out[2] = in[2]/denom;
}

Doh?

Now try writing a device driver for your wireless LAN adapter in Mathematica.
 
X

Xah Lee

Xah said:
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 algebar terminology, the new vector is called
the “normalized†vector of the original.
For those of you who don't know linear algebra but knows coding, this

If I were to guess who that would be ...
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]
In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.


Kaz said:
Really? ``50 or hundreds'' of lines in C?

#include <math.h> /* for sqrt */

void normalize(double *out, double *in)
{
double denom = sqrt(in[0] * in[0] + in[1] * in[1] + in[2] * in[2]);

out[0] = in[0]/denom;
out[1] = in[1]/denom;
out[2] = in[2]/denom;
}

Doh?

Kaz, pay attention:

Xah wrote: «Note, that the “norm†as defined above works for vectors
of any dimention, i.e. list of any length.»

The essay on the example of Mathematica expressiveness of defining
Normalize is now cleaned up and archived at:

• A Example of Mathematica's Expressiveness
http://xahlee.org/UnixResource_dir/writ/Mathematica_expressiveness.html

Xah
∑ http://xahlee.org/

☄
 
X

Xah Lee

Xah said:
For those of you who don't know linear algebra but knows coding, 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]
In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

Note, that the “norm†as defined above works for vectors of any
dimention, i.e. list of any length.


Ruby:

def norm a
s = Math.sqrt(a.map{|x|x*x}.inject{|x,y|x+y})
a.map{|x| x/s}
end

I don't know ruby, but i tried to run it and it does not work.

#ruby
def norm a
s = Math.sqrt(a.map{|x|x*x}.inject{|x,y|x+y})
a.map{|x| x/s}
end

v = [3,4]

p norm(v) # returns [0.6, 0.8]

The correct result for that input would be 5.

Also note, i wrote: «Note, that the “norm†as defined above works for
vectors of any dimention, i.e. list of any length.».

For detail, see:
• A Example of Mathematica's Expressiveness
http://xahlee.org/UnixResource_dir/writ/Mathematica_expressiveness.html

Xah
∑ http://xahlee.org/

☄
 
A

Arnaud Delobelle

Dotan Cohen said:
2008/12/10 said:
For those of you who don't know linear algebra but knows coding, 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]
In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

Ruby:

def norm a
s = Math.sqrt(a.map{|x|x*x}.inject{|x,y|x+y})
a.map{|x| x/s}
end

If someone doesn't counter with a Python one-liner then I'm going to
port that to brainfuck.

def unit(v):
return map((sum(map(lambda x:x*x, v))**0.5).__rdiv__, v)

The hard bit was to make it less readable than the Ruby version ;)
 
J

John W Kennedy

Xah said:
In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

C:

#include <stdlib.h>
#include <math.h>

void normal(int dim, float* x, float* a) {
float sum = 0.0f;
int i;
float divisor;
for (i = 0; i < dim; ++i) sum += x * x;
divisor = sqrt(sum);
for (i = 0; i < dim; ++i) a = x/divisor;
}

Java:

static float[] normal(final float[] x) {
float sum = 0.0f;
for (int i = 0; i < x.length; ++i) sum += x * x;
final float divisor = (float) Math.sqrt(sum);
float[] a = new float[x.length];
for (int i = 0; i < x.length; ++i) a = x/divisor;
return a;
}
 
D

Daniel Fetchinson

Xah said:
Kaz said:
Really? ``50 or hundreds'' of lines in C?

#include <math.h> /* for sqrt */

void normalize(double *out, double *in)
{
double denom = sqrt(in[0] * in[0] + in[1] * in[1] + in[2] *
in[2]);

out[0] = in[0]/denom;
out[1] = in[1]/denom;
out[2] = in[2]/denom;
}

Doh?

Kaz, pay attention:

Xah wrote: «Note, that the "norm" as defined above works for vectors
of any dimention, i.e. list of any length.»

That is still only 6 lines of C code and not 50 as you claimed:

double il = 0.0;
for (int i=0; i<n; ++i)
il += in * in;
il = 1.0 / sqrt(il);
for (int i=0; i<n; ++i)
out = il * in;

Try computing the Fourier transform of:

0.007 + 0.01 I, -0.002 - 0.0024 I



Funniest thread ever!
Actual real money changing hands, did this happen ever in a newsgroup?

Xah Lee rulez! Xah Lee for president! (No kidding, I like the guy.)

Cheers,
Daniel
 
A

Arne Vajhøj

Jon said:
Xah said:
Kaz said:
Really? ``50 or hundreds'' of lines in C?

#include <math.h> /* for sqrt */

void normalize(double *out, double *in)
{
double denom = sqrt(in[0] * in[0] + in[1] * in[1] + in[2] *
in[2]);

out[0] = in[0]/denom;
out[1] = in[1]/denom;
out[2] = in[2]/denom;
}

Doh?
Kaz, pay attention:

Xah wrote: «Note, that the “norm†as defined above works for vectors
of any dimention, i.e. list of any length.»

That is still only 6 lines of C code and not 50 as you claimed:

double il = 0.0;
for (int i=0; i<n; ++i)
il += in * in;
il = 1.0 / sqrt(il);
for (int i=0; i<n; ++i)
out = il * in;


Not that it matters, but the above requires C99 (or C++).

Arne
 
B

Bakul Shah

John said:
Xah said:
In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

C:

#include <stdlib.h>
#include <math.h>

void normal(int dim, float* x, float* a) {
float sum = 0.0f;
int i;
float divisor;
for (i = 0; i < dim; ++i) sum += x * x;
divisor = sqrt(sum);
for (i = 0; i < dim; ++i) a = x/divisor;
}

Java:

static float[] normal(final float[] x) {
float sum = 0.0f;
for (int i = 0; i < x.length; ++i) sum += x * x;
final float divisor = (float) Math.sqrt(sum);
float[] a = new float[x.length];
for (int i = 0; i < x.length; ++i) a = x/divisor;
return a;
}


q){x%sqrt sum x}3 4
0.6 0.8
 
B

Bakul Shah

Bakul said:
John said:
Xah said:
In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

C:

#include <stdlib.h>
#include <math.h>

void normal(int dim, float* x, float* a) {
float sum = 0.0f;
int i;
float divisor;
for (i = 0; i < dim; ++i) sum += x * x;
divisor = sqrt(sum);
for (i = 0; i < dim; ++i) a = x/divisor;
}

Java:

static float[] normal(final float[] x) {
float sum = 0.0f;
for (int i = 0; i < x.length; ++i) sum += x * x;
final float divisor = (float) Math.sqrt(sum);
float[] a = new float[x.length];
for (int i = 0; i < x.length; ++i) a = x/divisor;
return a;
}


q){x%sqrt sum x}3 4
0.6 0.8


Oops. I meant to write {x%sqrt sum x*x}3 4
 
X

Xah Lee

Xah said:
In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

C:

#include <stdlib.h>
#include <math.h>

void normal(int dim, float* x, float* a) {
    float sum = 0.0f;
    int i;
    float divisor;
    for (i = 0; i < dim; ++i) sum += x * x;
    divisor = sqrt(sum);
    for (i = 0; i < dim; ++i) a = x/divisor;

}

Java:

static float[] normal(final float[] x) {
    float sum = 0.0f;
    for (int i = 0; i < x.length; ++i) sum += x * x;
    final float divisor = (float) Math.sqrt(sum);
    float[] a = new float[x.length];
    for (int i = 0; i < x.length; ++i) a = x/divisor;
    return a;

}


Thanks to various replies.

I've now gather code solutions in ruby, python, C, Java, here:

• A Example of Mathematica's Expressiveness
http://xahlee.org/UnixResource_dir/writ/Mathematica_expressiveness.html

now lacking is perl, elisp, which i can do well in a condensed way.
It'd be interesting also to have javascript... and perhaps erlang,
OCaml/F#, Haskell too.

Xah
∑ http://xahlee.org/

☄
 
W

William James

Jon said:
Xah said:
Ruby:

def norm a
s = Math.sqrt(a.map{|x|x*x}.inject{|x,y|x+y})
a.map{|x| x/s}
end

I don't know ruby, but i tried to run it and it does not work.

#ruby
def norm a
s = Math.sqrt(a.map{|x|x*x}.inject{|x,y|x+y})
a.map{|x| x/s}
end

v = [3,4]

p norm(v) # returns [0.6, 0.8]

That is the correct answer.
The correct result for that input would be 5.

No, you're confusing normalization with length.

Expanded for easier comprehension.

def norm a
# Replace each number with its square.
b = a.map{|x| x*x }
# Sum the squares. (inject is reduce or fold)
c = b.inject{|x,y| x + y }
# Take the square root of the sum.
s = Math.sqrt( c )
# Divide each number in original list by the square root.
a.map{|x| x/s }
end

1.upto(4){|i|
a = (1..i).to_a
p a
p norm( a )
}

--- output ---
[1]
[1.0]
[1, 2]
[0.447213595499958, 0.894427190999916]
[1, 2, 3]
[0.267261241912424, 0.534522483824849, 0.801783725737273]
[1, 2, 3, 4]
[0.182574185835055, 0.365148371670111, 0.547722557505166,
0.730296743340221]
 
C

Chris Rathman

I've now gather code solutions in ruby, python, C, Java, here:

now lacking is perl, elisp, which i can do well in a condensed way.
It'd be interesting also to have javascript... and perhaps erlang,
OCaml/F#, Haskell too.

Pay me $600 for my time and I'll even throw in an Algol-68
version. :)
 
J

Juan Pablo Romero Méndez

In R:

norm = function(v) v/sqrt(sum(v^2))

:)


Juan Pablo




2008/12/10 Arnaud Delobelle said:
Dotan Cohen said:
2008/12/10 said:
For those of you who don't know linear algebra but knows coding, 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]


In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

Ruby:

def norm a
s = Math.sqrt(a.map{|x|x*x}.inject{|x,y|x+y})
a.map{|x| x/s}
end

If someone doesn't counter with a Python one-liner then I'm going to
port that to brainfuck.

def unit(v):
return map((sum(map(lambda x:x*x, v))**0.5).__rdiv__, v)

The hard bit was to make it less readable than the Ruby version ;)
 
R

Roberto Bonvallet

Arnaud said:
def unit(v):
return map((sum(map(lambda x:x*x, v))**0.5).__rdiv__, v)

The hard bit was to make it less readable than the Ruby version ;)

I loved the use of __rdiv__ :)
I would have proposed the more straightforward:

def u(v):
return [x/sum(x**2 for x in v)**0.5 for x in v]

or, in order to avoid computing the norm for each element:

def u(v):
return (lambda norm: [x/norm for x in v])(sum(x**2 for x in v)
**0.5)
 
T

toby

For those of you who don't know linear algebra but knows coding, 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]
In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

void normalise(float d[], float v[]){
float m = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
d[0] = v[0]/m; // My guess is Xah Lee
d[1] = v[1]/m; // hasn't touched C
d[2] = v[2]/m; // for near to an eternitee
}
 
P

Paul Rudin

Dotan Cohen said:
2008/12/10 said:
For those of you who don't know linear algebra but knows coding, 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]
In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

Ruby:

def norm a
s = Math.sqrt(a.map{|x|x*x}.inject{|x,y|x+y})
a.map{|x| x/s}
end

If someone doesn't counter with a Python one-liner then I'm going to
port that to brainfuck.

from numpy.linalg import norm

:)
 
G

Gerard flanagan

Xah said:
[...]

Thanks to various replies.

I've now gather code solutions in ruby, python, C, Java, here:

• A Example of Mathematica's Expressiveness
http://xahlee.org/UnixResource_dir/writ/Mathematica_expressiveness.html

now lacking is perl, elisp, which i can do well in a condensed way.
It'd be interesting also to have javascript...

mmm, stone soup...

javascript:

var map = function(fn, a) {
var b = new Array(a.length);
for (i = 0; i < a.length; i++) {
b = fn(a);
}
return b
};

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

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

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

var Unit = function(a) {
var N = norm(a);
return map(function(x) { return x/N }, a)
};
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,787
Messages
2,569,630
Members
45,335
Latest member
Tommiesal

Latest Threads

Top