Wolfram Mathematica

Pages: 12
@helios,
I didn't think about that...
I see that opinions are really divided into a clear yes and a clear no. SAGE seems interesting too, but I dislike that it converts via Python to C. (Rather than directly from Mathematica to C++.) What I was really interested in is implementing Mathematica functions like D and Solve in C++ (by using MathCode C++), does anyone have any experience with that? (Is it even possible the way I have it in mind?)
Of course you could implement "Solve" in C++, but I don't know if it's possible the way you have in mind.

Oh while we're at it - I am rather new to Mathematica, and just to get more used to it I wanted to write a function that displays a simple recursive tree:

(*Edited (fixed) version of the function  - also has another branch*)
tree[n_, pos_, dir_] := 
 Module[{ i, right = RotationTransform[-45 \[Degree]] , 
   left = RotationTransform[45 \[Degree]], onethirdpos, twothirdpos, 
   res1, res2, res3, result = {} },
  
  If[n > 0,
   (* Calculate positions of branches *)
   onethirdpos = pos + 1/3 dir;
   twothirdpos = pos + 2/3 dir;
   (* Draw sub trees *)
   res1 = tree[(n - 1), onethirdpos, 1/2 (left[dir])];
   res2 = tree[(n - 1), twothirdpos, 1/2 (right[dir])];
   res3 = tree[(n - 1), pos + dir, 2/3 dir];
   (* Join returned lists to result list *)
   result = Join[res1, res2, res3];
   (* Return line list of this branch *)
    AppendTo[result, Line[{pos, pos + dir}]];
   Return [result];,
   (* If leaf, just return a one-element list with a single line *)
   Return[{Line[{pos, pos + dir}]}];
   ] (* end of If*)
  ] (* end of module*)


Now I was told that this is highly inefficient (well, I can see why - Append pushes the entire list on the stack every call, and I need lots and lots of interations to reassemble the list at any recursion depth, and I can also directly feel the problem - with n=6 the function breaks) and that I should use a more 'math like' approach rather than a procedural one - the problem is, I just don't know how a mathematical approach at generating a recursive tree would look like. Can anyone show me, or even just push me in the right direction here?
Last edited on
Append pushes the entire list on the stack every call
Mmh... Are lists singly linked?
If you have TCO, pass by reference, and a few node construction functions, you can write an append function that works in constant space. I just happened to be playing with this in Scheme yesterday.
1
2
3
4
5
6
7
8
9
10
11
12
(define (prepend-in-reverse from to)
  (define (iter next accum)
    (if (null? next)
        accum
        (iter (cdr next) (cons (car next) accum))
    )
  )
  (iter from to)
)
(define (concat l1 l2)
  (prepend-in-reverse (reverse l1) l2)
)
Just to fill you in quickly:
A Scheme list is formed by a series of pairs (or "conses") where the first member points to a value (or "atom") and the second points to another pair. The last node points to nothing.
null? returns true when the parameter is the empty list.
car returns the atom pointed to by the first member of a cons. Can also be understood to return the top of a list.
cdr returns the atom pointer to by the second member of a cons; or everything past the top of the list.
cons constructs a cons from a pair of values.
reverse is pretty obvious, but it should be noted that it also works (or, at least, can be implemented to work) in constant space.

EDIT: However, this may be somewhat time-inefficient. At least you won't overflow the stack by pushing huge structures onto it. There probably is a more functional (I'm guessing that's what they meant by "math-like") way to do what you're doing that will be more efficient
Last edited on
Mmh... Are lists singly linked?

I don't know, but the problem is that Append doesn't actually append an element to a list, it creates a new list with the element appended.
A bit off topic of the last few posts, but to point out a few free alternatives to Mathematica, besides SAGE (all of those are included in SAGE together with a python interface):

GAP(general purpose oriented towards algebra), Maxima(calculus+algebra), Macaulay2 (algebra), singular (algebra, probably the fastest), R (statistics)


You can use the source code of all of these directly (I presume, unlike Mathematica); I also presume these projects are written by experts (btw, GAP is at the moment the best computer algebra system for computing in my field of mathematics (and it does a lot more); I hope that, in my limited field of mathematics, my project will soon come out for a solid second place, hehe).

Oh, and one more super cool computer algebra system, but still in very early development (possibly not usable as general-purpose):
barvinok
(but for what it is meant for it kicks ass)

and one not-so-general-purpose:
LattE
(similar comment as barvinok, but not as praise-ful)
Last edited on
closed account (zwA4jE8b)
http://www.wolframalpha.com
Tition, thanks for pointing out the different tools that are available, I will definitely look into them at some point later on. Right now, however, a friend of mine that's already going to University got me to test Mathematica on his laptop now and then. So I'll have it right here for some testing. Just now, I was busy with modeling the Collatz Conjecture as a directed graph. I would start out with a graph that has just one edge (connecting 2 -> 1) and then call a MakePath function that would take in the graph and a number as arguments and edit the graph to add the given number to it (including a path on how to get back to 1).

I got the logic all figured out, but I'm stuck on the code. What I have is this:
1
2
3
4
5
6
7
MakePath[x_Integer, y_] := 
  If[EdgeCount[y, x \[DirectedEdge] _] == 0 && x == 1,
   VertexAdd[y, x]
    If[x Mod 2,
     y = EdgeAdd[y, {x \[DirectedEdge] x/2}],
     y = EdgeAdd[y, {x \[DirectedEdge] 3 x + 1}]]
   , 0];


Does anyone see what I'm doing wrong? (\[DirectedEdge] is replaced by the -> arrow thing)
Last edited on
You need a semicolon after VertexAdd[y,x]
I now have this:
1
2
3
4
5
6
7
8
MakePath[x_Integer, y_] := 
  If[EdgeCount[y, x \[DirectedEdge] _] == 0 && x == 1,
   VertexAdd[y, x];
   If[x Mod 2,
    y = EdgeAdd[y, {x \[DirectedEdge] x/2}],
    
    y = EdgeAdd[y, {x \[DirectedEdge] 3 x + 1}]]
   , y];


But it just returns the old y.
Then either EdgeCount isn't 0 or x isn't 1.
I found that Mod is a function and that I swapped x/2 and 3x+1. That brings me to this:
1
2
3
4
5
6
7
8
MakePath[x_Integer, y_] := 
  If[EdgeCount[y, x \[DirectedEdge] _] == 0 && x != 1,
   VertexAdd[y, x];
   If[Mod[x, 2],
    EdgeAdd[y, {x \[DirectedEdge] 3 x + 1}],
    
    EdgeAdd[y, {x \[DirectedEdge] x/2}]]
   , y];


EDIT:
Nevermind, figured it out. Thanks for the help though. This is what it was supposed to be:
1
2
3
4
5
6
7
8
MakePath[x_Integer, y_] := 
  If[EdgeCount[y, x \[DirectedEdge] _] == 0 && x != 1,
   VertexAdd[y, x];
   If[Mod[x, 2] == 1,
    MakePath[3 x + 1, EdgeAdd[y, {x \[DirectedEdge] 3 x + 1}]],
    
    MakePath[x/2, EdgeAdd[y, {x \[DirectedEdge] x/2}]]]
   , y];
Last edited on
Topic archived. No new replies allowed.
Pages: 12