how to use "ezplot" to plot implicit functions? - matlab

How Can I use ezplot to plot something like this:
syms Vg L a b z c
c=sym('a*Vg+z');
A=sym('a*Vg+b+c*L');
A=subs(A,[a b z],[1 2 3]);
ezplot(A)
where I want to plot Vg versus L.
The point is that A contains another sym which is c.
The above code yields an error.

The error when running your example is quite telling;
"The number of variables must not exceed two when plotting an equation".
In your case, you're attempting to implicitly plot a function which contains three variables; the output of your symbolic equation is
...
A =
Vg + L*c + 2
Now, from the reference documentation of ezplot:
Passing Additional Arguments
If your function has additional parameters, for example k in myfun:
function z = myfun(x,y,k)
z = x.^k - y.^k - 1;
then you can use an anonymous function to specify that parameter:
ezplot(#(x,y)myfun(x,y,2))
Hence, one alternative is to can create a function for this 3-variable expression:
% myfun.m
function z = myfun(Vg,L,c)
z = Vg + L.*c + 2;
end
And thereafter use ezplot by calling this function with an anonymous function for the first two parameters (#(Vg,L)), and a fixed value of the third (c).
Example usage, repeated ezplot:s for varying (fixed) values of c:
% plot 'Vg + L*c + 2 = 0' for values of c in [0,5]
hold on, box on
for c = 0:0.05:5
ezplot(#(Vg,L)myfun(Vg,L,c))
end
As another alternative, you could simply use subs(...) for e.g. the Vg symbolic to plot the implicit function for the remaining two for varying (fixed) values of Vg:
syms Vg L a b z c
c=sym('a*Vg+z');
A=sym('a*Vg+b+c*L');
A=subs(A,[a b z],[1 2 3]);
hold on, box on
for VgVal = -6:6
ezplot(subs(A, Vg, VgVal))
end
title([char(A), ', with Vg \in [-6, 6]'])

Related

Use symbolic matlab for flexible number of arguments and functions

I have a function F which takes as an input a vector a. Both the output of the function and a are vectors of length N, where N is arbitrary. Each component Fn is of the form g(a(n),a(n-k)), where g is the same for each component.
I want to implement this function in matlab using its symbolic functionality and calculate its Jacobian (and then store both the function and its jacobian as a regular .m file using matlabFunction). I know how to do this for a function where each input is a scalar that can be handled manually. But here I want a script that is capable of producing these files for any N. Is there a nice way to do this?
One solution I came up with is to generate an array of strings "a0","a1", ..., "aN" and define each component of the output using eval. But this is messy and I was wondering if there is a better way.
Thank you!
[EDIT]
Here is a minimal working example of my current solution:
function F = F_symbolically(N)
%generate symbols
for n = 1:N
syms(['a',num2str(n)]);
end
%define output
F(1) = a1;
for n = 2:N
F(n) = eval(sprintf('a%i + a%i',n,n-1));
end
Try this:
function F = F_symbolically(N)
a = sym('a',[1 N]);
F = a(1);
for i=2:N
F(i) = a(i) + a(i-1);
end
end
Note the use of sym function (not syms) to create an array of symbolic variables.

Understanding Non-homogeneous Poisson Process Matlab code

I have found the following Matlab code to simulate a Non-homogeneous Poisson Process
function x = nonhomopp(intens,T)
% example of generating a
% nonhomogeneousl poisson process on [0,T] with intensity function intens
x = 0:.1:T;
m = eval([intens 'x']);
m2 = max(m); % generate homogeneouos poisson process
u = rand(1,ceil(1.5*T*m2));
y = cumsum(-(1/m2)*log(u)); %points of homogeneous pp
y = y(y<T); n=length(y); % select those points less than T
m = eval([intens 'y']); % evaluates intensity function
y = y(rand(1,n)<m/m2); % filter out some points
hist(y,10)
% then run
% t = 7 + nonhomopp('100-10*',5)
I am new to Matlab and having trouble understanding how this works. I have read the Mathworks pages on all of these functions and am confused in four places:
1) Why is the function defined as x and then the intervals also called x? Like is this an abuse of notation?
2) How does the square brackets affect eval,
eval([intens 'x'])
and why is x in single quotations?
3) Why do they use cumsum instead of sum?
4) The given intensity function is \lambda (t) = 100 - 10*(t-7) with 7 \leq t \leq 12 How does t = 7 + nonhomopp('100-10*',5) represent this?
Sorry if this is so much, thank you!
To answer 2). That's a unnecessary complicated piece of code. To understand it, evaluate only the squared brackets and it's content. It results in the string 100-10*x which is then evaluated. Here is a version without eval, using an anonymous function instead. This is how it should have been implemented.
function x = nonhomopp(intens,T)
% example of generating a
% nonhomogeneousl poisson process on [0,T] with intensity function intens
x = 0:.1:T;
m = intens(x);
m2 = max(m); % generate homogeneouos poisson process
u = rand(1,ceil(1.5*T*m2));
y = cumsum(-(1/m2)*log(u)); %points of homogeneous pp
y = y(y<T); n=length(y); % select those points less than T
m = intens(y); % evaluates intensity function
y = y(rand(1,n)<m/m2); % filter out some points
hist(y,10)
Which can be called like this
t = 7 + honhomopp(#(x)(100-10*x),5)
the function is not defined as x: x is just the output variable. In Matlab functions are declared as function [output variable(s)] = <function name>(input variables). If the function has only one output, the square brackets can be omitted (like in your case). The brackets around the input arguments are, as instead, mandatory, no matter how many input arguments there are. It is also good practice to end the body of a function with end, just like you do with loops and if/else.
eval works with a string as input and the square brackets apprently are concatenating the string 'intens' with the string 'x'. x is in quotes because, again, eval works with input in string format even if it's referring to variables.
cumsum and sum act differently. sum returns a scalar that is the sum of all the elements of the array whereas cumsum returns another array which contains the cumulative sum. If our array is [1:5], sum([1:5]) will return 15 because it's 1+2+3+4+5. As instead cumsum([1:5]) will return [1 3 6 10 15], where every element of the output array is the sum of the previous elements (itself included) from the input array.
what the command t = 7 + nonhomopp('100-10*',5) returns is simply the value of time t and not the value of lambda, indeed by looking at t the minimum value is 7 and the maximum value is 12. The Poisson distribution itself is returned via the histogram.

How to generate chaotic sequences from Chen's hyperchaotic system?

I need to generate two chaotic sequences based on chen's hyperchaotic system.It has to be generated from the following four formulas
X=ay-x;
Y=-xz+dx+cy-q;
Y=xy-bz;
Q=x+k;
where a,b,c,d,x,y,z,q are all initialised as follows.
I need only X and Y
where
X=[x1,x2,...x4n]
Y=[y1,y2,...y4n]
a=36 ;
b=3 ;
c=28 ;
d=16 ;
k=0.2 ;
x=0.3 ;
y=-0.4 ;
z=1.2 ;
q=1 ;
n=256 ;
I tried the following code but i'm not able to get it properly.
clc
clear all
close all
w=imread('C:\Users\Desktop\a.png');
[m n]=size(w)
a=36;
b=3;
c=28;
d=16;
k=0.2;
x(1)=0.3;
y(1)=-0.4;
z(1)=1.2;
q(1)=1;
for i=1:1:4(n)
x(i+1)=(a*(y(i)-x(i)));
y(i+1)=-(x(i)*z(i))+(d*x(i))+(c*y(i))-q(i);
z(i+1)=(x(i)*y(i))-(b*z(i));
q(i+1)=x(i)+k;
end
disp(x);
disp(y);
pls help. thanks in advance.
Your code isn't even close to doing what you want it to. Fortunately, I'm vaguely interested in the problem and I have a bunch of spare time, so I thought I'd try and implement it step by step to show you what to do. I've left a few gaps for you to fill in.
It sounds like you want to integrate the hyperchaotic chen system, which has various definitions online, but you seem to be focusing on
So let's write a matlab function that defines that system
function vdot = chen(t, v, a, b, c, d, k)
% Here you unpack the input vector v -
x = v(1); y = v(2); z = v(3); q = v(4);
% Here you need to implement your equations as xdot, ydot etc.
% xdot = ...
% ydot = ...
% I'll leave that for you to do yourself.
% Then you pack them up into an output vector -
vdot = [xdot; ydot; zdot; qdot];
end
Save that in a file called chen.m. Now you need to define the values of the parameters a, b, c, d and k, as well as your initial condition.
% You need to define the values of a, b, c, d, k here.
% a = ...
% b = ...
% You also need to define the vector v0, which is a 4x1 vector of your
% initial conditions
% v0 = ...
%
This next line creates a function that can be used by Matlab's integration routines. The first parameter t is the current time (which you don't actually use) and the second parameter is a 4x1 vector containing x, y, z, q.
>> fun = #(t,v) chen(t,v,a,b,c,d,k)
Now you can use ode45 (which does numerical integration using a 4th order runge-kutta scheme) to integrate it and plot some paths. The first argument to ode45 is the function you want to be integrated, the second argument is the timespan to be integrated over (I chose to integrate from 0 to 100, maybe you want to do something different) and the third argument is your initial condition (which hopefully you already defined).
>> [t, v] = ode45(fun, [0 100], v0);
The outputs are t, a vector of times, and v, which will be a matrix whose columns are the different components (x, y, z, q) and whose rows are the values of the components at each point in time. So you can pull out a column for each of the x and y components, and plot them
>> x = v(:,1);
>> y = v(:,2);
>> plot(x,y)
Which gives a reasonably chaotic looking plot:
#Abirami Anbalagan and Sir #Chris Taylor, I have also studied hyperchaotic system up to some extent. According to me, for system to be chaotic, values should be like
a= 35; b= 3; c= 12; d= 7;
v(n) = [-422 -274 0 -2.4]transpose
where v(n) is a 4*1 Matrix.

How can i create a multivariable function in matlab out of matrix data?

but i want to make a program in which i can generate a function of multiple variables that depend on the number of rows of a matrix.
for k = 1:sizel;
f(k)=(alpha(k,1)+(beta(k,1)*p(k))+(gamma(k,1)*p(k)^2));
end
cost=(sum(f))
this is for the purpose of optimization so i need that at the end the variables are declares as p(1),p(2),p(3)... these will be the input for my function.
Note: i dont want to assign values to the variables because this will be done be the optimization algorithm in the optimization toolbox.
here is the complete code
function cost = cost(p) ;
clc
clear
costfunctionconstantsmatrix;
sizel=size(CostFormulaconstants);
alpha=CostFormulaconstants(:,1);
beta=CostFormulaconstants(:,2);
gamma=CostFormulaconstants(:,3);
for k = 1:sizel;
f(k)=(alpha(k,1)+(beta(k,1)*p(k))+(gamma(k,1)*p(k)^2));
end
cost=(sum(f))
end
i used the symbolic approach and i got the correct answer for the cost indeed, i got something like this: (53*p(1))/10 + (11*p(2))/2 + (29*p(3))/5 + p(1)^2/250 + (3*p(2)^2)/500 + (9*p(3)^2)/1000 + 1100. But when i try to specify my function to be optimized in the optimization toolbox it tells me that the variables p are sym and cannot be converted to double. the trouble is how to convert this expression to double so that the optimization algorithm can input values for the variable p(1), p(2) and p(3)
Can you pass the matrix as an argument to the function?
function cost = fcn(my_mat)
[m,n] = size(my_mat);
f = zeros(m,1);
for k = 1:m % for example
f(k)=(alpha(k,1)+(beta(k,1)*p(k))+(gamma(k,1)*p(k)^2));
end
cost = sum(f);
end
Your problem is not entirely clear to me but I believe you wish to generate a series of functions in which the variables alpha, beta, gamma are constants with different values for each function, and the vector p is an argument.
What confuses me in your question is that you use the index k for both the constants and the arguments, which I think is not what you intended to write. Assuming I understand your goal, a solution may make use of function handles.
The notation f(k) = #(p) p(1)+p(2) for example, generates a function that adds p(1) and p(2). Abbreviating CostFormulaconstants to cf, the following would generate a series of functions, one for each row in cf.
for k = 1 : size(cf, 1)
f{k} = #(p) cf(k,1) + cf(k,2)*p(1) + cf(k,3)*p(2)^2;
end
You can supply individual function handles to callers from the optimization toolbox simply with f{3} for the third function, for example. A call to f{3} would look like
a = f{3}([3,4]);
If your functions are indeed all polynomials, polyval may be worth a look as well.
EDIT: After clarification, the problem seems a bit simpler, no need for function handles. Why not simply
function c = cost(p)
c = 0;
cf = [...]; % your coefficients here.
for k = 1 : size(cf, 1)
c = c + cf(k,1) + cf(k,2)*p(k) + cf(k,3)*p(k)^2;
end

Get function handle of fit function in matlab and assign fit parameters

I'm fitting custom functions to my data.
After obtaining the fit I would like to get something like a function handle of my fit function including the parameters set to the ones found by the fit.
I know I can get the model with
formula(fit)
and I can get the parameters with
coeffvalues(fit)
but is there any easy way to combine the two in one step?
This little loop will do the trick:
x = (1:100).'; %'
y = 1*x.^5 + 2*x.^4 + 3*x.^3 + 4*x.^2 + 5*x + 6;
fitobject = fit(x,y,'poly5');
cvalues = coeffvalues(fitobject);
cnames = coeffnames(fitobject);
output = formula(fitobject);
for ii=1:1:numel(cvalues)
cname = cnames{ii};
cvalue = num2str(cvalues(ii));
output = strrep(output, cname , cvalue);
end
output = 1*x^5 + 2*x^4 + 3*x^3 + 4*x^2 + 5*x + 6
The loop needs to be adapted to the number of coefficients of your fit.
Edit: two slight changes in order to fully answer the question.
fhandle = #(x) eval(output)
returns a function handle. Secondly output as given by your procedure doesn't work, as the power operation reads .^ instead of x, which can obviously be replaced by
strrep(output, '^', '.^');
You can use the Matlab curve fitting function, polyfit.
p = polyfit(x,y,n)
So, p contains the coefficients of the polynomial, x and y are the coordinates of the function you're trying to fit. n is the order of the polynomial. For example, n=1 is linear, n=2 is quadratic, etc. For more info, see this documentation centre link. The only issue is that you may not want a polynomial fit, in which case you'll have to use different method.
Oh, and you can use the calculated coefficients p to to re-evaluate the polynomial with:
f = polyval(p,x);
Here, f is the value of the polynomial with coefficients p evaluated at points x.