Matlab Error Expression or statement is incorrect--possibly unbalanced - matlab

Hello i get this error when i run the program I think it is from e (exponent)
the question is
Show that the function f(x) = e^x −(x^2/2) -x -1
has zero of multiplicity 3 at α = 0
and then, find the approximate solution of the zero of the function with the help
of the Newton’s method, first and second modified Newton’s methods, by taking
initial approximation x0 = 1.5 within an accuracy of 10^−4
.
function sol=newton(fn,dfn,x0,tol)
old=x0+1;
while abs(x0-old)>tol
old=x0;
x0=old-feval(fn,old)/feval(dfn,old)
end
sol=x0;
I typed this
fn = #(x) e^x -(x^2/2) -x -1
and the other inputs
i got the error on the title

Yes, it's the e. Replace the e with exp for the exponential operator.
fn = #(x) exp(x) -(x^2/2) -x -1;
FWIW, the derivative of the above function dfn is:
dfn = #(x) exp(x) - x - 1;

Related

Octave integration does not evaluate definite integral with symbolic variables

I am trying to evaluate a convolution integral using the symbolic int() function and instead of returning a useful answer, my program is returning the integral itself. Here is my code
clc; clear;
pkg load symbolic
syms t tau Wn % Declare symbolic variables
f = tau^2 * sin( Wn *(t-tau) );
convolution = int( f, tau, [0 t] ); % Specify tau as the integration variable
% and integration limits are from 0 to t
pretty(convolution)
The code runs, but does not return something useful. Instead of returning an answer, it returns this:
t
⌠
⎮ 2
⎮ τ ⋅sin(Wn⋅t - Wn⋅τ) dτ
⌡
0
i.e. the original integral with the function inside of it.
I've tried troubleshooting the problem in the following ways:
Copy/pasting example code from the Octave int() help page, this works and evaluates the definite integral
Changing the integration syntax from 0, t to [0, t] this changes nothing
Making variable f and storing the function there, instead of the function being inside of int(). This changes nothing
I know the symbolic package is working, because the example code returns the correct definite integral.
Thanks.
You can use eval in order to "evaluate" (duh) the integral. E.g. with your code above, I get:
octave:9> eval( convolution )
ans = (sym)
⎧ 2
⎪t 2⋅cos(Wn⋅t) 2
⎪── + ─────────── - ─── for Wn > -∞ ∧ Wn < ∞ ∧ Wn ≠ 0
⎨Wn 3 3
⎪ Wn Wn
⎪
⎩ 0 otherwise
Note that if you actually 'define' some of those symbols on the workspace, then these get taken into account:
octave:10> Wn = 1; % or preferably `sym('1')` ...
octave:11> eval( convolution )
ans = (sym)
2
t + 2⋅cos(t) - 2

Taylor series for (exp(x) - exp(-x))/(2*x)

I've been asked to write a function that calculates the Taylor series for (exp(x) - exp(-x))/(2*x) until the absolute error is smaller than the eps of the machine.
function k = tayser(xo)
f = #(x) (exp(x) - exp(-x))/(2*x);
abserror = 1;
sum = 1;
n=2;
while abserror > eps
sum = sum + (xo^n)/(factorial(n+1));
n=n+2;
abserror = abs(sum-f(xo));
disp(abserror);
end
k=sum;
My issue is that the abserror never goes below the eps of the machine which results to an infinite loop.
The problem is expression you're using. For small numbers exp(x) and exp(-x) are approximately equal, so exp(x)-exp(-x) is close to zero and definitely below 1. Since you start with 1 and only add positive numbers, you'll never reach the function value.
Rewriting the expression as
f = #(x) sinh(x)/x;
will work, because it's more stable for these small values.
You can also see this by plotting both functions:
x = -1e-14:1e-18:1e-14;
plot(x,(exp(x) - exp(-x))./(2*x),x,sinh(x)./x)
legend('(exp(x) - exp(-x))/(2*x)','sinh(x)/x')
gives

Derivative of Anonymous Function

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

Fitting model to data in matlab

i have some experimental data and a theoretical model which i would like to try and fit. i have made a function file with the model - the code is shown below
function [ Q,P ] = RodFit(k,C )
% Function file for the theoretical scattering from a Rod
% R = radius, L = length
R = 10; % radius in Å
L = 1000; % length in Å
Q = 0.001:0.0001:0.5;
fun = #(x) ( (2.*besselj(1,Q.*R.*sin(x)))./...
(Q.*R.*sin(x)).*...
(sin(Q.*L.*cos(x)./2))./...
(Q.*L.*cos(x)./2)...
).^2.*sin(x);
P = (integral(fun,0,pi/2,'ArrayValued',true))*k+C;
end
with Q being the x-values and P being the y-values. I can call the function fine from the matlab command line and it works fine e.g. [Q,P] = RodFit(1,0.001) gives me a result i can plot using plot(Q,P)
But i cannot figure how to best find the fit to some experimental data. Ideally, i would like to use the optimization toolbox and lsqcurvefit since i would then also be able to optimize the R and L parameters. but i do not know how to pass (x,y) data to lsqcurvefit. i have attempted it with the code below but it does not work
File = 30; % the specific observation you want to fit the model to
ydata = DataFiles{1,File}.data(:,2)';
% RAdius = linspace(10,1000,length(ydata));
% LEngth = linspace(100,10000,length(ydata));
Multiplier = linspace(1e-3,1e3,length(ydata));
Constant = linspace(0,1,length(ydata));
xdata = [Multiplier; Constant]; % RAdius; LEngth;
L = lsqcurvefit(#RodFit,[1;0],xdata,ydata);
it gives me the error message:
Error using *
Inner matrix dimensions must agree.
Error in RodFit (line 15)
P = (integral(fun,0,pi/2,'ArrayValued',true))*k+C;
Error in lsqcurvefit (line 199)
initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation. LSQCURVEFIT cannot continue.
i have tried i) making all vectors/matrices the same length and ii) tried using .* instead. nothing works and i am giving the same error message
Any kind of help would be greatly appreciated, whether it is suggestion regading what method is should use, suggestions to my code or something third.
EDIT TO ANSWER Osmoses:
A really good point but i do not think that is the problem. just checked the size of the all the vectors/matrices and they should be alright
>> size(Q)
ans =
1 1780
>> size(P)
ans =
1 1780
>> size(xdata)
ans =
2 1780
>> size([1;0.001]) - the initial guess/start point for xdata (x0)
ans =
2 1
>> size(ydata)
ans =
1 1780
UPDATE
I think i have identified the problem. the function RodFit works fine when i specify the input directly e.g. [Q,P] = RodFit(1,0.001);.
however, if i define x0 as x0 = [1,0.001] i cannot pass x0 to the function
>> x0 = [1;0.001]
x0 =
1.0000
0.0010
>> RodFit(x0);
Error using *
Inner matrix dimensions must agree.
Error in RodFit (line 15)
P = (integral(fun,0,pi/2,'ArrayValued',true))*k+C;
The same happens if i use x0 = [1,0.001]
clearly, matlab is interpreting x0 as input for k only and attempts to multiplay a vector of length(ydata) and a vector of length(x0) which obviously fails.
So my problem is that i need to code so that lsqcurvefit understands that the first column of xdata and x0 is the k variable and the second column of xdata and x0 is the C variable. According to the documentation - Passing Matrix Arguments - i should be able to pass x0 as a matrix to the solver. The solver should then also pass the xdata in the same format as x0.
Have you tried (that's sometimes the mistake) looking at the orientation of your input data (e.g. if xdata & ydata are both row/column vectors?). Other than that your code looks like it should work.
I have been able to solve some of the problems. One mistake in my code was that the objective function did not use of vector a variables but instead took in two variables - k and C. changing the code to accept a vector solved this problem
function [ Q,P ] = RodFit(X)
% Function file for the theoretical scattering from a Rod
% R = radius, L = length
% Q = 0.001:0.0001:0.5;
Q = linspace(0.11198,4.46904,1780);
fun = #(x) ( (2.*besselj(1,Q.*R.*sin(x)))./...
(Q.*R.*sin(x)).*...
(sin(Q.*L.*cos(x)./2))./...
(Q.*L.*cos(x)./2)...
).^2.*sin(x);
P = (integral(fun,0,pi/2,'ArrayValued',true))*X(1)+X(2);
with the code above, i can define x0 as x0 = [1 0.001];, and pass that into RodFit and get a result. i can also pass xdata into the function and get a result e.g. [Q,P] = RodFit(xdata(2,:));
Notice i have changed the orientation of all vectors so that they are now row-vectors and xdata has size size(xdata) = 1780 2
so i thought i had solved the problem completely but i still run into problems when i run lsqcurvefit. i get the error message
Error using RodFit
Too many input arguments.
Error in lsqcurvefit (line 199)
initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation. LSQCURVEFIT cannot continue.
i have no idea why - does anyone have any idea about why Rodfit recieves to many input arguments when i call lsqcurvefit but not when i run the function manual using xdata?

use fsolve to return some other variable beside the x vector

I have used the fsolve function to find the vector x ( the answer ) but I need my function to return some other value like A but the below code does not work.
This is my function:
function [F,A] = myfun(x,c)
F = [ 2*x(1) - x(2) - exp(c*x(1))
-x(1) + 2*x(2) - exp(c*x(2))];
.
.
.
A = 1;
this is the caller:
[x,a] = fsolve(#(x) myfun(x,c),[-5;-5])
but in the above a holds the F(x) values (which must be nearly zero) instead of A.
your last line
[x,a] = fsolve(#(x) myfun(x,c),[-5;-5])
requests a to be the second output of fsolve (fval). Internally, fsolve only uses the first output of your function; any other outputs are ignored.
The easiest way to get the second output of your function at the solution point, is to just evaluate the function once more after fsolve:
x = fsolve(#(x) myfun(x,c),[-5;-5]);
[~,a] = myfun(x,c);