How to do multivariable assignment in octave? - matlab

I want to do multivariable assignment. I can do [a,b] = min([1 2 3]) but I can't do [a,b] = [1,2]. Why? Is there any workaround?

The [1,2] on the right hand side of the assignment is interpreted as array with the two elements 1 and 2.
If you want to do the multi-variable-assignment in one line, you can use deal in Matlab. This should work in Octave as well according to the documentation here.
>> [a,b] = deal(1,2)
a =
1
b =
2
The advantage of using deal is that it works in Matlab as well, where the solution with [a b] = {1 2}{:} won't.

Octave basics: How to assign variables from a vector
>> [a b c] = {5 6 7}{:}
a = 5
b = 6
c = 7

To adapt Cobusve's answer to Matlab, two lines are required:
>> h={5 6 7}
h =
[5] [6] [7]
>> [a b c]=h{:}
a =
5
b =
6
c =
7

Related

MATLAB: Compare matrices built with repelem and repmat

I have an array a of size ZxW.
Z = 20;
W = 30;
A = 40; %will be used below
size(a)
20 30
Then I apply to a two different transformations, and then after those I delete a and I cannot go back to it.
First transformation:
b = repelem(a(:,1),A,A);
Second transformation:
c = repmat(a,[1,1,A,A]);
d = c(:,1,:,:);
After those transformations and deleting a (which cannot be used for the following), I want to compare d and b using
assert( isequal(b,f) )
Where f is a transformation of d that makes the assertion true.
My first idea was a simple reshape:
f = reshape(squeeze(d),[Z*A,A]);
Which does not work as repelem and repmat move entries differently. How can I do this?
Thanks for the attention.
Sincerely
Luca
EDIT: changed
c = repmat(a,[A,A]);
with
c = repmat(a,[1,1,A,A]);
The answer (by Jan Simon) is:
f = reshape(permute(d, [3,1,4,2]), [Z*A,A]);
isequal(b, f) % 1: equal
Thanks for the help.
Luca
NOTE: This solution is obsoleted with the edited question, please refer to the other solutions posted.
Look closely at what the pattern of b and d are:
b = [1 1 1 2 2 2 3 3 3].'
d = [1 2 3 1 2 3 1 2 3].'
Hence, the transformation f can be:
f = reshape(d, [A, A]).'
f = f(:)
This will convert d to be exactly b or vice versa.

Subset array to members of another array in Matlab

I am looking for a functionality i Matlab to subset and array like the IN function in SQL or %in% in R. I.e. I have the following data:
a = 1:3;
b = 2:4;
Then I want to write something like:
(a %in% b)
And it should produce:
ans =
0 1 1
However using %in% clearly doesn't work.
You are probably looking for the function ismember, which checks which members of one matrix are also member of a second matrix. It returns true/false for each entry in your matrix a if it can/cannot be found in your matrix b.
ismember(a, b)
ans =
0 1 1
As a side note: % is the character, which starts a comment.
You could also do it with bsxfun:
result = sum(bsxfun(#eq, a(:).', b(:)), 1);
This has the advantage that it tells you how many elements of b equal each element of a. For example,
>> a = [1 2 3];
>> b = [2 3 4 2];
>> result = sum(bsxfun(#eq, a(:).', b(:)),1)
result =
0 2 1

How to Convert Vector to String in Matlab

I'm hoping to find a simple way of converting a vector of numbers to a string in matlab.
Lets say I have a vector b,
b[1 2 4 3];
is there something simple such as
b = vect2str(b);
how about
b = [1 2 4 3];
b = num2str(b);

Matlab: Vectorize the transpose in one step? [duplicate]

This question already has an answer here:
effective way of transformation from 2D to 1D vector
(1 answer)
Closed 9 years ago.
I would like to use the (:) operator and the transpose at the same time. Is this possible? Basically I would like to do something like
output = A'(:)
except that this does not work. Does anyone know a workaround?
Thanks!
Immo
The : operator in this case is shorthand for reshaping the matrix into a vector. You can work around the limitation of where you use the operator by using the reshape function explicitly:
octave> A = [1 2;3 4]
A =
1 2
3 4
octave> B=A'
B =
1 3
2 4
octave> C=B(:)
C =
1
2
3
4
octave> D=reshape(A',[],1) #% vectorize transpose in one line
D =
1
2
3
4
Try with:
output = reshape( A.', numel(A), 1);
>> A = rand(4,3);
>> output = reshape( A.', numel(A), 1);
A =
0.447213 0.046896 0.679087
0.903294 0.768745 0.651481
0.701071 0.122534 0.611390
0.535844 0.478595 0.772810
output =
0.447213
0.046896
0.679087
0.903294
0.768745
0.651481
0.701071
0.122534
0.611390
0.535844
0.478595
0.772810
Beware that reshape reads the matrices accessing along columns so you may not need to transpose the matrix A.
Also, remember that the operator ' is the hermitian operator, namely, conjugated of the transposed, whereas .' is simply transposition, which you could also get by transpose(A).
You may want to do everything in a single line without re-typing all every time. One solution is creating a function handles as boop:
>> boop = #(x) reshape( transpose(x), numel(x), 1)
>> output = boop(A)
output =
0.447213
0.046896
0.679087
0.903294
0.768745
0.651481
0.701071
0.122534
0.611390
0.535844
0.478595
0.772810

"Desort" a vector (undo a sorting)

In Matlab, sort returns both the sorted vector and an index vector showing which vector element has been moved where:
[v, ix] = sort(u);
Here, v is a vector containing all the elements of u, but sorted. ix is a vector showing the original position of each element of v in u. Using Matlab's syntax, u(ix) == v.
My question: How do I obtain u from v and ix?
Of course, I could simply use:
w = zero(size(v));
for i = 1:length(v)
w(ix(i)) = v(i)
end
if nnz(w == u) == length(u)
print('Success!');
else
print('Failed!');
end
But I am having this tip-of-the-tongue feeling that there is a more elegant, single-statement, vectorized way of doing this.
If you are wondering why one would need to do this instead of just using u: I was trying to implement the Benjamini-Hochberg procedure which adjusts each element of the vector based on its position after sorting, but recovering the original order after adjusting was important for me.
The solution is:
w(ix) = v;
This is a valid Matlab operation provided that w is either at least as big as v, or not yet declared.
Example:
>> u = [4 8 10 6 2];
>> [v, ix] = sort(u)
v = 2 4 6 8 10
ix = 5 1 4 2 3
>> u(ix)
ans = 2 4 6 8 10
>> w(ix) = v
w = 4 8 10 6 2
(Apologies for the trivial question-answer, but I realized the solution as I was typing the question, and thought it might be useful to someone.)