How can I make reverse function of diff of Matlab? [duplicate] - matlab

I am trying to resolve why the following Matlab syntax does not work.
I have an array
A = [2 3 4 5 8 9...]
I wish to create an indexed cumulative, for example
s(1) = 2; s(2)=5, s(3)=9; ... and so on
Can someone please explain why the following does not work
x = 1:10
s(x) = sum(A(1:x))
The logic is that if a vector is created for s using x, why would not the sum function behave the same way? The above returns just the first element (2) for all x.

For calculating the cumulative sum, you should be using cumsum:
>> A = [2 3 4 5 8 9]
A =
2 3 4 5 8 9
>> cumsum(A)
ans =
2 5 9 14 22 31
The issue is that 1:x is 1 and that sum reduces linear arrays. To do this properly, you need a 2d array and then sum the rows:
s(x)=sum(triu(repmat(A,[prod(size(A)) 1])'))

You are asking two questions, really. One is - how do I compute the cumulative sum. #SouldEc's answer already shows how the cumsum function does that. Your other question is
Can someone please explain why the following does not work
x = 1:10
s(x) = sum(A(1:x))
It is reasonable - you think that the vector expansion should turn
1:x
into
1:1
1:2
1:3
1:4
etc. But in fact the arguments on either side of the colon operator must be scalars - they cannot be vectors themselves. I'm surprised that you say Matlab isn't throwing an error with your two lines of code - I would have expected that it would (I just tested this on Freemat, and it complained...)
So the more interesting question is - how would you create those vectors (if you didn't know about / want to use cumsum)?
Here, we could use arrayfun. It evaluates a function with an array as input element-by-element; this can be useful for a situation like this. So if we write
x = 1:10;
s = arrayfun(#(n)sum(A(1:n)), x);
This will loop over all values of x, substitute them into the function sum(A(1:n)), and voila - your problem is solved.
But really - the right answer is "use cumsum()"...

Actually what you are doing is
s(1:10)= sum(A(1:[1,2,3...10]))
what you should do is
for i=1:10
s(i)=sum(A(1:i))
end
hope it will help you

Related

How to create an Octave function that evaluate the sum of pairs of numbers in the vector?

It's like a reverse version of Pascal's triangle.
I want to create a vector-input function named
y = lastnum(vect) on Octave, that evaluate the sum of each pair of numbers in any vectors to output the single number from the evaluation loops like this
0 1 2 3 4
1 3 5 7
4 8 12
12 20
32
And the input and output would be like this,
lastnum([0 1 2 3 4])
ans = 32
I mean... is there any progresses that I can do??? You may not understand but, the reverse triangle above can guide you about my question.
I also tagged MATLAB since it has similar language. MATLAB pros may help my problem.
Notice that the number of times each element gets added to produce the final result comes from Pascals triangle itself, so, e.g., for the vector [a b c d] the result will be a+3b+3c+d. So create a vector of entries in Pascals triangle and multiply and add with the original vector v.
I only have access to Matlab, Octave may not have all these functions.
This is a one-liner diag(fliplr(pascal(numel(v)))).'*v(:).
Or a looping version
s = 0;
for i = 0:numel(v)-1
s = s+nchoosek(numel(v)-1,i)*v(i+1);
end
s
Simplest thing I can think of is:
while length(x) > 0
disp(x)
x = x(1:end-1) + x(2:end);
end
or did I misunderstand the question?
Here is the version for both MATLAB and Octave:
function y = lastnum(v)
while 1
if length(v) == 2
y = sum(v)
break;
end
# disp(v); # if you want to print the progress
vt = [];
for k = 1:(length(v)-1)
vt(end+1) = sum(v(k:(k+1)));
end
v = vt;
end
end

Issue regarding loop to find Root mean square error in MATLAB

I have 6 different data sets from sensor and I want to find out the Root mean Square error but of the limited signal with limits means RMSE of sig_diff_lim.
I have tried to apply loop but it’s not working can anybody tell me where I am at fault.
Thanks in anticipation.
clc
drv(1)=load('a.mat');
drv(2)=load('b.mat');
drv(3)=load('c.mat');
drv(4)=load('d.mat');
drv(5)=load('e.mat');
drv(6)=load('h.mat');
for i= 1:numel(drv)
t=drv(i).T;
ref=drv(i).P;
lws=drv(i).SWA;
sig_diff(i,:) =lws(i)-ref(i);
swvel_thres=10;
vehvel=30;
SAmax=90;
sig_diff_lim(i,:)=sig_diff((lws(i)<SAmax)&(lws(i)>-SAmax)&(swav(i)<swvel_thres)&(vel(i)>vehvel));
square_error(i,:) = (sig_diff_lim(i)).^2;
mse(i,:)= mean(square_error(i));
rmse(i,:) = sqrt(mse(i));
end
rmse
mse
It seems to me that while assigning to sig_diff_lim(i,:) requires a row vector of size 1*n, the matrix that is returned by
vec=sig_diff((lws_7(i)<SAmax)&(lws_7(i)>-SAmax)&(swav(i)<swvel_thres)&(vel(i)>vehvel))
is of a different size.
Edit
First, are you sure that sig_diff((lws(i)... shouldn't be sig_diff(i,:)((lws(i).... on the assignemnt line?
Now, try element-wise multiplication (operator .* ) between sig_diff (or sig_diff(i,:)), depending on your answer to my previous point) with your logical indexing, like this:
sig_diff.*((lws(i)<... %%%% instead of sig_diff((lws(i)<...
%%% or
sig_diff(i,:).*(lws(i)<...
I think that should do the trick.
Regardless of whether or not this worked, try this example to understand what is going on with that sort of logical indexing:
>> t=[1 2 3 5 7;1 5 6 8 10];
>> t(1,:)(l<7 & l>-7)
ans =
1 2 3 5
>> t(1,:)(l<7 & l>-2)
ans =
1 2 5
Of course, in this example, t is fixed while the thresholds are changing , while in your code the matrix itself is changing. But it shows you that your indexing will return matrices of variable length.
But, with the solution I proposed above,
>> t(1,:).*(l<7 & l>-2)
>> t(1,:).*(l<7 & l>-7)
are both of size 5*1.

Cumulative Sum of a Vector - Syntax

I am trying to resolve why the following Matlab syntax does not work.
I have an array
A = [2 3 4 5 8 9...]
I wish to create an indexed cumulative, for example
s(1) = 2; s(2)=5, s(3)=9; ... and so on
Can someone please explain why the following does not work
x = 1:10
s(x) = sum(A(1:x))
The logic is that if a vector is created for s using x, why would not the sum function behave the same way? The above returns just the first element (2) for all x.
For calculating the cumulative sum, you should be using cumsum:
>> A = [2 3 4 5 8 9]
A =
2 3 4 5 8 9
>> cumsum(A)
ans =
2 5 9 14 22 31
The issue is that 1:x is 1 and that sum reduces linear arrays. To do this properly, you need a 2d array and then sum the rows:
s(x)=sum(triu(repmat(A,[prod(size(A)) 1])'))
You are asking two questions, really. One is - how do I compute the cumulative sum. #SouldEc's answer already shows how the cumsum function does that. Your other question is
Can someone please explain why the following does not work
x = 1:10
s(x) = sum(A(1:x))
It is reasonable - you think that the vector expansion should turn
1:x
into
1:1
1:2
1:3
1:4
etc. But in fact the arguments on either side of the colon operator must be scalars - they cannot be vectors themselves. I'm surprised that you say Matlab isn't throwing an error with your two lines of code - I would have expected that it would (I just tested this on Freemat, and it complained...)
So the more interesting question is - how would you create those vectors (if you didn't know about / want to use cumsum)?
Here, we could use arrayfun. It evaluates a function with an array as input element-by-element; this can be useful for a situation like this. So if we write
x = 1:10;
s = arrayfun(#(n)sum(A(1:n)), x);
This will loop over all values of x, substitute them into the function sum(A(1:n)), and voila - your problem is solved.
But really - the right answer is "use cumsum()"...
Actually what you are doing is
s(1:10)= sum(A(1:[1,2,3...10]))
what you should do is
for i=1:10
s(i)=sum(A(1:i))
end
hope it will help you

Statistical error computing Matlab

I have two vectors of values and I want to compare them statistically. For simplicity assume A = [2 3 5 10 15] and B = [2.5 3.1 4.8 10 18]. I want to compute the standard deviation, the root mean square error (RMSE), the mean, and present conveniently, maybe as histogram. Can you please help me how to do it so that I understand? I know question is probably simple, but I am new into this. Many thanks!
edited:
This is how I wanted to implement RMSE.
dt = 1;
for k=1:numel(A)
err(k)=sqrt(sum(A(1,1:k)-B(1,1:k))^2/k);
t(k) = dt*k;
end
However it gives me bigger values than I expect, since e.g. 3 and 3.1 differ only in 0.1.
This is how I calculate error between reference value of each cycle with corresponding estimated in that cycle.
Can you tell me, am I doing right, or what's wrong?
abs_err = A-B;
The way you are looping through the vectors is not element by element but rather by increasing the vector length, that is, you are comparing the following at each iteration:
A(1,1:k) B(1,1:k)
-------- --------
k=1 [2] [2.5]
=2 [2 3] [2.5 3.1]
=3 [2 3 5] [2.5 3.1 4.8]
....
At no point do you compare only 2 and 2.1!
Assuming A and B are vectors of identical length (and both are either column or row vectors), then you want functions std(A-B), mean(A-B), and if you look in matlab exchange, you will find a user-contributed rmse(A-B) but you can also compute the RMSE as sqrt(mean((A-B).^2)). As for displaying a histogram, try hist(A-B).
In your case:
dt = 1;
for k=1:numel(A)
stdab(k) = std(A(1,1:k)-B(1,1:k));
meanab(k) = mean(A(1,1:k)-B(1,1:k));
err(k)=sqrt(mean((A(1,1:k)-B(1,1:k)).^2));
t(k) = dt*k;
end
You can also include hist(A(1,1:k)-B(1,1:k)) in the loop if you want to compute histograms for every vector pair difference A(1,1:k)-B(1,1:k).

Efficient way of finding average difference between elements in array

Hope title isn't confusing. It's simple to show by example. I have a row vector like so: [1 5 6]. I want to find the average difference between each element. The differences in this example are 4 and 1 so the average is 2.5. This is a small example. My row vectors might be very large. I'm new to MatLab so is there some efficient way of using MATLAB's efficient matrix/array manipulation to do this nicely?
There is a similar question on SOF already but this question is specifically for MATLAB!
Thanks :)
EDIT: As queried by #gnovice, I wanted the absolute difference.
Simple solution using diff and mean
aveDiff = mean(diff(myVector)) %#(1)
Example
>> v=[1 5 6]
v =
1 5 6
>> mean(diff(v))
ans =
2.5000
This works but #Jonas' answer is the correct solution.
Edit
From #gnovice, #vivid-colours and #sevenless comments.
The mean of the absolute value of the difference can be found by inserting abs into (1)
aveDiff = mean(abs(diff(myVector))) %#(2)
If you have an array array, then the average difference is
(array(end) - array(1))/(length(array)-1)
because diff(array), where array = [a b c d], is [b-a c-b d-c]. The average of that is (b-a+c-b+d-c)/3, which simplifies to (d-a)/3.
In your example
array = [1 5 6];
(array(end)-array(1))/2
ans =
2.5
If X is your vector, you can do
mean( X(2:end) - X(1:end-1) )