Error using vertcat-Dimensions of matrices being concatenated are not consistent - matlab

I'm new to Matlab and am trying to implement this scheme.
Scheme: Un+1 = Minv*((1+2theta)*Un + *Un-1 +bn+1 + fn+1
Given the following equation:
ut(x; t) = cuxx(x; t) + f(x; t)
where x belongs to ]0; 1[: t belongs to ]0; T[, T > 0 and c>0
with Dirichlet boundaries
conditions:
u(0; t) = alpha(t)
u(1; t) = beta(t)
t belongs to [0; T]
The goal of the function in the code is to determine the error(defined in the code).
I keep getting:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Error in wave1d_func11910448 (line 60)
uh=[UL;U;UR];
The code:
function [ h,err ] = wave1d_func11910448( nx )
a=0.0; b=1.0;
nx=20;
c=1.0;
tfinal=1;
h=(b-a)/(nx-1);
dt=0.5*h*h/c;
lambda=c*dt/h/h;
theta=1;
x=linspace(a,b,nx);
%defining the function f(x,t)
f = #(x,t) (pi^2-1)*exp(-t)*cos(pi*x)+4*x-2;
Fh=zeros(nx-2,1);%filling the vector f(n+1)
%defining the function g(x,t):initial condition-filling the vector U0
u = #(x) x.^2+cos(pi*x);
U0=u(x(2:end-1));
%defining the exact solution exact(x,t)
exact=#(x,t) x.^2+4*x*t+cos(pi*x)*exp(-t);
%filling the vector u1
U1=exact(x(2:end-1),1);
%defining the functions alpha(t) and beta(t)
alpha = #(t) exp(-t);
beta = #(t) -exp(-t)+4*t+1;
%filling the matrix Mh
Ah=diag(0.0*ones(1,nx-2),0)+diag(1.0*ones(1,nx-3),1)+diag(1.0*ones(1,nx-
3),-1);
Mh=eye(nx-2,nx-2)*(1+theta+2*lambda)-lambda*Ah;
Minv=inv(Mh);
Bh = zeros(nx-2,1);%filling the vector b
time=0.0;
i=0.0;
U2=Minv.*((1+2*theta )*U1-theta*U0+Bh+ dt*Fh);
while(time<tfinal)
time=time+dt;
i=i+1;
Bh(1)=lambda*alpha(time);Bh(nx-2)=lambda*beta(time);
Fh=f(x(2:end-1),time);
U=Minv.*((1+2*theta )*U1-theta*U0+Bh+ dt*Fh);
U0=U1;
U1=U2;
UL=alpha(time);
UR=beta(time);
uh=[UL;U;UR];
error(i) = norm(uh - exact(x,time),inf);
end
err=max(error);
expected results: err= a positive number <1
error message:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Error in wave1d_func11910448 (line 60)
uh=[UL;U;UR];

Related

matlab jacobi iteration method, giving me matrix dimensions must agree

below is my code to perform jacobi iterations to solve Ax=b.
I try this code on the matrix A =[4 -1 1; 4 -8 1; -2 1 5] and b=[7 -21 15].
and x is a first guess 1 x 3 vector. Are not these dimensions correct? It gives me the error in the code that calculates: r = b - x*A
and M\(x*N + b)
What am I missing?!? how do I fix this? please help!
function [x, error, iter, flag] = jacobi(A, x, b, maxiter, tol)
%implement jacobi iterations
%[x, error, iter, flag] = jacobi(A, x, b, maxiter, tol)
%jacobi.m solves the linear system Ax=b using the Jacobi iteration
%
%
%INPUT A the matrix of the system Ax=b
% x the first guess vector Ax=b
% b the vector in the system
% maxiter the maximum number of iteration to perform
% tol the tolerance
%
%OUTPUT x the solution vector
% error error norm
% niter the number of iterations it took
% flag indicates whether a solution was found. 0 means there was a
% solution and 1 means there was not a solution
iter = 0;
flag = 0;
bnrm2 = norm(b);
if (bnrm2 == 0)
bnrm2 = 1.0;
end
r = b - x*A;
error = norm(r) / bnrm2;
if (error<tol)
return;
end
[m,n] = size(A);
M = diag(diag(A));
N = diag(diag(A)) - A;
for iter = 1:maxiter,
oldx = x;
x = M\(x*N + b);
error = norm(x - oldx) / norm(x);
if (error <= tol)
break;
end
end
if (error > tol)
flag = 1;
end
Since, in the code, you're solving what I'll call (not sure if it's proper since I never do it) the left-multiply problem, the operator and order of matrices are, in some sense, reversed.
If you were solving the problem A*x = b with the residual r = b - A*x (i.e., x and b are column vectors), you would perform right-vector multiplies and left-matrix divides. Therefore, the update line in the loop would be
x = M \ (N*x + b);
Conversely, if you were solving the problem x*A = b with the residual r = b - x*A (i.e., x and b are row vectors), you would perform left-vector multiplies and right-matrix divides. Therefore, the update line in the loop would be
x = (x*N + b) / M;
Note that \ resolves to the function mldivide and / resolves to mrdivide. There is no function distinction for the multiply.
It appears your current updater mixes the two, which is bad news bears for dimension matching.

Strange error invoking ilaplace function in matlab

I am using ilaplace transform in matlab to compute the inverse Laplace transform of a function, however, I meet a strange error I cannot handle. Here is the output from matlab command line, where >> is the prompt. (s and t are syms symbolic variables)
>> N
N =
-(2.7071747341794232778783099808678e-34*(3.5938879023008902403763863659998e33*s - 68267793397927900578281423804583.0))/s^2
>> ilaplace(N)
Error using mupadmex
Error in MuPAD command: The argument is invalid. [_concat]
Evaluating: partfrac
Error in transform (line 74)
F = mupadmex('symobj::vectorizeSpecfunc', f.s, x.s, w.s, trans_func,
'infinity');
Error in sym/ilaplace (line 31)
F = transform('ilaplace', 's', 't', 'x', L, varargin{:});
>> ilaplace(-(2.7071747341794232778783099808678e-34*(3.5938879023008902403763863659998e33*s - 68267793397927900578281423804583.0))/s^2)
ans =
(23990078920530555628928726307903*t)/1298074214633706907132624082305024 - 4933332333844707562298796153537/5070602400912917605986812821504
The prblem is, if I directly invoke ilaplace(N), I have an error. However, if I pass the expression to ilaplace, I have the right answer. I don't know why.
EDIT: The complete code file is as follows.
syms s t;
syms s positive;
syms t positive;
tau = 4.2562313045743237429846099474892;
V_fitted = 1 - 1.015*exp(-0.0825*t); % CDF function
V_fitted_right_shift = subs(V_fitted, t, t - tau); % right shift CDF by tau
lambda_out = 1 / ( tau + int((1 - V_fitted_right_shift), [tau, Inf]) ); %arrival rate of the process
K = 4; %number of processes
V_CDF_superposed = 1 - (1 - V_fitted_right_shift)*(lambda_out * int((1-V_fitted_right_shift), [t-tau, Inf]))^(K - 1); %new CDF
FV_CDF_superposed = vpa(V_CDF_superposed);
Laplace_V_CDF_superposed = laplace(FV_CDF_superposed); %laplace transform
N = Laplace_V_CDF_superposed/(1 - s * Laplace_V_CDF_superposed);
N = vpa(N);
N = simplify(N);
N_t = ilaplace(N);

Use Matlab/Maple to find roots of a nonlinear equation

I am having difficulty in finding roots of a nonlinear equation. I have tried Matlab and Maple both, and both give me the same error which is
Error, (in RootFinding:-NextZero) can only handle isolated zeros
The equation goes like
-100 + 0.1335600000e-5*H + (1/20)*H*arcsinh(2003.40/H)
The variable is H in the equation.
How do I find the roots (or the approximate roots) of this equation?
Matlab Code:
The function file:
function hor_force = horizontal(XY, XZ, Lo, EAo, qc, VA)
syms H
equation = (-1*ZZ) + (H/qc)*(cosh((qc/H)*(XZ- XB))) - H/qc + ZB;
hor_force = `solve(equation);`
The main file:
EAo = 7.5*10^7;
Lo = 100.17;
VA = 2002;
XY = 0;
ZY = 0;
XB = 50;
ZB = -2;
XZ = 100;
ZZ = 0;
ql = 40;
Error which Matlab shows:
Error using sym/solve (line 22)
Error using maplemex
Error, (in RootFinding:-NextZero) can only handle isolated zeros
Error in horizontal (line 8)
hor_force = solve(equation);
Error in main (line 34)
h = horizontal(XY, XZ, Lo, EAo, ql, VA)
http://postimg.org/image/gm93z3b7z/
You don't need the symbolic toolbox for this:
First, create an anonymous function that can take vectors at input (use .* and ./:
equation = #(H) ((-1*ZZ) + (H./qc).*(cosh((qc./H).*(XZ- XB))) - H./qc + ZB);
Second, create a vector that you afterwards insert into the equation to find approximately when the sign of the function changes. In the end, use fzero with x0 as the second input parameter.
H = linspace(1,1e6,1e4);
x0 = H(find(diff(sign(equation(H))))); %// Approximation of when the line crosses zero
x = fzero(equation, x0) %// Use fzero to find the crossing point, using the initial guess x0
x =
2.5013e+04
equation(x)
ans =
0
To verify:
You might want to check out this question for more information about how to find roots of non-polynomials.
In Maple, using the expression from your question,
restart:
ee := -100 + 0.1335600000e-5*H + (1/20)*H*arcsinh(2003.40/H):
Student:-Calculus1:-Roots(ee, -1e6..1e6);
[ 5 ]
[-1.240222868 10 , -21763.54830, 18502.23816]
#plot(ee, H=-1e6..1e6, view=-1..1);

Create flexible function handle

I am using numerical integration in MATLAB, with one varibale to integrate over but the function also contains a variable number of terms depending on the dimension of my data. Right now this looks like the following for the 2-dimensional case:
for t = 1:T
fxt = #(u) exp(-0.5*(x(t,1)-theta*norminv(u,0,1)).^2) .* ...
exp(-0.5*(x(t,2) -theta*norminv(u,0,1)).^2);
f(t) = integral(fxt,1e-4,1-1e-4,'AbsTol',1e-3);
end
I would like to have this function flexible in the sense that there could be any number of data points in, each in the following term:
exp(-0.5*(x(t,i) -theta*norminv(u,0,1)).^2);
I hope this is understandable.
If x and u have a valid dimension match (vector-vector or array-scalar) for the subtraction, you can put the whole matrix x into the handle and pass it to the integral function using the name-parameter pair ('ArrayValued',true):
fxt = #(u) exp(-0.5*(x - theta*norminv(u,0,1)).^2) .* ...
exp(-0.5*(x - theta*norminv(u,0,1)).^2);
f = integral(fxt,1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
[Documentation]
You may need a loop if integral ever passes a vector u into the handle.
But in looking at how the integral function is written, the integration nodes are entered as scalars for array-valued functions, so the loop shouldn't be necessary unless some weird dimension-mismatch error is thrown.
Array-Valued Output
In response to the comments below, you could try this function handle:
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1)).^2),2);
Then your current loop would look like
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1)).^2),2);
k = 2;
for t = 1:T
f(t) = integral(#(u)fx(u,t,k),1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
end
The ArrayValued flag is needed since x and u will have a dimension mismatch.
In this form, another loop would be needed to sweep through the k indexes.
However, we can improve this function by skipping the loop altogether since each iterate of the loop is independent by using the ArrayValued mode:
fx = #(u,k) prod(exp(-0.5*(x(:,1:k)-theta*norminv(u,0,1)).^2),2);
k = 2;
f = integral(#(u)fx(u,k),1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
Vector-Valued Output
If ArrayValued is not desired, which may be the case if the integration requires a lot of subdivisions and a vector-valued u is preferable, you can also try a recursive version of the handle using cell arrays:
% x has size [T,K]
fx = cell(K,1);
fx{1} = #(u,t) exp(-0.5*(x(t,1) - theta*norminv(u,0,1)).^2);
for k = 2:K
fx{k} = #(u,t) fx{k-1}(u,t).*exp(-0.5*(x(t,k) - theta*norminv(u,0,1)).^2);
end
f(T) = 0;
k = 2;
for t = 1:T
f(t) = integral(#(u)fx{k}(u,t),1e-4,1-1e-4,'AbsTol',1e-3);
end
ThanksTroy but now I run into the follwing:
x = [0.3,0.8;1.5,-0.7];
T = size(x,1);
k = size(x,2);
theta= 1;
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k) - theta*norminv(u,0,1))^2));
for t = 1,T
f(t) = integral(#(u)fx(u,t,k),1e-4,1-1e-4,'AbsTol',1e-3);
end
Error using -
Matrix dimensions must agree.
Error in #(u,t,k)prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1))^2))
Error in #(u)fx(u,t,k)
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 133)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 76)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 89)
Q = integralCalc(fun,a,b,opstruct);

Cubic spline interpolation of function

I am trying to interpolate the following function using the MATLAB function spline,
at equidistant points xi = i./n, i = 0,1,...,n, and for n = 2^j, j = 4,5,...,14.
For each calculation, I record the maximum error at the points x = 0:0.001:1 and plot these errors against n using a loglog plot.
Below is the code,
index=1
for j = 4:1:14;
n = 2^j;
i = 0:1:n;
xi = i./n;
yi = ((exp(3*xi))*sin(200.*(xi.^2))) ./(1+20.*(xi.^2));
x = 0:.001:1;
ye = ((exp(3*x))*sin(200*x.^2)) ./(1+20*x.^2);
yp = spline(x,xi,yi);
err = ye - yp;
merr(index) = max(err);
index = index+1;
end
n1 = 10:10:170;
loglog(n1, merr,'.')
xlabel('n');
ylabel('errors');
title('Cubic Splines');
but when I run the code, I got the following error:
Error using * Inner matrix dimensions must agree.
Error in (line 9) yi = ((exp(3*xi))sin(200.(xi.^2)))
./(1+20.*(xi.^2));
I'm just starting learning MatLab, can anyone help?
You want element-wise multiplication (.*) for the following part of code:
yi = ((exp(3*xi))*sin(200.*(xi.^2))) ./(1+20.*(xi.^2));
should be
yi = ((exp(3*xi)).*sin(200.*(xi.^2))) ./(1+20.*(xi.^2));
The same issue is present for the computation of ye.
When you use mtimes (*), MATLAB tries to do matrix multiplication, which in your case (1-by-n times 1-by-n) is invalid.
Then you will run into a problem with your spline command. Change it to yp = spline(xi,yi,x); so that the values at which you want to interploate (x) are the last argument.