Transfer selected feature points to a new variable - matlab

I'm planning to transfer only a few feature descriptors which have been classified using SVM. I tried to put the selected descriptors in a matrix but I can't match them properly. Here's the code that I made in order to transfer the selected descriptors to another variable.
[nrows, ncolumns] = size(fdImage);
SVMResultFace = svmclassify(SVMStructFace, fdImage);
ClassifiedFace = [];
for row = 1:nrows
if SVMResultFace(row,1) == 1
ClassifiedFace = [ClassifiedFace; fdImage(row,:)];
end
end
is there a more proper way to do this? Thanks!

The easiest way to eliminate those rows from fdImage is just to use logical indexing:
SVMResultFace = svmclassify(SVMStructFace, fdImage);
include_row = SVMResultFace(:,1) == 1;
ClassifiedFace = fdImage(include_row,:);

Related

Select nonzero elements from MDF files in MATLAB

I am currently working with MDF file(.mf4) in MATLAB and I don't want to see the ChannelNumsamples that contain no values or lets say zero values so how to do that? I have tried with this code. but it is not helping me to extract nonzeroes elements.
cc = table2array(dd(1,:))
if table2array(A(x,"ChannelGroupNumSamples")) >= 0
disp('YES');
A(x,3)
size(cc);
else disp('nodata')
numel(cc)
Elements = sum(cc ~= 0)
elementscount = nonzeros(Elements)
end
To open an MDF file and read the data from it, but remove channel groups that don't contain any samples, you can do something like
m = mdf('myMDFfile.mf4');
mData = m.read;
for group = 1:numel(m.ChannelGroup)
if m.ChannelGroup(group).NumSamples == 0
mData(group) = [];
end
end
Now mData is a cell array of timetables containing only the data from the channel groups that had one or more samples.

How can I avoid this for-loop in spite of every element having to be checked individually?

Using Matlab R2019a, is there any way to avoid the for-loop in the following code in spite of the dimensions containing different element so that each element has to be checked? M is a vector with indices, and Inpts.payout is a 5D array with numerical data.
for m = 1:length(M)-1
for power = 1:noScenarios
for production = 1:noScenarios
for inflation = 1:noScenarios
for interest = 1:noScenarios
if Inpts.payout(M(m),power,production,inflation,interest)<0
Inpts.payout(M(m+1),power,production,inflation,interest)=...
Inpts.payout(M(m+1),power,production,inflation,interest)...
+Inpts.payout(M(m),power,production,inflation,interest);
Inpts.payout(M(m),power,production,inflation,interest)=0;
end
end
end
end
end
end
It is quite simple to remove the inner 4 loops. This will be more efficient unless you have a huge matrix Inpts.payout, as a new indexing matrix must be generated.
The following code extracts the two relevant 'planes' from the input data, does the logic on them, then writes them back:
for m = 1:length(M)-1
payout_m = Inpts.payout(M(m),:,:,:,:);
payout_m1 = Inpts.payout(M(m+1),:,:,:,:);
indx = payout_m < 0;
payout_m1(indx) = payout_m1(indx) + payout_m(indx);
payout_m(indx) = 0;
Inpts.payout(M(m),:,:,:,:) = payout_m;
Inpts.payout(M(m+1),:,:,:,:) = payout_m1;
end
It is possible to avoid extracting the 'planes' and writing them back by working directly with the input data matrix. However, this yields more complex code.
However, we can easily avoid some indexing operations this way:
payout_m = Inpts.payout(M(1),:,:,:,:);
for m = 1:length(M)-1
payout_m1 = Inpts.payout(M(m+1),:,:,:,:);
indx = payout_m < 0;
payout_m1(indx) = payout_m1(indx) + payout_m(indx);
payout_m(indx) = 0;
Inpts.payout(M(m),:,:,:,:) = payout_m;
payout_m = payout_m1;
end
Inpts.payout(M(m+1),:,:,:,:) = payout_m1;
It seems like there is not a way to avoid this. I am assuming that each for lop independently changes a variable parameter used in the main calculation. Thus, it is required to have this many for loops. My only suggestion is to turn your nested loops into a function if you're concerned about appearance. Not sure if this will help run-time.

MATLAB: Set individual number of rows to zero without loop

In a matrix mat I would like to set an individual number of rows to zero according a cell array startRowsthat holds row numbers. I do have a working solution, however, I am wondering whether I can avoid the loop and replace it with some more sophisticated code?
mat = ones(100,5);
startRows = {10,10,30,10,40};
% How to avoid this loop?
for c = 1 : 5
mat(1:startRows{c}-1, c) = 0;
end
You can use Matlab's auto expansion of mismatched array sizes in recent versions. For older version of Matlab you will need to use bsxfun in the last line
mat = ones(100,5);
startRows = {10,10,30,10,40};
startRowsMatrix = [startRows{:}]
mat((1:100)' < [startRows{:}]) = 0;

Looping a process, outputting numerically labelled variables each time

I have about 50 different arrays and I want to perform the following operation on all of them:
data1(isnan(data1)) = 0;
coldata1 = nonzeros(data1);
avgdata1 = mean(coldata1);
and so on for data2, data3 etc... the goal being to turn data1 into a vector without NaNs and then take a mean, saving the vector and the mean into coldata1 and avgdata1.
I'm looking for a way to automate this for all 50, rather than copy it 50 times and change the numbers... any ideas? I've been playing with eval but no luck so far. Also tried:
for y = 1:50
data(y)(isnan(data(y))) = 0;
coldata(y) = nonzeros(data(y));
avgdata(y) = mean(coldata(y));
end
You can do it with eval but really should not. Rather use a cell array as suggested here: Create variables with names from strings
i.e.
for y = 1:50
data{y}(isnan(data{y})) = 0;
coldata{y} = nonzeros(data{y});
avgdata{y} = mean(coldata{y});
end
Also read How can I create variables A1, A2,...,A10 in a loop? for alternative options.

How to apply an equation to multiple columns separately in a matrix?

I have 4 different lengths of data (in rows) and they all have a differing ammount of columns. I need to apply an equation to each of these columns and then extract the max value from each of them.
The equation I am trying to use is:
averg = mean([interpolate(1:end-2),interpolate(3:end)],2); % this is just getting your average value.
real_num = interpolate(2:end-1);
streaking1 = (abs(real_num-averg)./averg)*100;
An example of one of my data sets is 5448 rows by 13 columns
EDIT
This is the current adapation of Ben A.'s Solution and it is working.
A = interpolate;
averg = (A(1:end-2,:) + A(3:end,:))/2;
center_A = A(2:end-1,:);
streaking = [];
for idx = 1:size(A,2)
streaking(:,idx) = (abs(center_A(idx,:)-averg(idx,:))./averg(idx,:))*100;
end
I'm not entirely sure that I fully follow what you're doing in each step, but here is a stab at it:
A = interpolate;
averg = (A(1:end-2,:) + A(3:end,:))/2;
center_A = A(2:end-1,:);
streaking = [];
for idx = 1:size(A,2)
streaking(:,idx) = (abs(center_A(idx,:)-averg(idx,:))./averg(idx,:))*100;
end
Averg will be a vector of means for each column. I just use the values in the given column as the real_num variable that you had before. I'm not clear why you would need to index that the way you are as nothing is at risk of breaking index rules.
If this helps, great! If not let me know and I'll see if I can revise somewhat.