2

I have an array as shown here. Here Bandit is a class that I created.

bandits = [Bandit(m1),Bandit(m2),Bandit(m3)];

Now, I want to do the following. Following is Python code which immediately gives me the maxarg of the value of the mean of each of these objects.

j = np.argmax([b.mean for b in bandits])

How can I do the same in MATLAB? To give more clarity, every bandit object has an attribute mean_value. I.e. if b1 is a bandit object, then I can get that value using dot operator (b1.mean_value). I want to find which among b1, b2, b3 has maximum mean_val and need to get the index for it. (See the python code above. If b2 has the highest mean_val, then finally, j will contain index 2.)

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • Possible duplicate of [Index of max and min value in an array](https://stackoverflow.com/questions/14556733/index-of-max-and-min-value-in-an-array) – David Parks Apr 11 '18 at 20:46
  • Also on matlabcentral: https://www.mathworks.com/matlabcentral/answers/76467-how-do-i-find-argmax – David Parks Apr 11 '18 at 20:49
  • Not at all. My question is more specific. The array contains objects of a user-defined class. I want to select the index of an object whose mean (ie egLobject1.mean) is maximum. In Python, it is a one-liner. Want to knowhow this can be done in MATLAB – user3137598 Apr 11 '18 at 20:50
  • 1
    @DavidParks: This is not a duplicate of that question. The answer there only works for numeric arrays, not for arrays of a custom type. – Cris Luengo Apr 11 '18 at 21:02
  • Gotcha, thanks for the clarification. – David Parks Apr 11 '18 at 21:04

1 Answers1

1

arrayfun applies a function to each element of an array. It results in a new array with the results of the operation. To this result you can then apply max as usual:

[~,arg] = max(arrayfun(@mean,bandits));

Note that this might not work if you have overloaded the subsref or size methods for the Bandit class.


Edit:

So now I understand that mean was not a function but an attribute. The operation x.mean can be expressed as the function call subsref(x,substruct('.','mean')). Thus, it is possible to change the solution above to call this function on each array element:

op = @(x)subsref(x,substruct('.','mean'))
[~,arg] = max(arrayfun(op,bandits));

That is, instead of calling the function mean, we call the function subsref to index the attribute mean.

If bandits is a simple struct array, then the following will work also:

[~,arg] = max([bandits.mean]);

Here, bandits.mean will extract the mean value for each element of the struct array, yielding a comma-separated list. This list is captured with the square brackets to form a vector. This vector is again input into the max function as usual.

I'm not sure if this latter solution works also for custom classes. I don't have your Bandit class to test. Please let me know if this latter solution works, so I can update the post with correct information.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • To give more clarity, every bandit object has an attribute 'mean_value'. ie If b1 is a bandit object, then I can get that value using dot operator (b1.mean_value). I want to find which among b1,b2,b3 has maximum mean_val and need to get the index for it (see the python code above. It loops through bandits array. Check which among b1,b2,b3 has mean_val as maximum. If b2 has the highest mean_val, then finally, j will contain index 2) – user3137598 Apr 12 '18 at 05:16
  • @user3137598: I have edited the answer, I hope the nicer solution works for custom classes, but I don't know. Otherwise, the ugly solution can be used. :) – Cris Luengo Apr 12 '18 at 06:09