MATLAB save multiple outputs from a function many times over - matlab

In MATLAB, I am trying to create a matrix of the outputs of the built-in function [r, p] = corr(X1,Y1); after using this function on multiple X's and Y's. Then, I would like to consolidate all of the r and p into their respective matrices, R and P. For example, I can do this easily if I only call one output from corr:
R = [corr(X1,Y1), corr(X2,Y2); (...)
corr(X3,Y3), corr(X4,Y4)];
as corr returns the r value by default. Is there a way to achieve this for p as well? Below is the long way that I do it, I'm just wondering whether there is a shorter and easier method like above.
First find each r and p:
[r1, p1] = corr(X1,Y1);
[r2, p2] = corr(X2,Y2);
[r3, p3] = corr(X3,Y3);
....
Then combine them into the matrix:
R = [r1 r2; (...)
r3 r4; (...)
...];
P = [p1 p2; (...)
p3 p4; (...)
...];
Thanks.

You can try something along the lines of
for i=1:n,
[R(:,end+1), P(:,end+1)] = corr(X(:,i), Y(:,i));
end
Just make sure that R(:,1) and P(:,1) are sized correctly.
Assigning R(:,end+1) and P(:,end+1) will grow R and P automatically, without your having to combine them from temporary variables by hand.

Related

How to run a for loop using two variables at the same time in Matlab

I am using this command in Matlab:
grazAng = grazingang(H,R)
If i fix H, I can treat R as a vector:
z=[];
for i=1:1000
z(i)=abs(grazingang(1,i));
end
Now I would like to have both H and R to by dynamic. For example:
H=[0,0.25,0.5]
R=[1,2,3]
And I would like my loop to run three times, each time selecting a pair of (H,R) values with the same indexes, i.e. (0,1),(0.25,2),(0.5,3) and then store the result in z. Could anyone help me out with this?
Remember, everything in MATLAB is an array. To do this with a loop, you need to index into the arrays:
H = [0,0.25,0.5];
R = [1,2,3];
z = zeros(size(H)); % Pre-allocation is generally advised
for i = 1:1000
z(i) = abs(grazingang(H(i),R(i)));
end
But MATLAB functions generally accept vectors and do this for you, so all you need to do is:
H=[0,0.25,0.5];
R=[1,2,3];
z = abs(grazingang(H,R));

How to fix nan in anonymous function?

Suppose I have a function f(x) defined, which gives nan when it is very large, say x>100. Fortunately, when x>100, I can replace f by another function g. So I would like to define:
h = #(x)isnan(f(x)).*f(x)+isnan(f(x)).*g(x)
However, when I substitute h(1001), it gives nan. Is it possible to define h so that it gives g(1001) instead of nan? The only restriction is that I need to have anonymous function h for later use, say I would like to use it in integration, i.e., integral(h,0,inf).
Example: Suppose I have a function:
f = #(x)x.*1./x
This function is very easy and must be 1. I construct a function:
g = #(x)isnan(f(x)).*0+isnan(f(x)).*1
How to make g to be well defined so that I can still evaluate integral(g,-1,1)? For this example, I know I can evaluate it easily, but my restriction is that I need to define anonymous function g and use integral to do it.
You would need to make a regular function and wrap it with the anonymous function.
i.e.
function r = ternary(a, b, c)
if (a)
r = b;
else
r = c;
end
end
h = #(x)ternary(isnan(f(x)), g(x), f(x));
Note that this will evaluate your function twice. A less generalized solution for your particular case that won't evaluate the function twice.
function r = avoidNAN(a, b)
if (isnan(a))
r = b;
else
r = a;
end
end
There is a solution without any additional functions:
f = #(x)x.*1./x;
g = #(x)100+x;
h= #(x)getfield(struct('a',f(x),'b',g(x)),char(isnan(f(x))+'a'))

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.

Trouble iterating a function with one input and two outputs on Matlab

I've created a function (name it MyFunction) which, given a matrix A, outputs two matrices B and C i.e. [B C] = MyFunction(A).
I'm trying to create another function which, when given a matrix A, will calculate MyFunction(A) and then calculate MyFunction(B) = [D E] and MyFunction(C) = [F G], and then calculate MyFunction(D), MyFunction(E), MyFunction(F) and MyFunction(G), and so on, until the matrices it outputs start to repeat. I know this process necessarily terminates.
I'm really having difficulty constructing this code. Any advice would be really appreciated.
I think what you're trying to do is binary tree recursion. It's hard to give a good solution without knowing more about the problem, especially without knowing what you want as the output of this process.
I whipped this up to give an example of how you could do this. It's not necessarily the most efficient because it stores all of the results at every step. Given an input matrix A, it calculates a 2-output function [B, C] = MyFunction(A) and looks for either isequal(A, B) or isequal(A, C). When that occurs, it outputs the depth of the tree at that point, i.e. how many iterations had to occur before there was a repetition. The bit with global variables is just so that I could do a simple example with an easy fixed point (the k'th iteration is just A^k). It will iterate a maximum of 10 times.
function depth = myRecursor(A)
global A_orig;
A_orig = A;
depth = 1;
max_depth = 10;
pvs_level = cell(1);
pvs_level{1} = A;
while depth < max_depth,
this_level = cell(2*length(pvs_level), 1);
for ix = 1 : length(pvs_level),
[B, C] = MyFunction(pvs_level{ix})
if isequal(B, A) || isequal(C, A),
return;
end
this_level{2*ix - 1} = B;
this_level{2*ix} = C;
end
depth = depth + 1;
pvs_level = this_level;
end
function [B, C] = MyFunction(A)
global A_orig;
B = A_orig*A;
C = 2*A;
So, for example myRecursor(eye(2)) gives 1 (duh) and myRecursor([0 1; 1 0]) gives 2.
EDIT: rewritten wrong alg
function [list] = newFunction(A) % returns all matrix generated matrix
list{1}=A;
done=0;
ii = 1;
while(~done)
[B C] = myFunction(list{ii});
list = list{list{:}, B, C};
for jj=1:numel(list)-2
if(all(all(list{jj}==B)) || all(all(list{jj}==C)))
done = 1;
end
end
ii=ii+1;
end
end
UPDATE: a more general way to handle an unknown number of outputs is to modify myFunction so that it outputs all matrices within a single cell vector. This way you can concatenate list this way:
[newMat] = myFunctions(list{ii}); % where newMat={B,C,...}
list = {list{:}, newMat{:}}; % or list=cat(2,list,newMat)
for jj=1:numel(list)-numel(newMat)
for nn=1:numel(newMat) % checking for repetitions
if(all(all(list{jj}==newMat{nn})))
done=1;
end
end
end
I think you should use cells:
function [B]=Myfunction(A)
B=cell(1,numel(A)*2);
for n=1:numel(A)
B{n}=func1(A{n}) %%% put some processing here
B{numel(A)+n}=func2(A{n}) %%% put some other processing here
end
end

Matlab: how to create infinitly deep for-loops?

So we are given with some w and we want to so something like such pseudocode:
u = zeros(size(w));
for o=1:length(size(w))
for i=1:size(w)(1),
for j=1:size(w)(2),
...
for k=1:size(w)(length(size(w))),
u(i, j, ..., k )=1/(exp((-w(i,j, ..., k )))+25);
end
...
end
end
end
is such thing possible with Matlab and how to do it?
This is certainly possible, but also not recommended, since it's very non-idiomatic.
For simplicity, I assume that there is a typo in your question and that it should say exp(-w(i,j,...)).
Then, u can be calculated as
u = exp(-w);
You can use recursion - write a function, that iterates over the desired variables, and calls itself each time.
#Jonas's answer is the best option, however for a general-purpose code (one that #Jonas's 'matricized' answer does not apply), you can use a code-generation approach, for example:
fcode = fopen('manyForLoopsScript.m','w');
w = rand(2,3,4);
numLoops = length(size(w));
u = zeros(size(w));
% open the 'for' loops
for m = 1 : numLoops
fprintf(fcode, 'for a%d = 1:size(w,%d)\n',m,m);
end
% the actuall 'stuff'
indStr = [];
for m = 1 : numLoops
indStr = [indStr,sprintf('a%d,',m)];
end
indStr = indStr(1:end-1);
fprintf(fcode, ['u(' indStr ') = exp(-w(' indStr '));\n']);
% close the 'for' loops
for m = 1 : numLoops
fprintf(fcode, 'end\n');
end
fclose(fcode);
manyForLoopsScript
One option is to rewrite the function you want to apply to be vectorized, so that it is computed element-wise (the same way EXP built-in function works for scalar/vector/matrix input):
u = 1./(exp(-w)+25);
Otherwise, if you prefer a for-loop, all you need to do is to traverse the multi-dimensional input matrix using linear indices (in a column-major order), apply the function to each element, then RESHAPE the result back into the expected shape:
u = zeros(numel(w),1);
for i=1:numel(w)
u(i) = 1 ./ ( exp(-w(i)) + 25 );
end
u = reshape(u, size(w));
This is basically what the ARRAYFUN functions does for you:
u = arrayfun(#(x) 1./(exp(-x)+25), w);
In the chance that you also need access to the actual indices while looping over the elements of the matrix, you could always get them with IND2SUB (which converts linear indices to subscripts), or even generate all of them with functions like MESHGRID and NDGRID...