How to perform convolution using Fourier Series - matlab

OK let me cut to the chase.
I am trying to use MATLAB to
(i)generate the fourier series based on known coefficients and thereafter
(ii) determine the output function when the impulse is known.
So far I used this code to obtain the fourier series:
clear all
syms x k L n
evalin(symengine,'assume(k,Type::Integer)');
a = #(f,x,k,L) (2/(pi*k))* sin((pi*k)/(2 * L));
fs = #(f,x,n,L) (1/2*L) + symsum(a(f,x,k,L)*cos(k*2*pi*x/L),k,1,n);
f = x;
pretty(fs(f,x,11,1))
This works as desired. Now the impulse response is as follows:
h = heaviside(x) * exp(-5*x);
Now, in order to obtain the function, we need to perform the convolution with the respective functions.But when I input the following, I get the error:
x1 = fs(f,x,1,1);
conv(h,x1)
Undefined function 'conv2' for input arguments of type 'sym'.
Error in conv (line 38)
c = conv2(a(:),b(:),shape);
Any help would be appreciated

That is because conv is only defined for numeric inputs. If you want to find the convolution symbolically, you'll have to input the equation yourself symbolically using integration.
If you recall, the convolution integral is defined as:
Source: Wikipedia
Therefore, you would do this:
syms x tau;
F = int(h(tau)*x1(x-tau),'tau',-inf,+inf);
int is a function in MATLAB that does symbolic integration for you. Also note that the convolution integral is commutative, and so this also works:
Source: Wikipedia
Therefore, you should also get the same answer if you did:
syms x tau;
F = int(h(x-tau)*x1(tau),'tau',-inf,+inf);
Hope this helps!

Related

Solve complex matrix equation

I have a complex equation involving matrices:
R = expm(X)*A + (expm(X)-I)*inv(X)*B*U;
where R, B and U are known matrices.
I is an identity matrix.
I need to solve for X. Is there any way to solve this in MATLAB?
If your equation is nonlinear and you have access to MATLAB optimization toolbox you can use the fsolve function (You can still use it for a linear equation, but it may not be the most efficient approach). You just need to reformat your equation into the form F(x) = 0, where x is a vector or a matrix. For example, if X is a vector of length 2:
Define your function to solve:
function F = YourComplexEquation(X)
Fmatrix = expm(X)*A + (expm(X)-I)*inv(X)*B*U - R
% This last line is because I think fsolve requires F to be a vector, not a matrix
F = Fmatrix(:);
Then call fsolve with an initial guess:
X = fsolve(#YourComplexEquation,[0;0]);

Using Matlab's lsqcurvefit to Calculate Infinite Relaxation Spectrum

I am trying to replicate an analysis performed in a publication and am having trouble. This is about trying to calculate the infinite relaxation spectrum from rheological data.
Given an experimental data series (above), the authors extract the relaxation spectrum (H(tau)) by solving for the difference of the sum of squares between experimental (above) and model data (below).
This relaxation follows a distribution described by the following relationship.
This calculation was performed with matlabs lsqcurefit function. However, lsqcurvefit does not accept a function as a solvable parameter. I would like to know how this extraction can be accomplished using this matlab function.
EDIT: Following Bentoys comments, here is a clarification of my question.
I will detail the following just for G'' (Gdp) to save space.
I have a experimental data in the following form: a vector of frequency values (omega), xdata, and a vector of Gdp response values (Gdp).
I would like to calculate H(tau), and to do so I will need the parameters contained within that function. This gives the following expression that I need to resolve:
Gdp is a function of omega, and my xdata is a vector of omega values, but I am integrating with respect to ln(tau). This seems like it could be a possible problem?
Also, I do not have a clear ideal of expected initial values for the 6 variables, only for the resulting H(tau), so have chosen arbitrary values to begin with. I can optimise their relative values if calculated values can be obtained.
From your suggestions my matlab code is as follows:
w = numdata(:,1); %w is omega (experimental xdata)
GdpExp = numdata(:,3); % response values (ydata)
x0 = [10,10,0.1,0.1,1,1]; % arbitrary intial values
H = #(x, xdata) x(1)*exp(-(xdata-log(x(3))).^2/x(5)^2/2)...
+ x(2)*exp(-(xdata-log(x(4))).^2/x(6)^2/2);
Gdp = #(A_1, A_2, tau_1, tau_2, sigma_1, sigma_2, w) ...
integral(H([A_1, A_2, tau_1, tau_2, sigma_1, sigma_2], ...
u).* w.*exp(u)./(1+w.^2.*exp(2*u)), -Inf, Inf);
lsqcurvefit(Gdp, x0, w, GdpExp);
This currenlty gives the following error:
>> lsqcurvefit(Gdp, x0, w, GdpExp);
Not enough input arguments.
Error in
Inf_Spec_Test>#(A_1,A_2,tau_1,tau_2,sigma_1,sigma_2,w)integral
(H([A_1,A_2,tau_1,tau_2,sigma_1,sigma_2],u).*w.*exp(u)./(1+w.^2.*exp(2*u)),
-Inf,Inf)
Error in lsqcurvefit (line 202)
initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});
Caused by:
Failure in initial objective function evaluation. LSQCURVEFIT cannot
continue.
Am I correct in thinking that each function is self-contained or should the naming for A_1, A_2 etc. be the same as x(1), x(2), or are the A_1 etc. simply labels to refer to the calculated values?
The experimental data and calculated H(tau) should resemble the following figures.
I also found the following relationship, which could be used to transform the omega vector into a tau vector, which might be helpful for overcoming the discrepancy between the current xdata and the integral.
Assuming you have experimental data of H(tau) in the form of a vector Y, you want to fit your model H:
H = #(A_1, A_2, tau_1, tau_2, sigma_1, sigma_2, tau) ...
A1*exp(-(log(tau)-log(tau_1)).^2/sigma_1^2/2) + A2*exp(-(log(tau)-log(tau_2)).^2/sigma_2^2/2);
lsqcurvefit expects a function in the form f(x, xdata). Here xdata is the "time data", naming tau, and x all coefficients of your function. So, rewriting function H gives:
H = #(x, xdata) x(1)*exp(-(log(xdata)-log(x(3))).^2/x(5)^2/2) + x(2)*exp(-(log(xdata)-log(x(4))).^2/x(6)^2/2);
Then I asusme that you have some initial guess for the values of all six coefficients. If not, the fitting may not converge to the appropriate solution. I call this initial guess x0 which is a vector of length 6. To get the fit, just call:
lsqcurvefit(H, x0, tau, Y)
You may want to add more options (such as parameter bounds), see documentation of lsqcurvefit for more details.
EDIT
Following details in comments below, you have a vector of values G+G' for several values of omega (in a vector W).
So the function you want to fit is a little more complex:
H = #(x, xdata) x(1)*exp(-(xdata-log(x(3))).^2/x(5)^2/2) + x(2)*exp(-(xdata-log(x(4))).^2/x(6)^2/2);
GGp = #(A_1, A_2, tau_1, tau_2, sigma_1, sigma_2, w) ...
integral(H([A_1, A_2, tau_1, tau_2, sigma_1, sigma_2], u).* w.*exp(u).*(1+w.*exp(u))./(1+w.^2.*exp(2*u)), -Inf, Inf);
after a little change of variable, u = ln(tau).
Then it is exactly the same thing, except you have now a different function to fit:
lsqcurvefit(GGp, x0, W, Y)

Using matlab to find Laplace transform

f(t) = t*e^t when 0 <= t < 3
f(t) = 0 when 3 <= t
how to use Matlab to find Laplace transforms of functions which change according to different values of t
MATLAB has a function called laplace, and we can calculate it like:
syms x y
f = 1/sqrt(x);
laplace(f)
But it will be a very long code when we turn f(x) like this problem into syms.
Indeed, we can do this by using dirac and heaviside if we have to. Nevertheless, we could use this instead:
syms t s
f=t*exp((1-s)*t);
F=int(f,t,0,3)
It is because:
If you are interested in a numerical implementation of the Laplace transform, you can download from Matlab's file exchange the following Numerical Transform and the inverse transform ...

How to perform indefinite integration of this function in MATLAB?

I need to perform the following operations as shown in the image. I need to calculate the value of function H for different inputs(x) using MATLAB.
I am giving the following command from Symbolic Math Toolbox
syms y t x;
f1=(1-exp(-y))/y;
f2=-t+3*int(f1,[0,t]);
f3=exp(f2);
H=int(f3,[0,x]);
but the value of 2nd integral i.e. integral in the function H can't be calculated and my output is of the form of
H =
int(exp(3*eulergamma - t - 3*ei(-t) + 3*log(t)), t, 0, x)
If any of you guys know how to evaluate this or have a different idea about this, please share it with me.
Directly Finding the Numerical Solution using integral:
Since you want to calculate H for different values of x, so instead of analytical solution, you can go for numerical solution.
Code:
syms y t;
f1=(1-exp(-y))/y; f2=-t+3*int(f1,[0,t]); f3=exp(f2);
H=integral(matlabFunction(f3),0,100) % Result of integration when x=100
Output:
H =
37.9044
Finding the Approximate Analytical Solution using Monte-Carlo Integration:
It probably is an "Elliptic Integral" and cannot be expressed in terms of elementary functions. However, you can find an approximate analytical solution using "Monte-Carlo Integration" according to which:
where f(c) = 1/n Σ f(xᵢ)
Code:
syms x y t;
f1=(1-exp(-y))/y; f2=-t+3*int(f1,[0,t]); f3=exp(f2);
f3a= matlabFunction(f3); % Converting to function handle
n = 1000;
t = x*rand(n,1); % Generating random numbers within the limits (0,x)
MCint(x) = x * mean(f3a(t)); % Integration
H= double(MCint(100)) % Result of integration when x=100
Output:
H =
35.2900
% Output will be different each time you execute it since it is based
% on generation of random numbers
Drawbacks of this approach:
Solution is not exact but approximated.
Greater the value of n, better the result and slower the code execution speed.
Read the documentation of matlabFunction, integral, Random Numbers Within a Specific Range, mean and double for further understanding of the code(s).

parametric integration and numeric plotting of a 2D function

I am going to devise a 2D function as a probability density function, is which a function of two variables, i.e. f = f(x,n). Then, as the target is plotting the probability variation, the integration in related to parameter x should be taken into account. The t parameter is the variable planned to be the upper bound of the integration. It is suffice to say that n is the other tuning factor. Finally, with due attention to the considered meshgrid, the probability surface is supposed to be drawn.
My option for the integration process is the symbolic int function. But there is an error: Error using mupadmex
Here is my code:
clear;
syms x;
syms n;
syms t;
sigma = 1;
mu = 0;
[t,n] = meshgrid(0:0.01:20, 1:1:100);
f = (n./(2*sigma*sqrt(pi))).*exp(-((n.*x)./(2.*sigma)).^2);
ff = int(f, x, -inf, t);
mesh(n,t,ff);
And the error trace:
Error using mupadmex
Error in MuPAD command: The argument is invalid. [Dom::Interval::new]
Error in sym/int (line 153)
rSym = mupadmex('symobj::intdef',f.s,x.s,a.s,b.s,options);
Error in field (line 14)
ff = int(f, x, -inf, t);
Would you please helping me to overcome this tie?!
PS. I know that there are some ideas to do this stuff more numerically by integral function, but I am prone to handle this case by int function, if it is possible. Because this code should be used as a service by the other snippets and the generated ff parameter is completely deserving, however it won't be a closed form function.
Thanks in advance.
I have changed several details in your code, Ill try to explain all of them.
No need of defining symbolic variables that are not going to be symbolic.
code:
clear;
syms x;
sigma = 1;
mu = 0; % This is never used!
You want to integrate a function f(n,x) dx for different n. If you create a meshgrid of n (instead of a vector), you will have tons of repeated f(ni,x) that you are not going to use.
Just do:
t=(0:1:20);
n=(1:10:100);
% are you sure you dont want ((n.*x)-mu) here?
f = (n./(2*sigma*sqrt(pi))).*exp(-((n.*x)./(2.*sigma)).^2);
int does not accept a mesh of symbolic functions! (or I haven't managed to make it work...).
So put a couple of for's there!
for ii=1:length(n)
for jj=1:length(t)
ff(ii,jj) = int(f(ii), x, -inf, t(jj));
end
end
Now we DO want a meshgrid for the plot!
Like this:
[t,n] = meshgrid(t, n);
And you want to plot the numerical value, so use double() to convert from symbolic to numerical:
plot!:
mesh(n,t,double(ff));
Result (with low amount of points due to the obvious computational effort needed)