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
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.
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);
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);
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);
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.