I'm working on bisection method which I wrote by myself. The following code works fine - it displays correct results(Tested on x^2-25) and it gave correct results. But that's not all what I wanted to realize.I need draw a plot displaying all correct results on it.
As I told - I took expression
x^2-25
, and results are
5 and -5
Now, I need to draw parabola and display results.
My Code
function [] = bisectionWindow()
clc;
f = #(x) x^2-25; % specified function
a=5;
b=6;
e=0.0001;
syms x;
% Main loop
while abs(b-a)>e
c=(b+a)/2;
if sign(f(c)) == sign(f(a))
a=c;
else
b=c;
end
end
disp(['Answer x='])
solve(f(x))
%note: ans displays because of 'sign' operator presence
My Attempt to draw plot
function [] = checkWin(a,b,x)
%draws plot
Limits = [a b];
len = b-a;
for i=1:len
x = X(i);
y=x^2-25;
%y=0.5*x^3-2*x^2+1;
figure(1),clf,hold on
fplot('x^2-25',Limits),grid
plot(x,y,'o')
end
end
UPD: To clear some things up
I understand how to draw a plot. My objective is:
Show the plot
Show results as o's on it
The problem is - this should be unique code (as for example i took parabola, but let's take another function which has only one result) and it should execute things metioned above. So basically this is why i'm working on.
There's 2 options:
Modify existing code - which i dunno how
Rewrite - no ideas how.
I'm stuck for a long time I guess.
Thanks for Advices.
I don't get why you need the loop in your code. The following script works fine and gives the same result as yours:
f = #(x) x^2-25; % specified function
disp(['Answer x='])
disp(solve(f(x)))
You can plot your function by typing ezplot(f):
Typing ezplot(f,[-5,5]) would plot function with x between -5 and 5
If you want to use plot function, you need to rewrite your function as:
f = #(x) x.^2-25
This is because ^2 operation is regarded as multiplication of matrix by itself that is inapplicable to vectors, whereas .^2 is squaring of each matrix element.
Then, you need to create two vectors with x and y data and use plot function:
x = -10:0.1:10;
y = f(x);
plot(x,y), grid on
where grid on provides your plot with gridlines. There are many other plot options that you can use to customize your graph. You can find them here
UPD. Modified code with comments:
f = #(x) x.^2-25; %//specified function
disp(['Answer x='])
q = solve(f); %//-5 and 5 would be in one vector
disp(q) %//display -5 and 5
h = ezplot(f,[-10,10]); %//plot f(x) from -10 to 10
grid on; %//add grid to plot
set(h,'LineWidth',3); %//set line width to 3px
hold on;%//prevent the current graph from being replaced
plot(q,f(q),'ro','MarkerSize',10,'LineWidth',3)
%//plot two O-s at -5 and 5. Also, make O-s 10px in width and 3px thick
hold off;
This yields:
Related
I want to plot the error in the composite simpson's rule
... Here is my code
for r=1:100
n=600;
a=0;
b=5;
err=[];
x=zeros(1,n);
f=#(x)cos(x)+x.^2;
h=(b-a)/n;
xexact=integral(f,a,b);
p=0;
q=0;
for i=1:n
x(i)=a+(i-1)*h;
end
for i=1:n-1
p=p+2*(f(x(i)))+4*(f(x(i)+h/2));
end
x=(h/6)*(f(a)+f(a+h/2)+p+f(b))
err(end+1)=x-xexact;
plot(r,x,'*')
end
When I run the code I get one point in the plot .. I want to have all the points ploted in the plot , How to do that ?
thanks
The simplest fix is to put hold on; before your code here and hold off; after it. That way, each of your calls to plot will add a point to an existing plot, rather than creating a new one. (What is happening at the moment is that you are plotting a point with r=1, and then replacing that plot with one for r=2, etc. So what you end up with is a plot showing just what happens for r=100.)
You might do better, though, to build up an array containing your xs as your loop runs, and then do a single plot(1:100, xs, '*'); at the end.
There is a conceptual problem in your code: you want to plot the x variable which is not function of r and that will never change for each r value. So you will plot a row of r dots with a fixed x value.
Moreover I think that, if possible, is good to avoid for loops in Matlab because there are more powerful and optimized ways to do things that you do with them. For example I will write this code in this form:
function [x, err] = compSimp(n, a, b)
err = [];
x=zeros(1,n+1);
f=#(x)cos(x)+x.^2;
h=(b-a)/n;
xexact=integral(f,a,b);
% x_0 = a
x(1)=a;
% x_n = b
x(n+1)=b;
p=0;
% x_j = a + j*h with j = 1, 2, ... , n-2, n-1 (no need to set again x_0 and x_n)
x(2:n)= a + (1:(n-1))*h;
% summations
for i=2:2:n
p = p + 2*(f(x(i+1))) + 4*(f(x(i)));
end
x=(h/3)*(f(a) + p + f(b));
err(end+1)=x-xexact;
end
As you can see i've changed some code logic, following wikipedia for theory. If you want, you can also change code so that you can pass a custom f function to the compSimp function.
The following equation is given.
I know that i need to break the 2 second order ODE's into 4 first order ODE's. This i what i've got. Ive first introduced the new variable u and in the bottom of the picture i've written my matlab function that i use with ODE45.
Now the problem is that im supposed to get a parabola shaped figure(blue line) but that is not what I am getting.
I've gone through my code a thousand times with no results. Can detect any errors in my function?
main program
global g H R alfa
alfa=pi/2;
g = 20.0;
R = 1;
H=2.3;
k = 0:0.01:2;
[T,Y] = ode45(#fspace,k,[H 0 0 0]);
plot(T,Y(:,1))
hold on
fi= 0:2*pi/60:2*pi;
xx =R*cos(fi);
yy =R*sin(fi);
plot(xx,yy)
function f
function f = fspace(x,u)
global g R H alfa G
G=(g*R.^2)./((R+H).^2);
f = [u(2) G*cos(alfa)-g*((R.^2)/u(1).^2)+u(1)*u(4)^2 u(4) (G*sin(alfa)-2*u(2)*u(4))/u(1)];
I think your problem lies with those lines:
fi= 0:2*pi/60:2*pi;
xx =R*cos(fi);
yy =R*sin(fi);
plot(xx,yy)
You are plotting a circle of radius R. phi is part of the solution from the ode solver, so you should have instead:
plot(R*cos(Y(:,3)),R*sin(Y(:,3)))
but that will always give you a circle of radius R, never a parabola. Or is the parabola meant to refer to plot(T,Y(:,1)).
The equations and the code appear to be correct as far as I can see. Replacing your definition of phi by Y(:,3) gives essentially the same plot, except that the resolution is less. As I said, you'll always get a circle by plotting yy vs xx. You need to clarify what the parabola should refer to.
Generate a plot showing the graphs of
y=(2*a+1)*exp(-x)-(a+1)*exp(2*x)
in the range x ∈ <-2, 4> for all integer values of a between -3 and 3
I know how to make typical plot for 2 values and set a range on the axes, but how to draw the graph dependent on the parameter a?
To elaborate on Ben Voigt's comment: A more advanced technique would be to replace the for-loop with a call to bsxfun to generate a matrix of evaluations of M(i,j) = f(x(i),a(j)) and call plot with this matrix. Matlab will then use the columns of the matrix and plot each column with individual colors.
%%// Create a function handle of your function
f = #(x,a) (2*a+1)*exp(-x)-(a+1)*exp(2*x);
%%// Plot the data
x = linspace(-2, 4);
as = -3:3;
plot(x, bsxfun(f,x(:),as));
%%// Add a legend
legendTexts = arrayfun(#(a) sprintf('a == %d', a), as, 'uni', 0);
legend(legendTexts, 'Location', 'best');
You could also create the evaluation matrix using ndgrid, which explicitly returns all combinations of the values of x and as. Here you have to pay closer attention on properly vectorizing the code. (We were lucky that the bsxfun approach worked without having to change the original f.)
f = #(x,a) (2*a+1).*exp(-x)-(a+1).*exp(2*x); %// Note the added dots.
[X,As] = ndgrid(x,as);
plot(x, f(X,As))
However for starters, you should get familiar with loops.
You can do it using a simple for loop as follows. You basically loop through each value of a and plot the corresponding y function.
clear
clc
close all
x = -2:4;
%// Define a
a = -3:3;
%// Counter for legend
p = 1;
LegendText = cell(1,numel(a));
figure;
hold on %// Important to keep all the lines on the same plot.
for k = a
CurrColor = rand(1,3);
y= (2*k+1).*exp(-x)-(k+1).*exp(2.*x);
plot(x,y,'Color',CurrColor);
%// Text for legend
LegendText{p} = sprintf('a equals %d',k);
p = p+1;
end
legend(LegendText,'Location','best')
Which gives something like this:
You can customize the graph as you like. Hope that helps get you started!
i have created a function that represents a triangle sign.
this function does not work on vectors. i want to evaluate a vector x:
x=[-2:0.01:2]
and save the answer in vector y, for this purpose i came up with the following code:
for i=1:400, y(i) = triangle(x(i))
after i got the ans i plotted is using plot. in this case it worked ok but i am interested on observing the influence of time shifting and shrinking so when i try to use lets say:
for i=1:200, y(i) = triangle(x(2*i))
i get a vector y not the same length as vector x and i cant even plot them... is there any easy way to achieve it? and how should i plot the answer?
here is my function:
function [ out1 ] = triangle( input1 )
if abs(input1) < 1,
out1 = 1 - abs(input1);
else
out1 = 0;
end
end
y is a different length in each for loop because each loop iterated a different number of times. In the example below, I use the same for loops and plot y2 with the corresponding values of x. i is already defined in matlab so I've changed it to t in the example below.
clear all
x=[-2:0.01:2];
for t=1:400
y(t) = triangle(x(t));
end
for t=1:200
y2(t) = triangle(x(2*t));
end
Or, if you want to see y2 plotted over the same range you can increase the size of x:
clear all
x=[-2:0.01:8];
for t=1:400
y(t) = triangle(x(t));
end
for t=1:400
y2(t) = triangle(x(2*t));
end
plot(x(1:length(y)),y,'r')
hold on
plot(x(1:length(y2)),y2,'b')
for an implicit equation(name it "y") of lambda and beta-bar which is plotted with "ezplot" command, i know it is possible that by a root finding algorithm like "bisection method", i can find solutions of beta-bar for each increment of lambda. but how to build such an algorithm to obtain the lines correctly.
(i think solutions of beta-bar should lie in an n*m matrix)
would you in general show the methods of plotting such problem? thanks.
one of my reasons is discontinuity of "ezplot" command for my equation.
ok here is my pic:
alt text http://www.mojoimage.com/free-image-hosting-view-05.php?id=5039TE-beta-bar-L-n2-.png
or
http://www.mojoimage.com/free-image-hosting-05/5039TE-beta-bar-L-n2-.pngFree Image Hosting
and my code (in short):
h=ezplot('f1',[0.8,1.8,0.7,1.0]);
and in another m.file
function y=f1(lambda,betab)
n1=1.5; n2=1; z0=120*pi;
d1=1; d2=1; a=1;
k0=2*pi/lambda;
u= sqrt(n1^2-betab^2);
wb= sqrt(n2^2-betab^2);
uu=k0*u*d1;
wwb=k0*wb*d2 ;
z1=z0/u; z1_b=z1/z0;
a0_b=tan(wwb)/u+tan(uu)/wb;
b0_b=(1/u^2-1/wb^2)*tan(uu)*tan(wwb);
c0_b=1/(u*wb)*(tan(uu)/u+tan(wwb)/wb);
uu0= k0*u*a; m=0;
y=(a0_b*z1_b^2+c0_b)+(a0_b*z1_b^2-c0_b)*...
cos(2*uu0+m*pi)+b0_b*z1_b*sin(2*uu0+m*pi);
end
fzero cant find roots; it says "Function value must be real and finite".
anyway, is it possible to eliminate discontinuity and only plot real zeros of y?
heretofore,for another function (namely fTE), which is :
function y=fTE(lambda,betab,s)
m=s;
n1=1.5; n2=1;
d1=1; d2=1; a=1;
z0=120*pi;
k0=2*pi/lambda;
u = sqrt(n1^2-betab^2);
w = sqrt(betab^2-n2^2);
U = k0*u*d1;
W = k0*w*d2 ;
z1 = z0/u; z1_b = z1/z0;
a0_b = tanh(W)/u-tan(U)/w;
b0_b = (1/u^2+1/w^2)*tan(U)*tanh(W);
c0_b = -(tan(U)/u+tanh(W)/w)/(u*w);
U0 = k0*u*a;
y = (a0_b*z1_b^2+c0_b)+(a0_b*z1_b^2-c0_b)*cos(2*U0+m*pi)...
+ b0_b*z1_b*sin(2*U0+m*pi);
end
i'd plotted real zeros of "y" by these codes:
s=0; % s=0 for even modes and s=1 for odd modes.
lmin=0.8; lmax=1.8;
bmin=1; bmax=1.5;
lam=linspace(lmin,lmax,1000);
for n=1:length(lam)
increment=0.001; tolerence=1e-14; xstart=bmax-increment;
x=xstart;
dx=increment;
m=0;
while x > bmin
while dx/x >= tolerence
if fTE(lam(n),x,s)*fTE(lam(n),x-dx,s)<0
dx=dx/2;
else
x=x-dx;
end
end
if abs(real(fTE(lam(n),x,s))) < 1e-6 %because of discontinuity some answers are not correct.%
m=m+1;
r(n,m)=x;
end
dx=increment;
x=0.99*x;
end
end
figure
hold on,plot(lam,r(:,1),'k'),plot(lam,r(:,2),'c'),plot(lam,r(:,3),'m'),
xlim([lmin,lmax]);ylim([1,1.5]),
xlabel('\lambda(\mum)'),ylabel('\beta-bar')
you see i use matrix to save data for this plot.
![alt text][2]
because here lines start from left(axis) to rigth. but if the first line(upper) starts someplace from up to rigth(for the first figure and f1 function), then i dont know how to use matrix. lets improve this method.
[2]: http://www.mojoimage.com/free-image-hosting-05/2812untitled.pngFree Image Hosting
Sometimes EZPLOT will display discontinuities because there really are discontinuities or some form of complicated behavior of the function occurring there. You can see this by generating your plot in an alternative way using the CONTOUR function.
You should first modify your f1 function by replacing the arithmetic operators (*, /, and ^) with their element-wise equivalents (.*, ./, and .^) so that f1 can accept matrix inputs for lambda and betab. Then, run the code below:
lambda = linspace(0.8,1.8,500); %# Create a vector of 500 lambda values
betab = linspace(0.7,1,500); %# Create a vector of 500 betab values
[L,B] = meshgrid(lambda,betab); %# Create 2-D grids of values
y = f1(L,B); %# Evaluate f1 at every point in the grid
[c,h] = contour(L,B,y,[0 0]); %# Plot contour lines for the value 0
set(h,'Color','b'); %# Change the lines to blue
xlabel('\lambda'); %# Add an x label
ylabel('$\overline{\beta}$','Interpreter','latex'); %# Add a y label
title('y = 0'); %# Add a title
And you should see the following plot:
Notice that there are now additional lines in the plot that did not appear when using EZPLOT, and these lines are very jagged. You can zoom in on the crossing at the top left and make a plot using SURF to get an idea of what's going on:
lambda = linspace(0.85,0.95,100); %# Some new lambda values
betab = linspace(0.95,1,100); %# Some new betab values
[L,B] = meshgrid(lambda,betab); %# Create 2-D grids of values
y = f1(L,B); %# Evaluate f1 at every point in the grid
surf(L,B,y); %# Make a 3-D surface plot of y
axis([0.85 0.95 0.95 1 -5000 5000]); %# Change the axes limits
xlabel('\lambda'); %# Add an x label
ylabel('$\overline{\beta}$','Interpreter','latex'); %# Add a y label
zlabel('y'); %# Add a z label
Notice that there is a lot of high-frequency periodic activity going on along those additional lines, which is why they look so jagged in the contour plot. This is also why a very general utility like EZPLOT was displaying a break in the lines there, since it really isn't designed to handle specific cases of complicated and poorly behaved functions.
EDIT: (response to comments)
These additional lines may not be true zero crossings, although it is difficult to tell from the SURF plot. There may be a discontinuity at those lines, where the function shoots off to -Inf on one side of the line and Inf on the other side of the line. When rendering the surface or computing the contour, these points on either side of the line may be mistakenly connected, giving the false appearance of a zero crossing along the line.
If you want to find a zero crossing given a value of lambda, you can try using the function FZERO along with an anonymous function to turn your function of two variables f1 into a function of one variable fcn:
lambda_zero = 1.5; %# The value of lambda at the zero crossing
fcn = #(x) f1(lambda_zero,x); %# A function of one variable (lambda is fixed)
betab_zero = fzero(fcn,0.94); %# Find the value of betab at the zero crossing,
%# using 0.94 as an initial guess