I've written a matlab m-file to draw a double integral as below. Does everybody can show me its equivalent in mathematica???
tetha = pi/4;
lamb = -1;
h = 4;
tetha0 = 0;
syms x y l
n = [h.*((cos(tetha)).^2)./sin(tetha); h.*abs(cos(tetha)); 0];
ft = ((tetha - pi/2)./sin(tetha)).^4;
Rt = [cos(tetha) -sin(tetha); sin(tetha) cos(tetha)];
zt = [cos(tetha0) -sin(tetha0); sin(tetha0) cos(tetha0)];
lt = [x;y];
integrand = #(x,y)(ft.*h.*((abs(cos(tetha)).* (x.*cos(tetha)-y.*sin(tetha)))-((cos(tetha)).^2/sin(tetha)).*(x.*sin(tetha)+y.*cos(tetha))));
PhiHat = #(a,b)(dblquad(integrand,0,a,0,b));
ezsurfc(PhiHat,[0,5,0,5])
Here you go (only minimal changes made), but you'll have to do your homework to understand function definitions, integration, plotting etc. in Mathematica. Also, this is not idiomatic Mathematica, but let's not go there...
tetha=Pi/4;
lamb=-1;
h=4;
tetha0=0;
n={h*((Cos[tetha])^2)/Sin[tetha],h*Abs[Cos[tetha]],0};
ft=((tetha-Pi/2)/Sin[tetha])^4;
Rt={{Cos[tetha], -Sin[tetha]}, {Sin[tetha], Cos[tetha]}};
zt={{Cos[tetha0], -Sin[tetha0]}, {Sin[tetha0], Cos[tetha0]}};
integrand[x_,y_]:= (ft*h*((Abs[Cos[tetha]]*(x*Cos[tetha]-y*Sin[tetha]))-((Cos[tetha])^2/Sin[tetha])*(x*Sin[tetha]+y*Cos[tetha])));
PhiHat[a_,b_]:=NIntegrate[integrand[x,y],{x,0,a},{y,0,b}];
Plot3D[PhiHat[x,y],{x,0,5},{y,0,5}]
Related
I wrote a script to compare the answers between integrating an equation exactly, summing it, and using various built-in numerical integration functions.
Here is my program:
xmin = -2*pi;
xmax = -xmin;
dx = 0.01;
x = [xmin:dx:xmax];
f = sin(x);
fstar = conj(f);
y = fstar.*f; %for the sum
fy = #(x) y;
fsum1 = sum(y.*dx); %approximation by treating integral as a sum
%definite integral (specific to int(sin^2(x)))
fsum2 = 0.5.*(xmax - sin(xmax).*cos(xmax) - xmin + sin(xmin).*cos(xmin));
%numerical integrations:
fsum3 = quad(fy,xmin,xmax);
fsum4 = quadv(fy,xmin,xmax);
fsum5 = quadl(fy,xmin,xmax);
fsum6 = quadgk(fy,xmin,xmax);
fsum7 = quadcc(fy,xmin,xmax);
Everything runs fine until it hangs on fsum4. Well, I should say that fsum1 and fsum2 work. However, fsum3 = 7.53812e-031 (wrong) and fsum4 = a matrix the same size as x. When I plot fsum4 vs. x I get a (sin(x))^2 function with an amplitude of a little over 12.
I've gotten the quad integration function to work before, but I don't understand what I'm doing wrong here.
I'm trying to solve a system of ordinary differential equations in MATLAB.
I have a simple equation:
dy = -k/M *x - c/M *y+ F/M.
This is defined in my ode function test2.m, dependant on the values X and t. I want to trig 'F' with a signal, generated by my custom function squaresignal.m. The output hereof, is the variable u, spanding from 0 to 1, as it is a smooth heaviside function. - Think square wave. The inputs in squaresignal.m, is t and f.
u=squaresignal(t,f)
These values are to be used inside my function test2, in order to enable or disable variable 'F' with the value u==1 (enable). Disable for all other values.
My ode function test2.m reads:
function dX = test2(t ,X, u)
x = X (1) ;
y = X (2) ;
M = 10;
k = 50;
c = 10;
F = 300;
if u == 1
F = F;
else
F = 0,
end
dx = y ;
dy = -k/M *x - c/M *y+ F/M ;
dX = [ dx dy ]';
end
And my runscript reads:
clc
clear all
tstart = 0;
tend = 10;
tsteps = 0.01;
tspan = [0 10];
t = [tstart:tsteps:tend];
f = 2;
u = squaresignal(t,f)
for ii = 1:length(u)
options=odeset('maxstep',tsteps,'outputfcn',#odeplot);
[t,X]=ode15s(#(t,X)test2(t,X,u(ii)),[tstart tend],[0 0],u);
end
figure (1);
plot(t,X(:,1))
figure (2);
plot(t,X(:,2));
However, the for-loop does not seem to do it's magic. I still only get F=0, instead of F=F, at times when u==1. And i know, that u is equal to one at some times, because the output of squaresignal.m is visible to me.
So the real question is this. How do i properly pass my variable u, to my function test2.m, and use it there to trig F? Is it possible that the squaresignal.m should be inside the odefunction test2.m instead?
Here's an example where I pass a variable coeff to the differential equation:
function [T,Q] = main()
t_span = [0 10];
q0 = [0.1; 0.2]; % initial state
ode_options = odeset(); % currently no options... You could add some here
coeff = 0.3; % The parameter we wish to pass to the differential eq.
[T,Q] = ode15s(#(t,q)diffeq(t,q,coeff),t_span,q0, ode_options);
end
function dq = diffeq(t,q,coeff)
% Preallocate vector dq
dq = zeros(length(q),1);
% Update dq:
dq(1) = q(2);
dq(2) = -coeff*sin(q(1));
end
EDIT:
Could this be the problem?
tstart = 0;
tend = 10;
tsteps = 0.01;
tspan = [0 10];
t = [tstart:tsteps:tend];
f = 2;
u = squaresignal(t,f)
Here you create a time vector t which has nothing to do with the time vector returned by the ODE solver! This means that at first we have t[2]=0.01 but once you ran your ODE solver, t[2] can be anything. So yes, if you want to load an external signal source depending on time, then you need to call your squaresignal.m from within the differential equation and pass the solver's current time t! Your code should look like this (note that I'm passing f now as an additional argument to the diffeq):
function dX = test2(t ,X, f)
x = X (1) ;
y = X (2) ;
M = 10;
k = 50;
c = 10;
F = 300;
u = squaresignal(t,f)
if u == 1
F = F;
else
F = 0,
end
dx = y ;
dy = -k/M *x - c/M *y+ F/M ;
dX = [ dx dy ]';
end
Note however that matlab's ODE solvers do not like at all what you're doing here. You are drastically (i.e. non-smoothly) changing the dynamics of your system. What you should do is to use one of the following:
a) events if you want to trigger some behaviour (like termination) depending on the integrated variable x or
b) If you want to trigger the behaviour based on the time t, you should segment your integration into different parts where the differential equation does not vary during one segment. You can then resume your integration by using the current state and time as x0 and t0 for the next run of ode15s. Of course this only works of you're external signal source u is something simple like a step funcion or square wave. In case of the square wave you would only integrate for a timespan during which the wave does not jump. And then exactly at the time of the jump you start another integration with altered differential equations.
Following code throws out an error.
syms z positive;
syms n;
syms m;
N = 10;
Ms = 10;
Es = 1;
pd = 0.9;
pd_dash = 1-pd;
pf = 0.1;
pf_dash = 1-pf;
pr = 0.1;
qr = 1-pr;
p = 0.005
pi = pf_dash*p;
pb = pd_dash*p;
qi = 1-pi;
qb = 1-pb;
sm = symsum( z^((n+1)*Es), n, 0, N-1 );
temp_sum = symsum(z^((n+m+1)*Es)*qr^(n+m)*pr, m, 0, N-1);
z=1; %assume a value of z
x = eval(sm); %works fine
y = eval(temp_sum);
% Error:The expression to the left of the equals sign is not a valid target for an assignment.
Please suggest a way to resolve this.
The problem that I suspect is: the temp_sum comes out to be in piecewise(...) which eval is not capable of evaluating.
What you actually did:
Create a symbolic expression
Create a variable z which is unused
Call a undocumented function sym/eval
I assume you wanted to:
Create a symbolic expression
Substitute z with 1: temp_sum=subs(temp_sum,z,1)
get the result. Here I don't know what you really have because I don't know which variables are symbolic unknowns and which constants. Try simplify(temp_sum). If you substituted all unknowns it should return a number.
So, currently I am trying to find the numerical solutions for the berger equation, $u_t+u∗u_x=0$. The numerical solution to this equation is:
$u^{n+1}_j=u_n^j−\frac{Δx}{Δt}u^n_j(u^n_j−u^n_{j−1})$
I wrote code on Matlab that computes this. As you can see, there is only one for-loop in the code. However, my u matrix extremely large, the algorithm becomes slow. Is there a way for me to use no loops at all. I was thinking about using the command cumsum, but I am not sure how to integrate that to my program. Please look at my code. Thanks.
dx = 0.9;
dt = 0.9;
tf = 10;
l = 10;
xstep = [-1:dx:l];
tstep = [0:dt:tf];
uinit = zeros(length(tstep),length(xstep));
%%Setting Initial and Boundary Conditions
bc.left = #(t) 2;
bc.right = #(t) -1;
ic = #(x) ...
2*(x<=0) ...
-1*(x>0);
uinit(1, :) = ic(xstep);
uinit(:, 1) = bc.left(tstep);
uinit(:, end) = bc.right(tstep);
%% Numerical method part
for c=1:(length(tstep)-1)
uinit(2:end -1, c+1) = uinit(2:end -1, c) - dx/dt*(uinit(2:end -1, c).*(uinit(2:end-1, c) - uinit(1:end-2, c)));
end
surf(xstep,tstep,uinit)
I'm following a Numerical Methods course and I made a small MATLAB script to compute integrals using the trapezoidal method. However my script uses a FOR loop and my friend told me I'm doing something wrong if I use a FOR loop in Matlab. Is there a way to convert this script to a Matlab-friendly one?
%Number of points to use
N = 4;
%Integration interval
a = 0;
b = 0.5;
%Width of the integration segments
h = (b-a) / N;
F = exp(a);
for i = 1:N-1
F = F + 2*exp(a+i*h);
end
F = F + exp(b);
F = h/2*F
Vectorization is important speed and clarity, but so is using built-in functions whenever possible. Matlab has a built in function for trapezoidal numerical integration called trapz. Here is an example.
x = 0:.125:.5
y = exp(x)
F = trapz(x,y)
It is recommended to vectorize your code.
%Number of points to use
N = 4;
%Integration interval
a = 0;
b = 0.5;
%Width of the integration segments
h = (b-a) / N;
x = 1:1:N-1;
F = h/2*(exp(a) + sum(2*exp(a+x*h)) + exp(b));
However, I've read that Matlab is no longer slow at for loops.