1
$\begingroup$

I would like to define a function which produces an $N\times N$ matrix where each element is a function of the input values ($N$ is a fixed constant). However, each element of the function needs to be computed from a predefined list of values.

In the specific example I am working on, I have a two lists, A and B: A contains the $(i,j)$ matrix indices and B contains vectors $\vec{v}$ corresponding to those matrix indeces (in the same order) For this example my vectors are three dimensional. However in the first list some indices are repeated more than once. Consider if I have some function $g(\vec{r}\cdot\vec{v})$, and I want to define a matrix $f_{ij}(\vec{r})$ such that each element is the sum of $g(\vec{r}\cdot\vec{v})$ for each $\vec{v}$ which corresponds to the index $(i,j)$.

I could make a matrix by simply defining an empty matrix of zeroes and looping over the list index,

f = ConstantArray[0, {N, N}]
For[i = 1, i <= Length[A], i++,
  f[[ A[[i, 1]], A[[i, 2]] ]] += g[B[[i]].{x,y,0}]
]`

But I can't do this if f is a function

f[x_,y_] := ConstantArray[0, {N, N}]
For[i = 1, i <= Length[A], i++,
  f[[ A[[i, 1]], A[[i, 2]] ]] += g[B[[i]].{x,y,0}]]
]`

I'm sure there's better ways but I just wanted to give a basic example of how I was thinking of approaching it. For now I built the matrix for the first way, printed it out in MatrixForm, copied and defined f[x_,y_] = and pasted the entire matrix. This is obviously not ideal, especially for larger matrices.

$\endgroup$
  • $\begingroup$ Please provide A and B lists. Also function definition is f[x_] := ... and not f[x_] = .... When you define f[x_,y_] := ..., you do not need to use double brackets as f[[ a1, a2 ]] to use it. f[[ a1, a2 ]] means the a2th element of a1th row of the matrix f. $\endgroup$ – Navid Rajil Feb 13 '18 at 20:57
  • $\begingroup$ Hi sorry if my question was unclear, I fixed the := and clarified the code slightly. In the first example f is just a matrix and I am referencing its elements. In the second example (which is pseudocode), f is a function which returns a matrix, and I want to apply the same logic: f[[i,j]] (pseudocode: the {i,j} element of the matrix returned by f[x_,y_]) is the sum of all g[B[[n]].{x,y,0}] such that A[[n]] = {i,j}. $\endgroup$ – Kai Feb 14 '18 at 17:10
2
$\begingroup$
m = 10;
n = 10;
A = RandomInteger[{1, m}, {n, 2}];
B = RandomReal[{-1, 1}, {n, 3}];
sparsematrix = SparseArray[A -> g /@ (B.{x, y, 0}), {m, m}];
matrix = Normal[sparsematrix]

And as function

f = r \[Function] SparseArray[A -> g /@ (B.r), {m, m}]

or

f = r \[Function] Normal[SparseArray[A -> g /@ (B.r), {m, m}]]

If indices in A have duplicates, you have to switch to additive matrix assembly wrapping SparseArray with some "decorations":

With[{spopt = SystemOptions["SparseArrayOptions"]},
 Internal`WithLocalSettings[
  SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> Total}],
  SparseArray[A -> g /@ (B.{x, y, 0}), {m, m}],
  SetSystemOptions[spopt]]
 ]

The wrapping with Internal`WithLocalSettings ensures that, afterwards, the value of "TreatRepeatedEntries" will be the same as before.

$\endgroup$
  • $\begingroup$ Thank you for this, I was not aware that SpareArray could be used in this way. I also haven't seen \[Function] used like this but it makes sense. However I still have the same problem that I started with which is that in the list A there are repeated indices, and I want to sum the corresponding g[B.r]. $\endgroup$ – Kai Feb 14 '18 at 17:12
  • $\begingroup$ Kai, even better: Typing in Mathematica, you can enter \[Function] by typing "esc" "f" "n" "esc". $\endgroup$ – Henrik Schumacher Feb 14 '18 at 17:18
  • $\begingroup$ Thanks, this is pretty neat, I have no experience using these sorts of system options, I don't have much experience beyond what is in the basic documentation! $\endgroup$ – Kai Feb 15 '18 at 4:00
  • $\begingroup$ how would I generalize this to make f a function of x and y, instead of the vector r? $\endgroup$ – Kai Feb 15 '18 at 4:04
  • $\begingroup$ Do you mean f = {x,y} \[Function] SparseArray[A -> g /@ (B.{x,y,0}), {m, m}]? $\endgroup$ – Henrik Schumacher Feb 15 '18 at 6:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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