# Maximizing functions with Which statements

I'd like to be able to find the maximum value that my Capex function (see below) generates. This is a fairly simple function so I could just add it up but I have more complex functions of a similar form that I'll need to maximize.

Capex[romSize_, CCSPsize_, washRate_, miningRate_] :=
Module[{val, rom = romSize, CCSP = CCSPsize, wash = washRate},
val = 0;
Which[CCSP > 500, val = val - 100];
Which[rom >= 200 && rom < 300, val = val - 5, rom >= 300,
val = val - 10];
Which[wash >= 1300 && wash < 1500, val = val - 10, wash >= 1500,
val = val - 20];
Which[miningRate >= 5.5 && miningRate < 5.7, val = val - 10,
miningRate >= 5.7, val = val - 20];
Return[val]
];


The problem I have is that because it contains Which statements the Maximize function doesn't seem to work. I could spam the Capex function with values in the domain and pick the largest value but I was hoping Mathematica had some functionality to make it a little easier, kind of like Goal Seek in Excel.

An example of a simple maximize call would be

Maximize[{Capex[x, 600, 1500, 6], 120 <= x <= 300}, {x}]


The max value of -240 is correct but x=300 is not

• I'm getting $x=120$ as the value from Maximize[]; have a look at Plot[Capex[x, 600, 1500, 6], {x, 120, 300}] to see why. – J. M.'s ennui Oct 30 '12 at 2:40

Since you're not using Which for more complex constructs or using a "default value", I suggest discarding the Which construct and instead adopting a far simpler approach to defining your Capex function:

capex[rom_, CCSP_, wash_, mining_] :=
-100 ( CCSP   >  500                 ) +
-5   ( rom    >= 200  && rom < 300   ) +
-10  ( rom    >= 300                 ) +
-10  ( wash   >= 1300 && wash < 1500 ) +
-20  ( wash   >= 1500                ) +
-10  ( mining >= 5.5  && mining < 5.7) +
-20  ( mining >= 5.7                 ) /. {True -> 1, False -> 0}


or as J. M. notes, using Boole and Dot:

capex[rom_, CCSP_, wash_, mining_] :=
{-100, -5, -10, -10, -20, -10, -20}.Boole[{CCSP > 500, 200 <= rom < 300, 300 <= rom,
1300 <= wash < 1500, 1500 <= wash, 5.5 <= mining < 5.7, 5.7 <= mining}]


You can verify that the above and your function return the same value for the same input.

• As an alternative implementation: capex[rom_, CCSP_, wash_, mining_] := {-100, -5, -10, -10, -20, -10, -20}.Boole[{CCSP > 500, 200 <= rom < 300, 300 <= rom, 1300 <= wash < 1500, 1500 <= wash, 5.5 <= mining < 5.7, 5.7 <= mining}] – J. M.'s ennui Oct 30 '12 at 2:36
• I can confirm that it returns the same value. Is there an easy way to maximize your capex function? – Cam Oct 30 '12 at 2:37
• @Cam Why isn't it working for you? NMaximize[{capex[x, 600, 1500, 6], 120 <= x <= 300}, {x}] gives me {-140., {x -> 120.911}} – rm -rf Oct 30 '12 at 3:22
• I've modified my capex function to use the Boole function and that worked when I tried to maximize it. Thanks for the help guys, it would have taken me ages to figure that one out by myself. – Cam Oct 30 '12 at 4:26
• @Cam: you might also be interested in the functions ArgMax[] and MaxValue[], if you only need particular components of the output of Maximize[]. – J. M.'s ennui Oct 30 '12 at 8:55