Matlab: how to calculate the definite integral of a function over multiple limits? - matlab

Assume:
z = [0.4 0.5 0.75]'
function y = myfunct(x)
y = quad(#sin, 0, x)
I'd like to calculate the definite integral of sin(x) from 0 to 0.4, to 0.5, and 0.75, using:
myfunct(z)
However, Matlab returns:
??? Error using ==> quad at 70
The limits of integration must be scalars.
I'd be thankful for any constructive suggestions.

You can use the arrayfun function in recent versions of MATLAB:
z = [0.4 0.5 0.75]';
y = arrayfun(#(upperLim)(quad(#sin,0,upperLim)),z);

You can also use quadv to do this. BUT, instead of making a vector of integration limits, make an array valued function so that when you integrate each element, the range of integration will be 0 to 1.
To be more specific, you want to integrate sin(x) from x = 0 to z. This is the same as integrating sin(u z)*z from u = 0 to 1 (u-substitution). Make an array function
F = #(u) [sin( .4 * u) * .4, sin( .5 * u ) * .5, sin( .75 * u ) * .75 ];
Then do
quadv(F,0,1)

Related

MATLAB: Solve system of linear equalities while constraining some values to be positive

A paper I'm reading contains the following theorem.
I wrote some MATLAB code to try and reproduce results that appear later in the paper, and initially it seemed to work well.
M = 6;
Sigma = [1 .5 .15 .15 0 0;
.5 1 .15 .15 0 0;
.15 .15 1 .25 0 0;
.15 .15 .25 1 0 0;
0 0 0 0 1 .1;
0 0 0 0 .1 1];
Delta = [0 0 .2 .2 .5 .5]';
cov_vect = [.3 .3 .35 .35 .25 .25];
u = ones(M,1);
lastcol = [u' 0];
First = Sigma+(Delta*Delta');
First(M+1,:) = u;
First(:,M+1) = lastcol;
Third = [cov_vect 1]';
X = linsolve(First,Third);
This code creates results that match those from the paper.
I want to use my code with other data sets, but when I try to do that I encounter a problem. M, Sigma, Delta, and cov_vect will vary from data set to data set, but the rest of the code should stay the same.
When I use my code on new data sets, then although the vector w sums to 1 (as it should) it sometimes contains negative values. According to the paper, this shouldn't happen. It's fine for lambda to be negative, but none of the values in the w vector can be negative.
How can I get MATLAB to constrain the results so that all the values in w must be positive, while maintaining the requirement that the vector w sum to 1?
Your question appears to reference this paper.
Theorem 2 you reference is the solution to the following optimization problem (see error/typos section, I've had to make at least one correction).
minimize (over w) w' * (Sigma + delta * delta') * w - 2 * cov_vect' * w
subject to: w'*ones(n, 1) = 1
This can be solved using Matlab function quadprog with:
H = 2 * (Sigma + delta * Delta'); % see quadprog docs, it solves 1/2 so we need 2
f = - 2 * cov_vect;
A = [];
b = [];
Aeq = ones(1,6);
beq = 1;
w = quadprog(H, f, A, b, Aeq, beq);
You can add the lower bound constraint of 0 with:
lb = zeros(6, 1);
ub = [];
w2 = quadprog(H, f, A, b, Aeq, beq, lb, ub);
How to solve this in CVX (awesome optimization package)
cvx_begin
variables y(n);
minimize(y' * (Sigma + Delta * Delta') * y - 2 * cov_vect * y)
subject to:
y'*ones(n,1) == 1;
y >= 0;
cvx_end
Link to cvx.
Typo in appendix of paper as posted on researchgate:
(typo) Their proof of theorem 2 omits the 2*w in term 2*cov_vect' * w of thier objective function. The minimization problem should be:
minimize (over w) w' * (Sigma + delta * delta') * w - 2*cov_vect' * w
Which indeed gives solution:
0.1596 0.1596 0.2090 0.2090 0.1314 0.1314
Or equivalently:
minimize (over w) .5 * w' * (Sigma + delta * delta') * w - cov_vect' * w

How to numerically integrate with infinite limit in MATLAB?

I want to numerically integrate an integral with infinite limit. Does anyone have any idea how should I do that?
int(x* exp (v*x + (1-exp(v*x))/v),x, o , inf) does not work.
Note that I will have values for v.
%n=10;
kappa=.5;
delta0=.5;
Vmax=500;
Vdep=2.2;
l=2.2;
kbT=4.1;
%xb=.4;
fb=10;
k=1;
V0=5;
e1=(fb*l/kbT)*(kappa/delta0);
e2=Vmax/V0;
e3=Vdep/V0;
w=zeros(1,25);
for v=1:25
w(:,v)=integral(#(x) x.*exp(v*x+((1-exp(v*x))/v)),0,inf);
end
e12=e2*exp(-e1*(1:25).*w.^2)-e3;
plot(e12);
ylim([0 25]);
hold on;
plot(0:25,0:25);
xlim([0 25]);
%hold off;
The plot is not matching the real data in the article!(for the e12 curve specially)
I need to calculate the intersection of the 2 curves (which is ~13.8 based on the paper) and then in the second part I have to add a term in e12 which contains an independent variable:
v=13.8;
w= integral(#(x) x.*exp(v*x+((1-exp(v*x))/v)),0,inf)
e4 = zeros (1,180);
fl = 1:180;
e4(:,fl)= (fl*l/kbT)*(kappa/n);
e12=e2*exp(-e1*v*w^2-e4)-e3
But again the problem is that running this code I will end with a negative value for e12 which should be just approaching zero in large values of fl (fl>160)
to show how this code is different from the expected curve you can plot these data on the same figure:
fl = [0, 1, 4, 9, 15, 20, 25, 40, 60, 80, 100, 120, 140, 160, 180];
e12 = [66, 60, 50, 40, 30, 25.5, 20, 15.5, 10.5, 8.3, 6.6, 5, 2.25, 1.1, 0.5];
which obviously does not match the curve generated by the code.
Assuming the question is about this full code:
syms x;
v = 1; % For example
int(x*exp(v*x + (1-exp(v*x))/v),x, 0, Inf)
and the issue is that it returns itself (i.e., int doesn't find an analytic solution), one can set the 'IgnoreAnalyticConstraints' option to true (more details) to get a solution:
syms x;
v = 1; % For example
int(x*exp(v*x + (1-exp(v*x))/v),x, 0, Inf, 'IgnoreAnalyticConstraints', true)
returns -ei(-1)*exp(1), where ei is the exponential integral function (see also expint for numerical calculations). For negative values of v the solution will also be in terms of eulergamma, the Euler-Mascheroni constant. And of course the integral is undefined if v is 0.
Using Mathematica 10.0.2's Integrate yields a full solution for symbolic v.
Integrate[x Exp[v x - (Exp[v x] - 1)/v], {x, 0, Infinity}]
returns
ConditionalExpression[(E^(1/v) (EulerGamma + Gamma[0, 1/v] + Log[1/v]))/v, Re[v] < 0]
Applying Assumptions:
Integrate[x Exp[v x - (Exp[v x] - 1)/v], {x, 0, Infinity}, Assumptions -> v > 0]
Integrate[x Exp[v x - (Exp[v x] - 1)/v], {x, 0, Infinity}, Assumptions -> v < 0]
returns
(E^(1/v) Gamma[0, 1/v])/v
and
(E^(1/v) (2 EulerGamma - 2 ExpIntegralEi[-(1/v)] + Log[1/v^2]))/(2 v)
where Gamma is the upper incomplete gamma function. These appear match up with the results from Matlab.
To evaluate these numerically in Matlab:
% For v > 0
v_inv = 1./v;
exp(v_inv).*expint(v_inv).*v_inv
or
% For v < 0
v_inv = 1./v;
exp(v_inv).*(2*double(eulergamma)+2*(expint(v_inv)+pi*1i)+log(v_inv.^2)).*v_inv/2
Numerical integration is performed by summing the function at discrete points with distance dx. The smaller dx you choose, the better approximation you get. For example integrating from x=0 to x=10 is done by:
x = 0:dx:10;
I = sum(x.* exp (v*x + (1-exp(v*x))/v))*dx;
obviously, you can't do that for x=inf. But I believe you function decays rapidly. Therefore, you can assume that x* exp (v*x + (1-exp(v*x))/v) = 0 for large enough x. Otherwise the integral is divergent. So all you have to do is set the limit on x. If you are not sure what the limit should be, you can perform a loop with a stopping condition:
I = 0;
prevI = -1;
x = 0;
while abs(I-prevI)>err
prevI = I;
I = I + x.* exp (v*x + (1-exp(v*x))/v)*dx;
x = x + dx;
end
Now, all you have to do is set the desired dx and err
You must read this:Mathwork Link
perhaps you are making a mistake in the function that you use. Also note that MATLAB syntax is case sensitive..

Writing Own fft2() Function on MATLAB

I want to write my own 2 Dimensional DFT function with reduced loops.
What I try to implement is Discrete Fourier Transform:
Using the separability property of transform (actually exponential function), we can write this as multiplication of two 1 dimensional DFT. Then, we can calculate the exponential terms for rows (the matrix wM below) and columns (the matrix wN below) of transform. Then, for summation process we can multiply them as "F = wM * original_matrix * wN"
Here is the code I wrote:
f = imread('cameraman.tif');
[M, N, ~] = size(f);
wM = zeros(M, M);
wN = zeros(N, N);
for u = 0 : (M - 1)
for x = 0 : (M - 1)
wM(u+1, x+1) = exp(-2 * pi * 1i / M * x * u);
end
end
for v = 0 : (N - 1)
for y = 0 : (N - 1)
wN(y+1, v+1) = exp(-2 * pi * 1i / N * y * v);
end
end
F = wM * im2double(f) * wN;
The first thing is I dont want to use 2 loops which are MxM and NxN times running. If I used a huge matrix (or image), that would be a problem. Is there any chance to make this code faster (for example eliminating the loops)?
The second thing is displaying the Fourier Transform result. I use the codes below to display the transform:
% // "log" method
fl = log(1 + abs(F));
fm = max(fl(:));
imshow(im2uint8(fl / fm))
and
% // "abs" method
fa = abs(F);
fm = max(fa(:));
imshow(fa / fm)
When I use the "abs" method, I see only black figure, nothing else. What is wrong with "abs" method you think?
And the last thing is when I compare the transform result of my own function with MATLAB' s fft2() function', mine displays darker figure than MATLAB' s result. What am I missing here? Implementation misktake?
The transform result of my own function:
The transform result of MATLAB fft2() function:
I am happy you solved your problem but unfortunately you answer is not completely right. Indeed it does the job, but as I commented, im2double will normalize everything to 1, therefore showing the scaled result you have. What you want (if you are looking for performance) is not doing im2doubleand then multiply by 255, but directly casting to double().
You can eliminate loops by using meshgrid.
For example:
M = 1024;
tic
[ mX, mY ] = meshgrid( 0 : M - 1, 0 : M - 1 );
wM1 = exp( -2 * pi * 1i / M .* mX .* mY );
toc
tic
for u = 0 : (M - 1)
for x = 0 : (M - 1)
wM2( u + 1, x + 1 ) = exp( -2 * pi * 1i / M * x * u );
end
end
toc
all( wM1( : ) == wM2( : ) )
The timing on my system was:
Elapsed time is 0.130923 seconds.
Elapsed time is 0.493163 seconds.

matlab quadprog constraints issue

I have a portfolio of weights I am using quadprog in matlab.
I have all the inputs for the quadprog optimizer. I am just having some trouble formulating
the constraints
I would like my constraints to have a lower bound of either 0 or 1%, is there a way to do that while maintainng my objective function
Thanks!
I am not sure if I understand your question well.
If your weights are already defined in terms of percentage, it is directly the definition of quadprog:
x = quadprog(H, f, [], [], [], [], lb, [])
So H, e, and f should be provided by the matlab description of:
quadprog(H,f) - returns a vector x that minimizes 1/2 * x' * H * x + f' * x. H must be positive definite for the problem to have a finite minimum."
And lb is a vector of the constraints. For instance if x is a vector 3 x 1, then lb = [0.01; 0.01; 0.01] in the case of the desired percentage is 0.01 (1%)
On the other hand, lets assume the sum_{i=1}^{n} w_i is not equal to 1. Therefore, w_i is not defined in terms of percentage.
Therefore, the constraint that you need is p_i (percentage)= w_i / (sum w_i) >= 0.01 (in the case of the lower bound be 1%).
Note that the constraint in this case is
w_i >= 0.01 * (sum w_i)
Or
-0.01 * (sum_{j=1}^{i-1} w_j) + 0.99 * w_i - 0.01 * (sum_{j=i+1}^{n} w_j) >= 0
Or
0.01 * (sum_{j=1}^{i-1} w_j) - 0.99 w_i + 0.01 * (sum_{j=i+1}^{n} w_j) <= 0
Therefore, this is a constraint of the type Ax <= b.
So
A_ij = 0.01 when i is different from j
A_ij = -0.99 when i = j and b = zeros(n, 1)
In this case you are using
x = quadprog(H, f, A, b)
I hope I helped you!
Daniel

ezmesh offsets all z values by over 500

I'm using octave's ezmesh to plot a linear regression defined as follows:
f = #(x,y) 1 * theta(1) + x * theta(2) + y * theta(3) + x * y * theta(4)
For some fixed vector theta:
octave:275> theta
theta =
9.4350e+00
1.7410e-04
3.3702e-02
1.6498e-07
I'm using a domain of [0 120000 0 1400], and can evaluate:
octave:276> f(0, 0)
ans = 9.4350
octave:277> f(120000, 1400)
ans = 105.23
However, if I run:
octave:278> ezmesh(f, [0 120000 0 1400])
The resulting mesh has a z value of around 570 for (0, 0) and just under 640 for (120000, 1400). I'm baffled. What could be causing this?
EDIT: Even if I simplify f to the following, similar behavior occurs:
octave:308> f = #(x, y) (x * y)
Why is ezmesh not handling multiplication as expected (by me), so that the function evaluates as I expect, and the values change when the function is used inside of ezmesh?
ezmesh invokes the function handle on a matrix of values (to benefit from vectorization performance). Use .* for multiplication.