0

Is there a way to label an array by a variable instead of an integer? For example calling the array I[i,j] with {i,j} = {x,y,z} instead of {i,j} = {1,2,3}?

For example, I might want to label the components of the Inertia tensor by I[x,x], I[x,y].. instead of I[1,1], I[1,2]..

Öskå
  • 8,587
  • 4
  • 30
  • 49
DJBunk
  • 683
  • 1
  • 8
  • 18
  • I find this question opaque. Could you please give a practical example of what you want? – Mr.Wizard Jun 18 '13 at 15:45
  • l[x,y]=34;l["s", j]=54 and now you index l[x,y]? Also, x=1;y=2 and l[[x,x]] becomes l[[1,1]]? – Rojo Jun 18 '13 at 15:48
  • @Mr.Wizard - I added an practical example. Thanks for the clarification. – DJBunk Jun 18 '13 at 15:49
  • Sorry, but I still don't understand. What do you mean by label? Are you trying to extract an element based on a particular tag, e.g. v = {1, 2, 3} and then you want v[["x"]] to return 2? (Note the string "x" to illustrate an arbitrary tag.) Or, is this a display issue of some kind? – Mr.Wizard Jun 18 '13 at 15:53
  • As you've been on stackexchange awhile now, I would suggest you learn how to correctly format your questions. For inline code, wrap them in grave marks (`). For block code, indent each line by 4 spaces, with a blank line preceding and following the code. – rcollyer Jun 18 '13 at 15:53
  • @Mr.Wizard - yes, that is exactly what I want to do. – DJBunk Jun 18 '13 at 15:55
  • @rcollyer - Sorry, I usually format things, but I didn't think it mattered in the context of a sentence. I'll be more careful next time. Thanks for the heads up. – DJBunk Jun 18 '13 at 15:56
  • Assuming that there is not a global mapping of tags to positions for all arrays or you are only doing this for one array you will need a way to identify a particular array for Mathematica to know which mapping to use. Will the arrays always be assigned to and accessed by a symbol? Please also see these related posts: (1), (2) – Mr.Wizard Jun 18 '13 at 16:03

2 Answers2

3

Maybe you just want something like this?

inertia = Array[\[CapitalIota] @@ {"x", "y", "z"}[[{##}]] &, {3, 3}];    
MatrixForm[inertia]

$$\left( \begin{array}{ccc} I(\text{x},\text{x}) & I(\text{x},\text{y}) & I(\text{x},\text{z}) \\ I(\text{y},\text{x}) & I(\text{y},\text{y}) & I(\text{y},\text{z}) \\ I(\text{z},\text{x}) & I(\text{z},\text{y}) & I(\text{z},\text{z}) \\ \end{array} \right)$$

Here I used the Greek I to avoid confusion with the complex I, and made the text labels appear as strings in a list {"x", "y", "z"} whose parts are selected based on the position in the 2D Array over integers from 1 to 3. This matrix inertia is now ready to be used for symbolic manipulations.

Jens
  • 97,245
  • 7
  • 213
  • 499
1

Say you have a data structure and some labels, which I will arrange for convenience this way:

data = Thread[{x, "charlie", y, z, "bob"} -> {5, 17, 24, 7, 1}]

The goal is to have a function, which, when called with x will give 5, when called with y will give 24, when called with "bob" will give 1, etc. Here is one way to achieve such indexing:

y //.data
24

{x, "bob"} //. data
{5, 1}

This can be made into a function easily:

locate[x_] := x //. data

so that locate[x] is 5, locate[{"bob", z}] is {1, 7}, etc.

Handling matrices or tensors of values can be done similarly. Set up the desired labels in labelMat and the corresponding values in vals. Then create the list of rules as in data2

labelMat = {{"I[x,x]", "I[x,y]"}, {"I[y,x]", "I[y,y]"}};
vals = {{1, 3}, {5, 7}};
data2 = Thread[Flatten[labelMat] -> Flatten[vals]];

This can then be applied to individual terms or lists of terms:

{"I[x,y]", "I[y,y]"} //. data2
{3,7}
bill s
  • 68,936
  • 4
  • 101
  • 191
  • For vectors, much better, and I'll retract my prior comment. However it is not yet complete for arbitrary tensors. I suspect this question will end up being a duplicate, though I'm waiting for certain clarifications from the OP. – Mr.Wizard Jun 18 '13 at 16:18