# Find the minimum element of a row of a matrix and its column index for each row

I am trying to find the minimum value of a row of a matrix and its corresponding column. Please run the code below. OptV is the matrix that I would like to create which must give the output of the minimum of each row and its corresponding column index in VAll matrix.

    Clear[OptV, V,VAll, NU, EDD, PCP]
binc = 0.2;
InitV[cs_, cc_, ED_, P_, NL_, pR_, pW_, b_] = Table[1, {b, 0, 1, binc}];
V[1] := InitV[cs, cc, ED, P, NL, pR, pW, b];
NU[cs_, cc_, ED_, P_, NL_, pR_, pW_, b_] = Table[NL + (1 - b) (cs + (1 - pR) (P + pW ED)) + b ED, {b, 0, 1,
binc}];
PCP[cs_, cc_, ED_, P_, NL_, pR_, pW_, b_] = Table[(1 - b) cs +
b cc + (1 - (1 - b) pR) (P + (b + (1 - b) pW) ED), {b, 0, 1,
binc}];
EDD[cs_, cc_, ED_, P_, NL_, pR_, pW_, b_] = Table[ED, {b, 0, 1, binc}];

For[i = 2, i < 20, i++, V[i_Integer] := V[i] = Min /@ Transpose[{Table[(1 - b) cs + b cc + (1 - (1 - b) pR), {b, 0, 1,
binc}]*V[i - 1], PCP[cs, cc, ED, P, NL, pR, pW, b],
NU[cs, cc, ED, P, NL, pR, pW, b],
EDD[cs, cc, ED, P, NL, pR, pW, b]}]];
W[cs_, cc_, ED_, P_, NL_, pR_, pW_, b_] = Table[(1 - b) cs + b cc + (1 - (1 - b) pR), {b, 0, 1, binc}]*V[i];
VAll[cs_, cc_, ED_, P_, NL_, pR_, pW_, b_] =
Transpose[{W[cs, cc, ED, P, NL, pR, pW, b],
PCP[cs, cc, ED, P, NL, pR, pW, b],
EDD[cs, cc, ED, P, NL, pR, pW, b],
NU[cs, cc, ED, P, NL, pR, pW, b]}];
OptV[cs_, cc_, ED_, P_, NL_, pR_, pW_, b_] =
With[{m = Min@#}, {m, Position[#, m][[1, 1]]}] & /@
VAll[cs, cc, ED, P, NL, pR, pW, b];
With[{cs = 1, cc = 10, ED = 100, P = 25, NL = 5, pR = 0.1, pW = 0.25},
MatrixForm[VAll[cs, cc, ED, P, NL, pR, pW, b]]]
With[{cs = 1, cc = 10, ED = 100, P = 25, NL = 5, pR = 0.1, pW = 0.25},
MatrixForm[OptV[cs, cc, ED, P, NL, pR, pW, b]]]

• I presume the ai in the first two functions was meant as multiplication?
– ciao
Commented May 1, 2016 at 1:04
• Hi, yes it is multiplication, but please do not worry about the particular function written there. I am simply trying an example here a simple one. Commented May 1, 2016 at 1:05
• With[{m = Min@#}, {m, Position[#, m][[1, 1]]}] & /@ Opt[...] if only 1 minimum is expected per row, With[{m = Min@#}, {m, Position[#, m]}] & /@ Opt[...] if multiple minimums can be in a row, in which case the vector of positions results. If the array is going to be huge, there are more efficient ways...
– ciao
Commented May 1, 2016 at 1:10
• Hi, first of all thank you very much. And yes this will be a huge matrix most probably 1000 by 1000. Commented May 1, 2016 at 1:12
• 1k x 1k is not all that big, so performance s/b fine with the above. Give it a whirl, if you need faster, comment...
– ciao
Commented May 1, 2016 at 1:21

You have your matrix,

mat =
With[{cs = 1, cc = 10, ED = 100, P = 25, NL = 5, pR = 0.1,
pW = 0.25}, VAll[cs, cc, ED, P, NL, pR, pW, b]]
(* {{87.4, 46., 100, 51.}, {229.896, 62.6, 100, 61.8}, {402.204,
79.8, 100, 72.6}, {613.824, 97.6, 100, 83.4}, {864.756, 116., 100,
94.2}, {1100., 135., 100, 105.}} *)


You can get the list you want using Min, First, and Ordering,

{Min@#, First@Ordering[#, 1]} & /@ mat
(* {{46., 2}, {61.8, 4}, {72.6, 4}, {83.4, 4}, {94.2, 4}, {100,
3}} *)


You could make it slightly more efficient by using using With to avoid calling Min, but on a test matrix with over 400 million elements I got a speedup of less than .2 seconds.

Of course, this assumes that you only are interested to have a single column position for each row - so if the minimum value appears more than once you get the column number of its first appearance. From the OP it sounds like this is what is wanted.

• If you're going to assume that there's only one minimum per row (and/or only care about first found, as it appears in OP), With[{o = First@Ordering[#, 1]}, {#[[o]], o}] & is much more efficient, particularly on large arrays...
– ciao
Commented May 2, 2016 at 8:00
• @ciao - Thanks, that really does speed it up! Commented May 2, 2016 at 8:15

If I understand you right, you may want to try this,

k[a_, i_] := Position[opt[a, i], Min[opt[a, i]]] // Flatten


However, in your example the minimum will always be the upper leftmost element of your final array, Opt[a,i].

I would also advise using different symbols. Personally I avoid capitol letters generally and symbols that could conflict with Mathematica's built-in definitions.

• This did not work Commented May 2, 2016 at 2:45
• Could you check my code above? I edited my post now you can see the functions. Commented May 2, 2016 at 2:56
• What went wrong? My code was designed to return the row and column indices of the minimal element(s). Maybe that's not what you want? You can also find the minimal values themselves by the following code, mm[[Sequence @@ #]] & /@ k[a,i] Commented May 2, 2016 at 13:37
• I ran your first block of code and tested it the following code Position[test, Min[test]] // Flatten, where test is the matrix VAll evaluated at the values you specified. It gives the minimum at position {1,2}. test[[1,2]]=46 which, upon inspection of the matrix elements is correct. Again, maybe you are looking for something different than this? Commented May 2, 2016 at 14:13
• Okay, try this--a modification of your code, OptV= With[{cs = 1, cc = 10, ED = 100, P = 25, NL = 5, pR = 0.1, pW = 0.25}, {#, Position[#, Min@#][[1, 1]]} & /@ VAll[cs, cc, ED, P, NL, pR, pW, b]] This produces a list of each row and the position within that row of the minimal element. Commented May 2, 2016 at 14:30