One could convert the matrix to an association with string valued keys indicating matrix positions and use named slots.
For example:
(Slot["{1, 2}"]*Slot["{1, 1}"] &)@
KeyMap[ToString, Association@Most@ArrayRules@{{x1, y1}, {x2, y2}}]
Out: (* x1 y1 *)
That is rather lengthy to use. One could package that into auxiliary functions.
Auxiliary functions
The first list/matrix to association function:
listorule[list_] := KeyMap[ToString, Association@Most@ArrayRules@list]
The second function makes it a bit easier to write the Slot
arguments. One can change the notation as explained in the next section.
ss[indices__] := Slot@ToString@List[indices]
The last function replaces Function
or &
to control the evaluation order and makes it convenient to compose listtorule
on the right.
func[a_] := Function[Evaluate[a]]@*listorule;
Note: There might be cases where one does not want to use Evaluate
on the entire expression in which case func
above might evaluate too much of the expression.
Example above rewritten
Reconsidering the example above, one can code the following function
h = ss[1, 1]*ss[2, 2] // func
Test:
h@{{x1, y1}, {x2, y2}}
Out: (* x1 y2 *)
Possible modifications
The syntax could be simplified by adding an extra dictionary/association between a user defined notation and string of positions. For example, if the size of the matrix is smaller than 10 one could consider writing ss@12*ss@11
. The reason for the restriction on matrices smaller than 10 is to avoid ambiguity in something like ss@143
.
One might also consider maybe rewriting some of the steps above using With
and using symbols we feel comfortable with which would skip the Evaluate
part. That seems reasonable for a very long function but it is a bit tedious for a small function.