quad for multivariable functions - matlab

I have a function f(x, y, z, t) which has 4 different variables, and I want to find the numerical integration of it with quad in case of just one variable:
quad(f(x,y,z,t), x, 0, inf) %// numerical integration in case of x
Is it possible? I assume I need symbolic result. Do you have any other idea?

If you want to "fix" y, z and t to some parameters, say y0, z0 and t0 and integrate the function h(x) = f(x, y0, z0, t0) you can use annonymuous function:
quad( #(x) f( x, y0, z0, t0 ), x, 0, inf );
EDIT:
To get a matlab function that depends on y z and t you can do:
function area = marginalizeX( y0, z0, t0 )
% integrate f(x,y,z,t) over x while fixing y0, z0, and t0
area = quad( #(x) f( x, y0, z0, t0 ), x, 0, inf );

Related

Matlab solving ODEs can not understand this function description

I have stumbled upon this matlab code that solves this ODE
y'''(t) + a y(t) = -b y''(t) + u(t)
but I am confused by the ode_system function definition, specifically by the y(2) y(3) part. I would greatly appreciate if someone can shed some light
y(2) y(3) part in the ode_system function confuses me and how it contributes to overaal solution
% Define the parameters a and b
a = 1;
b = 2;
% Define the time horizon [0,1]
time_horizon = [0, 1];
% Define the initial conditions for y, y', and y''
initials = [0; 0; 0];
% Define the function handle for the input function u(t)
%sin(t) is a common example of a time-varying function.
% You can change the definition of u to any other function of time,
% such as a constant, a step function, or a more complex function, depending on your needs
u = #(t) sin(t);
% Define the function handle for the system of ODEs
odefunction = #(t, y) ode_system(t, y, a, b, u);
% Solve the ODEs using ode45
[t, y] = ode45(odefunction, time_horizon, initials);
% Plot the solution
plot(t, y(:,1), '-', 'LineWidth', 2);
xlabel('t');
ylabel('y');
function dydt = ode_system(t, y, a, b, u)
%Define the system of ODEs
dydt = [y(2); y(3); -b*y(3) + u(t) - a*y(1)];
end
This is more of a maths question than a Matlab one.
We would like to rewrite our ODE equation so that there is a single time derivative on the left-hand side and no derivatives on the right.
Currently we have:
y'''(t)+ay(t)=-by''(t)+u(t)
By letting z = y' and x = z' (= y''), we can rewrite this as:
x'(t)+a y(t)=-b x(t)+u(t)
So now we have 3 equations in the form:
y' = z
z' = x
x' = -b * x + u - a *y
We can also think of this as a vector equation where v = (y, z, x).
The right-hand side would then be,
v(1)' = v(2)
v(2)' = v(3)
v(3)' = -b * v(3) + u - a * v(1)
which is what you have in the question.

Plotting four variables u = f(x, y, z) with ranges of x, y, z in Matlab

I'm trying to plot four variables (x, y, z, u) in a 3D space.
Below I defined u = f(x,y,z) = (x-y)/z and ranges for x, y and z.
Then I used the scatter3 function for plotting.
But the linspace command only returned
u1 = f(x1, y1, z1)
u2 = f(x2, y2, z2)
...
I wanted to plot my variables so that I would get values of u for all x, y and z, so as well as u_i = f(x_i, y_i, z_i), I want:
u112 = f(x1, y1, z2)
u121 = f(x1, y2, z1)
...
Which function do I need to use for this?
Full code:
z = linspace(1,2,50);
y = linspace(0,0.5,50);
x = linspace(-1,1,50);
f = (x-y)./z;
scatter3(x,y,z,5,f,'filled')
for i=1:50
if f(i)<0
scatter3(x,y,z,5,f,'r','filled');
else
scatter3(x,y,z,5,f,'b','filled');
end
end
You need to pass your x, y, and z vectors to meshgrid to have it generate points to fill the whole 3-D volume:
z = linspace(1, 2, 50);
y = linspace(0, 0.5, 50);
x = linspace(-1, 1, 50);
[X, Y, Z] = meshgrid(x, y, z);
f = (X-Y)./Z;
These will be 50-by-50-by-50 matrices. To plot them with scatter3 you will need to reshape them into column vectors using the colon operator:
scatter3(X(:), Y(:), Z(:), 5, f(:), 'filled');
If you'd like to plot negative values of f as red and positive values as blue, you can call scatter3 like so and add a jet colormap (no loops necessary):
scatter3(X(:), Y(:), Z(:), 5, (f(:) < 0), 'filled');
colormap(jet);

Fit polynomial to the maximums of a function

I want to fit a polynomial to noisy data so that the approximated polynomial is always >= the original data. For example:
x = linspace (-2, 6);
y = (x-2).^2 + 1 + 2 * randn (size (x));
function ret = delta (P, x, y)
yP = polyval (P, x);
d = yP - y;
d (d < 0) *= 1000;
ret = sumsq (d);
endfunction
P0 = polyfit (x, y, 2);
f = #(P) delta (P, x, y);
[P, FVAL] = sqp (P0, f)
xi = linspace (min(x), max(x), 100);
yi = polyval (P, xi);
plot(x, y, xi, yi);
grid on
Is there a better way/method which also works with higher order polynomials?
The easies way would be to just use polyfit and then calculate max(y-yi) and add this as offset but this wouldn't be optimal...
EDIT: I want to use GNU OCtave but added "matlab" as tag because the language and functions are similiar.
EDIT: based on tvo's answer and real data:
x = [10 20 30 40 50 60 80 100];
y = [0.2372, 0.1312, 0.0936, 0.0805, 0.0614, 0.0512, 0.0554, 0.1407];
function ret = delta (P, x, y)
ret = sumsq (polyval (P, x) - y);
endfunction
f = #(P) delta (P, x, y);
h = #(P) polyval(P, x) - y;
P0 = polyfit (x, y, 3);
[P] = sqp (P0, f, [], h)
xi = linspace (min(x), max(x));
yi = polyval (P0, xi);
yio = polyval (P, xi);
plot(x, y, xi, yi, ";initial guess;", xi, yio, ";optimized;");
grid on
but as you can see, the optimized and evaluated poly has points < the orginal point which isn't allowed.
your method seems fine, and I see no reason it can't be used for higher-order polynomials actually. Please explain why if you think it can't be used.
You are using Octave's 'sqp' solver. Documentation is here: http://www.gnu.org/software/octave/doc/v4.0.1/Nonlinear-Programming.html
You may want to avoid multiplying the error by an arbitrary number (1000 in your example) when it is negative. This may fail for different data sets, especially if they are larger, i.e. more data points.
You could try to use the non-linear inequality constraint options that Octave's 'sqp' offers, i.e. the h(x)>=0 (see doc).
As objective function phi you could use a square norm error, as in your example, and add constraints of the form h(x)>=0 for every data point. Note that 'x' would be the polynomial coefficients you want to fit and h(x) is the polynomial evaluated at a specific data point.
For example:
phi = #(P) delta_mod (P, x, y); % mod: Don't increase the importance of negative residuals!!
h = #(P) polyval(P, x1) - y1;
Psol = sqp(P0, phi, [], h);
Notice that the constraint function 'h' ensures that the polynomial will lie above (x1,y1), and the objective function 'phi' will try to keep it as close as possible. You can extend 'h' to contain one constraint for every data point in your set (see doc).

First, second and third derivative of a vector function

I can define the following vector function
f(x, y, z) = [x2 - 1, x3 + y2, z]
In MatLab or in Maple.
I want to find (and evaluate) the first, second and third derivatives of it. How to find: ∇f, ∇2f and ∇3f? Here vector function f is differentiated with respect to vector (x, y, z). I can do the simple job of finding ∇f with Maple as follows:
f(x, y, z) = [x2 - 1, x3 + y2, z]
∇f = Jacobian(f, [x, y, z])
But how to differentiate ∇f?
Is there a function in MatLab (or in Maple) which may take the above function as an input and evaluate its derivatives for a given value of (x, y, z)?

Matlab - Odeset - Odeplot

I would like to use odeplot so stepwise get the result instead of plotting the result afterwards. I've tried to write it like this but I can't get it to work so I would appreciate some help.
%Parameters
s = 1;
q = 1;
w = 0.1610;
y0 = [30 1 30]; % Initial values
tspan = [0 10]; % Time 0<t<10
plot=odeset('OutputFcn','odeplot');
[t, y] = ode45(#(t,y) concentration(t, y, s, q, w), plot, tspan, y0);
You need to specify your output function via an ODE Options argument:
options = odeset('OutputFcn', #odeplot);
[t, y] = ode45(#(t,y)concentration(t, y, s, q, w), tspan, y0, options);
Of course you can make your own custom output function. Type edit odeplot to see what is required (much simpler functions are possible). Also check out odephas2 and odephas3.