# Function to create a square matrix with and assign values

I am trying to create a function that returns a matrix as in the description below.

The function has five inputs:

• M: name of the matrix
• n: size of the matrix nxn
• a, b, c: integer numbers with $0 \le a,b, c\le n$

Next I will assign elements of the matrix with both non-zero column and non-zero row indices as below. All the remaining elements are assigned 0 values.

M[[a,a]] = x11;

M[[a,b]] = x12;

M[[a,c]] = x13;

M[[b,a]] = x21;

M[[b,b]] = x22;

M[[b,c]] = x23;

M[[c,a]] = x31;

M[[c,b]] = x32;

M[[c,c]] = x33;

How can I do this? I don't know how to give name M as an input to a function, and also this function is complex to me. I haven't written any function with more many code lines like this.

For now I am just starting something, but I am not sure if it is correct.

myfunc[M_, n_, a_, b_, c_] := (M = Table[0, {n}, {n}];

If[a > 0, M[[a,a]] = x11, M[[a,a]] = 0];
If[a > 0 && b > 0, M[[a,b]] = x12, M[[a,b]] = 0];
If[a > 0 && c > 0, M[[a,c]] = x13, M[[a,c]] = 0];
If[b > 0, M[[b,b]] = x22, M[[b,b]] = 0];
If[b > 0 && a > 0, M[[b,a]] = x21, M[[b,a]] = 0];
If[b > 0 && c > 0, M[[b,c]] = x23, M[[b,c]] = 0];
If[b > 0 && a > 0, M[[b,a]] = x21, M[[b,a]] = 0];
If[b > 0, M[[b,b]] = x22, M[[b,b]] = 0];
If[b > 0 && c > 0, M[[b,c]] = x23, M[[b,c]] = 0];
If[c > 0 && a > 0, M[[c,a]]= x31, M[[c,a]] = 0];
If[c > 0 && b > 0, M[[c,b]] = x32, M[[c,b]] = 0];
If[c > 0, M[[c,c]] = x33, M[[c,c]] = 0];)

Here is another, (more flexible?) way:

f[n_Integer, list_?VectorQ, vals_?MatrixQ] := Module[{M, idx, idx1},
idx = Pick[Range[Length[list]], UnitStep[list - 1] UnitStep[n - list], 1];
M = ConstantArray[0, {n, n}];
idx1 = list[[idx]];
M[[idx1, idx1]] = vals[[idx, idx]];
M
]

xx = Array[ToExpression[StringJoin["x", IntegerString[{##}]]] &, {3, 3}];
M = f[8, {1, 4, 7}, xx];
M//MatrixForm

$$\left( \begin{array}{cccccccc} \text{x11} & 0 & 0 & \text{x12} & 0 & 0 & \text{x13} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \text{x21} & 0 & 0 & \text{x22} & 0 & 0 & \text{x23} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \text{x31} & 0 & 0 & \text{x32} & 0 & 0 & \text{x33} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$$

Edit

Entries $i$ in list will now also be ignored if they do not fullfil $1 \leq i \leq n$.

• Thanks, short and great too! – anhnha Mar 10 '18 at 12:29
• Hi, when one input is zero, the code doesn't work. Assume that a = 0 but b, c are non-zero then elements with bc, cb also should be assigned as above. How can I fix that? – anhnha Mar 10 '18 at 17:47
• Mathematica's array are 1-based; index zero makes no sense. But you can enter, e.g., f[8, {4,7}, xx] if want to set only two colums and two rows. In fact, the second argument list can be any list of integers between 1 and n of length at most the length of the matrix vals (which is suppose to be a square matrix). – Henrik Schumacher Mar 10 '18 at 18:01
• Maybe you misunderstood a bit. For example, f[4,0,2,3] then only the elements [[2,2]], [[2,3]] [[3,2]], [[3,3]] are set to their x values. Like this: i.imgur.com/SUMOdiC.png – anhnha Mar 10 '18 at 18:22
• Ah, I think I got it. See my edit. – Henrik Schumacher Mar 10 '18 at 18:37

Here's one way:

myfunc[n_Integer?Positive, a_Integer?Positive, b_Integer?Positive, c_Integer?Positive] /;
Max[a, b, c] <= n :=
{x11, x12, x13, x21, x22, x23, x31, x32, x33}], {n, n}]]

Test:

myfunc[8, 1, 4, 7] // MatrixForm

$$\begin{pmatrix} \mathtt{x11} & 0 & 0 & \mathtt{x12} & 0 & 0 & \mathtt{x13} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \mathtt{x21} & 0 & 0 & \mathtt{x22} & 0 & 0 & \mathtt{x23} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \mathtt{x31} & 0 & 0 & \mathtt{x32} & 0 & 0 & \mathtt{x33} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{pmatrix}$$

If you want to be able to use 0 as an indicator to ignore an entry:

myfunc[n_Integer?Positive, a_Integer?NonNegative,
b_Integer?NonNegative, c_Integer?NonNegative] /; Max[a, b, c] <= n :=
Tuples[{a, b, c}, {2}] ->
{x11, x12, x13, x21, x22, x23, x31, x32, x33}], FreeQ[First[#], 0] &], {n, n}]]

Test:

myfunc[8, 0, 4, 7] // MatrixForm

$$\begin{pmatrix} 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & \mathtt{x22} & 0 & 0 & \mathtt{x23} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & \mathtt{x32} & 0 & 0 & \mathtt{x33} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{pmatrix}$$

Here's a SparseArray[] equivalent of Henrik's routine:

myfuncgen[n_Integer?Positive, idx_List, ent_?SquareMatrixQ] /;
Length[idx] <= n && Length[idx] == Length[ent] &&
VectorQ[idx, IntegerQ] && 0 <= Min[idx] && Max[idx] <= n :=
FreeQ[First[#], 0] &], {n, n}]]

Test:

myfuncgen[8, {1, 0, 7},
Array[Symbol["x" <> IntegerString[#1] <> IntegerString[#2]] &, {3, 3}]]

$$\begin{pmatrix} \mathtt{x11} & 0 & 0 & 0 & 0 & 0 & \mathtt{x13} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \mathtt{x31} & 0 & 0 & 0 & 0 & 0 & \mathtt{x33} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{pmatrix}$$

• Thanks a lot. Look great but that beyond my current lever! I need to practice more! I wrote my code above. It is somewhat long and many errors. – anhnha Mar 10 '18 at 12:27
• Hi, I just checked that when one input is zero, the code doesn't work. Assume that a = 0 but b, c are non-zero then elements with bc, cb also should be assigned as above. How can I fix that? – anhnha Mar 10 '18 at 14:04
• For example, f[4,0,2,3] then only the elements [[2,2]], [[2,3]] [[3,2]], [[3,3]] are set to their x values. We only set elements with indices non-zero Like this:i.imgur.com/SUMOdiC.png – anhnha Mar 10 '18 at 18:23
• @anhnha, check now – J. M.'s torpor Mar 10 '18 at 21:48
• Yeah, it works well now. Thanks! – anhnha Mar 10 '18 at 22:59