# Tri-diagonal Matrix with varying diagonals

6 views (last 30 days)
Kevin Osborn on 4 Nov 2021
I am trying to create a tri-diagonal matrix with ones and a diagonal that changes according to a function.
Right now I have
z=zeros(99,1); z(1)=25; z(2)=1; A=toeplitz(z)
where the 25 is just a placeholder number for now. The value of 25 is what I want to change according the following for loop of
n = 99;
h = 0;
for i = 1:n
h = h + 1/n;
z = (2 + (0.1)*(h)^2)/.01
end
This gives 99 values from 200 to 210, but they change by a non-constant amount.
One thought I had was to put these output into a vector and then just use the diag() command and add the other diag(1)'s to it. But when I use the code
vector = [z]
it only returns the last value of 210 to me, not all 99 different values.
How would I go about changing all of the diagonals to be the number output by the for loop? Preferably, I would also like the a_11 and a_99 to also just be 1 instead of the values of the function, if possible.
Thank you very much.
Kevin Osborn on 4 Nov 2021
I could do this all manualy like this
v = [-1 200.0010 200.0041 200.0092 200.0163 200.0255 200.0367 200.0500 200.0653 200.0826];
w = [1 1 1 1 1 1 1 1 1];
u = [1 1 1 1 1 1 1 1 1];
diag(-v) + diag(w, 1) + diag(u, -1)
where this is just the 10x10 example instead of the full 99x99, but I was trying to avoid having to do everything by hand.

Bjorn Gustavsson on 4 Nov 2021
You have to set the elements of z to the values you want. In your version you set z to a new scalar (first time around the loop you convert the 99-by-1 z array to a scalar) every time around the loop. This you can do like this:
n = 99;
h = 0;
for i1 = 1:n % I changed the loop variable to i1 instead of i since i is also the imaginary unit
h = h + 1/n;
z(i1) = (2 + (0.1)*(h)^2)/.01;
end
z([11 99]) = 1;
HTH
##### 2 CommentsShowHide 1 older comment
Bjorn Gustavsson on 4 Nov 2021
It is not clear exactly what you want (to me at least). Can you boil it down to a smaller illustrating example then it might be easy enough to scale up the length of your arrays and fill the full matrix the way you want.
Do you want to put your z array on the main diagonal and have the first sub and sup-diagonals filled with ones? If so this ought to work:
n = 99;
h = 0;
for i1 = 1:n % I changed the loop variable to i1 instead of i since i is also the imaginary unit
h = h + 1/n;
z(i1) = (2 + (0.1)*(h)^2)/.01; % fill the array according to your original loop
end
z([11 99]) = 1; % setting the eleventh and ninetyfirst elements to 1.
dm1 = ones(numel(z)-1,1); % creating an array for the first sub-diagonal with 1
dp1 = ones(numel(z)-1,1); % creating an array for the first sup-diagonal with 1
M = diag(z) + diag(dm1,-1) + diag(dp1,1);