Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting an If-Else statement into a Formula

I have code as follows:

`if (a <= 10){
    z = 5;
 } else {
    z = -1;
 }`

I figured out that when s(10 - a) = |10 - a| / (10 - a) where it outputs a 1 or -1. It outputs 1 if a < 10 and -1 if a > 10.

Then, I just solve the linear equation z = s(10 - a) * m + b, to find constants m and b.

5 = 1 * m + b and -1 = -1 * m + b Which outputs b = 2, m = 3.

Then this can be modeled as z = 3 * s(10 - a) + 2.

Now the question becomes more tricky. What if I have two variables in nested if statements? Such as:

`if (a <= 10){
    if(b <= 3){
       z = 3;
    } else {
       z = 1;
    }
 } else {
    if(b <= -5){
       z = -11;
    } else {
     z = 4;
    }
}`

I tried to solve this using another series of linear equations.

  1. 3 = A * s(10 - a) + B * s(3 - b) + C
  2. 1 = A * s(10 - a) + B * s(3 - b) + C
  3. -11 = A * s(10 - a) + D * s(-5 - b) + C
  4. 4 = A * s(10 - a) + D * s(-5 - b) + C

with A, B, C, D as constants. However, this isn't giving me the right answer. What am I doing wrong?

like image 211
Steven Avatar asked Sep 29 '16 02:09

Steven


2 Answers

An if statement can be transformed into a formula by using the following trick: we need to find a formula that's 1 if the if statement is true and 0 otherwise. We can use the signum function for this:

 f(x, y) = (sign(y - x) + 1) / 2

f(x, y) is 1 if x < y and 0 if x > y. The inverse g(x, y) = 1 - f(x, y).

So with those two formulas we can easily put together the whole thing:

f(a, 10) * (f(b, 3) * 3 + g(b, 3) * 1) + g(a, 10) * (f(b, -5) * -11 + g(b, -5) * 4)
like image 156
maraca Avatar answered Oct 18 '22 09:10

maraca


A general equation of the form:

((z2+z1)/2) + (|z2-z1|/2)*f(a,b)

where f(a,b) = |a-b|/(a-b)

In english: (midpoint between 2 given z values) + (distance from midpoint to either z value)*|a-b|/(a-b)

trying this on the original example:

if (a <= 10){
    z = 5;
 } else {
    z = -1;
 }

you get:

z1=5 z2=-1

f(a,b)=f(10,a)=|10-a|/(10-a)

plugging these in...

((5-1)/2) + (|5-(-1)|/2)*|10-a|/(10-a)

simplifying to your original z = 3 * s(10 - a) + 2

When applying this to nested conditional:

if (a <= 10) {
  ... // z1
} else {
  ... // z2
}

for z1 i get z1 = 2 + |3-b|/(3-b)

for z2 i get -3.5 + 7.5*(|-5-b|/(-5-b)). z1 seems ok but z2 doesn't seem to work since if you tried b=0 you have z2 = -3.5 - 7.5*(1) but since 0>-5 you would expect z2 = 4 since:

if (b <= -5) {
  z = -11;
} else {
  z = 4;
}

to get the correct expression i swapped the definition of f(a,b) = |a-b|/(a-b) to f(a,b) = |b-a|/(b-a) the new result being z2 = -3.5 + 7.5*(|b+5|/(b+5)) and testing b=0 gives the correct result of 4. This reduces the nested conditional to look like the simpler problem

if (a <= 10) z =  2 + |3-b|/(3-b)

else z = -3.5 + 7.5*(|b+5|/(b+5))

which assuming you know b you can apply the same method above used for the simple case.

like image 34
Bobas_Pett Avatar answered Oct 18 '22 09:10

Bobas_Pett