I am not very good with MATLAB. Here is the problem statement & my attempt at a
ID: 3550557 • Letter: I
Question
I am not very good with MATLAB. Here is the problem statement & my attempt at a solution, please find the errors in the code so that it will perform the operation prescribed. Please do not write your own code from scratch, adjust the one given accordingly. [One of the problems I noticed was that the matrix I created was not filled with actual numbers, just the words 'double']
The code must include a working 10x10 example. (answer with output included will be favored)
function y = btridiag( a, b, c, f )
% Solves the [nxn] block - tridiagonal system for y
A = cell(5,5); %%create [5x5] matrix A
for i=1:5
for j=1:5
A{i,j}=rand(2,2); %%fill matrix A with random [2x2] submatrices
end
end
B = cell(5,1); %%create [5x1] matrix B
for i=1:5
for j=1:1
B{i,j}=rand(2,1); %%fill matrix B with random [2x1] submatrices
end
end
n=5;
a = rand(2,2);
b = rand(2,2);
c = rand(2,2);
f = rand(2,2);%% a,b,c,f are randomly generated vectors of length n
n = length(f);
B = zeros(n,1);
y(1) = B(1); %%define variables
w(1) = 1/a(1);
for i=2:n %recursive algorithm for value of x(i)
y(i) = B(i)-c(i)*w(i-1)*y(i-1);
w(i) = (a(i)-c(i)*w(i-1)*b(i-1))^-1;
end %%End forward sweep
x(n) = w(n)*y(n); %%Compute value of x3
for j=1:n-1;
k = n-j;
x(k) = w(k)*y(k)-w(k)*b(k)*x(k+1);
end %%End backward sweep, plug back in
%%Example
diagA(i, j) = a(i,j);
diagA(i, j+1) = b(i,j);
diagA(i-1, j) = c(i,j);
y = btridiag( a, b, c, f );
Explanation / Answer
Hello there I am attaching my code please go through it you will get the desired results
function A = blktridiag(Amd,Asub,Asup,n)
% BLKTRIDIAG: computes a sparse (block) tridiagonal matrix with n blocks
% usage: A = BLKTRIDIAG(Amd,Asub,Asup,n) % identical blocks
% usage: A = BLKTRIDIAG(Amd,Asub,Asup) % a list of distinct blocks
%
% BLKTRIDIAG runs in two distinct modes. The first mode
% supplies three blocks, one for the main diagonal, and
% the super and subdiagonal blocks. These blocks will be
% replicated n times down the main diagonals of the matrix,
% and n-1 times down the sub and super diagonals.
%
% The second mode is to supply a list of distinct blocks
% for each diagonal, as planes of 3d arrays. No replication
% factor is needed in this mode.
%
% arguments: (input mode 1)
% Amd - pxq array, forming the main diagonal blocks
%
% Asub - pxq array, sub diagonal block
% Asub must be the same size and shape as Amd
%
% Asup - pxq array, super diagonal block
% Asup must be the same size and shape as Amd
%
% n - scalar integer, defines the number of blocks
% When n == 1, only a single block will be formed, A == Amd
%
% arguments: (input mode 2)
% Amd - pxqxn array, a list of n distinct pxq arrays
% Each plane of Amd corresponds to a single block
% on the main diagonal.
%
% Asub - pxqx(n-1) array, a list of n-1 distinct pxq arrays,
% Each plane of Asub corresponds to a single block
% on the sub-diagonal.
%
% Asup - pxqx(n-1) array, a list of n-1 distinct pxq arrays,
% Each plane of Asup corresponds to a single block
% on the super-diagonal.
%
% Note: the sizes of Amd, Asub, and Asup must be consistent
% with each other, or an error will be generated.
%
% arguments: (output)
% A - (n*p by n*q) SPARSE block tridiagonal array
% If you prefer that A be full, use A=full(A) afterwards.
%
%
% Example 1:
% Compute the simple 10x10 tridiagonal matrix, with 2 on the
% diagonal, -1 on the off diagonal.
%
% A = blktridiag(2,-1,-1,10);
%
%
% Example 2:
% Compute the 5x5 lower bi-diagonal matrix, with blocks of
% [1 1;1 1] on the main diagonal, [2 2;2 2] on the sub-diagonal,
% and blocks of zeros above.
%
% A = blktridiag(ones(2),2*ones(2),zeros(2),5);
%
% Example 3:
% Compute the 3x6 tridiagonal matrix, with non-square blocks
% that vary along the main diagonal, [2 2] on the sub-diagonal,
% and [1 1] on the super-diagonal. Note that all blocks must have
% the same shape.
%
% A = blktridiag(rand(1,2,3),2*ones(1,2,2),ones(1,2,2));
%
%
% Which mode of operation are we in?
if nargin==4
% replicated block mode
% verify the inputs in this mode are 2-d arrays.
if (length(size(Amd))~=2) || ...
(length(size(Asub))~=2) || ...
(length(size(Asup))~=2)
error 'Inputs must be 2d arrays if a replication factor is provided'
end
% get block sizes, check for consistency
[p,q] = size(Amd);
if isempty(Amd)
error 'Blocks must be non-empty arrays or scalars'
end
if any(size(Amd)~=size(Asub)) || any(size(Amd)~=size(Asup))
error 'Amd, Asub, Asup are not identical in size'
end
if isempty(n) || (length(n)>1) || (n<1) || (n~=floor(n))
error 'n must be a positive scalar integer'
end
% scalar inputs?
% since p and q are integers...
if (p*q)==1
if n==1
A = Amd;
else
% faster as Jos points out
A = spdiags(repmat([Asub Amd Asup],n,1),-1:1,n,n);
end
% no need to go any farther
return
end
% use sparse. the main diagonal elements of each array are...
v = repmat(Amd(:),n,1);
% then the sub and super diagonal blocks.
if n>1
% sub-diagonal
v=[v;repmat(Asub(:),n-1,1)];
% super-diagonal
v=[v;repmat(Asup(:),n-1,1)];
end
elseif nargin==3
% non-replicated blocks, supplied as planes of a 3-d array
% get block sizes, check for consistency
[p,q,n] = size(Amd);
if isempty(Amd)
error 'Blocks must be (non-empty) arrays or scalars'
end
if (p~=size(Asub,1)) || (q~=size(Asub,2)) || (p~=size(Asup,1)) || (q~=size(Asup,2))
error 'Amd, Asub, Asup do not have the same size blocks'
end
if (n>1) && (((n-1) ~= size(Asub,3)) || ((n-1) ~= size(Asup,3)))
error 'Asub and Asup must each have one less block than Amd'
end
% scalar inputs?
if (p*q)==1
if n==1
A = Amd(1);
else
% best to just use spdiags
A = spdiags([[Asub(:);0], Amd(:), [0;Asup(:)]],-1:1,n,n);
end
% no need to go any farther
return
end
% The main diagonal elements
v = Amd(:);
% then the sub and super diagonal blocks.
if n>1
% sub-diagonal
v=[v;Asub(:)];
% super-diagonal
v=[v;Asup(:)];
end
else
% must have 3 or 4 arguments
error 'Must have either 3 or 4 arguments to BLKTRIDIAG'
end
% now generate the index arrays. first the main diagonal
[ind1,ind2,ind3]=ndgrid(0:p-1,0:q-1,0:n-1);
rind = 1+ind1(:)+p*ind3(:);
cind = 1+ind2(:)+q*ind3(:);
% then the sub and super diagonal blocks.
if n>1
% sub-diagonal
[ind1,ind2,ind3]=ndgrid(0:p-1,0:q-1,0:n-2);
rind = [rind;1+p+ind1(:)+p*ind3(:)];
cind = [cind;1+ind2(:)+q*ind3(:)];
% super-diagonal
rind = [rind;1+ind1(:)+p*ind3(:)];
cind = [cind;1+q+ind2(:)+q*ind3(:)];
end
% build the final array all in one call to sparse
A = sparse(rind,cind,v,n*p,n*q);
% ====================================
% end mainline
% ====================================
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.