Changing value of specific element in an array. (Converting code from MATLAB to Mathematica)

Can we change the value of a specific element of an array in Mathematica?

Basically, I have the following given MATLAB script which writes a big 3N-by-3N matrix $$h$$ by combining two 3-by-3 matrices $$Hch$$ and $$tau$$. The connection between big $$h$$ and $$Hch$$ and $$tau$$ is as follows (for N=5):

$$h= \begin{bmatrix} Hch &tau &0 &0 &0 \\ tau'&Hch &tau &0 &0\\ 0 &tau'&Hch &tau &0\\ 0 &0&tau'&Hch &tau\\ 0 &0 &0 &tau'&Hch\\ \end{bmatrix}$$ I don't know how to convert my Matlab code's expressions like h( (3*x)+1:...) = Hch into Mathematica. Please help. Is there any other way to get what my Matlab code doing in Mathematica?

Hch = -[-4*Delta     f(k1)*T   T';
f(-k1)*T'   -4*Delta       T;
T       T'      -4*Delta];

tau = -[0        0       T';
0        0   T*exp(-1i*k1);
0        0       0];

h = zeros(3*N,3*N);

for x = 0:N-1

h((3*x)+1:(3*(x+1)),(3*x)+1:(3*(x+1))) = Hch; %diagonal elements-> (3*x)+1 : 3*(x+1) = Hch

if x~=N-1 %assigning off-diagonal elements.
h((3*x)+1:(3*(x+1)), (3*(x+1))+1:(3*(x+2))) = tau;
h((3*(x+1))+1:(3*(x+2)), (3*x)+1:(3*(x+1))) = tau';
end

end

h(1,1)= h(1,1)-Delta;
h(end,end)=h(end,end)-Delta;


In Mathematica you can do Part assignment just like in MATLAB. The basic trick is to first find the Part ([[...]]) specification that gets you the element(s) you want to change and then set new values to them. For example:

mat = RandomReal[1, {5, 4}];
mat // MatrixForm


Suppose you want to set new values to the top-left 2x2 block. You can access this block with (see: Span):

mat[[1 ;; 2, 1 ;; 2]]


{{0.30199, 0.0987905}, {0.985639, 0.475623}}

Now you can either set them all to the same value with:

mat[[1 ;; 2, 1 ;; 2]] = 0;
mat // MatrixForm


You can also set the values to a new matrix with the same dimensions. For example:

mat[[1 ;; 2, 1 ;; 2]] = {{2, -1}, {-2, 3}};
mat // MatrixForm


You can similarly set a row or column to new values. The 3rd column is accessed by:

mat[[All, 3]]


{0.428241, 0.282653, 0.615479, 0.144433, 0.407897}

Set new values to it:

mat[[All, 3]] = {1, 2, 3, 2, 1};
mat // MatrixForm


As long as you make sure that whatever you're assigning to a part has the same shape as whatever comes out when you access that part, it should work. Or you can also assign a constant, like in the first example.

Just be sure to use only a single Part query. You can't assign something to mat[[1]][[2]] (1st row, 2nd column) because that uses two queries. Use mat[[1, 2]] instead. Other than that, you can use all legal Part queries for assignment, such as mat[[All, {1, 4}]] (1st and 4th column) and mat[[{1, 3, 5}, {2, 4}]] (rows 1, 3 and 5 and columns 2 and 4).

• right to the point. even though this is longer than the answer given by Ms/Sir flinty, I would like to accept this as answer to my question because of the title of my question. Jul 23, 2020 at 14:50

You can use KroneckerProducts to expand a matrix block at elements where a 1 appears with zero everywhere else:

h = KroneckerProduct[IdentityMatrix[5], Hch] +
KroneckerProduct[DiagonalMatrix[ConstantArray[1, 4], 1], tau] +
KroneckerProduct[DiagonalMatrix[ConstantArray[1, 4], -1], ConjugateTranspose[tau]]


This will give you a $$15\times15$$ matrix with the $$Hch$$ matrix blocks on the main block diagonal, $$tau$$ on the above block band diagonal, and $$tau^\top$$ on the below block band diagonal.

• wow. that's very easy. Thank you very much. Jul 23, 2020 at 14:49

Here is an alternate approach using SparseArray, ReplaceAll, and ArrayFlatten:

sa = SparseArray[{{i_, i_} -> Hch, {i_, j_} /; i - j == 1 ->
ConjugateTranspose[tau], {i_, j_} /; i - j == -1 -> tau}, {5, 5}];
subs = {
Hch -> -{{-4*Delta, f (k1)*T, T'},
{f (-k1)*T', -4*Delta, T},
{T, T', -4*Delta}},

tau -> -{{0, 0, T'},
{0, 0, T*Exp[-1 I*k1]},
{0 , 0, 0}},
0 -> ConstantArray[0, {3, 3}]
};
s = Normal[sa] /. subs;