Group Abstract Group Abstract

Message Boards Message Boards

0
|
7.9K Views
|
7 Replies
|
0 Total Likes
View groups...
Share
Share this post:

Symbolic vector generator

The module

BracketedVector[letter,n]:=Module[{i}, name=Symbol[letter], Return[Table[name[i],{i,n}]]];

called as

Q=.; v=BracketedVector["Q",4];

returns {Q[1],Q[2],Q[3],Q[4]} as expected but

Q=aaa; v=BracketedVector["Q",4];

returns {aaa[1],aaa[2],aaa[3],aaa[4]} - not good. It is necessary to clear Q before the call:

Q=aaa; Q=.; v=BracketedVector["Q",4];

works OK. To clean the logic I tried to put the clear inside the Module but Symbol[letter]=. generates an error message. Next I tried

BracketedVector[letter,n]:=Module[{i}, name=Symbol[letter]; name=.; name=Symbol[letter]; Return[Table[name[i],{i,n}]]];

Doesn't work either, the value aaa is "remembered" although name is supposed to be a global variable. Is there a way to clear Q inside the Module?

POSTED BY: Carlos Felippa
7 Replies

Hi,

The Array solution is certainly elegant. Actually BracketedVector is part of a set of symbolic vector and matrix generators. Here is the one that constructs a n x n bisymmetric matrix (also called centrosymmetric by some authors, following Muir). Could this be simplified by using Array?

BracketedBiSymmMatrix[letter_,n_]:=Module[{i,j,S}, Clear[letter]; S=Symbol[letter]; Return[Table[If[i+j<n+2,S[Min[i,j],Max[i,j]], S[Min[n-j+1,n-i+1],Max[n-j+1,n-i+1]]],{i,n},{j,n}]]];

POSTED BY: Carlos Felippa

ClearAll is just needed to be sure you don't have multiple definitions of your BracketedVector function:

BracketedVector[letter_String,n_Integer] := .......

will not automatically overwrite

BracketedVector[letter_,n_] := ....

So you are left with two definitions! It will first check the most specific one (is your first argument a string, and the second an integer?), if that one doesn't match it will try the second definition.

In your case you don't need to clear letter. This is part of the pattern (by using an underscore) and is therefore local, In fact you really don't need the module at all:

BracketedVector[letter_, n_] := Table[Symbol[letter][i], {i, n}]

will just work fine, and gives identical results. Module is just needed if you want some local variables, here you don't need any. i,n,letter are all 'local' in some sense: letter and n are local because they are part of SetDelayed, and i is local because it is used in Table. To make your code even more easy to read, you can ditch Table and it's variable i altogether, and use Array:

BracketedVector[letter_, n_] := Array[Symbol[letter], n]

again, same output, incredibly easy to read, no other variables, and better performance!

POSTED BY: Sander Huisman

Another way:

BracketedVector[letter_String, n_Integer] := 
 ToExpression[
  StringJoin["Array[HoldForm[", letter, "],{", ToString[n], "}]"]]

But if all you want is an inert vector, why not use strings directly, instead of symbols? For example

BracketedVector2[letter_String, n_Integer] := Array[letter, {n}]
POSTED BY: Gianluca Gorni

OK, I tried David's and Sander's suggestions, and one does the trick:

      Clear[letter]   inside the module

ClearAll[BracketedVector] is not needed and in fact "deinitializes" the module name. So the new code is a one liner:

BracketedVector[letter_,n_]:=Module[{i}, Clear[letter]; Return[Table[Symbol[letter][i],{i,n}]]];

I was able to redo my 6 matrix/vector symbolic constructors (vector, rectangular matrix, square matrix, symmetric matrix, bisymmetric matrix, and entry debracketer) and all test fine. Thanks again!

POSTED BY: Carlos Felippa

Thanks for the replies, I'll try that. Sorry, I had underscores after the module arguments, but there were automatically erased by the posted in window. The comma after name=Symbol[letter] was my typo.

Why is it necessary to clear BracketedVector? That is a module name, not a variable. Is it necessary to do before each invocationof the module? As regards Return, I always use it, since it self documents what is being returned - exactly as in C.

POSTED BY: Carlos Felippa

Try the following code: Notice that I added the underscores, replaced the comma with a semicolon, and the return is not required.

ClearAll[BracketedVector]
BracketedVector[letter_String,n_]:=Module[{i,name},
 name=Symbol[letter];
 Table[name[i],{i,n}]
]
POSTED BY: Sander Huisman

This one is an easy trap to fall into! The problem is that's it's difficult to get Symbol to not evaluate its argument. But you can Clear symbols either by Symbols or by symbol names. And Clear has the Attribute HoldAll. So try this:

ClearAll[BracketedVector]
BracketedVector[letter_String, n_Integer?Positive] :=
  Module[{name, vector},
   Clear[letter];
   name = Symbol[letter];
   Table[name[i], {i, n}]
   ];
Q = aaa;
BracketedVector["Q", 4]

If you are interested in a nice Mathematica Application for working with vector expressions in Mathematica you might take a look at this Grassmann Calculus.

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard