5

I am running this command in Mathematica 8.0.4.0:

Minimize[(x1*1 - 1)^2 + (x1*0.823202 + x2*1 - 0.7551)^2 + 
         lambda*(Boole[x1 != 0] + Boole[x2 != 0]), {x1, x2}]

Now, with lambda=0 (negating the Boole functions), I get:

{7.70372*10^-34, {x1 -> 1., x2 -> -0.068102}}

With lambda=1, I get:

{2., {x1 -> 1., x2 -> -0.068102}}

It seems to be ignoring the Boole functions, because clearly x2 -> 0 is a better solution:

(x1*1 - 1)^2 + (x1*0.823202 + x2*1 - 0.7551)^2 + 
 lambda*(Boole[x1 != 0] + Boole[x2 != 0]) /. {x1 -> 1, x2 -> 0}

1.00464

I assume Mathematica is minimizing this function numerically; is it simply incapable of doing this with Boole functions, given their stepwise nature?

rcollyer
  • 33,976
  • 7
  • 92
  • 191
Craig W
  • 155
  • 3

1 Answers1

9

It switches to NMinimize (a numerical solver) automatically because you have inexact numbers in the expression, which don't go well with symbolic calculations.

Use Rationalize to convert them to exact numbers.

labmda = 1

Minimize[Rationalize[(x1*1 - 1)^2 + (x1*0.823202 + x2*1 - 0.7551)^2 + 
   lambda*(Boole[x1 != 0] + Boole[x2 != 0])], {x1, x2}]

{420574853802/419415383201, {x1 -> 405399957550/419415383201, x2 -> 0}}

Actually I am surprised that Minimize can handle things as general as Boole.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • So with the addition of Rationalize, it actually solves it analytically? How is that possible with the Boole functions? – Craig W Mar 02 '12 at 19:01
  • The problem I am really trying to solve is a little more complex, and the Rationalize trick doesn't seem to work for that: Minimize[Rationalize[(x11 - 1)^2 + (x10.823202 + x21 - 0.7551)^2 + (x10.396947 + x20.823202 + x31 - 0.3738)^2 + lambda*(Boole[x1 != 0] + Boole[x2 != 0] + Boole[x3 != 0])], {x1, x2, x3}] – Craig W Mar 02 '12 at 19:02
  • 3
    Use Minimize[Rationalize[(x1*1 - 1)^2 + (x1*0.823202 + x2*1 - 0.7551)^2 + (x1*0.396947 + x2*0.823202 + x3*1 - 0.3738)^2 + lambda*(Boole[x1 != 0] + Boole[x2 != 0] + Boole[x3 != 0]), 0], {x1, x2, x3}] to force Rationalize to produce an exact fraction even if the denominator will be terribly large. Sorry for no time for a more detailed explanation ... – Szabolcs Mar 02 '12 at 19:14
  • That works, thanks! A more detailed explanation of what is going on would be nice when you have time. – Craig W Mar 02 '12 at 19:18
  • 2
    @Szabolcs @Craig Just wanted to add that SetPrecision[..., Infinity] is a possible alternative to Rationalize[..., 0], which most likely will give a better representation if the inexact numbers are intended to represent particular machine double values rather than just some arbitrary real number. – Oleksandr R. Mar 02 '12 at 23:13