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?

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.

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}]
]

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.

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!

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}]

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!

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}]]];