Return and call multiple value from function - matlab

I am trying to return all values of for loop from my function and also I need to call them outside of the function.But i only get last row of the for loop, I also need previous result of for loop.
Here is my code
i=input('Enter a start row: ');
j=input('Enter a end row: ');
c=input('Enter classifier variable column number:')
search= importfiledataset('search-queries-features.csv',i,j);
[n,p]=size(search);
if j>n
disp('Please enter a smaller number!');
end
[D1,Eps1]=findD(i,j,c,search);
disp(D1);
disp(n1);
function [D1,Eps1] = findD(i,j,c,search) %Find D vlaues with for loop for each classification value
for numOfClassifier = 1 : 100
a = search(search(:,c)==numOfClassifier,:) ;
q1 = a(all(~isnan(a),2),:); % for nan - rows
D1 = a(:,all(~isnan(a))) % for nan - columns WE FIND D1
n1=size(D1,1) %number of record belongs to classification
sampleSpace = size(search,1) %sample space of the priop probability(#of c1 + #of c2 .... cn)
pc1 = n1/sampleSpace %prior probability of the n
mu1 = mean(D1) %mean of D1
Z1 = D1 - mu1 % centered data of D1
Eps1 = (1/n1)*(transpose(Z1)*Z1) %covariance matrix if Z1
numOfClassifier = numOfClassifier + 1;
if search(:,c) ~= numOfClassifier
break
end
end
end
I need to return
D1
Eps1
I want to return the entire values of for loop but I only end up with values from the last row.

You can store the iteration results in a cell array, and return the cell array:
Function returning two cell arrays (I named them allD1 and allEps1):
function [allD1, allEps1] = findD(i,j,c,search)
Initialize the cell arrays to empty cells before the loop:
allD1 = {};
allEps1 = {};
Add D1 and Eps1 to the end of the cell arrays (place it before the line with the break statement):
allD1{end + 1} = D1;
allEps1{end + 1} = Eps1;
Here is the modified code:
i=input('Enter a start row: ');
j=input('Enter a end row: ');
c=input('Enter classifier variable column number:')
search= importfiledataset('search-queries-features.csv',i,j);
[n,p]=size(search);
if j>n
disp('Please enter a smaller number!');
end
[D1,Eps1]=findD(i,j,c,search);
disp(D1);
disp(n1);
function [allD1, allEps1] = findD(i,j,c,search) %Find D vlaues with for loop for each classification value
%Initialize empty cell arrays
allD1 = {};
allEps1 = {};
for numOfClassifier = 1 : 100
a = search(search(:,c)==numOfClassifier,:) ;
q1 = a(all(~isnan(a),2),:); % for nan - rows
D1 = a(:,all(~isnan(a))) % for nan - columns WE FIND D1
n1=size(D1,1) %number of record belongs to classification
sampleSpace = size(search,1) %sample space of the priop probability(#of c1 + #of c2 .... cn)
pc1 = n1/sampleSpace %prior probability of the n
mu1 = mean(D1) %mean of D1
Z1 = D1 - mu1 % centered data of D1
Eps1 = (1/n1)*(transpose(Z1)*Z1) %covariance matrix if Z1
%Add D1 (and Eps1) to the end of the cell array
allD1{end + 1} = D1;
allEps1{end + 1} = Eps1;
numOfClassifier = numOfClassifier + 1;
if search(:,c) ~= numOfClassifier
break
end
end
end
Cell arrays are more general then arrays - cells can store values of different types and shapes, opposed to arrays where all elements must be of the same type.
In your case, multi-dimensional arrays might fit, but it's more confusing.
With cell arrays, each cell holds the result of the matching iteration.
For example: allD1{3} holds the value of D1 in the third iteration.

Related

Multiply inverse matrix with another one

I want to multiply two matrices, the first matrix is the inverse of A, and the second matrix is B,
input('Enter The first Matrix')
A = [ 1 2 3 ; 4 5 6 ; 7 8 0 ]
[m n] = size(A)
if m==n
if det(A)==0
disp('inverse does not exist')
else
invv=inv(A)
disp(invv)
end
else
disp('Number of rows and columns are not equel , no inverse')
end
input('Enter The second Matrix')
B = [ 1 ; 1 ; 1 ]
How can I verify that the number of columns in the first matrix is equal to the number of rows in the second matrix, so that they can be multiplied?
function [X] = dot_inv(X,x)
% X - numeric array
% x - cell array of numeric vectors
% DIM - dimensions to omit (asumes ndims(X) = numel(x))
% Y - inner product obtained by summing the products of X and x along DIM
% initialise dimensions
%--------------------------------------------------------------------------
[m n] = size(X)
if m==n
if det(X)==0
error('Error. \n inverse does not exist.')
else
X=inv(X)
end
else
error('Error. \n Number of rows and columns are not equel , no inverse!')
end
if iscell(x)
DIM = (1:numel(x)) + ndims(X) - numel(x);
else
DIM = 1;
x = {x};
end
% inner product using recursive summation (and bsxfun)
%--------------------------------------------------------------------------
for d = 1:numel(x)
s = ones(1,ndims(X));
s(DIM(d)) = numel(x{d});
X = bsxfun(#times,X,reshape(full(x{d}),s));
X = sum(X,DIM(d));
end
% eliminate singleton dimensions
%--------------------------------------------------------------------------
X = squeeze(X);
return

Align right-shifted waveforms (action potentials)

enter image description here
I am having difficulty with my code aligning right shifted waveforms by the minimum peak point. In the left shifted, I copy the difference in indices between the desired minimum point and the given one to left of the waveform, and then delete those extra points after once this aligns the waveform. However, the same technique is not working for the right shifted ones. Any help would be much appreciated! Input (vals) is any n x 97 matrix.
function [vals] = align_wvs(wvs)
%Align_wvs - Align waveforms to minimum point
%
%align_wvs(wvs)
%
%wvs - matrix of waveforms
%
%Returns 'vals' - newly aligned matrix of waveforms
wvfrms = (wvs*10^6); %convert to microvolts
wvfrms = wvfrms(:,all(~isnan(wvfrms)));
min_pt = min(wvfrms(:)); %find minimum point in wvs
[~,col] = find(wvfrms==min_pt); %find index of min poin
if numel(col)>1
col = col(1);
end
%and that of other wvfrms
vals = zeros(size(wvfrms)); %matrix of size wvfrms, vals
for i = 1:size(vals,1) %for length of input
vals(i,:) = wvfrms(i,:); %copy og wvfrm into vals
nums = vals(i,:); %get second copy
ind_min = min(nums);
[~,colmin] = find(nums==ind_min);
diff_col = col-colmin;
if (diff_col~=0) %if difference is not = 0
if (diff_col>0) %if wvfrm is shifted to the left
inds = nums(1:diff_col); %copy first n values of nums, where n is diff_rows
new_length = length(nums)+length(inds); %extend wvfrm by amount ind
new_vals = zeros(1,new_length); %create new array of size new_length
new_vals(1:(diff_col)) = inds; %add inds to begining of new array
new_vals(diff_col+1:end) = nums; %add nums to rest of array
new_vals(1:(diff_col)) = [];%delete diff_rows-1 values from end
vals(i,:) = new_vals; %add to values
else %if wvfrm is shifted to the right
inds = nums(end+(diff_col+1):end); %copy last n values of nums, where n is diff_rows
new_length = length(nums)+length(inds); %extend wvfrm by amount ind
new_vals = zeros(1,new_length); %create new array of size new_length
new_vals(end+(diff_col+1):end) = inds;%add inds to end of new array
new_vals(1:(end+(diff_col))) = nums;%add nums to rest of array
new_vals(1:(diff_col*-1)) = []; %delete diff_rows-1 values from begining
vals(i,:) = new_vals; %add to values
end
end
end
end
List item
Does replacing the if (diff_col~=0) block with the following work?
if (diff_col~=0)
if (diff_col>0)
vals(i,:) = [zeros(1,diff_col) nums(1:(end-diff_col))];
else
vals(i,:) = [nums((-diff_col+1):end) zeros(1,-diff_col)];
end
end

Performance of using a matrix as vector index

In my code I have a slow part of which the idea can be summarized in the following short example:
A = randi(10,5); %Random 5×5 matrix containing integers ranging from 0 to 10
B = rand(10,1); %Random 10×1 vector containing values ranging from 0 to 1
C = B(A); %New 5×5 matrix consisting of elements from B, indexed using A
In my case, the matrix A is sized 1000×1000, B is a 500×1 vector and C is also 1000×1000. Given that this 3rd line is in a for loop, where A is constant and B is updated every iteration, how can I further improve speed performance? According to the profile viewer 75% of code execution is at this single line. As expected, using a for loop for this operation is much slower (10x for a 1000×1000 matrix):
AA = A(:); %Convert matrix to vector
for k=1:length(AA) %Loop through this vector and use it as index
D(k) = B(AA(k));
end
E = reshape(D,5,5); %Reshape vector to matrix of 5x5
Any ideas to optimize this?
Edit: Script used to measure performance:
N = 1500;
A = randi(500,N);
AA = A(:);
D = zeros(N,N);
B = rand(500,1);
f1 = #() VectorIndex(A,B);
timeit(f1,1)
f2 = #() LoopIndex(AA,B,N);
timeit(f2,1)
function C = VectorIndex(A,B)
C = B(A);
end
function D = LoopIndex(AA,B,N)
D = zeros(N,N);
for k=1:length(AA)
D(k) = B(AA(k));
end
D = reshape(D,N,N);
end

Exclude value by the calculation

I have an array A (I have written so as to make it similar to the matrix that I am using) :
%%%%%%%%%%%%% This is Matrix %%%%%%%%%%%%%%%%%%%%
a = 3; b = 240; c = 10; d = 30; e = 1;
mtx1 = a.*rand(30,1) + a;
mtx2 = round((b-c).*rand(30,1));
mtx3 = round((d-e).*rand(30,1));
mtx4 = -9999.*ones(30,1);
A = [mtx1 mtx2 mtx3 mtx4];
for i = 10:12
for ii = 17 :19
A(i,:)= -9999;
A(ii,:)= 999;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
I would calculate some statistical values, excluding from the calculation the values **-9999 and 999.
the statistical values must be calculated with respect to each column.
the columns represent respectively: the wind speed, direction, and
other parameters
I wrote a code but it is not correct
[nr,ncc]=size(A);
for i=1:ncc
B = A(:,i); %// Temp Vector
Oup=1; Odw=1; %// for Vector Control
while Oup>0 %// || Odw>0 % Oup>0 OR Odw>0 , Oup>0 && (AND) Odw>0
B=sort(B,'descend');
U = find(B<999 & B>-9999); % find for each column of the temp
%vector
Oup = length(U); % Calculates the length
B(U)=[]; % Delete values -9999 and 9999
end
% calculates parameters with the vector temp
count(i)=length(B);
med(i)=mean(B);
devst(i)=std(B);
mediana(i)=median(B);
vari(i)=var(B);
kurt(i)=kurtosis(B);
Asimm(i)=skewness(B);
Interv(i)=range(B);
Mass(i)=max(B);
Mini(i)=min(B);
if length(B)<nr
B(length(B)+1:nr)=nan;
end
C(:,i)=B(:); %//reconstruction of the original matrix
end
would you have any suggestions?
If your data set is in A, and you want to operate on it with a function f, just use logical indexing, i.e.:
f(A( ~(A==999 & A==-9999) )) =...
Alternatively, use find and linear indexing:
ind = find( ~(A==999 & A==-9999) );
f(A(ind)) = ....

Store data in a row matrix

I have a MATLAB program like this
for m = 1:2
%# Some code to calculate a matrix (Ytotale)
%# Size of Ytotale is (1200 * 144) %%
%#...
Yfinal = Ytotale;
for l = 1:1200
i = l;
j = retard(l,1);
if Yfinal(i,j) == 0
Yfinal(i,j:end) = circshift(Yfinal(i,j:end),[retard(l,2) retard(l,2)]);
for j = retard(l,1):retard(l,1)+retard(l,2)-1
Yfinal(i,j) = 1;
end
else
Yfinal(i,j:end) = circshift(Yfinal(i,j:end),[retard(l,2) retard(l,2)]);
for j = retard(l,1):retard(l,1)+retard(l,2)-1
Yfinal(i,j) = 0;
end
end
end
%# ( Here i , j are index of matrix Ytotale , and l is the index
%# of matrix retard of size (1200 * 2)
for i =1:1200
not_char(i,1) = sum(Yfinal(i,1:144));
req(i,1) = sum(Ytotale(i,1:144));
end
final = req - not_char;
ve_delay = sum(Yfinal(:,1:144))';
end
The total process will iterate from m = 1 to 2 and two Ytotale matrix will form, hence I want to store the value of ve_delay and final in a row matrix for each Ytotale , but my code overwrites the matrix values .
please help...
This answer is adapted from the comment by macduf
Try final{m} = req - not_char; and ve_delay{m} = sum(Yfinal(:,1:144)); . These values are now stored in a cell matrix (the curly bracket notation). You can convert the cell array into a regular array afterward.