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
Related
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.
I am currently involved in a group project where we have to conduct portfolio selection and optimisation. The paper being referenced is given here: (specifically page 5 and 6, equations 7-10)
http://faculty.london.edu/avmiguel/DeMiguel-Nogales-OR.pdf
We are having trouble creating the optimisation problem using M-Portfolios, given below
min (wrt w,m) (1/T) * sum_(rho)*(w'*r_t - m) (Sorry I couldn't get the formatting to work)
s.t. w'e = 1 (just a condition saying that all weights add to 1)
So far, this is what we have attempted:
function optPortfolio = portfoliofminconM(returns,theta)
% Compute the inputs of the mean-variance model
mu = mean(returns)';
sigma = cov(returns);
% Inputs for the fmincon function
T = 120;
n = length(mu);
w = theta(1:n);
m = theta((n+1):(2*n));
c = 0.01*ones(1,n);
Aeq = ones(1,(2*n));
beq = 1;
lb = zeros(2,n);
ub = ones(2,n);
x0 = ones(n,2) / n; % Start with the equally-weighted portfolio
options = optimset('Algorithm', 'interior-point', ...
'MaxIter', 1E10, 'MaxFunEvals', 1E10);
% Nested function which is used as the objective function
function objValue = objfunction(w,m)
cRp = (w'*(returns - (ones(T,1)*m'))';
objValue = 0;
for i = 1:T
if abs(cRp(i)) <= c;
objValue = objValue + (((cRp(i))^2)/2);
else
objValue = objValue + (c*(abs(cRp(i))-(c/2)));
end
end
The problem starts at our definitions for theta being used as a vector of w and m. We don't know how to use fmincon with 2 variables in the objective function properly. In addition, the value of the objective function is conditional on another value (as shown in the paper) and this needs to be done over a rolling time window of 120 months for a total period of 264 months.(hence the for-loop and if-else)
If any more information is required, I will gladly provide it!
If you can additionally provide an example that deals with a similar problem, can you please link us to it.
Thank you in advance.
The way you minimize a function of two scalars with fmincon is to write your objective function as a function of a single, two-dimensional vector. For example, you would write f(x,y) = x.^2 + 2*x*y + y.^2 as f(x) = x(1)^2 + 2*x(1)*x(2) + x(2)^2.
More generally, you would write a function of two vectors as a function of a single, large vector. In your case, you could rewrite your objfunction or do a quick hack like:
objfunction_for_fmincon = #(x) objfunction(x(1:n), x(n+1:2*n));
I have tried to implement Laplace equation in my matlab code sequence as shown below. I created this LaplaceExplicit.m and thus used another function numgrid in the same. However, it shows error as "Input variable n is undefined". What should be done? The code is as below-
function [x,y,T]= LaplaceExplicit(n,m,Dx,Dy)
echo off;
numgrid(n,m);
R = 5.0;
T = R*ones(n+1,m+1); % All T(i,j) = 1 includes all boundary conditions
x = [0:Dx:n*Dx];y=[0:Dy:m*Dy]; % x and y vectors
for i = 1:n % Boundary conditions at j = m+1 and j = 1
6
T(i,m+1) = T(i,m+1)+ R*x(i)*(1-x(i));
T(i,1) = T(i,1) + R*x(i)*(x(i)-1);
end;
TN = T; % TN = new iteration for solution
err = TN-T;
% Parameters in the solution
beta = Dx/Dy;
denom = 2*(1+beta^2);
% Iterative procedure
epsilon = 1e-5; % tolerance for convergence
imax = 1000; % maximum number of iterations allowed
k = 1; % initial index value for iteration
% Calculation loop
while k<= imax
for i = 2:n
for j = 2:m
TN(i,j)=(T(i-1,j)+T(i+1,j)+beta^2*(T(i,j-1)+T(i,j+1)))/denom;
err(i,j) = abs(TN(i,j)-T(i,j));
end;
end;
T = TN; k = k + 1;
errmax = max(max(err));
if errmax < epsilon
[X,Y] = meshgrid(x,y);
figure(2);contour(X,Y,T',20);xlabel('x');ylabel('y');
title('Laplace equation solution - Dirichlet boundary conditions Explicit');
figure(3);surfc(X,Y,T');xlabel('x');ylabel('y');zlabel('T(x,y)');
title('Laplace equation solution - Dirichlet boundary conditions Explicit');
fprintf('Convergence achieved after %i iterations.\n',k);
fprintf('See the following figures:\n');
fprintf('==========================\n');
fprintf('Figure 1 - sketch of computational grid \n');
fprintf('Figure 2 - contour plot of temperature \n');
fprintf('Figure 3 - surface plot of temperature \n');
return
end;
end;
fprintf('\n No convergence after %i iterations.',k);
MATLAB will go through a standard look-up procedure to work out what it represents. First, is it a local variable? If not, is a function or script (command)? This also requires looking in a prescribed set of places. The simple version is: first look in the current directory, then look in the directories specified by the MATLAB path (in order).
Hence, if you write square_table.m and save it in C:\work\Moe\MATLAB then that directory needs to be either the current working directory on on the MATLAB path. Otherwise you will get an error ("undefined function or variable").
Sorry people, got my questions answered.. it was just some problem with initialisation and calling a function defined in another .m file. Resolved it and now the code's working fine.. :)
i have question,about which i am too much interested,suppose that i have two M-file in matlab, in the first one i have described following function for calculating peaks and peaks indeces
function [peaks,peak_indices] = find_peaks(row_vector)
A = [0 row_vector 0];
j = 1;
for i=1:length(A)-2
temp=A(i:i+2);
if(max(temp)==temp(2))
peaks(j) = row_vector(i);
peak_indices(j) = i;
j = j+1;
end
end
end
and in second M-file i have code for describing sinusoidal model for given data sample
function [ x ]=generate(N,m,A3)
f1 = 100;
f2 = 200;
T = 1./f1;
t = (0:(N*T/m):(N*T))';
wn = rand(length(t),1).*2 - 1;
x = 20.*sin(2.*pi.*f1.*t) + 30.*cos(2.*pi.*f2.*t) + A3.*wn;
end
my question is how to combine it together?one solution would be just create two M-file into folder,then call function from one M-file and made operation on given vector and get result,and then call second function from another M file on given result and finally get what we want,but i would like to build it in one big M-file,in c++,in java,we can create classes,but i am not sure if we can do same in matlab too,please help me to clarify everything and use find_peaks function into generate function
UPDATED:
ok now i would like to show simple change what i have made in my code
function [ x ] = generate(N,m,A3)
f1 = 100;
f2 = 200;
T = 1./f1;
t = (0:(N*T/m):(N*T))'; %'
wn = rand(length(t),1).*2 - 1;
x = 20.*sin(2.*pi.*f1.*t) + 30.*cos(2.*pi.*f2.*t) + A3.*wn;
[pks,locs] = findpeaks(x);
end
i used findpeaks built-in function in matlab,but i am getting following error
generate(1000,50,50)
Undefined function 'generate' for input arguments of type 'double'.
also i am interested what would be effective sampling rate to avoid alliasing?
You can simply put both in one file. The file must have the same name as the first function therein, and you will not be able to access subsequently defined functions from outside that file. See the MATLAB documentation on functions http://www.mathworks.co.uk/help/matlab/ref/function.html (particularly the examples section).
Also note that MATLAB has a built-in function findpeaks().
(By the way, you're still sampling at too low a frequency and will most certainly get aliasing - see http://en.wikipedia.org/wiki/Aliasing#Sampling_sinusoidal_functions )
Edit: As you requested it, here is some more information on the sampling theorem. A good and simple introduction to these basics is http://www.dspguide.com/ch3/2.htm and for further reading you should search for the Shannon/Nyquist sampling theorem.
Try with this, within a single MATLAB script
function test()
clc, clear all, close all
x = generate(1000,50,50);
[p,i] = find_peaks(x)
end
function x = generate(N,m,A3)
f1 = 100;
f2 = 200;
T = 1./f1;
t = (0:(N*T/m):(N*T))'; %'
wn = rand(length(t),1).*2 - 1;
x = 20.*sin(2.*pi.*f1.*t) + 30.*cos(2.*pi.*f2.*t) + A3.*wn;
end
function [peaks,peak_indices] = find_peaks(row_vector)
A = [0;row_vector;0];
j = 1;
for i=1:length(A)-2
temp=A(i:i+2);
if(max(temp)==temp(2))
peaks(j) = row_vector(i);
peak_indices(j) = i;
j = j+1;
end
end
end
In order to refactor my MATLAB code, I thought I'd pass around functions as arguments (what MATLAB calls anonymous functions), inspired by functional programming.
However, it seems performance is hit quite severely. In the examples below, I compare different approaches. (The code snippet is wrapped in a function in order to be able to use subfunctions)
The result I get is 0 seconds for direct, almost 0 seconds using a subfunction, and 5 seconds using anonymous functions. I'm running MATLAB 7.7 (R2007b) on OS X 10.6, on a C2D 1.8 GHz.
Can anyone run the code and see what they get? I'm especially interested in performance on Windows.
function [] = speedtest()
clear all; close all;
function y = foo(x)
y = zeros(1,length(x));
for j=1:N
y(j) = x(j)^2;
end
end
x = linspace(-100,100,100000);
N = length(x);
%% direct
t = cputime;
y = zeros(1,N);
for i=1:N
y(i) = x(i)^2;
end
r1 = cputime - t;
%% using subfunction
t = cputime;
y = foo(x);
r2 = cputime - t;
%% using anon function
fn = #(x) x^2;
t = cputime;
y = zeros(1,N);
for i=1:N
y(i) = fn(x(i));
end
r3 = cputime-t;
[r1 r2 r3]
end
You're cheating with the nested function. :) The anonymous function is being called inside a loop, so you're measuring the cost of calling it 100,000 times. The nested function only gets called once, so its function call overhead is negligible. To compare the cost of calling anonymous vs named functions, you should have the nested function do the same work as the anonymous function and then call it from inside a loop, too.
I did that and still got similar results. The anonymous function is about 20 times slower.
However, you can still use function handles with non-anonymous functions, and that doesn't have the same performance hit as anonymous functions. This works with either nested functions (as with the foo in your original test) or non-nested subfunctions (which don't act as closures and may have less overhead).
function [] = speedtest()
function y = foo(x)
y = x^2;
end
r = struct;
...
%% using nested function through function handle
fn = #foo;
y = zeros(1,N);
t = cputime;
for i=1:N
y(i) = fn(x(i));
end
r.nested_handle = cputime - t;
...
%% using subfunction through function handle
fn = #subfunction_foo;
y = zeros(1,N);
t = cputime;
for i=1:N
y(i) = fn(x(i));
end
r.subfunction_handle = cputime - t;
...
end % end function speedtest
function y = subfunction_foo(x)
y = x^2;
end
I get this on R2009b in Windows.
>> speedtest
direct: 0
nested: 0.0469
nested_handle: 0.0781
subfunction: 0.0313
subfunction_handle: 0.0313
anonymous: 1.2344
Another way to look at it is to structure your code so it's "vectorized" and operates on arrays, reducing the number of function calls and the cost of the function call doesn't matter so much. That would be more idiomatic Matlab: typical performance advice is to ignore the cost of function calls and loops because you ought to be doing fewer calls on larger arguments anyway.
I can confirm your findings Grav. The speedtest function returns the following on my computer.
>> speedtest()
ans =
0 0.0313 1.3906
As a sidenote, the function cputime is not the best method for measuring computation time. Use the tic and toc functions instead. see link
These functions provides a much higher time resolution, and using them I obtain the following.
>> speedtest()
ans =
0.0062 0.0162 1.3495
Results from a Windows machine, Matlab 2009a
>> test
ans =
0 0.0156 1.1094
I faced the same issue as Gary, just thought it would be good to check Andrew's answer on a more recent version of Matlab (2014a) (Mac). The results first:
direct: 0.0722
anonymous: 0.3916
subfunction: 0.2277
And the code I used:
function []=SpeedTest()
fanon = #(x,y) x*x+y*y;
iter=1000000;
x=1:iter;
y=1:iter;
var1=nan(size(x));
var2=nan(size(x));
var3=nan(size(x));
timefor=struct('direct',nan,'anonymous',nan','subfunction',nan);
tic;
for i=1:iter
var1(i)=x(i)*x(i)+y(i)*y(i);
end
timefor.direct=toc;
tic;
for i=1:iter
var2(i)=fanon(x(i),y(i));
end
timefor.anonymous=toc;
tic;
for i=1:iter
var3(i)=fsub(x(i),y(i));
end
timefor.subfunction=toc;
display(timefor);
end
function [z]=fsub(x,y)
z=x*x+y*y;
end