Question

I have a multi-dimensional maximization problem. There are (let's say) one state and two control variables (x1 and x2,x3 respectively): for each value of the state variable x1, we maximize some objective function by varying x2 and x3.

In Matlab, then, I have a 3-dimensional array, let's call it F, with x1 in the first dimension and (x2,x3) in the latter dimensions.

Getting the max is easy--just set: F_star=max(max(F,[],2),[],3); This returns the length-N_1 vector of maxima for each x1.

My problem is with getting the indices / coordinates of the maximizer(s).

My first guess was to use the extended function call:

[F_star, maximizers]=max(max(F,[],2),[],3);

However, this only operates on the OUTERMOST max function, and so will only return the maximizing index in the 3rd dimension.

One could, of course, just repeat this and permute the dimensions:

[F_star, maximizers_3]=max(max(F,[],2),[],3);

[F_star, maximizers_2]=max(max(F,[],3),[],2);

But it hardly seems efficient to take the max twice (which is important for my actual problem because there are actually 3 control variables and 7 state variables, so it is quite a burden to search over my whole array).

Any ideas for a simpler way to extract all of the coordinates or indices?

For concreteness, here's a simple example:

F = 10*rand(2,2,2)

[y, z3] = max(max(F,[],2),[],3)

[y, z2] = max(max(F,[],3),[],2)

F(:,:,1) =

    2.1203    9.1380

    0.7735    7.0672


F(:,:,2) =

    5.5779    1.6620

    3.1343    6.2250


y =

    9.1380

    7.0672


z3 =

     1

     1


y =

    9.1380

    7.0672


z2 =

     2

     2

By combining z2 & z3, we get what we want: The max when at the first value of x1 (i.e., in F(1,:,:)) is 9.1, which happens at (z2(1),z3(1)) -- F(1,z2(1),z3(1))=F(1,2,1)

The max when at the first value of x2 (i.e., in F(2,:,:)) is 7.1, which happens at (z2(2),z3(2)) -- F(1,z2(2),z3(2))=F(2,2,1)

It would be awesome to have something like: [F_star, z2, z3] = max(F,[2 3])

Was it helpful?

Solution

"Linearize" (combine) 2nd and 3rd dimensions with reshape; get the linear index of the maximizers along the combined dimensions; and convert to two subindices with ind2sub:

[F_star ind] = max(reshape(F, size(F,1), []), [], 2);
[z2 z3] = ind2sub([size(F,2) size(F,3)], ind);

That will give you the maximum (F_star) and its position in 2nd and 3rd dimensions (z2, z3), for each 1st-dimension slice.


For more than three dimensions, if you want to maximize for each 1st-dimension slice, the generalization is easy:

s = size(F);
[F_star ind] = max(reshape(F, s(1), []), [], 2);
z = cell(1,numel(s)-1);
[z{:}] = ind2sub(s(2:end), ind);

The position is given in a cell array z, such that z{1} is your z2, z{2} is your z3 etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top