TransWikia.com

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

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;

3 Answers

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

enter image description here

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

enter image description here

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

enter image description here

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

enter image description here

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 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 $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

enter image description here

Answered by Tim Laska on September 13, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP