Having trouble evaluating an anonymous function using feval on Matlab - matlab

I'm working on my own Matlab code for the bisection method, and have defined an anonymous function I am trying to find the root for. It produces a simple graph and I know it could easily find the root if it would run properly.
When my code gets up to evaluating the function at a given x value, it returns:
Error using feval
Function to evaluate must be represented as a string scalar, character vector, or
function_handle object.
Error in bisection (line 3)
fa = feval(f, a);
My full code is:
function m=bisection(f,a,b,imax,tol)
fa = feval(f, a);
fb = feval(f, b);
i=0;
if fa*fb>0
disp('No root here: pick a new interval')
return
end
while abs(b-a) >= tol
i = i + 1;
m=(a+b)/2;
fm = feval(f, m);
if fa*fb<0
b = m;
else
a = m;
end
abs(fm);
end
% Show the last approximation considering the tolerance
w = feval(f, m);
fprintf('\n x = %f produces f(x) = %f \n %i iterations\n', m, fm, i-1);
fprintf(' Approximation with tolerance = %f \n', tol);
end
With my function being:
function [T] = freezing(x)
alpha = 0.138*10^-6;
Ti = 20;
Ts = -15;
t = 60*60*24*60;
tol = 10^-13;
%x = linspace(0,3);
T = #(x) (Ti-Ts)*erf(x./(2*sqrt(alpha*t)))+Ts;
dT = #(x) (Ti-Ts)*(1/sqrt(pi*alpha*t))*exp(-x.^2./(4*alpha*t));
T = T(x);
end
I'm really not sure what the issue is here – in my command window, I can easily input x values and get output. Any suggestions are much appreciated!

feval needs f to be a function handle. When you call bisection, I suspect you're passing the result of freezing to bisection instead of the function handle to freezing
You need to do bisection(#freezing, ...) instead of bisection(freezing(...), ...)
The #freezing creates a function handle that is passed to bisection. Doing the latter passes the result of freezing to bisection.

Related

Issue with storing error at each iteration on Matlab - "unrecognized variable"

I've written a modified Newton's method code, and I'm looking to plot the error at each iteration vs the iteration, but after my code runs Matlab does not recognize my error function or the iterations.
function[x,k,e] = mynewton(x0,tol)
f = #(x) (x-1).^5*exp(x);
df = #(x) 5*(x-1).^4*exp(x)+(x-1).^5*exp(x);
kMax = 200;
format long
x=x0;
y=f(x);
e = [];
k = 0;
disp(' k x error')
while abs(y) > tol && k < kMax
k=k+1;
x = x - f(x)/df(x);
y = f(x);
e_k = abs(x-1);
e(k) = e_k;
disp([k x e_k])
end
end
The output will be 3 columns showing k, x, and e_k at each step, but it won't store these values properly into a vector. Instead, it shows
>> k
Unrecognized function or variable 'k'.
What am I doing wrong?
Any suggestions are very appreciated!!
You need to call your function as:
[x, k, e] = mynewton( x0, tol);
After this call, you can enter k at command window and see its value.

I want to feed in a function handle into a matlab function I made

I am trying to feed a function handle into the function I created below. I'm not exactly sure how to do this.
For example, how do I get:
conjugate_gradient(#(y) ABC(y), column_vector, initial_guess)
to not error?
If I use matlab's pcg function in the same way it will work:
pcg(#(y) ABC(y),b,tol).
I tried reading the pcg function, and they do take about this in the function description, however I'm still super inexperienced with MATLAB and had shall we say some difficulty understanding what they did.Thank You!
function [x] = conjugate_gradient(matrix, column_vector, initial_guess)
y = [];
col_size = length(column_vector);
temp = size(matrix);
mat_row_len = temp(2);
% algorithm:
r_cur = column_vector - matrix * initial_guess;
p = r_cur;
k = 0;
x_approx = initial_guess;
for i=1:mat_row_len
alpha = ( r_cur.' * r_cur ) / (p.' *(matrix* p));
x_approx = x_approx + alpha * p;
r_next = r_cur - alpha*(matrix * p);
fprintf(num2str(r_next'*r_next), num2str(i))
y = [y; i, r_next'*r_next];
%exit condition
if sqrt(r_next'*r_next) < 1e-2
y
break;
end
beta = (r_next.'* r_next )/(r_cur.' * (r_cur) );
p = r_next + beta * p;
k = k+1;
r_cur = r_next;
end
y
[x] = x_approx;
end
When you do
f = #(y) ABC(y)
You create a function handle. (Note that in this case it's the same as f=#ABC). This handle is a variable, and this can be passed to a function, but is otherwise the same as the function. Thus:
f(1)
is the same as calling
ABC(1)
You pass this handle to a function as the first argument, which you have called matrix. This seems misleading, as the variable matrix will now be a function handle, not a matrix. Inside your function you can do matrix(y) and evaluate the function for y.
However, reading your function, it seems that you treat the matrix input as an actual matrix. This is why you get errors. You cannot multiply it by a vector and expect a result!

MATLAB - Newton's Method to solve a system of nonlinear equations

I'm trying to write a function that uses Newton's Method to solve a system of nonlinear equations
Function:
[roots, count, resids, history] = Newtons(func,x0,tol)
with the following inputs and outputs.
I'm struggling with creating the function handle (the first input) and using it in the main function as well as understanding and generating the resids and history outputs. I would really appreciate some help with this function.
What I've done/tried so far: (I'm relatively new to Matlab and believe it is totally wrong and not worth looking at)
% function handle for the first input (func)
function [f, J] = jacobian(f, x)
n=length(x);
fx=f(x);
step=1e-10;
for i=1:n
xstep = x;
xstep(i)=x(i)+step;
J(:,i)=(f(xstep)-fx)/step;
end
end
function [roots, count, resids, history] = Newtons(func,x0,tol)
func = #jacobian;
if nargin == 2
tol = 10e-10;
end
MAXIT = 50;
xx = x0;
N = 0;
while N < 50
JJ = func(2);
end

Derivative of function in MATLAB

I have the following matlab code. 1st line after while gives error. i am trying to make Newtons method to find roots. for that i need derivative f`(p0).
plz guide me what i am doing wrong and how can i get derivative of function f;
I also tried D(f(p0)) but that didn't work, gives error: Undefined function or method 'D' for input arguments of type 'double'.
format long;
f=#(x) cos(x)-x;
p0 = 0.5;
TOLL = 1e-4;
N = 100;
i = 1;
while (i <= N)
p = p0-f(p0)/diff(f(p0)); %Error, returns empty results this produced error
if ( abs(p-p0) < TOLL)
fprintf('Root of given equation is %f\n', p);
return;
end
i=i+1;
p0 = p;
end
fprintf('Method failed after %d iteration\n', i);
The error is because p0 is a scalar, so f(p0) is a scalar. Then taking diff(f(p0)) wont work.
To find the derivative at p0, you could use this definition of the derivative:
f'(p0) = limit as h->0 of (f(x+h)-f(x))/h.
Pick h as some small number (say 1e-3), using (f(p0+h) and f(p0)), you should be able to get an approximation of the derivative of f at p0.

MATLAB - how to count the number of function calls

Currently I'm doing a code on the Secant Method, and so far the code runs ok.
However, I still have to update my "count.funcCount" by counting the number of function calls that I used in the "secant" function. How should I modify my code ?
This is what I have so far for the code:
function [ root, fcneval, count ] = secant(f, x0, x1, my_options)
my_options = optimset('MaxIter', 50, 'TolFun', 1.0e-5);
count = struct('iterations',0,'funcCount',0,'message',{'empty'});
xp = x0; %# Initialize xp and xc to match with
xc = x1; %# x0 and x1, respectively
MaxIter = 100;
TolFun = 1.0e-5;
%# Secant Method Loop
for i = 2:MaxIter
fd = f(xc) - f(xp); %# Together, the ratio of d and fd yields
d = xc - xp; %# the slope of the secant line going through xc and xp
xn = ((xc * fd) - (f(xc) * d)) / fd; %# Secant Method step
if (abs(xc - xn) < TolFun) && (abs(f(xn)) < TolFun) %# Stopping condition
break;
elseif i > MaxIter %# If still can't find a root after maximum
%# 100 iterations, consider not converge
count.message = sprintf('Do not converge');
end
xp = xc; % Update variables xc and xp
xc = xn;
end
%# Get outputs:
root = xn;
fcneval = f(root);
count.iterations = i;
end %# end function
---------------------------------------
function [f] = fun(x)
f = cos(x) + x;
end
Please help me, thank you in advance
Although I did not understand your question but still I think you can use a counter. Initialize it with zero and increment it every time your function is called. You are using an inbuilt function, just make necessary changes in its source code( FYI :you can do this in matlab) then save it with a new name and then use it in your main code.
You could create a nested function which have access to the variables of its parent function (including the function f and the counter count.funcCount). This function would call the actual method which does the computation, and then increment the counter.
Here is a rather silly example to illustrate the concept:
function [output,count] = myAlgorithm(f, x0)
count = 0;
output = x0;
while rand()<0.99 %# simulate a long loop
output = output + fcn(x0);
end
%# nested function with closure
function y = fcn(x)
%# access `f` and `count` inside the parent function
y = f(x); %# call the function
count = count + 1; %# increment counter
end
end
Now you call it as:
[output,count] = myAlgorithm(#(x)cos(x)+x, 1)