4
$\begingroup$

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

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$ Oct 30, 2012 at 2:40

1 Answer 1

8
$\begingroup$

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.

$\endgroup$
5
  • 1
    $\begingroup$ 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}] $\endgroup$ Oct 30, 2012 at 2:36
  • $\begingroup$ I can confirm that it returns the same value. Is there an easy way to maximize your capex function? $\endgroup$
    – Cam
    Oct 30, 2012 at 2:37
  • $\begingroup$ @Cam Why isn't it working for you? NMaximize[{capex[x, 600, 1500, 6], 120 <= x <= 300}, {x}] gives me {-140., {x -> 120.911}} $\endgroup$
    – rm -rf
    Oct 30, 2012 at 3:22
  • $\begingroup$ 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. $\endgroup$
    – Cam
    Oct 30, 2012 at 4:26
  • 1
    $\begingroup$ @Cam: you might also be interested in the functions ArgMax[] and MaxValue[], if you only need particular components of the output of Maximize[]. $\endgroup$ Oct 30, 2012 at 8:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.