I need to implement Lagrange iterpolation in MATLAB.
I (think I've) understood how it works. I don't get how to implement the x.
lets say I want to calculate for these point: (0,1) (1,1) (2,4)
So I need to do these:
l_0(x) = (x-1)(x-2)/(0-1)(0-2)
l_1(x) = (x-0)(x-2)/(1-0)(1-2)
l_2(x) = (x-0)(x-1)/(2-0)(2-1)
and so on...
So I want to do a MATLAB function that will receive the (x,y) points, and retrieves the coefficients of the resulting Polynomial.
In this case: ( 3/2, 3/2, 1 )
I DON'T WANT A CODE FOR AN ANSWER - just how to implement the above x variant.
Thanks
I'm not sure if this is what you need, but I think that what you are looking for is MATLAB anonymous functions
In your case, you would write
l_0 = #(x) (x-1)(x-2)/(0-1)(0-2)
l_1 = #(x) (x-0)(x-2)/(1-0)(1-2)
l_2 = #(x) (x-0)(x-1)/(2-0)(2-1)
Then you can use your Lagrange polynomials like regular functions:
val = y0 * l_0(x0) + y1 * l_1(x1) + y2 * l_2(x2)
Is that what you were looking for?
Well if you don't want code, then x is simply any value within the range of the input values of your x points. In your case, any value between 0 and 2.
Related
I want to check the calculation of the laplace filter from scipy.ndimage and compare it to my own method if differentiation. Below I have a piece of code that I ran
import scipy.ndimage.filters
n = 100
x_range = y_range = np.linspace(-1, 1, n)
X, Y = np.meshgrid(x_range, y_range)
f_fun = X ** 2 + Y ** 2
f_fun_laplace = 4 * np.ones(f_fun.shape)
res_laplace = scipy.ndimage.filters.laplace(f_fun, mode='constant')
I expect that the variable res_laplace will have the constant value of 4 over the whole domain (excluding the boundaries for simplicity), since this is what I would get by applying the laplace operator to my function f(x,y) = x^2 + y^2.
However, the value that res_laplace produces is 0.00163 in this case. So my question was.. why is this not equal to 4?
The answer, in this specific case, is that you need to multiply the output of scipy.ndimage.filters.laplace with a factor of (1/delta_x) ** 2. Where delta_x = np.diff(x_range)[0]
I simply assumed that the filter would take care of that, but in hindsight it is of course not able know the value delta_x.
And since we are differentiating twice, we need to square the inverse of this delta_x.
I have data like this:
y = [0.001
0.0042222222
0.0074444444
0.0106666667
0.0138888889
0.0171111111
0.0203333333
0.0235555556
0.0267777778
0.03]
and
x = [3.52E-06
9.72E-05
0.0002822918
0.0004929136
0.0006759156
0.0008199029
0.0009092797
0.0009458332
0.0009749509
0.0009892005]
and I want y to be a function of x with y = a(0.01 − b*n^−cx).
What is the best and easiest computational approach to find the best combination of the coefficients a, b and c that fit to the data?
Can I use Octave?
Your function
y = a(0.01 − b*n−cx)
is in quite a specific form with 4 unknowns. In order to estimate your parameters from your list of observations I would recommend that you simplify it
y = β1 + β2β3x
This becomes our objective function and we can use ordinary least squares to solve for a good set of betas.
In default Matlab you could use fminsearch to find these β parameters (lets call it our parameter vector, β), and then you can use simple algebra to get back to your a, b, c and n (assuming you know either b or n upfront). In Octave I'm sure you can find an equivalent function, I would start by looking in here: http://octave.sourceforge.net/optim/index.html.
We're going to call fminsearch, but we need to somehow pass in your observations (i.e. x and y) and we will do that using anonymous functions, so like example 2 from the docs:
beta = fminsearch(#(x,y) objfun(x,y,beta), beta0) %// beta0 are your initial guesses for beta, e.g. [0,0,0] or [1,1,1]. You need to pick these to be somewhat close to the correct values.
And we define our objective function like this:
function sse = objfun(x, y, beta)
f = beta(1) + beta(2).^(beta(3).*x);
err = sum((y-f).^2); %// this is the sum of square errors, often called SSE and it is what we are trying to minimise!
end
So putting it all together:
y= [0.001; 0.0042222222; 0.0074444444; 0.0106666667; 0.0138888889; 0.0171111111; 0.0203333333; 0.0235555556; 0.0267777778; 0.03];
x= [3.52E-06; 9.72E-05; 0.0002822918; 0.0004929136; 0.0006759156; 0.0008199029; 0.0009092797; 0.0009458332; 0.0009749509; 0.0009892005];
beta0 = [0,0,0];
beta = fminsearch(#(x,y) objfun(x,y,beta), beta0)
Now it's your job to solve for a, b and c in terms of beta(1), beta(2) and beta(3) which you can do on paper.
So I'm just trying to plot 4 different subplots with variations of the increments. So first would be dx=5, then dx=1, dx=0.1 and dx=0.01 from 0<=x<=20.
I tried to this:
%for dx = 5
x = 0:5:20;
fx = 2*pi*x *sin(x^2)
plot(x,fx)
however I get the error inner matrix elements must agree. Then I tried to do this,
x = 0:5:20
fx = (2*pi).*x.*sin(x.^2)
plot(x,fx)
I get a figure, but I'm not entirely sure if this would be the same as what I am trying to do initially. Is this correct?
The initial error arose since two vectors with the same shape cannot be squared (x^2) nor multiplied (x * sin(x^2)). The addition of the . before the * and ^ operators is correct here since that will perform the operation on the individual elements of the vectors. So yes, this is correct.
Also, bit of a more advanced feature, you can use an anonymous function to aid in the expressions:
fx = #(x) 2*pi.*x.*sin(x.^2); % function of x
x = 0:5:20;
plot(x,fx(x));
hold('on');
x = 0:1:20;
plot(x,fx(x));
hold('off');
I have the following anonymous function:
f = #(x)x^2+2*x+1
I'm using this so that I use it in the following way:
f(0) = 1
But what if I want to find the derivative of such a function while still keeping it's anonymous function capability? I've tried doing the following but it doesn't work:
f1 = #(x)diff(f(x))
but this just returns
[]
Any thoughts on how to accomplish this?
Of course I could manually do this in 3 seconds but that's not the point...
If you have symbolic math toolbox, you can use symbolic functions to achieve the desired as follows:
syms x
myFun=x^2+2*x+1;
f=symfun(myFun,x);
f1=symfun(diff(f),x);
%Check the values
f(2)
f1(2)
You should get 9 and 6 as answers.
When you do diff of a vector of n elements it just outputs another vector of n-1 elements with the consecutive differences.. so when you put a 1 element vector you get an empty one.
A way to go would be to decide an epsilon and use the Newton's difference quotient:
epsilon = 1e-10;
f = #(x) x^2+2*x+1;
f1 = #(x) (f(x+epsilon) - f(x)) / epsilon;
or just do the math and write down the formula:
f1 = #(x) 2*x+2;
http://en.wikipedia.org/wiki/Numerical_differentiation
#jollypianoman this works to me. Actually you need to say that the symfun has to be evaluate using eval command, then you get all the features of an anonymous function. the best is to read the example below...
clear
N0=1;N1=5;
N=#(t) N0+N1*sin(t);
syms t
Ndot=symfun(diff(N(t)),t);
Ndot_t=#(t) eval(Ndot);
Ndot_t(0)
ans = 5
Ndot_t(1)
ans = 2.7015
[tstop] = fsolve(Ndot_t,pi/3)
tstop =
1.5708
cheers,
AP
I'm fitting custom functions to my data.
After obtaining the fit I would like to get something like a function handle of my fit function including the parameters set to the ones found by the fit.
I know I can get the model with
formula(fit)
and I can get the parameters with
coeffvalues(fit)
but is there any easy way to combine the two in one step?
This little loop will do the trick:
x = (1:100).'; %'
y = 1*x.^5 + 2*x.^4 + 3*x.^3 + 4*x.^2 + 5*x + 6;
fitobject = fit(x,y,'poly5');
cvalues = coeffvalues(fitobject);
cnames = coeffnames(fitobject);
output = formula(fitobject);
for ii=1:1:numel(cvalues)
cname = cnames{ii};
cvalue = num2str(cvalues(ii));
output = strrep(output, cname , cvalue);
end
output = 1*x^5 + 2*x^4 + 3*x^3 + 4*x^2 + 5*x + 6
The loop needs to be adapted to the number of coefficients of your fit.
Edit: two slight changes in order to fully answer the question.
fhandle = #(x) eval(output)
returns a function handle. Secondly output as given by your procedure doesn't work, as the power operation reads .^ instead of x, which can obviously be replaced by
strrep(output, '^', '.^');
You can use the Matlab curve fitting function, polyfit.
p = polyfit(x,y,n)
So, p contains the coefficients of the polynomial, x and y are the coordinates of the function you're trying to fit. n is the order of the polynomial. For example, n=1 is linear, n=2 is quadratic, etc. For more info, see this documentation centre link. The only issue is that you may not want a polynomial fit, in which case you'll have to use different method.
Oh, and you can use the calculated coefficients p to to re-evaluate the polynomial with:
f = polyval(p,x);
Here, f is the value of the polynomial with coefficients p evaluated at points x.