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
Related
I have a small logical array (A) of size 256x256x256 with an unknown shape of ones somewhere in the array. Also there is a smaller double array (se) of size 13x13x13. In se there is a defined cube of logical ones in the middle of the array (se).
I need to run over every logical element in A and for each logical one in A the smaller array se needs to add its ones to A. Meaning dilating the shape of A by se.
Here is what I got so far. It works, but is of very poor performance in respect to speed.
Does anyone has a suggestion of how to speed up this coding task?
[p, q, r] = size(se);
[m, n, o] = size(A);
temp = zeros(m, n, o);
for i = 1:m
for j = 1:n
for k = 1:o
if img_g(i, j, k) == 1
for s = 1:p
for t = 1:q
for u = 1:r
if se(s, t, u) == 1
c = i + s;
d = j + t;
e = k + u;
temp(c, d, e) = 1;
end
end
end
end
end
end
end
end
B = temp;
I am very grateful for any help and suggestions that improve my programming skills.
dependent on the processor you're using, you can at least use "parfor" for the outer loop (first loop).
this enables parallel computing and accelerates your performance by the number of physical kernels your processor got.
I'm not 100% sure this does what you're asking (as I'm not completely clear on what your code does), but perhaps the methodology will give some inspiration.
I've not generated a "logical" A, but a random one, and I've set a cube inside equal to 1. Similar for se. I use meshgrid to get arrays corresponding to the indices, and use a mask of logical indexing. (perhaps my mask is what you have for A in the first place?)
A = rand(255,255,255);
A(40:50, 23:33, 80:100) = 1;
mask = (A==1);
[I,J,K] = meshgrid(1:255);
se = rand(13,13,13);
se(4:6, 3:7, 2:8) = 1;
se_mask = (se==1);
[se_I, se_J, se_K] = meshgrid(1:13);
Here I'm assuming that the cube in A is far enough from any edge (say 13 spaces) so we wont get c, d or e larger than 255.
I've flattened mask into a row vector so find gives a single index ii we can use to refer to any point in A, then the original i,j and k indices are in I(ii), J(ii), and K(ii) respectively. Similar for se_I etc.
temp = zeros(255, 255, 255);
for ii=find(mask(:).')
for jj=find(se_mask(:).')
c = I(ii) + se_I(jj);
d = J(ii) + se_J(jj);
e = K(ii) + se_K(jj);
temp(c,d,e) = 1;
end % for
end % for
The matrices I, J, K, se_I, se_J and se_K are regular, so if making/storing these becomes a bottleneck you can write functions to replace them. Matrix temp might be very sparse depending on the size of your cubes of ones, so you could look into using sparse.
I've not compared the timings against your solution.
I use dynamic programming for finding the shortest path between two matrices. I printed all the step of the shortest path, but I would also like to save all of them so I can print them as a 2D figure. I wrote the code like below but it doesn't work. I searched on the internet and it seems like it need to be pass by an object as the argument? Does anyone know how to get the path matrix from the returning value? Thanks in advance!
ttt=find_path(7,7)
function pathMat = find_path(a,b)
pathMat=[];
if (a==0 || b==0)
return;
end
filename = sprintf('/Users/name/Desktop/song1.wav');
[x, Fs]=audioread(filename);
s=x;
filename = sprintf('/Users/name/Desktop/song2.wav');
[x, Fs]=audioread(filename);
t=x;
% dynamic time warping
w=-Inf;
ns=size(s,2);
nt=size(t,2);
%% initialization
D=zeros(ns+2,nt+2)-Inf; % cache matrix
D(1,1)=0;
D(2,2)=0;
% similarity matrix (cosing similarity)
oost = zeros(ns+1,nt+1)-Inf;
for i=1:ns
for j=1:nt
oost(i+1,j+1) =
(dot(s(:,i),t(:,j))/(norm(s(:,i),2)*norm(t(:,j),2))); % = cos(theta)
end
end
%% begin dynamic programming
%find the maximal similarity between two matrix
for i=1:ns
for j=1:nt
D(i+2,j+2)=oost(i+1,j+1)+max([D(i,j+1)+oost(i,j+1), D(i+1,j)+oost(i+1,j), D(i+1,j+1)]);
end
end
d=max(D(:,nt+2));
d_len=nt+2;
while(max(D(:,d_len))==-Inf)
d_len=d_len-1;
d=max(D(:,d_len));
end
fprintf('(%d, %d)', a, b);
pathMat = [pathMat];
if (max([D(a,b+1)+oost(a,b+1), D(a+1,b)+oost(a+1,b), D(a+1,b+1)])==D(a,b+1)+oost(a,b+1))
fprintf('(%d, %d)', a-1, b);
pathMat=[pathMat;find_path(a-1,b)];
find_path(a-2,b-1);
elseif (max([D(a,b+1)+oost(a,b+1), D(a+1,b)+oost(a+1,b), D(a+1,b+1)])==D(a+1,b)+oost(a+1,b))
fprintf('(%d, %d)', a, b-1);
pathMat=[pathMat;find_path(a,b-1)];
find_path(a-1,b-2);
elseif (max([D(a,b+1)+oost(a,b+1), D(a+1,b)+oost(a+1,b), D(a+1,b+1)])==D(a+1,b+1))
find_path(a-1,b-1);
end
end
There are two approaches you can use, to retain values between function calls or store all results in a "global" variable.
Due to the clutter and length of your code (not everything is relevant to the question), I will take the example of a factorial program to describe the approach.
Let there be a function that not only computes the factorial of the given number recursively, but also all the intermediate results of numbers lesser than itself. I believe this is a close model of what you require. An example of what the function should do:
>> [fact, list] = factorial(5)
>> fact = 120
>> list = [1, 2, 6, 24, 120]
Approach 1: Use persistent variables
Persistent variables are the equivalent of static function variables (like in C) in MATLAB.
Persistent variables by default are assigned to [] on first use. Also, the value is retained across function calls as expected. A sample code using this approach to define our factorial program:
function [fact, list] = factorial(n)
if n <= 1
fact = 1;
else
fact = n * factorial(n-1);
end
persistent res;
res = [res, fact];
list = res;
end
This can be used as follows:
>> [f, list] = factorial(4)
f =
24
list =
1 2 6 24
>> clear factorial
>> [f, list] = factorial(3)
f =
6
list =
1 2 6
Approach 2: Sharing variables in nested functions
MATLAB supports nested function definitions, where the inner functions can share variables from the outer one, and modify them without explicitly being passing as arguments. A sample code using this approach:
function [fact, list] = factorial(n)
list = [];
fact = factorial_core(n);
function fact = factorial_core(n)
if n <= 1
fact = 1;
else
fact = n * factorial_core(n-1);
end
list = [list, fact];
end
end
This is used the same way as before, except that clear factorial (that clears the persistent variables) between function calls is not required.
I would recommend you to try out whichever suits your case best. Also, it appears that you are loading the wav files each time of the recursion, which is unnecessary and inefficient. These two approaches can be used to avoid that, apart from solve your problem.
I am going to find efficiently all loops with length 4 in a large graph.I have the following code for this purpose but it is not efficient.
[rows, cols, s] = find(Mystructure);
for i = 1:size(cols,1)
a = rows(i);
b = cols(i);
C=cols(find(rows==b));
for j=1:size(C)
c=C(j);
D=cols(find(and(rows==c, rows~=a)));
for k=1:size(D)
d=D(k);
if(d~=a && d~=b)
if(find(and(rows==d, cols==a)))
FourStructure=[FourStructure;a b c d] ;
end
end
end
end
end
Mystructure is a sparse matrix representing my graph. Mystructure(i,j) is one if and only if i,j be connected.
I have a classification problem with four classes of input vector.The four classes are
A = [1 , 1; 1 ,2];
B = [2,2; -1,0];
C = [-1,-2;2,1];
D = [-1,-2; -1,-2];
I wan Implement this problem by Matlab, I Use this code :
C = [-1,-2;2,1];
A = [1 , 1; 1 ,2];
B = [2,2; -1,0];
D = [-1,-2; -1,-2];
hold on
grid on
plot(A(1,:),A(2,:),'bs')
plot(B(1,:),B(2,:),'r+')
plot(C(1,:),C(2,:),'go')
plot(D(1,:),D(2,:),'m*')
a = [0 1]';
b = [1 1]';
c = [1 0]';
d = [0 0]';
P = [A B C D];
T = [repmat(a,1,length(A)) repmat(b,1,length(B)) repmat(c,1,length(C)) repmat(d,1,length(D)) ];
net = perceptron;
E = 1;
net.adaptParam.passes = 1;
linehandle = plotpc(net.IW{1},net.b{1});
n = 0;
while (sse(E))
n = n+1;
[net,Y,E] = adapt(net,P,T);
linehandle = plotpc(net.IW{1},net.b{1},linehandle);
drawnow;
end
but My Code does'nt work I have No idea why, please Help me....
As has been suggested by thewaywewalk, the trouble is your while-loop and the fact that you do not provide an adequate check for the statement you wish to evaluate.
Replace your while-statement with these two lines:
ACCEPTABLE_ERROR = 3.0;
while (sse(E)>ACCEPTABLE_ERROR)
And you should see your script terminate after three iterations. You can play with the ACCEPTABLE_ERROR variable to check which solution works best for you. If you set it too small, your while loop will not exit, because the statement will not be false.
An explanation to your original while-statement:
All you ever evaluated if sse(e) returned a results - which it did in each case. That's why it never stopped.
To the question of sse requires more than one input argument:
That depends on what input arguments you provide.
The documentation says:
perf = sse(net,t,y,ew) takes these input arguments and optional function parameters,
net: Neural network
t: Matrix or cell array of target vectors
y: Matrix or cell array of output vectors
ew: Error weights (default = {1})
and returns the sum squared error.
However, it is not necessary, to provide the error weights, ew, as the source code reveals:
Only the first three arguments are required. The default error weight is {1}, which weights the importance of all targets equally.
In your case you should, based on the documentation, call sse like this:
sse(net,T,Y)
Without being mentioned in the documentation (or I haven't found it), this is equivalent to what you have done, by providing simply the network errors, E as provided from adapt:
sse(E)
Both give the same results.
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...