Why use 'fplot' to plot functions when we can use 'plot'? I can't understand
With plot you have to manually define the x values and compute the corresponding y given by the function.
>> x = 0:.01:1;
>> y = sin(10*x);
>> plot(x,y,'.-')
With fplot you define the function generically, for example as an anonymous function; pass a handle to that function; and let Matlab choose the x values and compute the y values. As an example, take a difficult function:
>> f = #(x) sin(1/x);
Assume we want to plot that between 0.01 and 1:
>> lims = [.01 1];
>> fplot(f, lims, '.-')
See how Matlab does a pretty good job choosing closer x values in the left area, where the function becomes wilder.
Related
Thanks to the fimplicit function, I can plot implicit functions with 2 variables (x,y).
For a particular x, there is a particular y which makes F_imp=0. Now take this y as an input to another function g which produces z.
How can I plot x,z for x's between [0.1 1]?
Of course, I could have found the inverse of g(y) and replace in F(x,y) but there is not closed form of inverse of g(y).
Below are the functions I am dealing with:
F_imp = #(x,y) log(100-x*90) - x*log(10+0.9*y) - (1-x)*log(100-0.1*y);
fimplicit(F_imp,[0.1 1 0 100])
g=0.1*log(10+y*0.9)+0.9*log(100-0.1*y)
You can use the ImplicitFunctionLine object, which is an optional return value of the fimplicit() function. In this way you get access to the correspondent x and y data.
Then just use y to calculate g and plot g against x:
clear;
F_imp = #(x,y) log(100-x*90) - x*log(10+0.9*y) - (1-x)*log(100-0.1*y);
fp = fimplicit(F_imp,[0.1 1 0 100]); %returns the ImplicitFunctionLine object
%get calculated data points from the object
x = fp.XData;
y = fp.YData;
%set y as input for g
g=0.1*log(10+y*0.9)+0.9*log(100-0.1*y);
plot(x, g);
grid minor;
Here is the result:
As far as I can tell, no one has asked this.
I've been asked to compute the double integral of a function, and also the same double integral but with the order of integration swapped (i.e: first integrate for dydx, then dxdy). Here is my code:
%Define function to be integrated
f = #(x,y) y^2*cos(x);
%First case. Integration order: dydx
ymin = #(x) cos(x);
I = integral2(f,ymin,1,0,2*pi)
%Second case. Integration order: dxdy
xmin = #(y) asin(y)+2*pi/2;
xmax = #(y) asin(y)-pi/2;
B = integral2(f,xmin,xmax,-1,1)
The error I'm getting is this:
Error using integral2 (line 71)
XMIN must be a floating point scalar.
Error in EngMathsA1Q1c (line 5)
I = integral2(f,ymin,1,0,2*pi)
I'm sure my mistake is something simple, but I've never used Integral2 before and I'm lost for answers. Thank you.
Per the integral2 documentation, the variable limits are given as the second pair of limits. So your first integral should be
% Define function to be integrated
f = #(x,y) y.^2.*cos(x);
% First case. Integration order: dydx
ymin = #(x) cos(x);
I = integral2(f,0,2*pi,ymin,1);
The set of constant limits always goes first, and Matlab assumes the first argument of f is associated with the first set of limits while the second argument of f is associated with the second set of limits, which may be a function of the first argument.
I point out that second part because if you wish to switch the order of integration, you also need to switch the order of the inputs of f accordingly. Consider the following example:
fun = #(x,y) 1./( sqrt(2*x + y) .* (1 + 2*x + y).^2 )
A nice little function that is not symmetric in its arguments (i.e., fun(x,y) ~= fun(y,x)). Let's integrate this over an elongated triangle in the first quadrant with vertices at (0,0), (2,0), and (0,1). Then integrating with dA == dy dx, we have
>> format('long');
>> ymax = #(x) 1 - x/2;
>> q = integral2(fun,0,2,0,ymax)
q =
0.220241017339352
Cool. Now let's integrate with dA == dx dy:
>> xmax = #(y) 2*(1-y);
>> q = integral2(fun,0,1,0,xmax)
q =
0.241956050772765
Oops, that's not equal to the first calculation! That's because fun is defined with x as the first argument and y as the second, but the previous call to integral2 is implying that y is the first argument to fun, and it has constant limits of 0 and 1. How do we fix this? Simply define a new function that flips the arguments:
>> fun2 = #(y,x) fun(x,y);
>> q = integral2(fun2,0,1,0,xmax)
q =
0.220241017706984
And all's right with the world. (Although you may notice small differences between the two correct answers due to the error tolerances of integral2, which can be adjusted via options per the documentation.)
The error states that you can't pass in a function for the limits of integration. You need to specify a scalar value for each limit of integration. Also, there are some errors in the dimensions/operations of the function. Try this:
%Define function to be integrated
f = #(x,y) y.^2.*cos(x);%changed to .^ and .*
%First case. Integration order: dydx
%ymin = #(x) cos(x);
I = integral2(f,-1,1,0,2*pi)%use scalar values for limits of integration
%Second case. Integration order: dxdy
%xmin = #(y) asin(y)+2*pi/2;
%xmax = #(y) asin(y)-pi/2;
B = integral2(f,0,2*pi,-1,1)% same issue, must use scalars
I've already searched it here but I couldn't found it the way I was looking for.
I kind managed to do it using Symbolic Math but I don't understand it quite well. For exemple, after doing that
syms y x
ezplot(-y + x + 1 == 0)
i get a nice graph, but can I use this expression later to calculate its value? like, first I want to plot -y + x + 1 == 0 and at another moment I want to solve f(3) for exemple, where f(x) = x + 1 (same equation).
I know I can write a function to do that, but as a function I don't know how to plot it. In the other way, I know how to plot using symbolic math, but I don't know how to calculate it after.
I'm writing a PLA algorithm and them I need to generate the 'a', 'b' 'c' for the equation, that why I need to know how to plot and solve in a "systematic code" way, and not typing one by one.
Thanks in advance!
The equation you gave us is a straight line, so a polynomial. The coefficients are y= -b/a*x -c/a.
% ay + bx + c = 0 reads y = -b/a*x - c/a*1
a = -1;
b = 1;
c = 1;
p = [-b/a, -c/a]; % polynomial representing your equation
% plot like this
x = linspace(-2,2, 50);
figure
plot(x, polyval(p,x)) % evaluate polynomial p at the positions x
% find the solution
roots(p) # -1
If you need or want to use ezplot, you can put the polyval-expression in an inline function and you can call ezplot with that handle:
f = #(x) polyval(p, x); % the function
ezplot(f)
Just define f to be a function of the symbolic variable x:
>> syms x
>> f = x+1;
Then you can use f as the input to ezplot:
>> ezplot(f)
which produces the graph
On the other hand, to solve the equation f(x)=0 use solve as follows:
>> solve(f)
ans =
-1
ezplot and solve can be used with string inputs as well, but the string has to be different in either case. To plot the graph:
>> ezplot('x+1');
To solve the equation:
>> solve('x+1=0')
ans =
-1
In MATLAB, if I want to plot density of a variable V I have to do
[x, y] = ksdensity(V);
plot (y, x);
If I do plot(ksdensity(V)), it only plots x and not x Vs y.
Is there an easier alternative to give ksdensity() as an argument to plot() and do the same job as plot(y, x)?
You can refactor it into a function that takes in V and plots y vs x:
function h = plot_ksdensity(V, varargin)
[x, y] = ksdensity(V);
h = plot (y, x, varargin{:});
end
using varargin means you will still have access to plot options like colours. hold on will also still work because this just calls the regular plot function.
Unfortunately no. If you don't specify explicitly the outputs, a function will return always the leftmost one from output parameter list. To convince yourself about that, create the function ftest() somewhere in your MATLAB path:
function [x, y] = ftest( )
x = 1;
y = 2;
end
then call it in the Command Window without specifying the outputs
>> ftest()
ans =
1
I've got function values in a vector f and also the vector containing values of the argument x. I need to find the define integral value of f. But the argument vector x is not uniform. Is there any function in Matlab that deals with integration over non-uniform grids?
Taken from help :
Z = trapz(X,Y) computes the integral of Y with respect to X using
the trapezoidal method. X and Y must be vectors of the same
length, or X must be a column vector and Y an array whose first
non-singleton dimension is length(X). trapz operates along this
dimension.
As you can see x does not have to be uniform.
For instance:
x = sort(rand(100,1)); %# Create random values of x in [0,1]
y = x;
trapz( x, y)
Returns:
ans =
0.4990
Another example:
x = sort(rand(100,1)); %# Create random values of x in [0,1]
y = x.^2;
trapz( x, y)
returns:
ans =
0.3030
Depending on your function (and how x is distributed), you might get more accuracy by doing a spline interpolation through your data first:
pp = spline(x,y);
quadgk(#(t) ppval(pp,t), [range])
That's the quick-n-dirty way. Ther is a faster and more direct approach, but that is fugly and much less transparent:
result = sum(sum(...
bsxfun(#times, pp.coefs, 1./(4:-1:1)) .*... % coefficients of primitive
bsxfun(#power, diff(pp.breaks).', 4:-1:1)... % all 4 powers of shifted x-values
));
As an example why all this could be useful, I borrow the example from here. The exact answer should be
>> pi/2/sqrt(2)*(17-40^(3/4))
ans =
1.215778726893561e+00
Defining
>> x = [0 sort(3*rand(1,5)) 3];
>> y = (x.^3.*(3-x)).^(1/4)./(5-x);
we find
>> trapz(x,y)
ans =
1.142392438652055e+00
>> pp = spline(x,y);
>> tic; quadgk(#(t) ppval(pp,t), 0, 3), toc
ans =
1.213866446458034e+00
Elapsed time is 0.017472 seconds.
>> tic; result = sum(sum(...
bsxfun(#times, pp.coefs, 1./(4:-1:1)) .*... % coefficients of primitive
bsxfun(#power, diff(pp.breaks).', 4:-1:1)... % all 4 powers of shifted x-values
)), toc
result =
1.213866467945575e+00
Elapsed time is 0.002887 seconds.
So trapz underestimates the value by more than 0.07. With the latter two methods, the error is an order of magnitude less. Also, the less-readable version of the spline approach is an order of magnitude faster.
So, armed with this knowledge: choose wisely :)
You can do Gaussian quadrature over each piecewise pair of x and sum them up to get the complete integral.