How to combine numerical and symbolic variables in MatLab - matlab

I've been trying to calculate and plot trajectories for orbital motion, but got stuck with the variable types.
All input variables are of double type, as well as the desired output. As a consequence, variables of orbital system (the ones with "_orb" in the names) are of double type.
Here's the script. The diffficulties start from "Velocity corrections" part, in which I want to calculate minimum for a function of velocity change:
function trajectory_final (x0, y0 , z0, vx0, vy0, vz0, q0, q1, q2, q3)
o = 0.00114;
xk = 0;
yk = -150;
zk = 150;
double t;
%% Coordinate system transition:
x0_orb = (1 - 2*q2*q2 - 2*q3*q3)*x0 + 2*(q1*q2 + q0*q3)*y0 + 2*(q1*q3 - q0*q2)*z0;
y0_orb = 2*(q1*q2 - q0*q3)*x0 + (1 - 2*q1*q1 - 2*q3*q3)*y0 + 2*(q2*q3 + q0*q1)*z0;
z0_orb = 2*(q1*q3 + q0*q2)*x0 + 2*(q2*q3 - q0*q1)*y0 + (1 - 2*q1*q1 - 2*q2*q2)*z0;
vx0_orb = (1 - 2*q2*q2 - 2*q3*q3)*vx0 + 2*(q1*q2 + q0*q3)*vy0 + 2*(q1*q3 - q0*q2)*vz0;
vy0_orb = 2*(q1*q2 - q0*q3)*vx0 + (1 - 2*q1*q1 - 2*q3*q3)*vy0 + 2*(q2*q3 + q0*q1)*vz0;
vz0_orb = 2*(q1*q3 + q0*q2)*vx0 + 2*(q2*q3 - q0*q1)*vy0 + (1 - 2*q1*q1 - 2*q2*q2)*vz0;
%% Velocity corrections:
vx1 = sym('(xk - x0_orb - (6*o*t - 6*sin(o*t))*y0_orb - (-2*cos(o*t)/o + 2/o)*((-3*cos(o*t) + 4)*y0_orb - yk))/(4*sin(o*t)/o - 3*t - (2*cos(o*t)/o - 2/o)*(2*cos(o*t)/o - 2/o))');
vy1 = sym('(-3*cos(o*t) + 4)*y0_orb + (2*cos(o*t)/o - 2/o)*vx1 - yk');
vz1 = sym('(zk - (cos(o*t))*z0_orb)/(sin(o*t)/o)');
dvx = vx1 - vx0_orb;
dvy = vy1 - vy0_orb;
dvz = vz1 - vz0_orb;
total = sqrt((dvx)^2 + (dvy)^2 + (dvz)^2);
D = diff(total);
D_math = matlabFunction(D);
root = fzero(D_math, 600);
However, several problems occur:
1) If I run it as is now, variables in vx1, vy1 and vz1 are not replaced with their values assigned at launch, resulting in "Not enough input arguments" for fzero.
2) If I make vx1, vy1 and vz1 numerical, the error "Undefined function or variable t" appears;
3) If I make vx1, vy1 and vz1 numerical AND assign boundaries for t, then I cannot find root for D_math function on the desired interval.
Could you please tell me what is the best way to handle this problem?

Related

How do I implement six initial conditions for a system of two coupled second order differential equations?

I am new to coding. Basic information about my problem is: r1 and r2 are two variables; u1 = dr1/dt, u2 = dr2/dt, and du1/dt = d^2r1/dt^2, du2/dt = d^2r2/dt^2. In Matlab code: r(1) implies r1, r(2) -> u1, r(3) -> r2, r(4) -> u2. rdot(2) is the expression for du1/dt and rdot(4) is the expression for du2/dt.
Ideally I should need just 4 initial conditions: r1(0), u1(0), r2(0), u2(0), which are 10d-6, 0, 5d-6, 0. But in my case du1/dt has dependence on du2/dt and vice versa. See last term of T1_1 and T2_1. And an ideal IC for both du1/dt and du2/dt is 0. But how do I implement this in my code?
My code is here.
function rdot = f(t, r)
P_stat = 1.01325d5;
P_v = 2.3388d3;
mu = 1.002d-3;
sigma = 72.8d-3;
c_s = 1481d0;
poly_exp = 1.4d0;
rho = 998.2071d0;
f_s = 20d3;
P_s = 1.01325d5;
r1_eq = 10d-6;
r2_eq = 4d-6;
d = 1d-3;
rdot(1) = r(2);
P1_bw = ( (P_stat - P_v + (2.d0*sigma/r1_eq))*((r1_eq/r(1))^(3.d0*poly_exp)) ) - (2.d0*sigma/r(1)) - (4.d0*mu*r(2)/r(1));
P1_ext = P_s*sin(2.d0*pi*f_s*(t + (r(1)/c_s)));
T2_1 = ((2.d0*r(3)*(r(4)^2.d0)) + ((r(3)^2.d0)*rdot(4)))/d;
T2_4 = (1.d0 - (r(2)/c_s))*r(1);
T2_5 = 1.5d0*(1.d0 - (r(2)/(3.d0*c_s)))*(r(2)^2.d0);
T2_6 = (1.d0 + (r(2)/c_s))*(P1_bw - P_stat + P_v - P1_ext)/rho;
T2_8 = ( (-3.d0*poly_exp*r(2)*(P_stat - P_v + (2.d0*sigma/r1_eq))*((r1_eq/r(1))^(3.d0*poly_exp)) ) + (2.d0*sigma*r(2)/r(1)) - (4.d0*mu*(- ((r(2)^2.d0)/r(1)))) )/r(1);
T2_9 = 2.d0*pi*f_s*P_s*(cos(2.d0*pi*f_s*(t + (r(1)/c_s))))*(1.d0 + (r(2)/c_s) );
T2_7 = (r(1)/(rho*c_s))*(T2_8 - T2_9);
rdot(2) = (T2_6 + T2_7 - T2_1 - T2_5)/(T2_4 + (4.d0*mu/(rho*c_s)));
rdot(3) = r(4);
P2_bw = ( (P_stat - P_v + (2.d0*sigma/r1_eq))*((r1_eq/r(3))^(3.d0*poly_exp)) ) - (2.d0*sigma/r(3)) - (4.d0*mu*r(4)/r(3));
P2_ext = P_s*sin(2.d0*pi*f_s*(t + (r(3)/c_s)));
T1_1 = ((2.d0*r(1)*(r(2)^2.d0)) + ((r(1)^2.d0)*rdot(2)))/d;
T1_4 = (1.d0 - (r(4)/c_s))*r(3);
T1_5 = 1.5d0*(1.d0 - (r(4)/(3.d0*c_s)))*(r(4)^2.d0);
T1_6 = (1.d0 + (r(4)/c_s))*(P2_bw - P_stat + P_v - P2_ext)/rho;
T1_8 = ( (-3.d0*poly_exp*r(4)*(P_stat - P_v + (2.d0*sigma/r1_eq))*((r1_eq/r(3))^(3.d0*poly_exp)) ) + (2.d0*sigma*r(4)/r(3)) - (4.d0*mu*(- ((r(4)^2.d0)/r(3)))) )/r(3);
T1_9 = 2.d0*pi*f_s*P_s*(cos(2.d0*pi*f_s*(t + (r(3)/c_s))))*(1.d0 + (r(4)/c_s) );
T1_7 = (r(3)/(rho*c_s))*(T1_8 - T1_9);
rdot(4) = (T1_6 + T1_7 - T1_1 - T1_5)/(T1_4 + (4.d0*mu/(rho*c_s)));
rdot = rdot';
clc;
clear all;
close all;
time_range = [0 3000d-6];
initial_conditions = [10d-6 0.d0 5d-6 0.d0];
[t, r] = ode45('bubble', time_range, initial_conditions);
plot(t, r(:, 1), t, r(:, 3));
For each degree of an ODE you'll need one initial condition. This is due to the amount of functions you are calculating. In your case you got a system of second order ODE's, which after being solved will provide a total of four functions: r(1), r(2), r(3), r(4)
Why do we even need initial conditions? Imagine you have a simple derivative:y'= y
We know that the function y = exp(x) * C solves this problem, but we need to adjust C in order to get "The one Solution". On the other hand side it makes no sense to give y' an initial condition, as it is fully defined, once y is defined. It doesn't matter whether the "foreign" variable appears in the form of a derivative or as a linear factor. It is independent from the amount of IC's.
I hope I could clarify it a bit. From my point of view your program should work that way, but I haven't had the chance to try it out.
I have fixed the problem, by introducing two new variables with initial conditions but then they are updated as the code runs. The new code is here with two variables: r2ddot and r1ddot;
function rdot = f(t, r)
P_stat = 1.01325d5;
P_v = 2.3388d3;
mu = 1.002d-3;
sigma = 72.8d-3;
c_s = 1481d0;
poly_exp = 1.4d0;
rho = 998.2071d0;
f_s = 20d3;
P_s = 1.01325d5;
r1_eq = 4d-6;
r2_eq = 5d-6;
d = 50*(r1_eq + r2_eq);
r2ddot = 0;
r1ddot = 0;
rdot(1) = r(2);
P2_bw = ( (P_stat - P_v + (2.d0*sigma/r2_eq))*((r2_eq/r(3))^(3.d0*poly_exp)) ) - (2.d0*sigma/r(3)) - (4.d0*mu*r(4)/r(3));
P2_ext = P_s*sin(2.d0*pi*f_s*(t + (r(3)/c_s)));
T1_1 = ((2.d0*r(1)*(r(2)^2.d0)) + ((r(1)^2.d0)*r1ddot))/d;
T1_4 = (1.d0 - (r(4)/c_s))*r(3);
T1_5 = 1.5d0*(1.d0 - (r(4)/(3.d0*c_s)))*(r(4)^2.d0);
T1_6 = (1.d0 + (r(4)/c_s))*(P2_bw - P_stat + P_v - P2_ext)/rho;
T1_8 = ( (-3.d0*poly_exp*r(4)*(P_stat - P_v + (2.d0*sigma/r2_eq))*((r2_eq/r(3))^(3.d0*poly_exp)) ) + (2.d0*sigma*r(4)/r(3)) - (4.d0*mu*(- ((r(4)^2.d0)/r(3)))) )/r(3);
T1_9 = 2.d0*pi*f_s*P_s*(cos(2.d0*pi*f_s*(t + (r(3)/c_s))))*(1.d0 + (r(4)/c_s) );
T1_7 = (r(3)/(rho*c_s))*(T1_8 - T1_9);
rdot(2) = (T1_6 + T1_7 - T1_1 - T1_5)/(T1_4 + (4.d0*mu/(rho*c_s))) ;
r2ddot = rdot(2);
rdot(3) = r(4);
P1_bw = ( (P_stat - P_v + (2.d0*sigma/r1_eq))*((r1_eq/r(1))^(3.d0*poly_exp)) ) - (2.d0*sigma/r(1)) - (4.d0*mu*r(2)/r(1));
P1_ext = P_s*sin(2.d0*pi*f_s*(t + (r(1)/c_s)));
T2_1 = ((2.d0*r(3)*(r(4)^2.d0)) + ((r(3)^2.d0)*r2ddot))/d;
T2_4 = (1.d0 - (r(2)/c_s))*r(1);
T2_5 = 1.5d0*(1.d0 - (r(2)/(3.d0*c_s)))*(r(2)^2.d0);
T2_6 = (1.d0 + (r(2)/c_s))*(P1_bw - P_stat + P_v - P1_ext)/rho;
T2_8 = ( (-3.d0*poly_exp*r(2)*(P_stat - P_v + (2.d0*sigma/r1_eq))*((r1_eq/r(1))^(3.d0*poly_exp)) ) + (2.d0*sigma*r(2)/r(1)) - (4.d0*mu*(- ((r(2)^2.d0)/r(1)))) )/r(1);
T2_9 = 2.d0*pi*f_s*P_s*(cos(2.d0*pi*f_s*(t + (r(1)/c_s))))*(1.d0 + (r(2)/c_s) );
T2_7 = (r(1)/(rho*c_s))*(T2_8 - T2_9);
rdot(4) = (T2_6 + T2_7 - T2_1 - T2_5)/(T2_4 + (4.d0*mu/(rho*c_s)));
r1ddot = rdot(4);
rdot = rdot';
clc;
clear all;
close all;
time_range = [0 1d-3];
initial_conditions = [4d-6 0.d0 5d-6 0.d0];
[t, r] = ode45('bubble', time_range, initial_conditions);
plot(t, r(:, 1), t, r(:, 3));
But I am not able to get the desired result. Actually I am trying to reproduce the results from the attached paper, see equation 7. enter link description here
The second set of equations can be obtained by interchanging indices 1 and 2.
Important note: There is a typo in the last term of equation 7 in Mettin's paper, that can be verified by using check on the dimensions of the various term. The correct last term can be seen from another paper https://journals.aps.org/pre/abstract/10.1103/PhysRevE.83.066313
See last term in eq.(1) below. Ignore the other extra terms in the equation. Important point is that the equation is of second order in Rj and the equation has a second order term in Ri at the end. And This is what I have tried to code.
Any help will be highly appreciated.
You have essentially the situation that
rdot(2) = a2 + b2*rdot(4)
rdot(4) = a4 + b4*rdot(2)
where a2,b2,a4,b4 contain all the other terms in your expressions.
This is a linear system that you have to solve to get the correct values to return. You can use a linear solver of Matlab or do in this simple 2-dimensional case do it by hand,
rdot(2) = a2 + b2*(a4 + b4*rdot(2)) ==> rdot(2) = (a2 + b2*a4) / (1 - b2*b4)
rdot(4) = a4 + b4*(a2 + b2*rdot(4)) ==> rdot(2) = (a4 + b4*a2) / (1 - b2*b4)
To apply this you need to split
T1_1 as T1_1a + T1_1b*rdot(4),
you can compute T1_1a and T1_1b from the given constant and state variables. Then where you have in the end
rdot(2)=(other + coeff*T1_1)/denom
you have to split into
a2 =(other + coeff*T1_1a) / denom and
b2 = coeff*T1_1b / denom
and do the same to the second part to get a4,b4 and then apply the solution formulas above.

Newton's Method

I am trying to find out the root of an equation constraint using Newton's Method (open to any other method). The equation constraint is dependent on the roots of a quadratic equation which has one unknown term. The equation descriptions (quadratic and constraint) are shown below. The roots of the quadratic equation are assumed to be p1 and p2.
x^2 + x*(c1*unknown/2 + C1*c2)/(c1*c2*c3*unknown/2) + 1/(c1*c2*c3*u/2) = 0
with constraint
(1/(p2-p1))*(exp(-0.3*p2) - 1)*(c1*c2 - p2) - (exp(-0.3*p1) - 1)*(c1*c2 - p1) - 0.04 = 0
I am wondering if there are any other approximation methods to solve this problem if Newton's Method is not going to do so.
Matlab Code
p0=10*10^6;
Cc=0.65*10^-6;Rp=100*10^3;Cp=55*10^-9; z1=1/(Cp*Rp);
N = 100;error = 0.02;
syms 'x'
a = 1;
b = ((Cc*(x/2+Rp))/(Cc*Cp*Rp*x/2));
c = 1/(Cc*Cp*Rp*x/2);
poles1 = (-b + sqrt(b^2 - 4*a*c))/(2*a);
poles2 = (-b - sqrt(b^2 - 4*a*c))/(2*a);
p1_subterm = (exp(-0.3*poles1) - 1)*(z1 - poles1);
p2_subterm = (exp(-0.3*poles2) - 1)*(z1- poles2);
f(x) = (1/(poles2 - poles1))*p2_subterm - p2_subterm - 0.04;
df = diff(f);
while i <= N
p = p0-(f(p0)/df(p0))
if (abs(p - p0)/abs(p)) < error
fprintf('Solution is %f \n', double(p))
return
end
i = i + 1;
p0 = p;
end
fprintf('Solution did not converge within %d iterations \n', N)
I don't think your code for f(x) corresponds to the equation listed above: In the MATLAB code 1/(poles2-poles1) multiplies both the exp((...)poles2) and the exp((...)poles1) terms and you have 1/(c1*c2) - poles1 instead of c1*c2 - poles1.
I have not checked through the poles1 and poles2 terms as I find the 10 sets of parenthesis intimidating. It would suggest making your code more readable by breaking up each of those equations in to a number of shorter, clearer lines.
Noting that we can multiply the quadratic by c1*c2*c3*unknown,
(c1*c2*c3*unknown)*x^2 + x*2*(c1*unknown/2 + C1*c2) + 2 = 0
then you can write the poles and f code as
% Here unknown is x
syms 'x'
a = c1*c2*c3*x;
b = c1*x + 2*c1*c2;
c = 2;
poles1 = (-b + sqrt(b^2 - 4*a*c))/(2*a);
poles2 = (-b - sqrt(b^2 - 4*a*c))/(2*a);
p1_subterm = (exp(-0.3*poles1) - 1)*(c1*c2 - poles1);
p2_subterm = (exp(-0.3*poles2) - 1)*(c1*c2 - poles2);
f(x) = (1/(poles2 - poles1))*p2_subterm - p2_subterm - 0.04;

Assignment has more non-singleton rhs dimensions than non-singleton subscripts

I am trying to code a GMM function. The problem is that for the next loop I get the next error:
Assignment has more non-singleton rhs dimensions than non-singleton subscripts.
The error is related to the loop part that starts here. Below the loop you have the whole code. I was searching on the Internet and I tried many things, but I really do not understand why I have this problem. I also checked the size of each variable included, they are all of (694,1), and I am pretty sure that the size of each one of the variable specified is the right one.
%
for i=1:T-3
% g(i,1)=((beta.*((c1(i).^(-alpha)) + (b*beta*(c2(i)).^(-alpha))).*dj(i)) - (b*beta.*(c1(i)).^(-alpha))) - 1;
a(:,i)=(((beta.*((c1(i).^(-alpha)) + (b*beta*(c2(i)).^(-alpha))).*dj(i)) - (b*beta.*(c1(i)).^(-alpha))) - 1);
b(:,i)=(((beta.*((c1(i).^(-alpha)) + (b*beta*(c2(i)).^(-alpha))).*dj(i)) - (b*beta.*(c1(i)).^(-alpha))) - 1)*dj(i);
c(:,i)=(((beta.*((c1(i).^(-alpha)) + (b*beta*(c2(i)).^(-alpha))).*dj(i)) - (b*beta.*(c1(i)).^(-alpha))) - 1)*consumpt(i);
% function [q] = Q(param,M,data,cond)
T = length(data);
% Population moments
% [PMvec] = populat0ion_moments(param);
%sigma = param(2);
alpha = param(1);
beta = param(2);
b = param(3);
% c = ( data(3:end,1) + b*(data(2:end-1,1)))./(data(2:end-1,1) + b*(data(1:end-2,1) + b*( data(3:end,1)) + b*(data(2:end-1,1))./(data(2:end-1,1) + b*(data(1:end-2,1)));
dj= data(2:end-2,2)./data(1:end-3,2);
cpr = data(1:end-3,1)
ctd = data(2:end-2,1)
ctw = data(3:end-1,1)
ctw2= data(4:end, 1)
c1 = (ctw+b.*ctd)./(ctd+b.*cpr);
c2 = (ctw2+b.*ctw)./(ctd+b.*cpr);
consumpt = data(2:end-2,1)./data(1:end-3,1);
[row,col] = size(cpr);
djinst = dj(1:row,1);
%z = [1 consumpt djinst]
a = zeros(1, 694);
b = zeros(1, 694);
c = zeros(1, 694);
for i=1:T-4
% g(i,1)=((beta.*((c1(i).^(-alpha)) + (b*beta*(c2(i)).^(-alpha))).*dj(i)) - (b*beta.*(c1(i)).^(-alpha))) - 1;
a(:,i)=(((beta.*((c1(i).^(-alpha)) + (b*beta*(c2(i)).^(-alpha))).*dj(i)) - (b*beta.*(c1(i)).^(-alpha))) - 1);
b(:,i)=(((beta.*((c1(i).^(-alpha)) + (b*beta*(c2(i)).^(-alpha))).*dj(i)) - (b*beta.*(c1(i)).^(-alpha))) - 1)*dj(i);
c(:,i)=(((beta.*((c1(i).^(-alpha)) + (b*beta (c2(i)).^(-alpha))).*dj(i)) - (b*beta.*(c1(i)).^(-alpha))) - 1)*consumpt(i);
I obtain the following error:
Assignment has more non-singleton rhs dimensions than non-singleton subscripts
Error in Q (line 43)
a(:,i)=(((beta.*((c1(i).^(-alpha)) + (bbeta*(c2(i)).^(-alpha))).*dj(i)) - (bbeta.*(c1(i)).^(-alpha))) - 1);
It looks like you are reassigning b from a scalar to a vector and that might be causing the problem.
b = param(3);
...
b = zeros(1, 694);

MATLAB: convert from euler (complex fourier) to sinus function (bn coefficients)

I have the following script
clc; clear all; close all;
syms x n
f = x;
L = 1;
subplot(2,1,1)
h = ezplot(f,[-L,L])
set(h, 'Color','r','LineWidth',1)
a0 = (1/L) * int(f * cos(0* pi*x/L),-L,L)
an = (1/L) * int(f * cos(n* pi*x/L),-L,L)
bn = (1/L)* int(f* sin(n* pi*x/L),-L,L)
fx = a0/2 + symsum((an* cos(n*pi*x/L) + bn* sin(n*pi*x/L)),n,1,5)
% for n =5, the answer: fx = (2*sin(pi*x))/pi - sin(2*pi*x)/pi +
%(2*sin(3*pi*x))/(3*pi) - sin(4*pi*x)/(2*pi) + (2*sin(5*pi*x))/(5*pi)
hold on
h = ezplot(fx,[-L,L])
grid on
%Solution with complex Fourier
c0 = (1/(2*L))*int(f*exp(-j*0*pi*x/L),-L,L)
cn = (1/(2*L))*int(f*exp(-j*n*pi*x/L),-L,L)
subplot(2,1,2)
h = ezplot(f,[-L,L])
set(h, 'Color','r','LineWidth',1)
fx_c = c0 + symsum(cn*exp(j*n*pi*x/L),n,-5,-1) + ...
symsum(cn*exp(j*n*pi*x/L),n,1,5) % n for complex -5,5
hold on
h = ezplot(fx_c,[-L,L])
grid on
My question: Since the answer of fx should be equal to fx_c (complex fourier). We can see from the figures produced by these 2 functions. They are same. But
fx =
(2*sin(pi*x))/pi - sin(2*pi*x)/pi + (2*sin(3*pi*x))/(3*pi) - sin(4*pi*x)/(2*pi) + (2*sin(5*pi*x))/(5*pi)
and
fx_c =
exp(-pi*x*i)*((pi*i - 1)/(2*pi^2) + (pi*i + 1)/(2*pi^2)) - exp(pi*x*i)*((pi*i - 1)/(2*pi^2) + (pi*i + 1)/(2*pi^2)) - exp(-pi*x*2*i)*((pi*2*i - 1)/(8*pi^2) + (pi*2*i + 1)/(8*pi^2)) + exp(pi*x*2*i)*((pi*2*i - 1)/(8*pi^2) + (pi*2*i + 1)/(8*pi^2)) + exp(-pi*x*3*i)*((pi*3*i - 1)/(18*pi^2) + (pi*3*i + 1)/(18*pi^2)) - exp(pi*x*3*i)*((pi*3*i - 1)/(18*pi^2) + (pi*3*i + 1)/(18*pi^2)) - exp(-pi*x*4*i)*((pi*4*i - 1)/(32*pi^2) + (pi*4*i + 1)/(32*pi^2)) + exp(pi*x*4*i)*((pi*4*i - 1)/(32*pi^2) + (pi*4*i + 1)/(32*pi^2)) + exp(-pi*x*5*i)*((pi*5*i - 1)/(50*pi^2) + (pi*5*i + 1)/(50*pi^2)) - exp(pi*x*5*i)*((pi*5*i - 1)/(50*pi^2) + (pi*5*i + 1)/(50*pi^2))
How to convert fx_c to be fx?
They are related by Euler's formula. You can check it with rewrite command:
>> rewrite(exp(1i*x), 'cos')
ans =
cos(x) + sin(x)*1i
Applying it to your function and simplifying a bit, you can get to the same expression:
>> expand(rewrite(fx_c, 'cos'), 'ArithmeticOnly', true)
ans =
(2*sin(pi*x))/pi - sin(2*pi*x)/pi + (2*sin(3*pi*x))/(3*pi) - sin(4*pi*x)/(2*pi) + (2*sin(5*pi*x))/(5*pi)
>> fx
fx =
(2*sin(pi*x))/pi - sin(2*pi*x)/pi + (2*sin(3*pi*x))/(3*pi) - sin(4*pi*x)/(2*pi) + (2*sin(5*pi*x))/(5*pi)

using quad to integrate function with respect to just one variable

is there any way i can integrate function of two variable, say
f=#(x) x^2 + x*y
over just x
tried quad(f, a, b)
but doesn't work, looking for alternative solution
Looks like you want something like this:
y = 100; % whatever y is
a = 0;
b = 2;
% you'll need to vectorize the integrand function
f = #(x) x.*x + x.*y
val = quad(f, a, b);
However, if you are looking for an algebraic answer, you'll need to use the Symbolic Toolbox, or some other software, or your calculus book. :-)
The whole "vectorize" thing comes from the Mathworks quad documentation that says:
The function y = fun(x) should accept a vector argument x and return a vector result y, the integrand evaluated at each element of x.
Sorry, but quad does not solve symbolic problems. It does only numerical integration.
syms x y
int(x^2 + x*y,x)
ans =
(x^2*(2*x + 3*y))/6
The natural way to solve a symbolic problem is to use a symbolic tool.
From the followup, Anya wants something in-between. To steal the words of an old rock star named Mick, "You can't always get what you want."
Again, quad can't be used if you wish to integrate ONLY over x, as quad is an adaptive tool.
In SOME SIMPLE cases, you can use a simple tool like Simpson's rule to do the work. For example, suppose you wanted to solve the above problem, with x integrated over the interval [0 1]. For purposes of comparison, I'll do it symbolically first.
syms x y
res = int(x^2 + x*y,x);
subs(res,x,1) - subs(res,0)
ans =
y/2 + 1/3
Now, lets try it using a numerical integration on x.
syms y
x = 0:.01:1;
coef = mod((0:100)',2)*2 + 2;
coef([1 end]) = 1;
coef = 0.01*coef/3;
(x.^2 + x.*y)*coef
ans =
y/2 + 1/3
So in this very SIMPLE case, it did work. How about something a little more complicated? Integrate x*exp(x*y) over the interval [-1 1]. Again, a known form is accessible symbolically.
syms x y
res = int(x*exp(x*y),x);
res = subs(res,x,1) - subs(res,-1)
res =
(exp(-y)*(y + 1))/y^2 + (exp(y)*(y - 1))/y^2
To test it out later, what value does this take on at y = 1/2?
vpa(subs(res,y,1/2))
ans =
0.34174141687554424792549563431876
Lets try the same trick, using Simpson's rule.
syms y
x = -1:.01:1;
coef = mod((-100:100)',2)*2 + 2;
coef([1 end]) = 1;
coef = 0.01*coef/3;
res = (x.*exp(x*y))*coef
res =
exp(y/2)/300 - exp(-y/2)/300 - exp(-y)/300 - exp(-y/4)/300 + exp(y/4)/300 - exp(-y/5)/750 + exp(y/5)/750 - exp(-(3*y)/4)/100 - exp(-(2*y)/5)/375 + exp((2*y)/5)/375 + exp((3*y)/4)/100 - exp(-(3*y)/5)/250 + exp((3*y)/5)/250 - (2*exp(-(4*y)/5))/375 + (2*exp((4*y)/5))/375 - exp(-y/10)/1500 + exp(y/10)/1500 - exp(-(3*y)/10)/500 + exp((3*y)/10)/500 - (7*exp(-(7*y)/10))/1500 + (7*exp((7*y)/10))/1500 - (3*exp(-(9*y)/10))/500 + (3*exp((9*y)/10))/500 - exp(-y/20)/1500 + exp(y/20)/1500 - exp(-(3*y)/20)/500 + exp((3*y)/20)/500 - exp(-y/25)/3750 + exp(y/25)/3750 - (7*exp(-(7*y)/20))/1500 - exp(-(2*y)/25)/1875 + exp((2*y)/25)/1875 + (7*exp((7*y)/20))/1500 - exp(-(3*y)/25)/1250 + exp((3*y)/25)/1250 - (3*exp(-(9*y)/20))/500 - (2*exp(-(4*y)/25))/1875 + (2*exp((4*y)/25))/1875 + (3*exp((9*y)/20))/500 - (11*exp(-(11*y)/20))/1500 - exp(-(6*y)/25)/625 + exp((6*y)/25)/625 + (11*exp((11*y)/20))/1500 - (7*exp(-(7*y)/25))/3750 + (7*exp((7*y)/25))/3750 - (13*exp(-(13*y)/20))/1500 - (4*exp(-(8*y)/25))/1875 + (4*exp((8*y)/25))/1875 + (13*exp((13*y)/20))/1500 - (3*exp(-(9*y)/25))/1250 + (3*exp((9*y)/25))/1250 - (11*exp(-(11*y)/25))/3750 + (11*exp((11*y)/25))/3750 - (17*exp(-(17*y)/20))/1500 - (2*exp(-(12*y)/25))/625 + (2*exp((12*y)/25))/625 + (17*exp((17*y)/20))/1500 - (13*exp(-(13*y)/25))/3750 + (13*exp((13*y)/25))/3750 - (19*exp(-(19*y)/20))/1500 - (7*exp(-(14*y)/25))/1875 + (7*exp((14*y)/25))/1875 + (19*exp((19*y)/20))/1500 - (8*exp(-(16*y)/25))/1875 + (8*exp((16*y)/25))/1875 - (17*exp(-(17*y)/25))/3750 + (17*exp((17*y)/25))/3750 - (3*exp(-(18*y)/25))/625 + (3*exp((18*y)/25))/625 - (19*exp(-(19*y)/25))/3750 + (19*exp((19*y)/25))/3750 - (7*exp(-(21*y)/25))/1250 + (7*exp((21*y)/25))/1250 - (11*exp(-(22*y)/25))/1875 + (11*exp((22*y)/25))/1875 - (23*exp(-(23*y)/25))/3750 + (23*exp((23*y)/25))/3750 - (4*exp(-(24*y)/25))/625 + (4*exp((24*y)/25))/625 - exp(-y/50)/7500 + exp(y/50)/7500 - exp(-(3*y)/50)/2500 + exp((3*y)/50)/2500 - (7*exp(-(7*y)/50))/7500 + (7*exp((7*y)/50))/7500 - (3*exp(-(9*y)/50))/2500 + (3*exp((9*y)/50))/2500 - (11*exp(-(11*y)/50))/7500 + (11*exp((11*y)/50))/7500 - (13*exp(-(13*y)/50))/7500 + (13*exp((13*y)/50))/7500 - (17*exp(-(17*y)/50))/7500 + (17*exp((17*y)/50))/7500 - (19*exp(-(19*y)/50))/7500 + (19*exp((19*y)/50))/7500 - (7*exp(-(21*y)/50))/2500 + (7*exp((21*y)/50))/2500 - (23*exp(-(23*y)/50))/7500 + (23*exp((23*y)/50))/7500 - (9*exp(-(27*y)/50))/2500 + (9*exp((27*y)/50))/2500 - (29*exp(-(29*y)/50))/7500 + (29*exp((29*y)/50))/7500 - (31*exp(-(31*y)/50))/7500 + (31*exp((31*y)/50))/7500 - (11*exp(-(33*y)/50))/2500 + (11*exp((33*y)/50))/2500 - (37*exp(-(37*y)/50))/7500 + (37*exp((37*y)/50))/7500 - (13*exp(-(39*y)/50))/2500 + (13*exp((39*y)/50))/2500 - (41*exp(-(41*y)/50))/7500 + (41*exp((41*y)/50))/7500 - (43*exp(-(43*y)/50))/7500 + (43*exp((43*y)/50))/7500 - (47*exp(-(47*y)/50))/7500 + (47*exp((47*y)/50))/7500 - (49*exp(-(49*y)/50))/7500 + (49*exp((49*y)/50))/7500 - exp(-y/100)/7500 + exp(y/100)/7500 - exp(-(3*y)/100)/2500 + exp((3*y)/100)/2500 - (7*exp(-(7*y)/100))/7500 + (7*exp((7*y)/100))/7500 - (3*exp(-(9*y)/100))/2500 + (3*exp((9*y)/100))/2500 - (11*exp(-(11*y)/100))/7500 + (11*exp((11*y)/100))/7500 - (13*exp(-(13*y)/100))/7500 + (13*exp((13*y)/100))/7500 - (17*exp(-(17*y)/100))/7500 + (17*exp((17*y)/100))/7500 - (19*exp(-(19*y)/100))/7500 + (19*exp((19*y)/100))/7500 - (7*exp(-(21*y)/100))/2500 + (7*exp((21*y)/100))/2500 - (23*exp(-(23*y)/100))/7500 + (23*exp((23*y)/100))/7500 - (9*exp(-(27*y)/100))/2500 + (9*exp((27*y)/100))/2500 - (29*exp(-(29*y)/100))/7500 + (29*exp((29*y)/100))/7500 - (31*exp(-(31*y)/100))/7500 + (31*exp((31*y)/100))/7500 - (11*exp(-(33*y)/100))/2500 + (11*exp((33*y)/100))/2500 - (37*exp(-(37*y)/100))/7500 + (37*exp((37*y)/100))/7500 - (13*exp(-(39*y)/100))/2500 + (13*exp((39*y)/100))/2500 - (41*exp(-(41*y)/100))/7500 + (41*exp((41*y)/100))/7500 - (43*exp(-(43*y)/100))/7500 + (43*exp((43*y)/100))/7500 - (47*exp(-(47*y)/100))/7500 + (47*exp((47*y)/100))/7500 - (49*exp(-(49*y)/100))/7500 + (49*exp((49*y)/100))/7500 - (17*exp(-(51*y)/100))/2500 + (17*exp((51*y)/100))/2500 - (53*exp(-(53*y)/100))/7500 + (53*exp((53*y)/100))/7500 - (19*exp(-(57*y)/100))/2500 + (19*exp((57*y)/100))/2500 - (59*exp(-(59*y)/100))/7500 + (59*exp((59*y)/100))/7500 - (61*exp(-(61*y)/100))/7500 + (61*exp((61*y)/100))/7500 - (21*exp(-(63*y)/100))/2500 + (21*exp((63*y)/100))/2500 - (67*exp(-(67*y)/100))/7500 + (67*exp((67*y)/100))/7500 - (23*exp(-(69*y)/100))/2500 + (23*exp((69*y)/100))/2500 - (71*exp(-(71*y)/100))/7500 + (71*exp((71*y)/100))/7500 - (73*exp(-(73*y)/100))/7500 + (73*exp((73*y)/100))/7500 - (77*exp(-(77*y)/100))/7500 + (77*exp((77*y)/100))/7500 - (79*exp(-(79*y)/100))/7500 + (79*exp((79*y)/100))/7500 - (27*exp(-(81*y)/100))/2500 + (27*exp((81*y)/100))/2500 - (83*exp(-(83*y)/100))/7500 + (83*exp((83*y)/100))/7500 - (29*exp(-(87*y)/100))/2500 + (29*exp((87*y)/100))/2500 - (89*exp(-(89*y)/100))/7500 + (89*exp((89*y)/100))/7500 - (91*exp(-(91*y)/100))/7500 + (91*exp((91*y)/100))/7500 - (31*exp(-(93*y)/100))/2500 + (31*exp((93*y)/100))/2500 - (97*exp(-(97*y)/100))/7500 + (97*exp((97*y)/100))/7500 - (33*exp(-(99*y)/100))/2500 + (33*exp((99*y)/100))/2500 + exp(y)/300
So I got a result, but its not the analytical one I wanted, and a bit of a nasty mess. Is it correct?
vpa(subs(res,y,1/2))
ans =
0.34174141693463006644516447861307
I'll copy the analytical result from above so we can compare...
0.34174141687554424792549563431876
As you can see, Simpson's rule, at a step size of 0.01 over [-1,1], did reasonably well, agreeing out to about 9 decimal digits.
There is no assurance that this technique will work as well on any more general kernel, but it might give you what you desire.