How to sum a series of values, ignoring any NaN values? - matlab

I use MATLAB version R2015a.
I get a series answer from solving the optimal problem several times, and I want to get their sum and average them. However, some of them are NaN. How do I write code to ignore those NaN and sum the others which are not NaN?

Option 1: toolbox free solution using sum and isnan from base MATLAB.
A = [1 2 3 4 5 6 7 8 9 NaN];
sum(A(~isnan(A))) % No toolbox required
Option 2: nansum (see this answer from OP)
Note: nansum requires the Statistics toolbox.
nansum(A) % Requires Statistics toolbox
Code tested using MATLAB R2018b.
Update from comments
Great suggestion from #Cris Luengo for those with more recent versions. Requires no toolbox.
sum(A,'omitnan') % No toolbox required
Another suggestion from #Ben Voigt for some applications. Also requires no toolbox.
sum(A(isfinite(A))) % No toolbox required

You can use inbuilt functions as suggested in the above answer. If you want to know the logic and use a loop..you can follow as shown below:
A = [NaN 1 2 NaN 3 4 7 -1 NaN] ;
count = 0 ;
thesum = 0 ;
for i = 1:length(A)
if ~isnan(A(i))
count = count+1 ;
thesum = thesum+A(i) ;
end
end

You can use the omitnan argument
A = [1 2 3 4 5 6 7 8 9 NaN];
s = sum( A, 'omitnan' )
Note, this is literally the same code as used by the nansum function from the Statistics toolbox, which was introduced before R2006a, so I would think compatibility is pretty good.

Related

What is the difference between predict and svmclassify?

I tried the following code
data = [27 9 0
11.6723281 28.93422177 0
25 9 0
23 8 0
5.896096039 23.97745722 1
21 6 0
21.16823369 5.292058423 0
4.242640687 13.43502884 1
22 6 0];
Attributes = data(:,1:2);
Classes = data(:,3);
train = [1 3 4 5 6 7];
test = [2 8 9];
%%# Train
SVMModel = fitcsvm(Classes(train),Attributes(train,:))
classOrder = SVMModel.ClassNames
sv = SVMModel.SupportVectors;
figure
gscatter(train(:,1),train(:,2),Classes)
hold on
plot(train(:,1),train(:,2),'ko','MarkerSize',10)
legend('good','bad','Support Vector')
hold off
I tried both predict and svmclassify; but it returns an error. What is the basic difference between these two functions?
[label,score] = predict(SVMModel,test);
label = svmclassify(SVMModel, test);
First off, there's quite a big note on top of the documentation page on svmclassify:
svmclassify will be removed in a future release. See fitcsvm, ClassificationSVM, and CompactClassificationSVM instead.
MATLAB is a bit vague in its naming of functions, as there's loads of functions named predict, using different schemes and algorithms. I suspect you'll want to use the one for SVMs. This should return the same result as svmclassify, but I think that either something went wrong in determining which predict MATLAB decided to use, or that predict has a newer algorithm than the unsupported svmclassify, hence a different output may result.
The conclusion is that you should use the newest functions to be able to run your code in future releases and get the newest algorithms. MATLAB will choose the correct version of predict based on what kind of input structure you feed it.

How to add two matrices and get rid of Nans

How can I add two matrices and keep only the numbers ignoring the NaN values?
for example:
A=[NaN 2 NaN];
B=[1 NaN 3];
I want some form of plus C=A+B such that:
C=[1 2 3]
You can achieve this without using any specific function call just by setting the NaNs to 0s and then performing the sum:
A(A~=A)=0
B(B~=B)=0
C=A+B
Edit: Another way of achieving this as #rayryeng suggested in the first comment is to use isnan:
A(isnan(A))=0
B(isnan(B))=0
C=A+B
You can use nansum (you need Statistics and Machine Learning Toolbox):
C = nansum([A;B])
and get:
C =
1 2 3
Alternatively, you can use sum with an excluding NaN flag:
C = sum([A;B],'omitnan')
And you will get the same result.

replace zero values with previous non-zero values

I need a fast way in Matlab to do something like this (I am dealing with huge vectors, so a normal loop takes forever!):
from a vector like
[0 0 2 3 0 0 0 5 0 0 7 0]
I need to get this:
[NaN NaN 2 3 3 3 3 5 5 5 7 7]
Basically, each zero value is replaced with the value of the previous non-zero one. The first are NaN because there is no previous non-zero element
in the vector.
Try this, not sure about speed though. Got to run so explanation will have to come later if you need it:
interp1(1:nnz(A), A(A ~= 0), cumsum(A ~= 0), 'NearestNeighbor')
Try this (it uses the cummax function, introduced in R2014b):
i1 = x==0;
i2 = cummax((1:numel(x)).*~i1);
x(i1&i2) = x(i2(i3));
x(~i2) = NaN;
Just for reference, here are some similar/identical functions from exchange central and/or SO columns.
nearestpoint ,
try knnimpute function.
Or best of all, a function designed to do exactly your task:
repnan (obviously, first replace your zero values with NaN)
I had a similar problem once, and decided that the most effective way to deal with it is to write a mex file. The c++ loop is extremely trivial. After you'l figure out how to work with mex interface, it will be very easy.

How does Matlab apply weight in its Euclidean distance weight function?

Does anyone know how Matlab’s Z=dist(W,P) works? The Matlab documentation does not specify an algorithm that uses the weight matrix, W.
I am using Octave and trying to mimic the behavior. So far, this stack overflow post helped me to prove that Octave’s Z=squareform(pdist(P')) is equivalent to Matlab’s Z=dist(P). I can also designate the elements of Z using a couple of for loops:
function z=dist(w,p)
for i=1:size(p,2)
for j=1:size(p,2)
u=p(:,i);
v=p(:,j);
z(i,j)=sum((u-v).^2).^0.5;
end
end
end
However, I am unable to find any online documentation on the weight matrix, W. I cannot simply multiply the output of squareform(pdist(P')) by W because the dimensions do not match. I have attempted to premultiply W, e.g. sqrt(W*(P(:,1)-P(:,2)).^2), like this stack overflow post but the output magnitudes are wrong.
Here is an example using Matlab:
P=
9 7 10
10 1 10
2 3 2
10 6 10
W=
10 9 5 8
5 2 10 10
>> D = dist(P)
0 10.0995 1.0000
10.0995 0 10.3441
1.0000 10.3441 0
>> D = dist(W,P)
3.8730 9.0000 3.7417
12.0000 8.3666 12.3693
Thanks in advance for any help you can provide!
It appears the Neural Network Toolbox is implemented in Matlab itself, so you can just look at those source files and figure it out.
If you open dist by entering edit dist in the command window, you see that it calls dist.apply or dist.distance to do the actual work, and the latter again dist.apply. Therefore, my guess is that what you are looking for can be found on line 9 of
toolbox/nnet/nnet/nndistance/+dist/apply.m
Type edit dist.apply in the command window to see it.

Questions about matlab median filter commands

This is a question about Matlab/Octave.
I am seeing some results of the medfilt1(1D Median filter command in matlab) computation by which I am confused.
EDIT:Sorry forgot to mention:I am using Octave for Windows 3.2.4. This is where i see this behavior.
Please see the questions below, and point if I am missing something.
1] I have a 1D data array b=[ 3 5 -8 6 0];
out=medfilt1(b,3);
I expected the output to be [3 3 5 0 0] but it is showing the output as [4 3 5 0 3]
How come? What is wrong here?
FYI-Help says it pads the data at boundaries by 0(zero).
2] How does medfilt2(2D median filter command in matlab) work.
Help says "Each output pixel contains the median value in the m-by-n neighborhood around the corresponding pixel in the input image".
For m=3,n=3, So does it calculate a 3x3 matrix MAT for each of input pixels placed at its center and do median(median(MAT)) to compute its median value in the m-by-n neighbourhood?
Any pointers will help.
thank you. -AD
I was not able to replicate your error with Matlab 7.11.0, but from the information in your question it seems like your version of medfilt1 does not differentiate between an odd or even n.
When finding the median in a vector of even length, one usually take the mean of the two median values,
median([1 3 4 5]) = (3+4)/2 = 3.5
This seems to be what happens in your case. Instead of treating n as odd, and setting the value to be 3, n is treated as even and your first out value is calculated to be
median([0 3 5]) = (3+5)/2 = 4
and so on.. EDIT: This only seems to happen in the endpoints, which suggest that the padding with zeros is not properly working in your Octave code.
For your second question, you are almost right, it calculates a 3x3 matrix in each center, but it does not do median(median(MAT)), but median(MAT(:)). There is a difference!
A = [1 2 3
14 5 33
11 7 13];
median(median(A)) = 11
median(A(:)) = 7