Fourier series graph generation from given coefficients an, bn in Matlab(Scilab) - matlab

I've calculated coefficients an, bn (100, T=2*pi) in c++ and checked that they are correct using few sources. Now i try to generate Fourier series graph for given example function in Scilab:
(x+2)*abs(cos(2*x*(x-pi/6)))
M=csvRead(filename, ";", [], 'double')
n=size(M,1)
for i = 1:n
A(i)=M(i)
B(i)=M(i + n)
end
function series=solution(x)
series=A(1)/2;
for i = 2:n
series=series+(A(i)*cos(i*x)+B(i)*sin(i*x));
end
endfunction
function series=solution2(x)
series=(x+2).*abs(cos(2.*x.*(x-%pi/6)));
endfunction
x = -%pi:%pi/100:%pi
plot2d(x, solution(x), 3)
x2 = -%pi:%pi/100:%pi
plot2d(x2, solution2(x2), 4)
Here is the result:
It clearly looks that tendency is ok but the beginning and the end of the period are wrong (reversed?). Do you see any issues in Scilab code? What could cause the problem - values in sin/cos in function solution(x)? Should i provide an, bn values and check for miscalculation there?

I don't know how did you calculated your A & B coefficients, but I assume that you used the usual notations to get the first line of the below formula:
Thus n starts from 1. Since Scilab starts vector indexing from 1, you correctly made your loop from 2, but forgot to compensate for this "offset".
Your function should be something like this:
function series=solution(x)
series=A(1)/2;
for i = 2:n
series=series+(A(i)*cos((i-1)*x)+B(i)*sin((i-1)*x));
end
endfunction
Since you didn't provided A & B, I can not check the result.
Additional note: Syntactically more correct if you explicitly define all input variables in a function, like this:
function series=solution(x,A,B)
This way you may be sure that your input is not changed somewhere else in the code.

Related

Function Definition Clarification in Matlab

I wrote some code that works just fine to evaluate theta on its own with some test input. However, I would like to take this code and turn it into a function that I can call within another matlab file. I keep getting the error message, "Function definitions are not permitted in this context."
I want to be able to define four vectors in another matlab file and call SP1 to evaluate theta for those inputs. I'm not sure where I'm going wrong, though. Please help!
Thanks so much.
clc
clear all
function theta = SP1(p,q1,w1,r)
% INPUT:
%function theta = SP1(p,q1,w1,r)
% p = [5; -7; 12];
% q1 = [17.3037; -3.1128; 2.48175];
% w1 = [1/sqrt(8); sqrt(3/8); 1/sqrt(2)];
% r = [1; 2; -3];
% Define vectors u and v as well as u' and v'.
u = p - r;
v = q1 - r;
w1_t = transpose(w1);
u_prime = u - w1 * w1_t * u;
v_prime = v - w1 * w1_t * v;
% Calculate theta if conditions are met for a solution to exist.
if (abs(norm(u_prime)-norm(v_prime))<0.01) & (abs((w1_t * u)-(w1_t * v))<0.01)
X = w1_t*cross(u_prime,v_prime);
Y = dot(u_prime,v_prime);
theta = atan2(X,Y)
else if (norm(u_prime) == 0 | norm(v_prime) == 0)
disp('Infinite Number of Solutions')
else
disp('Conditions not satisfied to find a solution')
end
end
I think you can just remove the top two lines,
clc
clear all
and save the rest of the code starting with function as SP1.m file.
Then you should be able to call this function as SP1 from other m files.
I think you're confused about how functions work. The first line of a function definition defines how many inputs and outputs MATLAB expects:
function theta = SP1(p,q1,w1,r)
This means that calling a function SP1 will require you to give four inputs, and will return one output. It doesn't mean that:
Your inputs need to be named p, q1 and so on
Your output will be called theta automatically
The function will automatically take in the input variables p, q1, etc if they exist in the workspace.
It also doesn't do any checking on the inputs; so if you require that inputs be of a certain type, size, etc. you need to write your own error checking at the start of the file. You might intend that those inputs be 3x1 vectors, but there's nothing in the function to tell MATLAB that. So, SP1(1,2,3,4) will work, to some extent - it will take those inputs and try to run them through the function, and if they don't cause an error it will give you an output. The output might be wrong, but the computer doesn't know that.
Once you have a function you can call it multiple ways from the command line or from within other functions or scripts. As previously mentioned you don't have to stick to the naming of variables within the function, as long as input variables exist when the function is called MATLAB will accept them:
theta = SP1(p8,q27,w35,not_r);
myoutput = SP1(any,variable,I,like);
I don't necessarily have to give an output (but then the first output will be routed to ans)
SP1(this,will,also,work);
If I have some variables stored in a *.mat file (the case you seem to be asking about), I can do it like this:
load('mydata.mat'); %this file contains stored variables p, q1, w1 and r
theta = SP1(p,q1,w1,r);

Implementing iterative solution of integral equation in Matlab

We have an equation similar to the Fredholm integral equation of second kind.
To solve this equation we have been given an iterative solution that is guaranteed to converge for our specific equation. Now our only problem consists in implementing this iterative prodedure in MATLAB.
For now, the problematic part of our code looks like this:
function delta = delta(x,a,P,H,E,c,c0,w)
delt = #(x)delta_a(x,a,P,H,E,c0,w);
for i=1:500
delt = #(x)delt(x) - 1/E.*integral(#(xi)((c(1)-c(2)*delt(xi))*ms(xi,x,a,P,H,w)),0,a-0.001);
end
delta=delt;
end
delta_a is a function of x, and represent the initial value of the iteration. ms is a function of x and xi.
As you might see we want delt to depend on both x (before the integral) and xi (inside of the integral) in the iteration. Unfortunately this way of writing the code (with the function handle) does not give us a numerical value, as we wish. We can't either write delt as two different functions, one of x and one of xi, since xi is not defined (until integral defines it). So, how can we make sure that delt depends on xi inside of the integral, and still get a numerical value out of the iteration?
Do any of you have any suggestions to how we might solve this?
Using numerical integration
Explanation of the input parameters: x is a vector of numerical values, all the rest are constants. A problem with my code is that the input parameter x is not being used (I guess this means that x is being treated as a symbol).
It looks like you can do a nesting of anonymous functions in MATLAB:
f =
#(x)2*x
>> ff = #(x) f(f(x))
ff =
#(x)f(f(x))
>> ff(2)
ans =
8
>> f = ff;
>> f(2)
ans =
8
Also it is possible to rebind the pointers to the functions.
Thus, you can set up your iteration like
delta_old = #(x) delta_a(x)
for i=1:500
delta_new = #(x) delta_old(x) - integral(#(xi),delta_old(xi))
delta_old = delta_new
end
plus the inclusion of your parameters...
You may want to consider to solve a discretized version of your problem.
Let K be the matrix which discretizes your Fredholm kernel k(t,s), e.g.
K(i,j) = int_a^b K(x_i, s) l_j(s) ds
where l_j(s) is, for instance, the j-th lagrange interpolant associated to the interpolation nodes (x_i) = x_1,x_2,...,x_n.
Then, solving your Picard iterations is as simple as doing
phi_n+1 = f + K*phi_n
i.e.
for i = 1:N
phi = f + K*phi
end
where phi_n and f are the nodal values of phi and f on the (x_i).

How solve a system of ordinary differntial equation with time-dependent parameters

How solve a system of ordinary differential equation ..an initial value problem ....with parameters dependent on time or independent variable?
say the equation I have
Dy(1)/dt=a(t)*y(1)+b(t)*y(2);
Dy(2)/dt=-a(t)*y(3)+b(t)*y(1);
Dy(3)/dt=a(t)*y(2);
where a(t) is a vector and b(t) =c*a(t); where the value of a and b are changing with time not in monotone way and each time step.
I tried to solve this using this post....but when I applied the same principle ...I got the error message
"Error using griddedInterpolant The point coordinates are not
sequenced in strict monotonic order."
Can someone please help me out?
Please read until the end to see whether the first part or second part of the answer is relevant to you:
Part 1:
First create an .m file with a function that describe your calculation and functions that will give a and b. For example: create a file called fun_name.m that will contain the following code:
function Dy = fun_name(t,y)
Dy=[ a(t)*y(1)+b(t)*y(2); ...
-a(t)*y(3)+b(t)*y(1); ...
a(t)*y(2)] ;
end
function fa=a(t);
fa=cos(t); % or place whatever you want to place for a(t)..
end
function fb=b(t);
fb=sin(t); % or place whatever you want to place for b(t)..
end
Then use a second file with the following code:
t_values=linspace(0,10,101); % the time vector you want to use, or use tspan type vector, [0 10]
initial_cond=[1 ; 0 ; 0];
[tv,Yv]=ode45('fun_name',t_values,initial_cond);
plot(tv,Yv(:,1),'+',tv,Yv(:,2),'x',tv,Yv(:,3),'o');
legend('y1','y2','y3');
Of course for the fun_name.m case I wrote you need not use sub functions for a(t) and b(t), you can just use the explicit functional form in Dy if that is possible (like cos(t) etc).
Part 2: If a(t) , b(t) are just vectors of numbers you happen to have that cannot be expressed as a function of t (as in part 1), then you'll need to have also a time vector for which each of them happens, this can be of course the same time you'll use for the ODE, but it need not be, as long as an interpolation will work. I'll treat the general case, when they have different time spans or resolutions. Then you can do something of the following, create the fun_name.m file:
function Dy = fun_name(t, y, at, a, bt, b)
a = interp1(at, a, t); % Interpolate the data set (at, a) at times t
b = interp1(at, b, t); % Interpolate the data set (bt, b) at times t
Dy=[ a*y(1)+b*y(2); ...
-a*y(3)+b*y(1); ...
a*y(2)] ;
In order to use it, see the following script:
%generate bogus `a` ad `b` function vectors with different time vectors `at` and `bt`
at= linspace(-1, 11, 74); % Generate t for a in a generic case where their time span and sampling can be different
bt= linspace(-3, 33, 122); % Generate t for b
a=rand(numel(at,1));
b=rand(numel(bt,1));
% or use those you have, but you also need to pass their time info...
t_values=linspace(0,10,101); % the time vector you want to use
initial_cond=[1 ; 0 ; 0];
[tv,Yv]= ode45(#(t,y) fun_name(t, y, at, a, bt, b), t_values, initial_cond); %
plot(tv,Yv(:,1),'+',tv,Yv(:,2),'x',tv,Yv(:,3),'o');
legend('y1','y2','y3');

need explanation about a matlab code snippet about moran process

I am new to Matlab. I was reading this code snippet, but in some parts (marked with asterisks) I don't understand what it means, so if anybody could help would be very much appreciated
function [A1nmb] = moran(initsize, popsize)
% MORAN generates a trajectory of a Moran type process
% which gives the number of genes of allelic type A1 in a population
% of haploid individuals that can exist in either type A1 or type A2.
% The population size is popsize and the initial number of type A1
% individuals os initsize.
% Inputs: initsize - initial number of A1 genes
% popsize - the total population size (preserved)
if (nargin==0)
initsize=10;
popsize=30;
end
A1nmb=zeros(1,popsize);
A1nmb(1)=initsize;
**lambda = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');
mu = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');**
x=initsize;
i=1;
while (x>1 & x<popsize+1)
if (lambda(x,popsize)/(lambda(x,popsize)+mu(x,popsize))>rand)
x=x+1;
A1nmb(i)=x;
else
x=x-1;
A1nmb(i)=x;
end;
i=i+1;
end;
nmbsteps=length(A1nmb);
***rate = lambda(A1nmb(1:nmbsteps-1),popsize) ...
+mu(A1nmb(1:nmbsteps-1),popsize);***
**jumptimes=cumsum(-log(rand(1,nmbsteps-1))./rate);**
jumptimes=[0 jumptimes];
stairs(jumptimes,A1nmb);
axis([0 jumptimes(nmbsteps) 0 popsize+1]);
The first line you marked
lambda = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');
creates something called an inline function. It is equivalent to defining a mathematical function. Example:
y = inline('x^2')
would allow you to do
>> y(2)
4
This immediately explains the second line you marked.
rate = lambda(A1nmb(1:nmbsteps-1),popsize) ...
+mu(A1nmb(1:nmbsteps-1),popsize);
will compute the value of the function lambda(x,N) at x = A1nmb(1:nmbsteps-1) and N = popsize.
I will say immediately here that you should take a look at anonymous functions, a different format used to accomplish the same as inline. Only, anonymous functions are generally better supported, and usually a lot faster than inline functions.
Then, for the final line,
jumptimes = cumsum(-log(rand(1,nmbsteps-1))./rate);
is a nested command. rand will create a matrix containing pseudorandom numbers, log is the natural logarithm ("ln"), and cumsum creates a new matrix, where all the elements in the new matrix are the cumulative sum of the elements in the input matrix.
You will find the commands doc and help very useful. Try typing
doc cumsum
or
help inline
on the Matlab command prompt. Try that again with the commands forming the previous statement.
As a general word of advice: spend an insane lot of time reading through the documentation. Really, for each new command you encounter, read about it and play with it in a sandbox until you feel you understand it. Matlab only becomes powerful if you know all its commands, and there are a lot to get to know.
It defines an inline function object. For example this
lambda = inline('(x-1).*(1-(x-1)./N)', 'x', 'N')
defines lambda as a function with 2 variables. When you call lambda(A,n) Matlab simply expands the function you define in the first string. Thus lambda(A,n) using the variables you provide in the function call. lambda(A,n) would will evaluate to:
(A-1).*(1-(A-1)./n)
it just expands the function using the parameters you supply. Take a look at this link for more specific details http://www.mathworks.co.uk/help/techdoc/ref/inline.html
The cumsum function just returns the cumulative sum of a matrix along a particular dimension. Say we call cumsum on a vector X, then the value at element i in the result is equal to the sum of elements in X from index 1 to i. For example X = [1 2 1 3] we would get
AA = cumsum(X);
we would have
AA = [1 3 5 8]
See this link for more details and examples http://www.mathworks.co.uk/help/techdoc/ref/cumsum.html

nlfilter taking same values twice

I used nlfilter for a test function of mine as follows:
function funct
clear all;
clc;
I = rand(11,11);
ld = input('Enter the lag = ') % prompt for lag distance
A = nlfilter(I, [7 7], #dirvar);
% Subfunction
function [h] = dirvar(I)
c = (size(I)+1)/2
EW = I(c(1),c(2):end)
h = length(EW) - ld
end
end
The function works fine but it is expected that nlfilter progresses element by element, but in first two iterations the values of EW will be same 0.2089 0.4162 0.9398 0.1058. But then onwards for all iterations the next element is selected, for 3rd it is 0.4162 0.9398 0.1058 0.1920, for 4th it is 0.9398 0.1058 0.1920 0.5201 and so on. Why is it so?
This is nothing to worry about. It happens because nlfilter needs to evaluate your function to know what kind of output to create. So it uses feval once before starting to move across the image. The output from this feval call is what you see the first time.
From the nlfilter code:
% Find out what output type to make.
rows = 0:(nhood(1)-1);
cols = 0:(nhood(2)-1);
b = mkconstarray(class(feval(fun,aa(1+rows,1+cols),params{:})), 0, size(a));
% Apply fun to each neighborhood of a
f = waitbar(0,'Applying neighborhood operation...');
for i=1:ma,
for j=1:na,
x = aa(i+rows,j+cols);
b(i,j) = feval(fun,x,params{:});
end
waitbar(i/ma)
end
The 4th line call to eval is what you observe as the first output from EW, but it is not used to anything other than making the b matrix the right class. All the proper iterations happen in the for loop below. This means that the "duplicate" values you observe does not affect your final output matrix, and you need not worry.
I hope you know what the length function does? It does not give you the Euclidean length of a vector, but rather the largest dimension of a vector (so in your case, that should be 4). If you want the Euclidean length (or 2-norm), use the function norm instead. If your code does the right thing, you might want to use something like:
sz = size(I,2);
h = sz - (sz+1)/2 - ld;
In your example, this means that depending on the lag you provide, the output should be constant. Also note that you might want to put semicolons after each line in your subfunction and that using clear all as the first line of a function is useless since a function will always be executed in its own workspace (that will however clear persistent or global variables, but you don't use them in your code).