How do i get aproximation of a function? - matlab

I have the following function :
f (t) = 0.05sin(1000t)+0.5cos(pit)-0.4*(10*t)
t are points distributed equidistantly between [0,1] for which i calculate values of f .
The following pairs (ti,f(ti)) are inputs for aproximation of function f with Lagrange and Least Squares.
This is what i tried, but doesn't seem to work, because i'm not sure if i'm doing f right
%Main function
t=linspace(0,1);
f = 0.05*sin(1000*t)+0.5*cos(pi*t)-0.4*sin(10*t);
lagrange(t,f); % returns coeficients of Lagrange polynomial of rank 1
least_squares(t,f) % returns coeficients of polynomial of rank n using least squares method
This is the lagrange function:
%Lagrange
function[L] = lagrange(x,y)
n = length(x);
lj= zeros(1,n)
Lj= zeros(n);
L=zeros(1,n);
jr=1:n;
for j=jr
mr=jr(jr~=j);%m-range 1<=m<=n, m~=j
lj=poly(x(mr));
mult=1/polyval(lj,x(j));
Lj(j,:)=mult*lj;
end
L=y*Lj;
X=-10:.1:10;
plot(x,y,'-*','linewidth',1,'markersize',5)
end
And the least_squares function:
function [yR] =least_squares(x,y)
stem(x,y);
a=[];
for i=1:length(x)
a=[a;x(i) 1];
end
c=a/y';
yR=c(1)*x+c(2);
plot(x,yR,"-*");
end

Related

Сonvert the coefficients of the Hermite polynomial into a function

I want to make a function from the output of Matlab Hermite function (for example, if we had an output from Hermite function [8 0 -12 0] it would be 8x^3 - 12x polynomial) and then integrate this function using the Simpson's 3/8 Rule.
I have already created a function in Matlab that integrate any function using this rule and also I have created function that returns coefficients of Hermite's polynomial (with the recursion relation) in the vector form.
My questions:
If it's possible, in Hermite function I want from this output [8 0 -12 0] make this output 8x^3 - 12x. This output I will able to integrate. How can I do this?
Can I combine these two functions and integrate Hermite's polynomial without convention the output of the first function?
Code of Hermite polynomial function, where n is the order of the polynomial:
function h = hermite_rec(n)
if( 0==n ), h = 1;
elseif( 1==n ), h = [2 0];
else
h1 = zeros(1,n+1);
h1(1:n) = 2*hermite_rec(n-1);
h2 = zeros(1,n+1);
h2(3:end) = 2*(n-1)*hermite_rec(n-2);
h = h1 - h2;
end
Code of Simpson function, that integrate function using the Simpson 3/8 Rule. a is a lower limit of integral, b is a upper limit of integral:
n = 3;
h = (b-a)/(3*n); %3h = (b-a)/n
IS2=0;
for i=1:n
IS2 = IS2+(f(a+(3*i-3)*h) + 3*f(a+(3*i-2)*h) + 3*f(a+(3*i-1)*h) + f(a+(3*i)*h))*3*h/8;
end
end
Thank you for any advice!
To create a polynomial function given its coefficients, you can use polyval (see also anonynmous functions):
p = [1 2]; % example. This represents the polynomial x+2
f = #(x) polyval(p, x); % anonymous function of x, assigned to function handle f
Now f is a function that you can integrate numerically.
If you want to include this directly as part of your Hermite function, just add something like this at the end:
h = #(x) polyval(p, x);
Then the Hermite function will return a function (handle) representing the Hermite polynomial.

Lagrange interpolation perturbation in matlab

This is my code for finding the centered coefficients for lagrange polynomial interpolation:
% INPUT
% f f scalar - valued function
% interval interpolation interval [a, b]
% n interpolation order
%
% OUTPUT
% coeff centered coefficients of Lagrange interpolant
function coeff = lagrangeInterp (f, interval , n)
a = interval(1);
b = interval(2);
x = linspace(a,b,n+1);
y = f(x);
coeff(1,:) = polyfit(x,y,n);
end
Which is called in the following script
%Plot lagrangeInterp and sin(x) together
hold on
x = 0:0.1*pi:2*pi;
for n = 1:1:4
coeff = lagrangeInterp(#(x)sin(x),[0,2*pi],n);
plot(x,polyval(coeff,x,'-'));
end
y = sin(x);
plot(x,y);
legend('1st order','2nd order','3rd order','4th order','sin(x)');
To check for stability I would like to perturb the function (eg g(x) = f(x) + epsilon). How would I go about this?
Well, a little trick for you.
You know randn([m,n]) in matlab generate a m*n random matrix. The point is to generate a random vector, and interp1 to a function of x. Like this:
x = linspace(a,b,n+1); % Your range of input
g = #(ep,xx)f(xx)+interp1(x,ep*randn([length(x),1]),xx);

Why is my third MATLAB function outputing only zeros when using ode45?

I need to model negative, positive and simple regulation of a gene for my systems biology class using MATLAB. The problem is that the functions for negative and simple regulation work but the positive regulation function is only outputting zeros.
My script is as follows:
% Simulation of simple regulation, negative autoregulation and positive
% autoregulation
% Define constants
global a b K n
a = 1;
b = 1;
K = 0.5;
n = 2; % Hill coefficient
% Simulation time
tspan = [0,10];
% Initial condition
X0 = 0;
% Run simulations
[t1,X1] = ode45(#autoregulation_f0,tspan,X0); % Simple regulation
[t2,X2] = ode45(#autoregulation_f1,tspan,X0); % Negative autoregulation
[t3,X3] = ode23(#autoregulation_f2,tspan,X0); % Positive autoregulation
% Plot results
figure;
plot(t1,X1,t2,X2,t3,X3);
legend('simple','negative','Location','southeast');
And my functions are:
function dxdt = autoregulation_f0(t,X)
global a b
dxdt = b - a*X;
end
function dxdt = autoregulation_f1(t,X)
global a b K n
dxdt = b/(1+(X^n)/(K^n)) - a*X;
end
function dxdt = autoregulation_f2(t,X)
global a b K n
dxdt = b*X.^n./(K.^n+X.^n) + a*X;
end
The third function "autoregulation_f2(t,X)" is the one that outputs zeros and therefore when plotting the graph I just get a straight line.
Does anyone know what could be causing this?
Thanks in advance!
It looks to be the correct result for the given function. Your provided dxdt has an X in every term. The initial X0=0 will result in dxdt=0, giving you no change in X. As a result you just end up with a flat line.

Problems with Cubic Hermite polynomial in Matlab

I am having trouble with this code for a piecewise cubic Hermite polynomial. In my assignment we are not allowed to use pchip. We are supposed to write a function which takes as it's input arguments an integer n and a 3 by n matrix which contains the x values, the values of a function evaluated at each x, and the values of the derivative evaluated at each x; in the first, second and third rows of the matrix respectively.
With this information we are supposed to calculate the coefficients for each Hermite polynomial on each subinterval of the interval given by the first row of the input matrix, then piece it altogether using mkpp.
Unfortunately, my code produces a very poor interpolating polynomial and I am having trouble figuring out why. For example for the function x^2 we have for instance n = 4 and M = [0,1,2,3; 0,1,4,9; 0,1,4,6] and when plugged into my function produces the following graph
I would really appreciate help with this, it's driving me nuts.
Here is my code:
function [ HP ] = HermiteInter( n,M )
%HermiteInter
% This function constructs a peicewise cubic Hermite polynomial.
% The input areguments are an integer n and M a 3 by n matrix, whose
% first row contains the values of x which a given function will be
% evaluated at. The second row contains the values of a function
% evaluated at those
% points and the third row contains the value of the derivative of
% the function evaluated at those points.
% Divided differences using these values are found by calling the
% function HermiteDD. These divided differences are then passed into the
% function mkpp to create the peicewise polynomial.
X = M(1,:);
Y = M(2,:);
Z = M(3,:);
Q = zeros(n-1,4);
for i = 1 : n-1
Q(i,:) = HermiteDD([X(i),X(i),X(i+1),X(i+1)],[Y(i),Y(i+1)],[Z(i),Z(i+1)]);
end
HP = mkpp(X,Q);
end
function [ HDD ] = HermiteDD(X,Y,Z)
%HermiteDD
% This function creates a table of divided differences for
% Hermite polynomials. The input arguments are X, the values at
% which a function was evaluated at, Y the values of the function at
% these points and Z the values of the derivative of the function at
% these points.
DD = zeros(4, 4);
DD(1, 1) = Y(1);
DD(2, 1) = Y(1);
DD(3, 1) = Y(2);
DD(4, 1) = Y(2);
DD(1, 2) = Z(1);
DD(2, 2) = (Y(1)-Y(2))/(X(1)-X(3));
DD(3, 2) = Z(2);
for j = 3 : 4
for i = 1 : (4 - j+1)
DD(i,j) = (DD(i + 1, j - 1) - DD(i, j - 1)) / (X(i + j-1) - X(i));
end
end
HDD = DD(1,:);
end

How to plot a function using a code that I wrote with a starting point?

I wrote the code for the secant algorithm , and now I have the function :
f(x) = 2x^3 - 4x^2 + 3x , with two initial points : x0 = -1 , x1 = 2 .
My question is how can I plot the function that I wrote ,i.e. secant , with the function above , f , and the results below , in one graph ?
Is it even possible to do that ?
The results that I got after I used the secant algorithm , are :
v =
-4.0000
2.2069
2.3699
2.6617
2.5683
2.5804
Those are 6 iterations that I used on my secant algorithm , for the given x0 & x1 above .
I'd appreciate if you can explain .
EDIT :
This is the code that I used in order to get the results :
[z,n,v]=secant([-1,2],10^(-5),10^(-5),10)
for the prototype :
function [x,n,v]=secant(X,d,e,N)
% x0 is the first point
% x1 is the end point
% d is the tolerance
% e is the requested precision
% N is the number of iterations
Thanks .
I quickly threw this together, it illustrates the powerful anonymous function
and it shows you how to plot the results of the secant function (the same way as on wikipedia: http://en.wikipedia.org/wiki/File:Secant_method.svg)
What I don't understand however is why your secant function has both a tolerance and a requested precision as an input; I would think the tolerance is the result of the secant algorithm..
function [ ] = tmp1( )
f=#(x) x.^2;
[xend,n,v]=secant(f,-4,3,1e-4,50);
fprintf('after %d iterations reached final x_end = %g, f(x_end) = %g\n',n,xend,f(xend))
figure;hold on;
xtmp = linspace(min(v),max(v),250);
plot(xtmp,f(xtmp),'r'); % plot the function itself
line([v(1:end-2) v(3:end)]',[f(v(1:end-2)) zeros(n+1,1)]','Color','b','Marker','.','MarkerEdgeColor','b'); % plot the secant lines
plot(v,f(v),'.','MarkerEdgeColor','r')% plot the intermediate points of the secant algorithm
line([v(3:end) v(3:end)]',[zeros(n+1,1) f(v(3:end))]','Color','k','LineStyle','--'); % vertical lines
ylim([-4 max(f(xtmp))]); % set y axis limits for nice plotting view algorithm
end
function [xnew,n,v]=secant(f, x0,x1,e,N)
% x0 is the first point
% x_end is the end point
% e is the requested precision
% N is the number of iterations
v=zeros(N+2,1);
v(1)=x0;
v(2)=x1;
for n=0:N-1
xnew = x1 - f(x1) * (x1-x0)/(f(x1)-f(x0));
v(3+n) = xnew;
if abs(f(xnew)) <e
break;
else
x0=x1;
x1=xnew;
end
end
v(n+4:end)=[];
end
You can plot the function, and the results as scatter points.
First, define the function in a vectorical way:
f(x) = #(x) ( 2*x.^3 - 4*x.^2 + 3*x );
Then draw the function over some range:
x = -10:10;
y = f(x);
figure(); plot(x,y);
Now, show the resuls:
hold on;
scatter(v,f(v));