3
$\begingroup$

I have a very simple problem, with me misunderstanding the use of Modules and Functions in general, in Mathematica.

I have a function of which I want to input a matrix, and in the function I have a need of knowing the number of columns to make operations upon these. To this I use Dimensions[], which works fine while using a matrix directly, but seems to fail whenever I try to input the formula to a function and/or Module.

The following lines works when using a matrix directly, yet if I want to save the output directly, I can't seem to make it work:

OrtMat[X_] = Module[{m = Dimensions[X][[2]]},
  For[i = 1, i < m + 1, i++,
   If[i > 1,
     For[j = 1, j < i, j++,
      X[[All, i]] = 
       X[[All, i]] - 
        X[[All, i]].X[[All, j]]/Norm[X[[All, j]]]*X[[All, j]];
      X[[All, i]] = X[[All, i]]/Norm[X[[All, i]]];
      ],
     X[[All, i]] = X[[All, i]]/Norm[X[[All, i]]]
    ];
   ]
  ]

which very simply orthogonalizes the matrix. As said the only error popping up is with dimensions, it comes with the output:

Part::partw: Part 2 of {} does not exist. >>
$\endgroup$
1
  • 2
    $\begingroup$ Have you seen Orthogonalize[] and Eigensystem[]? $\endgroup$ Mar 18, 2016 at 18:42

2 Answers 2

3
$\begingroup$

This makes your code work with some "style" modifications. The main problem was that you were assigning a value to the (immutable) parameter in the function. Use a scoped symbol instead.

Anyway, all those linear algebra functions are part of the Mathematica standard repertoire

OrtMat[y_] := Module[{m = Last@Dimensions[y], x = y},
  x[[1]] = Normalize@x[[1]];
  For[i = 2, i <= m, i++,
   For[j = 1, j < i, j++,
    x[[i]] = x[[i]] - (x[[i]].x[[j]]) Normalize@x[[j]];
    x[[i]] = Normalize@x[[i]];
    ]
   ];
  x]

OrtMat[{{3, 1}, {2, 2}}]
(* {{3/Sqrt[10], 1/Sqrt[10]}, {-(1/Sqrt[10]), 3/Sqrt[10]}}*)

But in Mathematica I would program it like this:

o[y_] := Module[{m = Last@Dimensions@y, x = y, n = Normalize},
  x[[1]] = n@x[[1]];
  (x[[#2]] = n[x[[#2]] - Dot @@ x[[{##}]] n@x[[#1]]]) & @@@ Subsets[Range@m, {2}];
  x]
$\endgroup$
2
  • $\begingroup$ Thanks for the help, I am well aware of the on-board functions giving the valid results. Yet this is to minimize time usage on exam relevant subjects, thus I am making pre-made modules giving me the results i seek, showing the basis of my knowledge. Thanks for the help though, it gives me some insight in how to solve some related trouble. On another subject, is there a directory to look up, on the programming language of mathematica, in more detail? The language is a bit unfamiliar to me in regard to usage of #, @ and other reference paramters. $\endgroup$
    – Oliver
    Mar 20, 2016 at 22:04
  • $\begingroup$ @Bijaelo mathematica.stackexchange.com/a/25616/193 $\endgroup$ Mar 20, 2016 at 22:44
1
$\begingroup$

Define functions with SetDelayed (i.e., :=), not with Set (i.e., =). Also, Mma passes by value, so you will need to start out with something like

OrtMat[mX_] := Module[{X = mX, m = Dimensions[mX][[2]]}, ...

Be sure to return the value you produce.

$\endgroup$
4
  • 1
    $\begingroup$ The problem isn't the "pass by value" but the immutability. Other languages "pass by value" but you can change the value of the local variable $\endgroup$ Mar 18, 2016 at 21:30
  • $\begingroup$ Well that cannot quite be the right description either, as the list is mutable. I though Mma types summarized this behavior by calling it pass by value, even thought that will not suit the comp sci types (as there is no copying). I think the right description is something like this: it may look (in a function definition) like you have introduced formal parameters to manipulate as lvalues, but bc Mma will simply replace those occurences with the arguments, you really only have rvalues. But I'm not a comp sci type. $\endgroup$
    – Alan
    Mar 19, 2016 at 16:52
  • $\begingroup$ Just in case, I was trying to explain why this fails f[s_List] := (s = {1}); f[{1}] $\endgroup$ Mar 20, 2016 at 17:46
  • $\begingroup$ Sure. I think it is even more informative to note that this does not work: g[s_Integer] := (s += 1; s); g[1] $\endgroup$
    – Alan
    Mar 21, 2016 at 18:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.