How can I integrate a function which needs to have a matrix calculation first? - matlab

I am doing my dissertation now. I stuck with a integral. My function is defined as
myfun =(exp(t*Q)*V*x)(j);
where Q and V are a matrix (n*n), x is a vector which elements are 1, then after calculation we get the j_th element of that vector then I need to integrate the function against t.
I want to use the quad in the matlab. However the point is that it will report the inner matrix is not the same size. Since A here is not a number ?....
How can I do this. Otherwise I could only write a loop against t itself, which is extremely slow.
Thanks

You can use SUBSREF for this (you still neet to loop over all j's, though):
myfunOfT = #(t)(subsref(exp(t*Q)*V*x,struct('type','()','subs',j);
This returns the value of the jth element of the array at time t.

Related

How to plot a function with an exponential multiplied by a sine function?

Hello I need help plotting the below equation in matlab.
v=10.0004+10.229*e^(-3*t)*sin(5.196*t-257.856)
here is what I have but I keep getting an error:
t=[0:0.1:2];
v=10.0004+10.229*exp(t)*sin(5.196*t+257.856);
plot(t,v)
Error using *
Incorrect dimensions for matrix multiplication. Check that the number of columns in the first matrix matches the
number of rows in the second matrix. To perform elementwise multiplication, use '.*'.
Error in example (line 2)
v=10.0004+10.229*exp(t)*sin(5.196*t+257.856);
Because t is a matrix, you cannot simply input it as you would a single variable. You have to access each value individually and calculate a corresponding v, then you store that value and move on. Rinse and repeat for each value.
This can be visualized with a for loop. Get the length of your time variable, which will determine how many values you need to calculate, then let the loop run for the corresponding number of elements. Make sure the loop counter is also used to index each element in v.
t = 0:0.1:2 ;
%For each element (n) in t, create a corresponding one of v.
for n = 1:length(t)
v(n) = 10.0004+10.229*exp(t(n))*sin(5.196*t(n)+257.856);
end
plot(t,v)
As we can interpret from the loop, there is a need to do element-wise (good keyword to remember) multiplication. In other languages, you might HAVE to use the loop method. Luckily in Matlab there is a dedicated operator for this '.*'. Therefore in Matlab you could simply modify your code as follows:
t=[0:0.1:2];
v=10.0004+10.229.*exp(t).*sin(5.196.*t+257.856);
plot(t,v)
Either method gives you the desired plot. The first I included to illustrate the underlying logic of what you're looking to do, and the second to simply it with Matlab's syntax. Hope this helps guide you in the future.
Best of luck out there.

Matlab fit with function returning vector with all the y(x_i) values

I am working on something and I haven't found any solution, maybe I didn't know how to correctly search for it...
I have two arrays of experimental data (x and y). x is a list of certain energies (512 values from 0 to 100 kev) and I want to fit them to a function which returns a vector of values of y for every x in the list (the energies are always the same, 512 certain values). This is because my function model contains several matrix and other functions.
So, I can't evaluate my function as f(x,a,b,c...) (with a,b,c the parameters to fit) and expect a single scalar, but I have to evaluate f(a,b,c...), and it returns a vector of y(x1),y(x2)...
Now, I want to fit my data to my model. But lsqcurvefit needs a function of the form f(x), I suppose that it evaluates every f(x). I could write my function so that every time it is called it evaluates the vector result, and then returns y for the given x, but it would be quite inefficient... And I'm sure there must be another way.
Any idea?
Maybe you can do an fminsearch on the sum of square errors? It is best to put all fitting parameters into one vector. Here I call it p.
f = #(x,p) (p(3)+p(1)*x.^p(2)).^(1/p(4); %example function with four free parameters
sqerr = #(x,y,p) sum((y-f(x,p)).^2); %sum of squared errors
p = [1,1,1,1]; %four starting conditions
p = fminsearch(#(p) sqerr(x,y,p),p); %fit
Then you can find your y(x_i) values by calling the function with the fitted paramters
f(x,p)

apply function to each column of a matrix (Vectorizing)

What is fastest way of applying function on each column of a matrix without looping through it?
The function I am using is pwelch but the concept should be the same for any function.
Currently I am looping though my matrix as such.
X = ones(5);
for i = 1:5 % length of the number of columns
result = somefunction(X(:,i))
end
Is there a way to vectorize this code?
You say
the concept should be the same for any function
Actually that's not the case. Depending on the function, the code that calls it can be made vectorized or not. It depends on how the function is written internally. From outside the function there's nothing you can do to make it vectorized. Vectorization is done within the function, not from the outside.
If the function is vectorized, you simply call it with a matrix, and the function works on each column. For example, that's what sum does.
In the case of pwelch, you are lucky: according to the documentation (emphasis added),
Pxx = pwelch(X) returns the Power Spectral Density (PSD) estimate, Pxx, ...
When X is a matrix, the PSD is
computed independently for each column and stored in the corresponding
column of Pxx.
So pwelch is a vectorized function.

How can I use NxM matrix to be my initial condition in `pdepe`

I solved a PDE using Matlab solver, pdepe. The initial condition is the solution of an ODE, which I solved in a different m.file. Now, I have the ODE solution in a matrix form of size NxM. How I can use that to be my IC in pdepe? Is that even possible? When I use for loop, pdepe takes only the last iteration to be the initial condition. Any help is appreciated.
Per the pdepe documentation, the initial condition function for the solver has the syntax:
u = icFun(x);
where the initial value of the PDE at a specified value of x is returned in the column vector u.
So the only time an initial condition will be a N x M matrix is when the PDE is a system of N unknowns with M spatial mesh points.
Therefore, an N x M matrix could be used to populate the initial condition, but there would need to be some mapping that associates a given column with a specific value of x. For instance, in the main function that calls pdepe, there could be
% icData is the NxM matrix of data
% xMesh is an 1xM row vector that has the spatial value for each column of icData
icFun = #(x) icData(:,x==xMesh);
The only shortcoming of this approach is that the mesh of the initial condition, and therefore the pdepe solution, is constrained by the initial data. This can be overcome by using an interpolation scheme like:
% icData is the NxM matrix of data
% xMesh is an 1xM row vector that has the spatial value for each column of icData
icFun = #(x) interp1(xMesh,icData',x,'pchip')';
where the transposes are present to conform to the interpretation of the data by interp1.
it is easier for u to use 'method of line' style to define different conditions on each mesh rather than using pdepe
MOL is also more flexible to use in different situation like 3D problem
just saying :))
My experience is that the function defining the initial conditions must return a column vector, i.e. Nx1 matrix if you have N equations. Even if your xmesh is an array of M numbers, the matrix corresponding to the initial condition is still Nx1. You can still return a spatially varying initial condition, and my solution was the following.
I defined an anonymous function, pdeic, which was passed as an argument to pdepe:
pdeic=#(x) pdeic2(x,p1,p2,p3);
And I also defined pdeic2, which always returns a 3x1 column vector, but depending on x, the value is different:
function u0=pdeic2(x,extrap1,extrap2,extrap3)
if x==extrap3
u0=[extrap1;0;extrap2];
else
u0=[extrap1;0;0];
end
So going back to your original question, my guess would be that you have to pass the solution of your ODE to what is named 'pdeic2' in my example, and depending on X, return a column vector.

Find minimum of following function in Matlab

I am trying to minimize sum((A-r*B).^2) in Matlab where A and B are matrices and r is the scalar I am manipulating. I tried the following code:
f = #(r) sum((A-r*B).^2);
Answer = fminbnd(f,lowrange,highrange);
But I get an error.
If A and B are matrices, then sum((A - r*B).^2) will not give you a single value. This will give you an array of values. If the input to sum is a matrix, the output of sum will give you an array where each element is the sum along the rows for each column in your matrix.
The function you are specifying to fminbnd must evaluate to a single value. I'm assuming you want to determine the sum of squared differences in your function, and so you need to wrap your sum with another sum. As such, try this instead:
f = #(r) sum(sum((A-r*B).^2));
Answer = fminbnd(f,lowrange,highrange);
The function f will now find the difference between matrices A and B which is weighted by r, square these differences and then add up all of these differences together.
Try that and see if it works.
If you don't need to impose limits on the possible values of the optimized scalar r, then you should be able to solve this equation directly without searching for the minimum. If A and B are vectors, use:
ropt=(B'*B)^(-1)*B'*A;
If A and B are arrays and you want to minimize the sum of squared residuals of all elements of the arrays then I believe the following will work (same formula, but convert A and B to vectors).
ropt=(B(:)'*B(:))^(-1)*B(:)'*A(:);
Examples:
b=[1;2;3]
a=2*b;
ropt=(b'*b)^(-1)*b'*a
returns ropt=2.0000, as desired
Similarly, for a matrix:
b=magic(3);
a=2*b;
ropt=(b(:)'*b(:))^(-1)*b(:)'*a(:)
also returns ropt=2.0000. This should work fine even if there isn't a perfect solution, as there is in the examples above.