Why does my Matlab Random Shuffle not work? - matlab

I tried figuring this out but it doesn't work.
Say I have
a = [5,1,5,6,7,2,4];
Now, if I do a(randperm(a)) i get :
ans =
1 7 6 5 5
Now, I also have
b = [1,2,3,4,5,6,7,8,9,10];
However, if I do b(randperm(b)) :
ans =
1
Why is this happening? This does not seem to make any sense to me. How do I shuffle a vector like :
z = [1,2,3,4.... 1500,6001,6002,6003... 8999];

randperm takes a single N and returns a permutation of the numbers 1 to N.
I don't have Matlab installed so I can't try this out, but this should work:
a(randperm(length(a)))

The parameter of randperm should not be the array but it's length.
Try
B(randperm(length(B)))

Related

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

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

Matlab: How to multiply sub vectors of two larger vectors?

Are there some nice way to do following.
I have 2 vectors where I want to only make sub vector multiplications. For examples,
a = 1:6; b = (1:6)'
Then I'd like the result:
result = [1*1+2*2+3*3; 4*4+5*5+6*6] = [14; 77]
So, I'd like to multiply each sub vectors of 3 element with each others. In the end, last element of the vector result would then be the sum or the result of a*b
Thank you in advance for your help
This can be done as
sum(reshape(a,3,[]).*reshape(b,3,[])).'
or
dot(reshape(a,3,[]),reshape(b,3,[])).'
maybe I'm missing something, but isn't it as simple as:
>> [a(1:3)*b(1:3) a(4:6)*b(4:6)]
ans =
14 77
??

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

Matrix to Vector Conversion in Matlab

I have a MxN Matrix and would like to convert into a vector MNx1 with all the elements of the row from the Matrix as the elements of the Vector.
I tried using reshape but I was not successful.
Here is the small code snippet and the expected result.
S=[0 1
1 0
1 1
1 1 ]
Expected Result:
S_prime= [ 0 1 1 0 1 1 1 1]
P.S: Using a loop and concatenation is not an option, I am sure there is a easy straight forward technique, which I am not aware.
Thanks
You could try transposing S and using (:)
S = S'
S_prime = S(:)
or for a row vector:
S_prime = S(:)'
Reshape takes the elements column wise so transpose S before reshaping.
>> reshape(S',1,[])
ans =
0 1 1 0 1 1 1 1
reshape(S',1,prod(size(S)))
or shortcut
reshape(S',1,[])
But the question makes me wonder what your original problem is, and if this way really is part of the correct solution to the original problem.
Octave has a very nice function: vec().
The document at http://www.mathcs.emory.edu/~nagy/courses/fall10/515/KroneckerIntro.pdf states the following.
vector x = vec(X)
can be obtained with the MATLAB statement: x = reshape(X, q*n, 1)

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) )