adding bounds to code, matlab - matlab

I am trying to add bounds to the code but having troubling figuring out where to put them. The equation goes: f(x) = e^(6x) + 1.441e^(2x) − 2.079e^(4x) − 0.333 = 0, -1>=x<=0
function c = newton(x0, delta)
c = x0;
fc = f(x0);
fprintf('initial guess: c=%d, fc=%d\n',c,fc)
if abs(fc) <= delta % check to see if initial guess satisfies
return; % convergence criterion.
end;
while abs(fc) > delta,
fpc = fprime(c);
if fpc==0, % if fprime is 0, abort.
error('fprime is 0') % the error function prints message and exits
end;
c = c - fc/fpc; % Newton step
fc = f(c);
fprintf(' c=%d, fc=%d\n',c,fc)
end;
function fx = f(x)
fx = exp(6*x)+1.441*exp(2*x)-2.079*exp(4*x)-0.333; % Enter your function here.
return;
function fprimex = fprime(x)
fprimex = 6*exp(6*x)+6*exp(2*x)*(ln(2))^2-4*exp(4*x)*ln(8); % Enter the derivative of function
return;

I would add the check after the Newton step. This won't protect against someone entering a -1 or 1 as an initial guess, but that could be done when you do your input validation. I took Ander Biguri's advice and changed the c to x:
function x = newton(x0, delta)
x = x0;
fx = f(x0);
fprintf('initial guess: x=%f, fx=%f\n',x,fx)
if abs(fx) <= delta % check to see if initial guess satisfies
return; % convergence criterion.
end;
while abs(fx) > delta,
fpx = fprime(x);
if fpx==0, % if fprime is 0, abort.
error('fprime is 0') % the error function prints message and exits
end;
x = x - fx/fpx; % Newton step
if( x > 1 || x < -1 )
error('x out of bounds!');
end
fx = f(x);
fprintf(' x=%f, fx=%f\n',x,fx)
end
end
function fx = f(x)
fx = exp(6*x)+1.441*exp(2*x)-2.079*exp(4*x)-0.333; % Enter your function here.
end
function fprimex = fprime(x)
fprimex = 6*exp(6*x)+6*exp(2*x)*(log(2))^2-4*exp(4*x)*log(8); % Enter the derivative of function
end
Here's the output I get:
>> x = newton(0.5, 0.5*1e-4)
initial guess: x=0.500000, fx=8.307733
x=0.375798, fx=2.908518
x=0.263566, fx=1.003444
x=0.165026, fx=0.340291
x=0.081315, fx=0.113210
x=0.012704, fx=0.036909
x=-0.041514, fx=0.011793
x=-0.082894, fx=0.003695
x=-0.113515, fx=0.001136
x=-0.135581, fx=0.000341
x=-0.151084, fx=0.000098
x=-0.161526, fx=0.000025
x =
-0.1615

Related

Why is Matlab's unifrnd(a,b) so slow?

I was doing a simple speed comparison between Matlab and Julia (using the tic, toc command) running a Gibbs sampler with rejection sampling. For Matlab I ran two different versions of the code. One was using the built-in unifrnd(a,b) while the other was drawing uniform random numbers in the interval (a,b) by calling the following function:
% Draw a uniform random sample in the interval (a,b)
function f = rand_uniform(a,b)
f = a + rand*(b - a);
end
I used the same function as above in the Julia code.
The results from running the code with 1000000 iterations were the following:
Case 1: Matlab using unifrnd(a,b):
x_bar = 1.0944
y_bar = 1.1426
Elapsed time is 255.201619 seconds.
Case 2: Matlab calling rand_uniform(a,b) (function above):
x_bar =1.0947
y_bar =1.1429
Elapsed time is 38.704601 seconds.
Case 3: Julia calling rand_uniform(a,b) (function above):
x_bar = 1.0951446303536603
y_bar = 1.142634615899686
Elapsed time: 3.563854193 seconds
Clearly using unifrnd(a,b) slowed the Matlab code down a lot but the question is why? The density is taken from one of the examples in Introduction to Applied Bayesian Statistics and Estimation for Social Scientists and if anyone is interested the theoretical mean, mu_x = 1.095 while mu_y = 1.143.
Case 1: The Matlab code using the built-in unifrnd(a,b) is:
clear;
clc;
tic
% == Setting up matrices and preliminaries == %
d = 1000000; % No. of iterations
b = d*0.25; % Burn-in length. We discard 25% of the sample (not used here)
x = zeros(1,d);
x(1) = -1;
y = zeros(1,d);
y(1) = -1;
m = 25; % The constant multiplied on g(x)
count = 0; % Counting no. of iterations
% == The Gibbs sampler using rejection sampling == %
for i = 2:d
% Sample from x|y
z = 0;
while z == 0
u = unifrnd(0,2);
if ((2*u+3*y(i-1)+2) > unifrnd(0,2)*m) % Height is (1/(b-a))*m = 0.5*25 = 12.5
x(i) = u;
z = 1;
end
end
% Sample from y|x
z = 0;
while z == 0
u = unifrnd(0,2);
if ((2*x(i)+3*u+2) > unifrnd(0,2)*m)
y(i) = u;
z = 1;
end
end
%count = count+1 % For counting no. of total draws from m*g(x)
end
x_bar = mean(x)
y_bar = mean(y)
toc
Case 2: The Matlab code calling rand_uniform(a,b) (function above):
clear;
clc;
tic
% == Setting up matrices and preliminaries == %
d = 1000000; % No. of iterations
b = d*0.25; % Burn-in length. We discard 25% of the sample (not used here)
x = zeros(1,d);
x(1) = -1;
y = zeros(1,d);
y(1) = -1;
m = 25; % The constant multiplied on g(x)
count = 0; % Counting no. of iterations
% == The Gibbs sampler using rejection sampling == %
for i = 2:d
% Sample from x|y
z = 0;
while z == 0
u = rand_uniform(0,2);
if ((2*u+3*y(i-1)+2) > rand_uniform(0,2)*m) % Height is (1/(b-a))*m = 0.5*25 = 12.5
x(i) = u;
z = 1;
end
end
% Sample from y|x
z = 0;
while z == 0
u = rand_uniform(0,2);
if ((2*x(i)+3*u+2) > rand_uniform(0,2)*m)
y(i) = u;
z = 1;
end
end
%count = count+1 % For counting no. of total draws from m*g(x)
end
x_bar = mean(x)
y_bar = mean(y)
toc
Case 3: The Julia code calling rand_uniform(a,b) (function above):
# Gibbs sampling with rejection sampling
tic()
# == Return a uniform random sample from the interval (a, b) == #
function rand_uniform(a, b)
a + rand()*(b - a)
end
# == Setup and preliminaries == #
d = 1000000 # No. of iterations
b = d*0.25 # Burn-in length. We discard 25% of the sample (not used here)
x = zeros(d)
x[1] = -1
y = zeros(d)
y[1] = -1
m = 25
# == The Gibbs sampler using rejection sampling == #
for i in 2:d
#Sample from y|x
z = 0
while z==0
u = rand_uniform(0,2)
if ((2*u+3*y[i-1]+2) > rand_uniform(0,2)*m) #Height is (1/(b-a))*m = 0.5*25 = 12.5
x[i] = u
z = 1
end
end
#Sample from x|y
z = 0
while z == 0
u = rand_uniform(0,2)
if ((2*x[i]+3*u+2) > rand_uniform(0,2)*m)
y[i] = u
z = 1
end
end
end
println("x_bar = ", mean(x))
println("y_bar = ", mean(y))
toc()

Solution of Burger equation by Newton-Raphson method in Matlab

I am solving Burger equation with Newton-Raphson method in Mathlab.
For the description of the problem see 1.
My problem is the following this code finds the solution upto time
$t=1$, but at this time a discontinuity develops and then the wave
moves forward (like a step function), but this code does not produce
correct solutions after time $t=1$.
Any suggestions or comments to improve the code.
Here is the Matlab code that I am using
function BurgerFSolve2
clc; clear;
% define a 1D mesh
a = -1; b = 3; Nx = 100;
x = linspace(a,b,Nx);
dx = (b-a)/Nx;
J = length(x);
% Iinitial condition
p_init = zeros(size(x));
p_init(x<=0) = 1;
p_init(x>0 & x<1)= 1-x(x>0 & x<1);
% storing results
P = zeros(length(p_init),3001);
P(:,1) = p_init;
% Boundary condition
pL = 1; pR = 0;
% solver
dt = 0.001;
t = 0;
T = zeros(1,3001);
c = dt/dx;
for i = 1:3000
t = t+dt;
T(i+1) = t;
options=optimset('Display','iter'); % Option to display output
p = fsolve(#(p) myfun1(p, pL, pR, c, J, P(:,i)), p_init, ...
options);
% Call solver
P(:,i+1) = p;
p_init = p;
figure(1);
plot(x, p, '-o');
title(['t= ' num2str(t) ' s']);
drawnow;
end
end
function F = myfun1(p, pL, pR, c, J, p_Old)
% Rewrite the equation in the form F(x) = 0
F(1) = p(1) + c*(p(1)^2 - p(1)*pL) - p_Old(1);
for i=2:J-1
F(i) = p(i) + c*(p(i)^2 - p(i-1)*p(i)) - p_Old(i);
end
F(J) = p(J) + c*(p(J)^2 - p(J-1)*p(J)) - p_Old(J);
end

Shidoku solver matlab code

I'm trying to write a Shidoku ( smaller and easier 4x4 variant of Sudoku) solver code in MATLAB.
I have found some soduko solver (9x9) but i could't revise them to be suitable for my problem. For example:
% Solving Sudoku Using Recursive Backtracking
function X = sudoku(X)
% SUDOKU Solve Sudoku using recursive backtracking.
% sudoku(X), expects a 9-by-9 array X.
% Fill in all “singletons”.
% C is a cell array of candidate vectors for each cell.
% s is the first cell, if any, with one candidate.
% e is the first cell, if any, with no candidates.
[C,s,e] = candidates(X);
while ~isempty(s) && isempty(e)
X(s) = C{s};
[C,s,e] = candidates(X);
end
% Return for impossible puzzles.
if ~isempty(e)
return
end
% Recursive backtracking.
if any(X(:) == 0)
Y = X;
z = find(X(:) == 0,1); % The first unfilled cell.
for r = [C{z}] % Iterate over candidates.
X = Y;
X(z) = r; % Insert a tentative value.
X = sudoku(X); % Recursive call.
if all(X(:) > 0) % Found a solution.
return
end
end
end
% ------------------------------
function [C,s,e] = candidates(X)
C = cell(9,9);
tri = #(k) 3*ceil(k/3-1) + (1:3);
for j = 1:9
for i = 1:9
if X(i,j)==0
z = 1:9;
z(nonzeros(X(i,:))) = 0;
z(nonzeros(X(:,j))) = 0;
z(nonzeros(X(tri(i),tri(j)))) = 0;
C{i,j} = nonzeros(z)';
end
end
end
L = cellfun(#length,C); % Number of candidates.
s = find(X==0 & L==1,1);
e = find(X==0 & L==0,1);
end % candidates
end % sudoku
Any help will be helpful.
Just reduce the problem dimensionality from 3 to 2 (I know now that it is said "9x9" instead of "3x3", but the important dimensional number for the puzzle is N=3):
% SHIDOKU Solve Shidoku using recursive backtracking.
% shidoku(X), expects a 4-by-4 array X.
function X = shidoku(X)
[C,s,e] = candidates(X);
while ~isempty(s) && isempty(e)
X(s) = C{s};
[C,s,e] = candidates(X);
end;
if ~isempty(e)
return
end;
if any(X(:) == 0)
Y = X;
z = find(X(:) == 0,1);
for r = [C{z}]
X = Y;
X(z) = r;
X = shidoku(X);
if all(X(:) > 0)
return;
end;
end;
end;
% ------------------------------
function [C,s,e] = candidates(X)
C = cell(4,4);
bi = #(k) 2*ceil(k/2-1) + (1:2);
for j = 1:4
for i = 1:4
if X(i,j)==0
z = 1:4;
z(nonzeros(X(i,:))) = 0;
z(nonzeros(X(:,j))) = 0;
z(nonzeros(X(bi(i),bi(j)))) = 0;
C{i,j} = transpose(nonzeros(z));
end;
end;
end;
L = cellfun(#length,C); % Number of candidates.
s = find(X==0 & L==1,1);
e = find(X==0 & L==0,1);
end % candidates
end % shidoku

Matlab error: Undefined function 'dmod' for input arguments of type 'double'. How come there is no dmod function as it should come with Matlab?

I have been working on some exam and need to do an exercise involving some frequency shift keying. That is why I use dmod function from Matlab - it comes with Matlab. But as I write in my console
yfsk=dmod([1 0], 3, 0.5, 100,'fsk', 2, 1);
it gives me this
`Undefined function 'dmod' for input arguments of type 'double'.
I have also tried doc dmod and it says 'page not found' in matlab help window.
Do you know wheter this is because I didn't install all the matlab packages or this function is not suported with matlab 2012a?
Thank you
This is gonna be helpful:
function [y, t] = dmod(x, Fc, Fd, Fs, method, M, opt2, opt3)
%DMOD
%
%WARNING: This is an obsolete function and may be removed in the future.
% Please use MODEM.PAMMOD, MODEM.QAMMOD, MODEM.GENQAMMOD, FSKMOD,
% MODEM.PSKMOD, or MODEM.MSKMOD instead.
% Y = DMOD(X, Fc, Fd, Fs, METHOD...) modulates the message signal X
% with carrier frequency Fc (Hz) and symbol frequency Fd (Hz). The
% sample frequency of Y is Fs (Hz), where Fs > Fc and where Fs/Fd is
% a positive integer. For information about METHOD and subsequent
% parameters, and about using a specific modulation technique,
% type one of these commands at the MATLAB prompt:
%
% FOR DETAILS, TYPE MODULATION TECHNIQUE
% dmod ask % M-ary amplitude shift keying modulation
% dmod psk % M-ary phase shift keying modulation
% dmod qask % M-ary quadrature amplitude shift keying
% % modulation
% dmod fsk % M-ary frequency shift keying modulation
% dmod msk % Minimum shift keying modulation
%
% For baseband simulation, use DMODCE. To plot signal constellations,
% use MODMAP.
%
% See also DDEMOD, DMODCE, DDEMODCE, MODMAP, AMOD, ADEMOD.
% Copyright 1996-2007 The MathWorks, Inc.
% $Revision: 1.1.6.5 $ $Date: 2007/06/08 15:53:47 $
warnobsolete(mfilename, 'Please use MODEM.PAMMOD, MODEM.QAMMOD, MODEM.GENQAMMOD, FSKMOD, MODEM.PSKMOD, or MODEM.MSKMOD instead.');
swqaskenco = warning('off', 'comm:obsolete:qaskenco');
swapkconst = warning('off', 'comm:obsolete:apkconst');
swmodmap = warning('off', 'comm:obsolete:modmap');
swamod = warning('off', 'comm:obsolete:amod');
opt_pos = 6; % position of 1st optional parameter
if nargout > 0
y = []; t = [];
end
if nargin < 1
feval('help','dmod')
return;
elseif isstr(x)
method = lower(deblank(x));
if length(method) < 3
error('Invalid method option for DMOD.')
end
if nargin == 1
% help lines for individual modulation method.
addition = 'See also DDEMOD, DMODCE, DDEMODCE, MODMAP, AMOD, ADEMOD.';
if method(1:3) == 'qas'
callhelp('dmod.hlp', method(1:4), addition);
else
callhelp('dmod.hlp', method(1:3), addition);
end
else
% plot constellation, make a shift.
opt_pos = opt_pos - 3;
M = Fc;
if nargin >= opt_pos
opt2 = Fd;
else
modmap(method, M);
return;
end
if nargin >= opt_pos+1
opt3 = Fs;
else
modmap(method, M, opt2);
return;
end
modmap(method, M, opt2, opt3); % plot constellation
end
return;
end
if (nargin < 4)
error('Usage: Y = DMOD(X, Fc, Fd, Fs, METHOD, OPT1, OPT2, OPT3) for passband modulation');
elseif nargin < opt_pos-1
method = 'samp';
else
method = lower(method);
end
len_x = length(x);
if length(Fs) > 1
ini_phase = Fs(2);
Fs = Fs(1);
else
ini_phase = 0; % default initial phase
end
if ~isfinite(Fs) | ~isreal(Fs) | Fs<=0
error('Fs must be a positive number.');
elseif length(Fd)~=1 | ~isfinite(Fd) | ~isreal(Fd) | Fd<=0
error('Fd must be a positive number.');
else
FsDFd = Fs/Fd; % oversampling rate
if ceil(FsDFd) ~= FsDFd
error('Fs/Fd must be a positive integer.');
end
end
if length(Fc) ~= 1 | ~isfinite(Fc) | ~isreal(Fc) | Fc <= 0
error('Fc must be a positive number. For baseband modulation, use DMODCE.');
elseif Fs/Fc < 2
warning('Fs/Fc must be much larger than 2 for accurate simulation.');
end
% determine M
if isempty(findstr(method, '/arb')) & isempty(findstr(method, '/cir'))
if nargin < opt_pos
M = max(max(x)) + 1;
M = 2^(ceil(log(M)/log(2)));
M = max(2, M);
elseif length(M) ~= 1 | ~isfinite(M) | ~isreal(M) | M <= 0 | ceil(M) ~= M
error('Alphabet size M must be a positive integer.');
end
end
if isempty(x)
y = [];
return;
end
[r, c] = size(x);
if r == 1
x = x(:);
len_x = c;
else
len_x = r;
end
% expand x from Fd to Fs.
if isempty(findstr(method, '/nomap'))
if ~isreal(x) | all(ceil(x)~=x)
error('Elements of input X must be integers in [0, M-1].');
end
yy = [];
for i = 1 : size(x, 2)
tmp = x(:, ones(1, FsDFd)*i)';
yy = [yy tmp(:)];
end
x = yy;
clear yy tmp;
end
if strncmpi(method, 'ask', 3)
if isempty(findstr(method, '/nomap'))
% --- Check that the data does not exceed the limits defined by M
if (min(min(x)) < 0) | (max(max(x)) > (M-1))
error('An element in input X is outside the permitted range.');
end
y = (x - (M - 1) / 2 ) * 2 / (M - 1);
else
y = x;
end
[y, t] = amod(y, Fc, [Fs, ini_phase], 'amdsb-sc');
elseif strncmpi(method, 'fsk', 3)
if nargin < opt_pos + 1
Tone = Fd;
else
Tone = opt2;
end
if (min(min(x)) < 0) | (max(max(x)) > (M-1))
error('An element in input X is outside the permitted range.');
end
[len_y, wid_y] = size(x);
t = (0:1/Fs:((len_y-1)/Fs))'; % column vector with all the time samples
t = t(:, ones(1, wid_y)); % replicate time vector for multi-channel operation
osc_freqs = pi*[-(M-1):2:(M-1)]*Tone;
osc_output = (0:1/Fs:((len_y-1)/Fs))'*osc_freqs;
mod_phase = zeros(size(x))+ini_phase;
for index = 1:M
mod_phase = mod_phase + (osc_output(:,index)*ones(1,wid_y)).*(x==index-1);
end
y = cos(2*pi*Fc*t+mod_phase);
elseif strncmpi(method, 'psk', 3)
% PSK is a special case of QASK.
[len_y, wid_y] = size(x);
t = (0:1/Fs:((len_y-1)/Fs))';
if findstr(method, '/nomap')
y = dmod(x, Fc, Fs, [Fs, ini_phase], 'qask/cir/nomap', M);
else
y = dmod(x, Fc, Fs, [Fs, ini_phase], 'qask/cir', M);
end
elseif strncmpi(method, 'msk', 3)
M = 2;
Tone = Fd/2;
if isempty(findstr(method, '/nomap'))
% Check that the data is binary
if (min(min(x)) < 0) | (max(max(x)) > (1))
error('An element in input X is outside the permitted range.');
end
x = (x-1/2) * Tone;
end
[len_y, wid_y] = size(x);
t = (0:1/Fs:((len_y-1)/Fs))'; % column vector with all the time samples
t = t(:, ones(1, wid_y)); % replicate time vector for multi-channel operation
x = 2 * pi * x / Fs; % scale the input frequency vector by the sampling frequency to find the incremental phase
x = [0; x(1:end-1)];
y = cos(2*pi*Fc*t+cumsum(x)+ini_phase);
elseif (strncmpi(method, 'qask', 4) | strncmpi(method, 'qam', 3) |...
strncmpi(method, 'qsk', 3) )
if findstr(method,'nomap')
[y, t] = amod(x, Fc, [Fs, ini_phase], 'qam');
else
if findstr(method, '/ar') % arbitrary constellation
if nargin < opt_pos + 1
error('Incorrect format for METHOD=''qask/arbitrary''.');
end
I = M;
Q = opt2;
M = length(I);
% leave to the end for processing
CMPLEX = I + j*Q;
elseif findstr(method, '/ci') % circular constellation
if nargin < opt_pos
error('Incorrect format for METHOD=''qask/circle''.');
end
NIC = M;
M = length(NIC);
if nargin < opt_pos+1
AIC = [1 : M];
else
AIC = opt2;
end
if nargin < opt_pos + 2
PIC = NIC * 0;
else
PIC = opt3;
end
CMPLEX = apkconst(NIC, AIC, PIC);
M = sum(NIC);
else % square constellation
[I, Q] = qaskenco(M);
CMPLEX = I + j * Q;
end
y = [];
x = x + 1;
% --- Check that the data does not exceed the limits defined by M
if (min(min(x)) < 1) | (max(max(x)) > M)
error('An element in input X is outside the permitted range.');
end
for i = 1 : size(x, 2)
tmp = CMPLEX(x(:, i));
y = [y tmp(:)];
end
ind_y = [1: size(y, 2)]';
ind_y = [ind_y, ind_y+size(y, 2)]';
ind_y = ind_y(:);
y = [real(y) imag(y)];
y = y(:, ind_y);
[y, t] = amod(y, Fc, [Fs, ini_phase], 'qam');
end
elseif strncmpi(method, 'samp', 4)
% This is for converting an input signal from sampling frequency Fd
% to sampling frequency Fs.
[len_y, wid_y] = size(x);
t = (0:1/Fs:((len_y-1)/Fs))';
y = x;
else % invalid method
error(sprintf(['You have used an invalid method.\n',...
'The method should be one of the following strings:\n',...
'\t''ask'' Amplitude shift keying modulation;\n',...
'\t''psk'' Phase shift keying modulation;\n',...
'\t''qask'' Quadrature amplitude shift-keying modulation, square constellation;\n',...
'\t''qask/cir'' Quadrature amplitude shift-keying modulation, circle constellation;\n',...
'\t''qask/arb'' Quadrature amplitude shift-keying modulation, user defined constellation;\n',...
'\t''fsk'' Frequency shift keying modulation;\n',...
'\t''msk'' Minimum shift keying modulation.']));
end
if r==1 & ~isempty(y)
y = y.';
end
warning(swqaskenco);
warning(swapkconst);
warning(swmodmap);
warning(swamod);
% [EOF]
I do believe that dmod function (Communication Toolbox) has been abandoned in the latest MATLAB releases.
It looks like dmod is no more :-)
Here is the link that says it was removed:
http://www.mathworks.com/help/comm/release-notes.html?searchHighlight=dmod
It should be replaced wit with comm.FSKModulator System object
I think you may be looking for the demodulation function (demod) from the signal processing toolbox.
http://www.mathworks.com.au/help/signal/ref/demod.html

Matlab Ridder's Method Code

I need to write a proper implementation of the Ridder's method in Matlab. I must define the function as
function [x sol, f at x sol, N iterations] = Ridders(f, x1, x2, eps f, eps x)
The explanation I was given is:
bracket the roots (x1, x2)
evaluate the midpoint (x1 + x2)/2
find new approximation for the root
x4 = x3 + sign(f1 - f2) [f3/((f3)^2 - f1f2)^1/2)](x3 - x1)
check if x4 satisfies the convergence condition. if yes, stop. if not...
rebracket the root using x4 and whichever of x1, x2, or x3 is closer to the root
loop back to 1
I have no idea how to implement this in matlab. Help?
In Matlab, you would define your function as:
function [list of outputs] = myfunc(list of input variables)
%function definition to compute outputs using the input variables.
In your case if you would like x4 (i.e root) to be your output, you would do:
function root = riddler(func, x1, x2, xaccuracy, N)
xl = x1;
xh = x2;
fl=func(x1)
fh=func(x2)
for i = 1:N
xm = 0.5*(xl+xh);
fm = func(xm);
s = sqrt(fm*fm - fl*fh)
if s == 0
return;
end
xnew = xm + (xm - xl)*sign(fl - fh)*fm/s %update formula
.
.
. % extra code to check convergence and assign final answer for root
. % code to update xl, xh, fl, fh, etc. (i.e rebracket)
.
end % end for
I wrote a Matlab implementation of Ridder's method on the Matlab file exchange: submission 54458. I've copied the code below for reference:
function xZero = rootSolve(func,xLow,xUpp)
% XZERO = ROOTSOLVE(FUNC, XLOW, XUPP)
%
% FUNCTION: This function uses Ridder's Method to return a root, xZero,
% of func on the interval [xLow,xUpp]
%
% INPUTS:
% func = a function for a SISO function: y = f(x)
% xLow = the lower search bound
% xUpp = the upper search bound
%
% OUTPUTS:
% xZero = the root of the function on the domain [xLow, xUpp]
%
% NOTES:
% 1) The function must be smooth
% 2) sign(f(xLow)) ~= sign(f(xUpp))
% 3) This function will return a root if one exists, and the function is
% not crazy. If there are multiple roots, it will return the first one
% that it finds.
maxIter = 50;
fLow = feval(func,xLow);
fUpp = feval(func,xUpp);
xZero = [];
tol = 10*eps;
if (fLow > 0.0 && fUpp < 0.0) || (fLow < 0.0 && fUpp > 0.0)
for i=1:maxIter
xMid = 0.5*(xLow+xUpp);
fMid = feval(func,xMid);
s = sqrt(fMid*fMid - fLow*fUpp);
if s==0.0, break; end
xTmp = (xMid-xLow)*fMid/s;
if fLow >= fUpp
xNew = xMid + xTmp;
else
xNew = xMid - xTmp;
end
xZero = xNew;
fNew = feval(func,xZero);
if abs(fNew)<tol, break; end
%Update
if sign(fMid) ~= sign(fNew)
xLow = xMid;
fLow = fMid;
xUpp = xZero;
fUpp = fNew;
elseif sign(fLow) ~= sign(fNew)
xUpp = xZero;
fUpp = fNew;
elseif sign(fUpp) ~= sign(fNew)
xLow = xZero;
fLow = fNew;
else
error('Something bad happened in riddersMethod!');
end
end
else
if fLow == 0.0
xZero = xLow;
elseif fUpp == 0.0
xZero = xUpp;
else
error('Root must be bracketed in Ridder''s Method!');
end
end
Some principal concepts that might help:
function handles (you need to provide f in this format)
valid variable names (many variable names in your definition are not valid)