## Friday, February 1, 2013

### atan2 in scala

atan2 function is defined as follows:

I wanted to try a small exercise of implementing this using scala(ignoring the fact that it is already natively implemented in java.lang.Math library).

The simplest implementation that I could think of is with a if expression this way:

```def atan2(x: Double, y: Double):Double = {
if (x >0)                     atan(y/x)
else if (y >= 0 && x < 0)     Pi + atan(y/x)
else if (y < 0 && x < 0)      atan(y/x) - Pi
else if (y > 0 && x==0)       Pi/2
else if (y < 0 && x==0)       -Pi/2
else                          Double.NaN
}
```

However, I wanted to see at this point if it could be reimplemented using a case-match expression, and I could only come up with a souped up version of if/else this way:

```def atan2(x: Double, y: Double): Double = {
true match {
case _ if (x>0)             => atan(y/x)
case _ if (y >= 0 && x < 0) => atan(y/x) + Pi
case _ if (y < 0 && x < 0)  => atan(y/x) - Pi
case _ if (y > 0 && x==0)   => Pi/2
case _ if (y <0 && x==0)    => -Pi/2
case _                      => Double.NaN
}
}
```

After reading up a little more on scala extractors, I could come up with a crazier version of the same:
```def atan2(x: Double, y: Double): Double = {
(x, y) match {
case xgt0()           => atan(y/x)
case ygte0Andxlt0()   => atan(y/x) + Pi
case ylt0Andxlt0()    => atan(y/x) - Pi
case ygt0Andxeq0()    => Pi/2
case ylt0Andxeq0()    => -Pi/2
case _                => Double.NaN
}
}
```

However, this unfortunately requires defining 5 extractors this way:
```object xgt0 {
def unapply(tup: (Double, Double)): Boolean = tup match { case (x,y) => (x>0)}
}

object ygte0Andxlt0 {
def unapply(tup: (Double, Double)): Boolean = tup match { case (x, y) => (y >= 0 && x < 0)}
}

object ylt0Andxlt0 {
def unapply(tup: (Double, Double)): Boolean = tup match { case (x, y) => (y < 0 && x < 0)}
}

object ygt0Andxeq0 {
def unapply(tup: (Double, Double)): Boolean = tup match { case (x, y) => (y > 0 && x == 0)}
}

object ylt0Andxeq0 {
def unapply(tup: (Double, Double)): Boolean = tup match { case (x, y) => (y < 0 && x == 0)}
}
```

The only conclusion I could make out of this is that if I had to re-write atan2 in scala the best approach is probably using the first one - using if expression. I am sure there is definitely a more scala way of doing this and would definitely appreciate any suggestions on these approaches