Interpolation between multiple 2D vector [fields] in a 3D space - matlab

I've attempted to look at MatLab documentation here:
http://www.mathworks.com/help/matlab/ref/interp3.html
and then in the
help interp3
section of MatLab, but I'm having trouble figuring out what I want actually and if interp3 is the thing that I'm looking for. But, I may just not be understanding if I'm able to use interp3 with the way I have things laid out as of now. I've attached a figure that I can create from a MatLab program that I wrote. It's taking NOAA lat/long (x/y), U/V directions for wind vectors, and then a Z value for the 2D levels to this field.
Using the format:
quiver3(x,y,z,u,v,w)
with the "W" component set to 0.
This is a very small section of the field, but what I'm trying to do is to interpolate between these 2D vector fields in order to create a 3D field.
Do I have to group U/X , V/Y, and W/Z into their own vectors in order to use interp3 ? I'm still not sure that the 3D function "V" section is in the interp3 syntax of
Vq = interp3(X,Y,Z,V,Xq,Yq,Zq)
This is a very small section of the field, but what I'm trying to do is to interpolate between these 2D vector fields in order to create a 3D field.
My code:
tic
clc
clear all
% You will have to change the directory to wherever you place the read_grib.r4
% file. In addition, It's necessary to have an external compiler connected
% to MatLab in order to build the mex-file that gives you the power to use
% the read_grib decoding. This is really tricky. On OSX I used Xcode as an
% environment and MatLab virtually worked immediately. On Windows, I have
% 2012(b) and had to use the call system('mxvc <BDS_unpack_mex5.c>') which
% utilized Microsoft's C-compiler that I had SOMEWHERE on my computer
% thankfully (may be pre-intalled). There are tutorials online for
% different compilers. In addition, if you're smart about it you can add
% the mex-file build to the start-up operations so you never have to worry
% about it, but my questionably legal MatLab copies seem to make this a
% little more difficult.
cd /Users/Sargent_PC/Downloads/read_grib.r4/
mex BDS_unpack_mex5.c
% ** Inventory doesn't need to be done every iteration **
% ** Uncomment the line below to get a record inventory **
%read_grib('NOAAdata.grb','inv');
% Creating a struct named "grib_struct" for each of the records I'm
% extracting out of the grib file. They exist in pairs with 6 records
% separating them. Should we want to extract ALL of the U and V wind
% components I'll iterate with a simple for-loop.
grib_struct=read_grib('NOAAdata.grb', [60,61,66,67]); %,72,73,78,79,84,85,90,91,96,97]);
UwindVec50mb = grib_struct(1).fltarray; %rec60
VwindVec50mb = grib_struct(2).fltarray; %rec61
UwindVec75mb = grib_struct(3).fltarray; %rec66
VwindVec75mb = grib_struct(4).fltarray; %rec67
% UwindVec100mb = grib_struct(5).fltarray; %rec72
% VwindVec100mb = grib_struct(6).fltarray; %rec73
% UwindVec125mb = grib_struct(7).fltarray; %rec78
% VwindVec125mb = grib_struct(8).fltarray; %rec79
% UwindVec150mb = grib_struct(9).fltarray; %rec84
% VwindVec150mb = grib_struct(10).fltarray; %rec85
% UwindVec175mb = grib_struct(11).fltarray; %rec90
% VwindVec175mb = grib_struct(12).fltarray; %rec91
% UwindVec200mb = grib_struct(13).fltarray; %rec96
% VwindVec200mb = grib_struct(14).fltarray; %rec97
%50mb range has records 60 and 61 for U and V respectively.
%75mb range has records 66 and 67 for U and V respectively.
%100mb range has records 72 and 73 for U and V respectively.
%125mb range has records 78 and 79 for U and V respectively.
%150mb range has records 84 and 85 for U and V respectively.
%175mb range has records 90 and 91 for U and V respectively.
%200mb range has records 96 and 97 for U and V respectively.
%These extracted sections of the grib file will read "extracted" on the
%left-hand side should they be successfully extracted.
load NOAAlatlongdata; % read the data into a matrix
lat_value = NOAAlatlongdata(:,3); % copy first column of NOAAlatlongdata into lat_value
long_value = NOAAlatlongdata(:,4); % and second column of NOAAlatlongdata into long_value
% I was going to add in a pressure to altitude change here, but
% it may be in our best interest to get a list of values for each
% pressure level that correspond to altitude and create our own
% vector of those values in order to simplify the calculations that
% the program has to do.
% z50mb_val = ;
% z75mb_val = ;
% z100mb_val= ;
% z125mb_val= ;
% z150mb_val= ;
% z175mb_val= ;
% z200mb_val= ;
% Creating vectors of the Z-values which are gotten from converting the
% pressure value to altitude. I feel like this is a very bulky way to do
% this, and I've included the tic-toc timing to show that it's ~30seconds
% per vector creation. For each altitude level that we add you'll add
% ~30seconds JUST to the vector creation component of the program.
tic; for i = 1:262792, z50mb_vec=67507*ones(i,1); end; toc;
tic; for i = 1:262792, z75mb_vec=60296*ones(i,1); end; toc;
% tic; for i = 1:262792, z100mb_vec=53084*ones(i,1); end; toc;
%
% tic; for i = 1:262792, z125mb_vec=48865*ones(i,1); end; toc;
%
% tic; for i = 1:262792, z150mb_vec=44646*ones(i,1); end; toc;
%
% tic; for i = 1:262792, z175mb_vec=43763*ones(i,1); end; toc;
%
% tic; for i = 1:262792, z200mb_vec=38661*ones(i,1); end; toc;
%
tic; for i = 1:262792, W_zerovec = 0*ones(i,1); end; toc;
%
% 3D quiver plots format: quiver3(x,y,z,u,v,w) -- Make sure dimensionality
% of all 6 components to that plot match up before plotting.
quiver3((lat_value(1:101)), (long_value(1:25)), ( z50mb_vec(1:25)), (UwindVec50mb(1:25)) ,(VwindVec50mb(1:25)) , W_zerovec(1:25))
hold on
quiver3((lat_value(1:101)), (long_value(1:251)), ( z75mb_vec(1:25)), (UwindVec75mb(1:25)) ,(VwindVec75mb(1:25)) , W_zerovec(1:25))
hold on
% quiver3((lat_value(1:101)), (long_value(1:101)), (z100mb_vec(1:101)), (UwindVec100mb(1:101)),(VwindVec100mb(1:101)), W_zerovec(1:101))
% hold on
% quiver3((lat_value(1:101)), (long_value(1:101)), (z125mb_vec(1:101)), (UwindVec125mb(1:101)),(VwindVec125mb(1:101)), W_zerovec(1:101))
% hold on
% quiver3((lat_value(1:101)), (long_value(1:101)), (z150mb_vec(1:101)), (UwindVec150mb(1:101)),(VwindVec150mb(1:101)), W_zerovec(1:101))
% hold on
% quiver3((lat_value(1:101)), (long_value(1:101)), (z175mb_vec(1:101)), (UwindVec175mb(1:101)),(VwindVec175mb(1:101)), W_zerovec(1:101))
% hold on
% quiver3((lat_value(1:101)), (long_value(1:101)), (z200mb_vec(1:101)), (UwindVec200mb(1:101)),(VwindVec200mb(1:101)), W_zerovec(1:101))
toc

A guy by the name of Failmond is provided me with this, which suitably solves my query! Thanks to all!
zLevels = 5; %number of interpolated points between z50 and z75
nStation = 100; %number of (lat,long) pairs to interpolate
for i = 1:nStation %for nStation different (lat, long) pairs generate interp. values
% generate zQuery points between z50 and z75 for each station
zQuery = ((1:zLevels)/zLevels)*range([z50mb_vec(i) z75mb_vec(i)]) + z75mb_vec(i);
% use interp1 to interpolate about the Z axis for U component
U(i,1:N) = interp1([z50mb_vec(i) z75mb_vec(i)],[UwindVec50mb(i) UwindVec75mb(i)],zQuery);
% and for V component
V(i,1:N) = interp1([z50mb_vec(i) z75mb_vec(i)],[VwindVec50mb(i) VwindVec75mb(i)],zQuery);
end
% defining some color codes for each zLevel, otherwise the plot is a mess
% of colors
colorcode = ['r' 'g' 'b' 'm' 'c' 'r' 'g' 'b' 'm' 'c' 'r'];
for j = 1:nStation
for i = 1:zLevels
quiver3(lat_value(j), long_value(j), zQuery(i), U(j,i), V(j,i), 0, colorcode(i));
hold on;
end
end

Related

Creating a heatmap of the logistic map for different values of lambda in matlab

So I am trying to create a heatmap of the logistic map for lambda =2.5 till lambda 4, showing that some outcomes are more common than others as part of my thesis. However so far I did not came far. I plotted the logistic map, however the heatmap part is a bit of a hassle and I can't find how to do it. So, how do I create a heatmap using the coding that I have?
% Logistics Map
% Classic chaos example. Plots semi-stable values of
% x(n+1) = r*x(n)*(1-x(n)) as r increases to 4.
%
clear
scale = 1000; % determines the level of rounding
maxpoints = 200; % determines maximum values to plot
N = 3000; % number of "r" values to simulate
a = 2.5; % starting value of "r"
b = 4; % final value of "r"... anything higher diverges.
rs = linspace(a,b,N); % vector of "r" values
M = 500; % number of iterations of logistics equation
% Loop through the "r" values
for j = 1:length(rs)
r=rs(j); % get current "r"
x=zeros(M,1); % allocate memory
x(1) = 0.5; % initial condition (can be anything from 0 to 1)
for i = 2:M, % iterate
x(i) = r*x(i-1)*(1-x(i-1));
end
% only save those unique, semi-stable values
out{j} = unique(round(scale*x(end-maxpoints:end)));
end
% Rearrange cell array into a large n-by-2 vector for plotting
data = [];
for k = 1:length(rs)
n = length(out{k});
data = [data; rs(k)*ones(n,1),out{k}];
end
% Plot the data
figure(97);clf
h=plot(data(:,1),data(:,2)/scale,'b.');
set(h,'markersize',0.25)
ylim([0 1])
set(gcf,'color','w')
Thanks a lot in advance!

bin2mat running slow need a faster solution

I am using bin2mat function from matlab file exchange, for some reason it runs very slow. Is it possible to make it run faster or is there an alternative? I am trying: zC = bin2mat(s.X,s.Y,s.Z,xC,yC); I am not sure where it gets bogged down. I need to do this on point cloud data to calculate volume and such.
Here is the code:
function ZG = bin2mat(x,y,z,XI,YI,varargin)
% BIN2MAT - create a matrix from scattered data without interpolation
%
% ZG = BIN2MAT(X,Y,Z,XI,YI) - creates a grid from the data
% in the (usually) nonuniformily-spaced vectors (x,y,z)
% using grid-cell averaging (no interpolation). The grid
% dimensions are specified by the uniformily spaced vectors
% XI and YI (as produced by meshgrid).
%
% ZG = BIN2MAT(...,#FUN) - evaluates the function FUN for each
% cell in the specified grid (rather than using the default
% function, mean). If the function FUN returns non-scalar output,
% the output ZG will be a cell array.
%
% ZG = BIN2MAT(...,#FUN,ARG1,ARG2,...) provides aditional
% arguments which are passed to the function FUN.
%
% EXAMPLE
%
% %generate some scattered data
% [x,y,z]=peaks(150);
% ind=(rand(size(x))>0.9);
% xs=x(ind); ys=y(ind); zs=z(ind);
%
% %create a grid, use lower resolution if
% %no gaps are desired
% xi=min(xs):0.25:max(xs);
% yi=min(ys):0.25:max(ys);
% [XI,YI]=meshgrid(xi,yi);
%
% %calculate the mean and standard deviation
% %for each grid-cell using bin2mat
% Zm=bin2mat(xs,ys,zs,XI,YI); %mean
% Zs=bin2mat(xs,ys,zs,XI,YI,#std); %std
%
% %plot the results
% figure
% subplot(1,3,1);
% scatter(xs,ys,10,zs,'filled')
% axis image
% title('Scatter Data')
%
% subplot(1,3,2);
% pcolor(XI,YI,Zm)
% shading flat
% axis image
% title('Grid-cell Average')
%
% subplot(1,3,3);
% pcolor(XI,YI,Zs)
% shading flat
% axis image
% title('Grid-cell Std. Dev.')
%
% SEE also RESHAPE ACCUMARRAY FEVAL
% A. Stevens 3/10/2009
% astevens#usgs.gov
%check inputs
error(nargchk(5,inf,nargin,'struct'));
%make sure the vectors are column vectors
x = x(:);
y = y(:);
z = z(:);
if all(any(diff(cellfun(#length,{x,y,z}))));
error('Inputs x, y, and z must be the same size');
end
%process optional input
fun=#mean;
test=1;
if ~isempty(varargin)
fun=varargin{1};
if ~isa(fun,'function_handle');
fun=str2func(fun);
end
%test the function for non-scalar output
test = feval(fun,rand(5,1),varargin{2:end});
end
%grid nodes
xi=XI(1,:);
yi=YI(:,1);
[m,n]=size(XI);
%limit values to those within the specified grid
xmin=min(xi);
xmax=max(xi);
ymin=min(yi);
ymax=max(yi);
gind =(x>=xmin & x<=xmax & ...
y>=ymin & y<=ymax);
%find the indices for each x and y in the grid
[junk,xind] = histc(x(gind),xi);
[junk,yind] = histc(y(gind),yi);
%break the data into a cell for each grid node
blc_ind=accumarray([yind xind],z(gind),[m n],#(x){x},{NaN});
%evaluate the data in each grid using FUN
if numel(test)>1
ZG=cellfun(#(x)(feval(fun,x,varargin{2:end})),blc_ind,'uni',0);
else
ZG=cellfun(#(x)(feval(fun,x,varargin{2:end})),blc_ind);
end
It is slower on these two steps for one run it took:
ZG=cellfun(#(x)(feval(fun,x,varargin{2:end})),blc_ind); took 33 secs
blc_ind=accumarray([yind xind],z(gind),[m n],#(x){x},{NaN}); took 10 secs
You can change blc_ind = ... to
ZG=accumarray([yind xind],z(gind),[m n],#mean,NaN);
and delete other codes form here so the is no need to if numel(test)>1....

Undefined function 'qquadrature' for input arguments of type 'double'

I'm a new user of Matlab, can you please help:
I have the following code in an .M file:
`% free vibration of non-prismatic Euler beams with or without axial load
%using differential quadrature method
clc;
ne=50;
n=ne+1;
nn=2*n;
no=4;
m=zeros(n,1);
x=zeros(n,1);
xi=zeros(n,1);
c=zeros(n,n,no);
d=zeros(n+4,n+4);
e=zeros(n+4,n+4);
z=zeros(n+4,1);
f=zeros(n+4,1);
alp=zeros(n,n);
bet=zeros(n,n);
zz=zeros(n,1);
ki=zeros(n,n);
eta=zeros(n,n);
const=1.0;
l=12;
ymod=200e09;
rho=7800;
format long;
for i=1:n
xi(i)=0.5*(1-cos((i-1)*pi/ne));
%mi(i)=0.000038*(1-xi(i)^2/2);
ar(i)=1/rho;
mi(i)=0.000038;
ki(i,i)=ymod*mi(i);
end
c=qquadrature(xi,n,no);
%c = harquadrature(xi,n,no)
for i = 1:n
alp(i,i) = 0;
bet(i,i) = 0;
for j = 1:n
alp(i,i) = alp(i,i)+c(i,j,1)*ki(j,j)/l;
bet(i,i) = bet(i,i)+c(i,j,2)*ki(j,j)/l^2;
end
end
d=zeros(n+4,n+4);
% free vibration of the beam
% axial load on the beam t=+ if it is compressive t=- if it is tensile
% weight of the beam / unit length
t=520895.0;
d(1:n,1:n)=2.0*alp*c(:,:,3)/l^3+bet*c(:,:,2)/l^2+ki*c(:,:,4)/l^4+eta+t*c(:,:,2)/l^2;
% boundary conditions
% clamped - free
% d(n+1,1)=1.0;
% d(n+2:n+2,1:n)=alp(n,n)*c(n,1:n,2)/l^2+ki(n,n)*c(n,1:n,3)/l^3+t*c(n,1:n,1)/l;
% d(n+3:n+3,1:n)=c(1,1:n,1)/l;
% d(n+4:n+4,1:n)=ki(n,n)*c(n,1:n,2)/l^2;
% d(1,n+1)=1.0;
% for i=1:n
% d(i,n+2)=d(n+2,i);
% d(i,n+3)=d(n+3,i);
% d(i,n+4)=d(n+4,i);
% end
% pinned - pinned
d(n+1,1)=1.0;
d(n+2:n+2,1:n)=ki(n,n)*c(n,1:n,2)/l^2;
d(n+3:n+3,1:n)=ki(1,1)*c(1,1:n,2)/l^2;
d(n+4,n)=1.0;
d(n,n+4)=1.0;
d(1,n+1)=1.0;
d(n+4,n)=1.0;
for i = 1:n
d(i,n+2)=d(n+2,i);
d(i,n+3)=d(n+3,i);
end
e=zeros(n+4,n+4);
for i=1:n
e(i,i)=rho*ar(i);
end
z=d\e;
[ev,euv]=eig(z);
for i=1:n
zz(z)=ev(i,5);
end
omega=sqrt(1/euv(5,5));
sprintf(' natural frequency\n')
omega;
figure(1);
plot(xi,zz)
xlabel(' x/L ')
ylabel(' z')
title (' fundamental mode shape ')`
I have stored this file (Untitled.M) in the normal Matlab path, and therefore I'm assuming that Matlab will read the function when it's starting and that this function therefore should be available to use.
Then I am trying to run this single M-files.
But "Undefined function 'qquadrature' for input arguments of type 'double'" message appears..
Can somebody show me where's the problem and how ti fix it?
Thankyou..

Reconstructing time series from FFT in MATLAB

I am trying to reconstruct the sunspots signal from the FFT, the time series and periodogram are in the following site http://www.mathworks.com/help/matlab/examples/using-fft.html . I wrote the following code but the result were not similar to original wave:
YY=Y(1:floor(n/2))
% magnitude
mag_fft = 2*abs(YY)/length(Y);
% phase angle
ang_fft = angle(YY);
[new_mag,new_i]=sort(mag_fft,'descend');
new_ang=ang_fft(new_i);
new_freq=freq(new_i)
wave=zeros(1,length(YY));
wave=new_mag(1);
t=1:length(YY)
for(i=1:70)
wave=wave+new_mag(i).*sin(2*pi*new_freq(i)*t+new_ang(i));
end
wave=wave-mag_fft(1)
figure;plot(year(t),wave,'-b')
hold on;plot(year(t),relNums(t),'-r')
any ideas?
%http://www.mathworks.com/help/matlab/examples/using-fft.html
% sunspots
% sunspots have period of 10 years
%%
clc;clear all;close all;
load sunspot.dat
year=sunspot(:,1);
relNums=sunspot(:,2);
figure;plot(year,relNums)
title('Sunspot Data')
plot(year(1:50),relNums(1:50),'b.-');
yfft = fft(relNums);%figure;plot(ifft(yfft)-data1d,'r')
%yfft = fft(data1d); iyfft=ifft(yfft);
[sum(relNums) yfft(1)]
yfft(1)=[]; % we grid rid of the first value as it corresponeding to zero frequency.
N=length(yfft)+1;
yfft=yfft.*2./N;
%%
power_fft = abs(yfft);power1_fft = sqrt(yfft.*conj(yfft));
figure;plot(power_fft,'-b');hold on;plot(power_fft,'rO')
ang_fft = angle(yfft);real_fft= real(yfft);imag_fft= imag(yfft);
figure;plot(real_fft);hold on;plot(imag_fft,'-r')
figure;plot(angle(yfft))
ph = (180/pi)*unwrap(ang_fft); % phase in degrees
% Now the total length of the per and all other powers should be N-1 because there is no
% more corresponding poweres and phases, and the number of frequencies before the nequiest is
Nneq=length(N./(1:N/2));
Nm1=N-1; per=N./(1:Nm1); freq=1./per;
[per'/12 power_fft(1:Nm1)/100 ] % so as to display the period in years
%% ytyt
ndat=length(relNums);
x=0:ndat-1;
sumharmony1(1:Nneq,1:ndat)=0;
sumharmony2(1:Nneq,1:ndat)=0;
for i=1:Nneq
% those two forms are equal, the last one is called the cos form.
% sumharmony1(i,:)=sumharmony1(i,:)+real_fft(i)*cos(2*pi*x/(per(i)))- imag_fft(i)*sin(2*pi*x/(per(i)));
sumharmony1(i,:)=sumharmony1(i,:)+power_fft(i)*cos(2*pi*x./(per(i))+ang_fft(i));
end
y1 =sum(relNums)/N+ sum(sumharmony1);
%y2 =sum(tmp)/N+ sum(sumharmony2);
figure;plot(relNums);hold on; plot( y1, 'r');
figure;plot((relNums-y1')) % However, the excellent results, we couldnot yet reach to the that of the built in function ifft.
figure;plot(relNums(1:100),'-ob');hold on; plot( y1(1:100), 'r');
% note that we multiply by 2 because of using the window hanning.enter code here

MATLAB: Plotting on one axes with a loop: solid line & legend

I have two distinct problems, but they're posted together because I believe the solutions are related. I'm testing Newton's and secant methods (each of which is implemented with a loop) and plotting the results versus computing time on the same axes to compare them. I want the (discrete) Newton's method results to be connected by a blue line and the secant method results by a red line. These lines, in turn, are annotated by a corresponding legend. This is not happening because each and every point on the plot seems to be considered at individual object because they were individually created. And the legend command brings up two blue asterisks instead a blue one and a red one (I wish I could post my plot here, but I don't have the image privilege yet.)
Here's my abbreviated code:
f = (x) % define function
figure
hold on
%% Newton
tic
while % terminating condition
% [Newtons method]
t = toc;
plot(t,log(abs(f(z)),'b*-')
end
%% Secant
tic
while % terminating condition
% [secant method]
t = toc;
plot(t,log(abs(f(z)),'r*-')
end
legend('Newton''s','Secant')
Needless to day, the '-' in the linespec doesn't do anything because only a point is being plotted, not a line. I know I could make a line plot with each iteration with something like plot([t_old t],[log(abs(f(z_old) log(abs(f(z)]), but that isn't ideal, not least because log(abs(f(z_old))) would have to be reevaluated each time. Besides, that would not solve the problem with the legend.
I think both problems will be solved if I can get MATLAB to understand that I'm trying to create just two objects on the axes, one blue line and one red line. Thank you.
If you don't want to store the x/y data in a vector and then replot the entire vector you could just add to the plotting line using code like this:
hNewton = [];
while % terminating condition
% [Newtons method]
t = toc;
if isempty(hNewton)
hNewton = plot(t,log(abs(f(z))),'b*-'); % First time through plot and save the line handle
else
% On all subsequent passes, just add to the lines X/Y data
set(hNewton,'XData',[get(hNewton,'XData') t]);
set(hNewton,'YData',[get(hNewton,'YData') log(abs(f(z)))]);
end
end
Since there are now only 2 lines, the legend works as expected.
Alternatively, you could put the code to add data to an existing line in a function
function hLineHandle = AddToLine( hLineHandle, xData, yData, lineStyle )
% AddToLine - Add data to a plotted line
if isempty(hLineHandle)
hLineHandle = plot(xData,yData, lineStyle);
else
set(hLineHandle,'XData',[get(hLineHandle,'XData') xData]);
set(hLineHandle,'YData',[get(hLineHandle,'YData') yData]);
end
end
Which makes the code in the main script/function a lot cleaner.
hNewton = [];
while % terminating condition
% [Newtons method]
t = toc;
hNewton = AddToLine(hNewton,t, log(abs(f(z))),'b*-' );
end
You can use line object, for example:
f = (x) % define function
figure
hold on
lHandle1 = line(nan, nan); %# Generate a blank line and return the line handle
lHandle2 = line(nan, nan); %# Generate a blank line and return the line handle
%% Newton
tic
while % terminating condition
% [Newtons method]
t = get(lHandle1, 'XData');
Y1 = get(lHandle1, 'YData');
t = toc;
Y1 = [Y1 log(abs(f(z)];
set(lHandle1, 'XData', t, 'YData', Y1, 'LineWidth', 2 ,'Color' , [0 1 0]);
end
%% Secant
tic
while % terminating condition
% [secant method]
t = get(lHandle2, 'XData');
Y2 = get(lHandle2, 'YData');
t = toc;
Y2 = [Y2 log(abs(f(z)];
set(lHandle2, 'XData', t, 'YData', Y2, 'LineWidth', 2 ,'Color' , [1 0 0]);
end
legend('Newton''s','Secant')
Good example of only showing the relevant parts of your code to ask a question. The others have explained tricks to have the legend behave as you want. I would go for a different solution, by saving your measurements in a vector and doing the plots after the loops. This has 2 advantages: you do not have to do the tricks with the legend, but more importantly, you are not doing a plot inside your loop, which potentially takes a lot of time. I would guess that your timing is dominated by the plotting, so the influence of your algorithm will hardly show up in the results. So change your code to something like this (untested):
f = (x) % define function
% preallocate plenty of space
[t_newton, t_secant, f_newton, f_secant] = deal(nan(1, 1000));
%% Newton
tic;
i = 1;
while % terminating condition
% [Newtons method]
f_newton(i) = current_result;
t_newton(i) = toc;
i = i + 1;
end
%% Secant
tic;
i = 1;
while % terminating condition
% [secant method]
f_secant(i) = current_result;
t_secant(i) = toc;
i = i + 1;
end
% trim NaNs (not really needed, not plotted anyhow)
t_newton = t_newton(isfinite(t_newton));
f_newton = f_newton(isfinite(f_newton));
t_secant = t_secant(isfinite(t_secant));
f_secant = f_secant(isfinite(f_secant));
% do the plot
semilogy(t_newton, abs(f_newton), t_secant, abs(f_secant))
legend('Newton''s','Secant')