Double integral in MATLAB - matlab

I'm trying to find the power in an aperture from a Gaussian beam, where the aperture is offset from the beam center. The solution is the following equation (reference) (sorry, no LaTeX here):
Wz is a constant, along with a and r. I'm not sure how I can do something like this with MATLAB. Does anyone have a suggestion? I know there's a dblquad() function, but it assumes that the limits of integration are fixed, and not dependent on each other.

Using a bit of mathematical footwork, you could reduce the double integral to a single one (albeit containing the error function) which should be easier to calculate numerically in MATLAB:
(With reservation for errors; check the calculations yourself if possible.)

It turns out that more recent versions of MATLAB now have a quad2d() function, which does a 2d integral over a surface. Example 2 on the reference page details an example of doing this type of integration.
My code ended up looking something like this:
powerIntegral = #(x,y) 2/(pi*W^2)*exp(-2*((x - offsetDist).^2 + y.^2)/(W^2));
ymin = #(x) -sqrt(radius.^2 - x.^2);
ymax = #(x) sqrt(radius.^2 - x.^2);
powerRatioGaussian = quad2d(powerIntegral,-radius,radius,ymin,ymax);
Pretty nifty. Thanks for the help.

I am not sure, but I think that the symbolic toolbox can help you here. It is suited for this kind of problems. You can define your variables as symbolic vars using the syms command, and compute the integral symbolically. Then, you can assign the variables values and find the actual value.
Disclaimer : I have never actually used it myself.

Generally speaking, for numeric integration, you can transform an integral with dependent boundary conditions to one with independent boundaries by multiplying by a function that is 1 if you are inside the original boundary and 0 if you are outside. Then take your limits to be a square that contains your original conditions. In other words here you would multiply by
g(x,y) = ((x^2 + y^2) < a^2)
and your limits would be -a
You have to be a little careful about the continuity assumptions in your integration method, but you should be OK unless something is very weird. You can always check by changing your cell size and making sure the computed integral value doesn't change.
In this particular case, you could also make the transformation from cartesian to polar coordinates;
x = rcos(t)
y = rsin(t)
dxdy = rdrdt
Then your limits of integration would be r from 0 to a and t from 0 to 2*pi

Related

Deriving dirac delta function using Matlab symbolic toolbox

i'm new in matlab. I didn't understand how to derive a dirac delta function and then shift it using symbolic toolbox.
syms t
x = dirac(t)
why can't i see the dirac delta function using ezplot(x,[-10,10]) for example?
As others have noted, the Dirac delta function is not a true function, but a generalized function. The help for dirac indicates this:
dirac(X) is not a function in the strict sense, but rather a
distribution with int(dirac(x-a)*f(x),-inf,inf) = f(a) and
diff(heaviside(x),x) = dirac(x).
Strictly speaking, it's impossible for Matlab to plot the Dirac delta function in the normal way because part of it extends to infinity. However, there are numerous workarounds if you want a visualization. A simple one is to use the stem plot function and the > operator to convert the one Inf value to something finite. This produces a unit impulse function (or Kronecker delta):
t = -10:10;
x = dirac(t) > 0;
stem(t,x)
If t and x already exist as symbolic variables/expressions rather than numeric ones you can use subs:
syms t
x = dirac(t);
t2 = -10:10;
x2 = subs(x,t,t2)>0;
stem(t2, x2)
You can write your own plot routine if you want something that looks different. Using ezplot is not likely to work as it doesn't offer as much control.
First, I've not met ezplot before; I had to read up on it. For things that are functionals like your x, it's handy, but you still have to realize it's exactly giving you what it promises: A plot.
If you had the job of plotting the dirac delta function, how would you go about doing it correctly? You can't. You must find a convention of annotating your plot with the info that there is a single, isolated, infinite point in your plot.
Plotting something with a line plot hence is unsuitable for anything but smooth functions (that's a well-defined term). Dirac Delta definitely isn't amongst the class of functions that are smooth. You would typically use a vertical line or something to denote the point where your functional is not 0.

solve trig equation over boundary

Firstly, I'm sure a simple answer exists for this, maybe I'm just not wording it right in searching for an answer online.
I'm trying to solve an equation that looks like this:
a*x*cot(a*x) == b
Where a and b are constants. Using
solve(a*x*cot(a*x) == b, x)
I'm getting a result I know is wrong (with the values I'm using for the constants, I'm getting like -227, and it should be something around +160.) I plotted it up in Mathematica as two separate functions, and they do cross each other right around there, but since the cot part is periodic, they do so many times.
I want to constrain Matlab's search for the solution to a specific interval, such as 0 to 200; how do I do that?
I'm pretty new to Matlab (rather more experienced in Mathematica).
You can specify the bounds on x using fzero with only two requirements
The function must be in a "residual" form (i.e., r(x) = 0)
The residual values at the two bounds must have opposite sign (this guarantees that a root exists within the interval for continuous functions).
So we re-write the function in residual form:
r = #(x) a*x*cot(a*x) - b;
define the interval
% These are just random numbers; the actual bounds should come
% from the graph the ensures r has different signs a xL and xR
xL = 150;
xR = 170;
and solve
x = fzero(r,[xL,xR]);
I see you were trying to use the Symbolic Toolbox for a solution, but since the equation is a non-linear combination of a polynomial and a trigonometric function, there is more than likely no closed form solution. So I differed to a non-linear, numeric root-finder.
I tried some values and it seems solve returns a numeric solution. This is the documented behaviour if no analytic solution is found.
In this case, you may directly call the numeric solver with a matching start value
vpasolve(a*x*cot(a*x) == b, x,160)
It's not exactly what you asked for, but using your reading from the plot as a start value should do it.

How to have square wave in Matlab symbolic equation

My project require me to use Matlab to create a symbolic equation with square wave inside.
I tried to write it like this but to no avail:
syms t;
a=square(t);
Input arguments must be 'double'.
What can i do to solve this problem? Thanks in advance for the helps offered.
here are a couple of general options using floor and sign functions:
f=#(A,T,x0,x) A*sign(sin((2*pi*(x-x0))/T));
f=#(A,T,x0,x) A*(-1).^(floor(2*(x-x0)/T));
So for example using the floor function:
syms x
sqr=2*floor(x)-floor(2*x)+1;
ezplot(sqr, [-2, 2])
Here is something to get you started. Recall that we can express a square wave as a Fourier Series expansion. I won't bother you with the details, but you can represent any periodic function as a summation of cosines and sines (Ă  la #RTL). Without going into the derivation, this is the closed-form equation for a square wave of frequency f, with a peak-to-peak amplitude of 2 (i.e. it goes from -1 to 1). Recall that the frequency is the amount of cycles per seconds. Therefore, f = 1 means that we repeat our square wave every second.
Basically, what you have to do is code up the first line of the equation... but how in the world would you do that? Welcome to the world of the Symbolic Math Toolbox. What we will need to do before hand is declare what our frequency is. Let's assume f = 1 for now. With the Symbolic Math Toolbox, you can define what are considered as mathematics variables within MATLAB. After, MATLAB has a whole suite of tools that you can use to evaluate functions that rely on these variables. A good example would be if you want to use this to define a closed-form solution of a function f(x). You can then use diff to differentiate and see what the derivative is. Try it yourself:
syms x;
f = x^4;
df = diff(f);
syms denotes that you are declaring anything coming after the statement to be a mathematical variable. In this case, x is just that. df should now give you 4x^3. Cool eh? In any case, let's get back to our problem at hand. We see that there are in fact two variables in the periodic square function that need to be defined: t and k. Once we do this, we need to create our function that is inside the summation first. We can do this by:
syms t k;
f = 1; %//Define frequency here
funcSum = (sin(2*pi*(2*k - 1)*f*t) / (2*k - 1));
That settles that problem... now how do we encapsulate this into an infinite sum!? The sum command in MATLAB assumes that we have a finite array to sum over. If you want to symbolically sum over a function, we must use the symsum function. We usually call it like this:
funcOut = symsum(func, v, start, finish);
func is the function we wish to sum over. v is the summation variable that we wish to use to index in the sum. In our case, that's k. start is the beginning of the sum, which is 1 in our case, and finish is where we wish to finish up our summation. In our case, that's infinity, and so MATLAB has a special keyword called Inf to denote that. Therefore:
xsquare = (4/pi) * symsum(funcSum, k, 1, Inf);
xquare now contains your representation of a square wave defined in terms of the Symbolic Math Toolbox. Now, if you want to plot your square wave and see if we have this right. We can do the following. Let's go between -3 <= t <= 3. As such, you would do something like this:
tVector = -3 : 0.01 : 3; %// Choose a step size of 0.01
yout = subs(xsquare, t, tVector);
You will notice though that there will be some values that are NaN. The reason why is because right at a multiple of the period (T = 1, 2, 3, ...), the behaviour is undefined as the derivative right at these points is undefined. As such, we can fill this in using either 1 or -1. Let's just choose 1 for now. Also, because the Fourier Series is generally a complex-valued function, and the square-wave is purely real, the output of this function will actually give you a complex-valued vector. As such, simply chop off the complex parts to get the real parts only:
yout = real(double(yout)); %// To cast back to double.
yout(isnan(yout)) = 1;
plot(tVector, yout);
You'll get something like:
You could also do this the ezplot way by doing: ezplot(xsquare). However, you'll see that at the points where the wave repeats itself, we get NaN values and so there is a disconnect between the high peak and low peak.
Note:
Natan's solution is much more elegant. I was still writing this post by the time he put something up. Either way, I wanted to give a more signal processing perspective to how to do this. Go Fourier!
A Fourier series for the square wave of unit amplitude is:
alpha + 2/Pi*sum(sin( n * Pi*alpha)/n*cos(n*theta),n=1..infinity)
Here is a handy trick:
cos(n*theta) = Re( exp( I * n * theta))
and
1/n*exp(I*n*theta) = I*anti-derivative(exp(I*n*theta),theta)
Put it all together: pull the anti-derivative ( or integral ) operator out of the sum, and you get a geometric series. Then integrate and finally take the real part.
Result:
squarewave=
alpha+ 1/Pi*Re(I*ln((1-exp(I*(theta+Pi*alpha)))/(1-exp(I*(theta-Pi*alpha)))))
I tried it in MAPLE and it works great! (probably not very practical though)

Matlab recursive curve fitting with custom equations

I have a curve IxV. I also have an equation that I want to fit in this IxV curve, so I can adjust its constants. It is given by:
I = I01(exp((V-R*I)/(n1*vth))-1)+I02(exp((V-R*I)/(n2*vth))-1)
vth and R are constants already known, so I only want to achieve I01, I02, n1, n2. The problem is: as you can see, I is dependent on itself. I was trying to use the curve fitting toolbox, but it doesn't seem to work on recursive equations.
Is there a way to make the curve fitting toolbox work on this? And if there isn't, what can I do?
Assuming that I01 and I02 are variables and not functions, then you should set the problem up like this:
a0 = [I01 I02 n1 n2];
MinFun = #(a) abs(a(1)*(exp(V-R*I)/(a(3)*vth))-1) + a(2)*(exp((V-R*I)/a(4)*vth))-1) - I);
aout = fminsearch(a0,MinFun);
By subtracting I and taking the absolute value, the point where both sides are equal will be the point where MinFun is zero (minimized).
No, the CFTB cannot fit such recursively defined functions. And errors in I, since the true value of I is unknown for any point, will create a kind of errors in variables problem. All you have are the "measured" values for I.
The problem of errors in I MAY be serious, since any errors in I, or lack of fit, noise, model problems, etc., will be used in the expression itself. Then you exponentiate these inaccurate values, potentially casing a mess.
You may be able to use an iterative approach. Thus something like
% 0. Initialize I_pred
I_pred = I;
% 1. Estimate the values of your coefficients, for this model:
% (The curve fitting toolbox CAN solve this problem, given I_pred)
I = I01(exp((V-R*I_pred)/(n1*vth))-1)+I02(exp((V-R*I_pred)/(n2*vth))-1)
% 2. Generate new predictions for I_pred
I_pred = I01(exp((V-R*I_pred)/(n1*vth))-1)+I02(exp((V-R*I_pred)/(n2*vth))-1)
% Repeat steps 1 and 2 until the parameters from the CFTB stabilize.
The above pseudo-code will work only if your starting values are good, and there are not large errors/noise in the model/data. Even on a good day, the above approach may not converge well. But I see little hope otherwise.

Multiplication of large number with small number

I'm trying to compute a rather ugly integral using MATLAB. What I'm having problem with though is a part where I multiply a very big number (>10^300) with a very small number (<10^-300). MATLAB returns 'inf' for this even though it should be in the range of 0-0.0005. This is what I have
besselFunction = #(u)besseli(qb,2*sqrt(lambda*(theta + mu)).*u);
exponentFuncion = #(u)exp(-u.*(lambda + theta + mu));
where qb = 5, lambda = 12, theta = 10, mu = 3. And what I want to find is
besselFunction(u)*exponentFunction(u)
for all real values of u. The problem is that whenever u>28 it will be evaluated as 'inf'. I've heared, and tried, to use MATLAB function 'vpa' but it doesn't seem to work well when I want to use functions...
Any tips will be appreciated at this point!
I'd use logarithms.
Let x = Bessel function of u and y = x*exp(-u) (simpler than your equation, but similar).
Since log(v*w) = log(v) + log(w), then log(y) = log(x) + log(exp(-u))
This simplifies to
log(y) = log(x) - u
This will be better behaved numerically.
The other key will be to not evaluate that Bessel function that turns into a large number and passing it to a math function to get the log. Better to write your own that returns the logarithm of the Bessel function directly. Look at a reference like Abramowitz and Stegun to try and find one.
If you are doing an integration, consider using Gauss–Laguerre quadrature instead. The basic idea is that for equations of the form exp(-x)*f(x), the integral from 0 to inf can be approximated as sum(w(X).*f(X)) where the values of X are the zeros of a Laguerre polynomial and W(X) are specific weights (see the Wikipedia article). Sort of like a very advanced Simpson's rule. Since your equation already has an exp(-x) part, it is particularly suited.
To find the roots of the polynomial, there is a function on MATLAB Central called LaguerrePoly, and from there it is pretty straightforward to compute the weights.