Mathematica Asked by Luqman Saleem on September 13, 2020
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).
Correct answer by Sjoerd Smit on September 13, 2020
You can use KroneckerProduct
s 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 $15times15$ 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.
Answered by flinty on September 13, 2020
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}];
MatrixForm[sa] // TraditionalForm
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;
s // MatrixForm // TraditionalForm
s = ArrayFlatten[s];
MatrixForm@s // TraditionalForm
Answered by Tim Laska on September 13, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP