Matlab function help with returning minimum in an array

Hello, I am tasked with translating matlab code into Julia. I know Julia better than I do Matlab, so I am trying to understand a line of code:
[~,pStar] = min(min([dPlus,dMinus],[],2))
pStar, dPlus, dMinus are variables that I have defined earlier. I am not entirely sure what the function is doing. I did read the function explanation on the mathworks site, but I still don't understand it entirely. Thank you.

1 Comment

"pStar, dPlus, dMinus are variables that I have defined earlier"
The code you have shown allocates the second output of min to the variable pStar, so any previous definition of pStar is irrelevant and will simply be discarded.

Sign in to comment.

 Accepted Answer

[~,pStar] = min(min([dPlus,dMinus],[],2))
[~, % ignores this output
pStar] % allocates second output (index) to pStar
= min( ) % call min with one input argument
min( 2) % call min, third input = min along second dimension.
,[], % only to ensure position of the third input argument
[dPlus,dMinus] % concatenate dPlus and dMinus horizontally
If the input [dPlus,dMinus] is a matrix then the code will find the row with the minimum value in it. You can check this be trying a simple example:
>> M = [1,1,1;1,1,0;1,1,1]
M =
1 1 1
1 1 0
1 1 1
>> min(M,[],2)
ans =
1
0
1
>> [~,row] = min(min(M,[],2))
row = 2

More Answers (3)

So to confirm, in plain english, the code returns the minimum element in each row into column form, then returns the index (row) of the minimum element?

17 Comments

I think I am getting a little tripped up on the complexity/redundancy of this. Why couldn't the code just return the index of the minimum right at the beginning?
"Why couldn't the code just return the index of the minimum right at the beginning?"
  • Which index: the row index, the column index, the linear index? A logical index? Or both subscripts at once? Which of these is the "proper" index that it should return? MATLAB has three supported indexing paradigms, all of which are useful in different situations. Which one do you want here?
  • Which minimum/s: the minimum per row (as this code seems to do), or the minimum overall in the entire input array?
What output do you expect?
So the code takes the minimum in each row, then returns it in column form, then takes the minimum in that column. At the end of the day, it's the row of the _very _minimum __of the entire array. Why not have a code to return the minimum from the start?
This is someone else's code that I have been tasked with translating into Julia, so I am not 100% sure of the expected outcome. I simply interpret what is written and will write the equivalent in Julia. Thank you
"At the end of the day, it's the row of the _very _minimum __of the entire array. Why not have a code to return the minimum from the start?"
Because what you want is not the only possible "minimum" that other users might want, nor is it the only kind of "index". Not all users want the global min/max like you do, some might want the minimums per row/col/page... just as not all users want a row/col/page/... index, but require a linear index. Or perhaps a logical index. How would you support all of these combinations with one function, using just a limited number of positional arguments? Of course the modern fashion is for languages to have named input arguments to select different modes, but this just transfers the complexity into selecting the correct combination of input options.
If you can show me a language where the min operator (without any others) can optionally return the global/row/column/page/.../multidim/... minimum value/s and optionally return the row/col/page/../linear/logical/... index/indices and uses exactly the same number of positional arguments as MATLAB's min does, then I would be very impressed indeed.
I would be curious to see how simply Julia can obtain the row index of the global minimum of a matrix: can you please show how this would look like? Is it much simpler?
PS: Note that MATLAB functions like min, max, sort, and other similar functions return the indices along the dimension operated along. This is simply what they are designed to do, and is clearly documented in the help.
I'm sensing a little miscommunication. I am not talking about matlab's judgement to make syntaxes, I am referring to the line of code in question. In other words, is the code written unnecessarily complex, or is there something the code is doing, that I have missed? I am guessing by your last answer, that it's done this way because matlab simply cannot do it the way I suggest.
Moreover, Julia seems to be able to return an index of the row which has the smallest element in it.
>>A=[5 7 3; 5 8 6; 2 5 7]
>3x3 Array{Int64,2}
5 7 3
5 8 6
2 5 7
>>indmin(A)
>3
"In other words, is the code written unnecessarily complex"
So far you have not actually told us any specifications about what you need that code to do (in particular the sizes of the input data, and the expected output), so I have no idea if it is too complex or not.
"Why not have a code to return the minimum from the start?"
min always returns the minimum/s and subscript index/indices along the dimension operated along. For some users that might be exactly what they need... and for some other users that might not be what they need. In my previous comments I explained how it would be impractical so support all possible output indices that all of these users might want (of which yours is just one).
PS: thank you for the Julia code. Please try it with this matrix:
A = [5 7 3; 5 8 0; 9 5 7]
As far as I can tell, Julia's indmin returns a linear index, and just because you happened to try a matrix where the third element is the smallest it looks as if it gives the row index. You are probably comparing apples with oranges.
PPS: if indmin really does return a linear index, then the simplest MATLAB equivalent would be:
>> A = [5 7 3; 5 8 6; 2 5 7];
>> [~,idx] = min(A(:))
idx = 3
where A(:) converts the entire array into a column vector.
PPPS: What is the Julia code to return the row index of the global minimum of a matrix? As far as I can tell, it would be:
idx = ind2sub(size(A),indmin(A))
and then take the first element of idx. As long as A was a matrix, then this would give the same output as the code in your question. As far as I can tell, indmin has no ability to specify a dimension, so for higher dimension arrays does not appear to be a Julia equivalent to the MATLAB code in your question.
indeed it does return a linear index. Looks like it was just a coincidence that it happened to be in the same row to make it appear as though it's returning a row index. So, then,
indmin(hcat(dPlus, dMinus))
appears to be the matlab equivalent in Julia...?
PS: the matlab code is the code that cannot change. It is already working correctly as it is. It is Julia that I am finding an equivalent for. Thank you!
indmin(hcat(dPlus, dMinus))

"appears to be the matlab equivalent in Julia...?"

Nope: remember that your original MATLAB code returns the row index, not the linear index like your Julia code. So you will need to wrap it all in ind2sub to get the row index. Because ind2sub also requires the array size it would be easiest to define it beforehand:

A = hcat(dPlus, dMinus)
idx = ind2sub(size(A),indmin(A))

and then get the first element of idx.

Hmmm... that reminds me of something someone told me once about MATLAB:

https://www.mathworks.com/matlabcentral/answers/394708-matlab-function-help-with-returning-minimum-in-an-array#comment_558726

In the original matlab code, dPlus and dMinus are concatenated aren't they? So concatenated they are the "A" matrix?

"In the original matlab code, dPlus and dMinus are concatenated aren't they? So concatenated they are the "A" matrix?"

Yes, that is correct: they are horizontally concatenated, using the [] shorthand operator. See:

https://www.mathworks.com/help/matlab/matlab_prog/matlab-operators-and-special-characters.html

The matlab code takes the minimum elements in each row and returns them in column form.
My julia is essentially taking all the elements and putting them in column form and returning the index of the minimum element? Are these true statements?
Although that is not the exactly the equivalent of the matlab code, it might still work, although I do understand my originally question was to ultimately find the exact equivalent, so I thank you for that. Please confirm I understand that right. Thanks

"The matlab code takes the minimum elements in each row and returns them in column form"

Correct. Then it returns the row index of the minimum in that column.

"My julia is essentially taking all the elements and putting them in column form and returning the index of the minimum element?"

Correct. Then it uses ind2sub to find the equivalent row index.

Note that MATLAB also has ind2sub, so exactly the same method could be applied in MATLAB. But Julia does not seem to natively implement anything equivalent to MATLAB's dimension argument...

I am finished for today. Thank you for the interesting question and discussion!

Hello, thanks for your answer and explanation yesterday. I have a small problem that I am stuck on that I was hoping you could help me with.

The matlab code that I have is:

[~,pStar] = min(min([dPlus,dMinus],[],2));
        rOSCD = r(pStar) - R(pStar,:)*xOSCD + R(pStar,pStar)*xOSCD(pStar);
        xOSCD(pStar) = sign(rOSCD)*max(0,abs(rOSCD)-lambdaOSCD)/ ...
            R(pStar,pStar);

which includes a part from yesterday. I have written the translation in Julia, but I am getting the error: MethodError: Cannot `convert` an object of type Array{Float64,2} to an object of type Float64 This may have arisen from a call to the constructor Float64(...), since type constructors fall back to convert methods.

I have narrowed it down to this line of the code:

xOSCD(pStar) = sign(rOSCD)*max(0,abs(rOSCD)-lambdaOSCD)/ ...
          R(pStar,pStar);

the xOSCD is a 25x1 array {float 64,2} which indexes pStar (I think), = the sign of rOSCD (which I believe is a floating number, so it cannot convert from an array of float64 to a float64 (understandably).

Is matlab converting it, or am I translating it wrong in Julia? I could really use your help on this one, I think I am close to being done. I have pasted in the entire matlab code for your reference, but I am only focusing on %%OSCD-TWL. Thank you so much.

@Ryan Lockwood: I moved the code to a file, and uploaded this to your comment. If the MATLAB code runs correctly then this is a Julia problem, and you should ask on a Julia forum.
I guess you will have to do basic debugging: work through the variables, break that line down into its atomic operations, identify where the problem occurs, read the Julia documentation to see how to fix it, and compare against the MATLAB documentation. Do experiments and test what you are seeing on small sample data.
Fair enough. I wasn't sure if Matlab was able to auto convert from the array to a single floating point number, and Julia cannot. Totally stumped on this one. Thanks anyway. Though.

Sign in to comment.

I am actually not sure if the input [dMinus, Dplus] is vector or a matrix. Does the same apply still? Thanks

1 Comment

The inner min has the dimension specified, so it will always operate along the second dimension of the input, regardless of the shape of the input. This means that for any input array of size AxBxCx... it will return an array of size Ax1xCx...
The outer min will operate along the first non-singleton dimension. If the input has no more than two non-singleton dimensions (of which one is the second) then the outer min will get a vector input, and its output will be one single value. Otherwise it will return an array. As in your question you did not write what size dPlus and dMinus have I cannot say more than this.

Sign in to comment.

Would you happen to know what the equivalent to this is in Julia code?

Asked:

on 13 Apr 2018

Edited:

on 20 Apr 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!