Generic conversion to Numeric - scala

I would like to write a generic conversion function converting a sequence of Doubles into any Numeric class, something along the lines of:
def construct[T : Numeric](a: Seq[Double]): Seq[T] = {
val n = implicitly[Numeric[T]]
a.map { value =>
value
???
}
}
The inverse is easy, using Numeric toDouble, but I did not find a way how to do this direction. How can that be done?

There is n.fromInt(value.toInt), but if you don't want to lose precision your are out of luck with scala.math.Numeric. I would suggest implementing your own type class:
trait Num[T] { def fromDouble(d: Double): T }
object Num { implicit val wateveryouneed = ... }
def construct[T](a: Seq[Double])(implicit n: Num[T]: Seq[T] =
a.map(n.fromDouble)

Related

Implicit conversion not performed on Int

In Scala, I want to generate some aliases for basic types, and then implement conversions through a type class. This is both useful for me, and an opportunity to understand type classes. The code is the following:
type Index = Int
val Index = Int
type Integer = Int
val Integer = Int
type Real = Double
val Real = Double // to have companion object of Double also be the companion object of Real
trait Convertible[A] {
def toIndex(a: A): Index
def toInteger(a: A): Integer
def toReal(a: A): Real
}
implicit val ConvertibleIndex: Convertible[Index] = new Convertible[Index] {
def toIndex(i: Index) = i
def toInteger(i: Index) = i
def toReal(i: Index) = i.toDouble
}
implicit val ConvertibleInteger: Convertible[Integer] = new Convertible[Integer] {
def toIndex(i: Integer) = i
def toInteger(i: Integer) = i
def toReal(i: Integer) = i.toDouble
}
implicit val ConvertibleReal: Convertible[Real] = new Convertible[Real] {
def toIndex(r: Real) = r.toInt
def toInteger(r: Real) = r.toInt
def toReal(r: Real) = r
}
implicit val ConvertibleString: Convertible[String] = new Convertible[String] {
def toIndex(s: String) = s.toInt
def toInteger(s: String) = s.toInt
def toReal(s: String) = s.toDouble
}
implicit class ConvertibleSyntax[A](a: A)(implicit val c: Convertible[A]) {
def toIndex = c.toIndex(a)
def toInteger = c.toInteger(a)
def toReal = c.toReal(a)
}
Consider now:
val a = 3.toReal
val b = 3.0.toReal
val c = "3".toReal
The statement for a does not compile, with the compilation error: method toReal is not a member of Int. But, for the b and c statements, the implicit conversion to ConvertibleSyntax is properly done.
Why is the implicit conversion not working on Int, but is working on Double and String ?
Because you define ambiguous implicits for Index and Integer (both Int).
Which one should be chosen by compiler?
I think you might be a little confused about how Scala does implicit conversions. (A common mistake, as implicit is a little overused.)
I think that what you want, first of all, is an implicit conversion function - or even an implicit class. Here's how you could do this using the latter:
Note: Int, Index and Integer are treated identically, so are Real and Double, confusing matters somewhat, so I've pared this down to something that will work. Also, Convertible does not need to be generic as its conversion functions need no arguments. Finally, you shouldn't have both type and val declarations for your types.
type Index = Int
type Integer = Int
type Real = Double
trait Convertible {
def toIndex: Index
def toInteger: Integer
def toReal: Real
}
// Implicit classes cannot be defined in top-level scope, so they belong to an object.
object Implicits {
implicit class ConvertibleInt(i: Int)
extends Convertible {
override def toIndex = i
override def toInteger = i
override def toReal = i.toDouble
}
implicit class ConvertibleDouble(d: Double)
extends Convertible {
override def toIndex = d.toInt
override def toInteger = d.toInt
override def toReal = d
}
implicit class ConvertibleString(s: String)
extends Convertible {
override def toIndex = s.toInt
override def toInteger = s.toInt
override def toReal = s.toDouble
}
}
Now try this:
import Implicits._
val a = 3.toReal
val b = 3.0.toReal
val c = "3".toReal
What's happening here? Well, the implicit class declarations define classes that decorate the sole constructor argument with additional functions. If the compiler sees that you're trying to call a method on a type that doesn't have that method, it will look to see if there's an implicit conversion, in scope, to a type that does. If so, it is used and the function is called; if not, you get a compiler error. (The import statement is used to bring the classes into your current scope.)
So, for example, when the compiler sees "3".toReal it firstly determines that "3" is a String. Since this type doesn't have a .toReal member, it tries to find a conversion from a String to a type that does have such a member. It finds the ConvertibleString implicit class that takes a String argument and provides a .toReal method. Yay! So the compiler creates an instance of this class by passing "3" to ConvertibleString's constructor, then calls .toReal on the result.
On the other hand, when implicit is used with a value, it tells the compiler that the value is a default for any matching implicit arguments of the same type that are not provided. NEVER USE implicit WITH A PRIMITIVE OR COMMON LIBRARY TYPE!
For example:
final case class Example(i: Int)
// Default.
implicit val nameCanBeAnythingAtAll = Example(5)
// Function with implicit argument.
def someFunc(implicit x: Example): Unit = println(s"Value is $x")
Now, if you write something like this:
someFunc
the output will be Value is Example(5).
implicit values and arguments are an advanced topic, and I wouldn't worry about how they're used right now.

Correct usage of inheritance for wrapper classes

I am trying to write a scala-wrapper for matrix operations, using the ejml library. Basically I just use SimpleMatrix. However, I want different classes for matrix and vector, for example to only be able to invert a matrix or to explicitly state that a function returns a vector, not a matrix. Currently, I am having trouble returning the concrete classes instead of the trait.
I started with a trait, MLMatrixLike:
trait MLMatrixLike {
def data: SimpleMatrix
protected def internalMult(implicit that: MLMatrixLike): SimpleMatrix = {
data.mult(that.data)
}
def *(implicit that: MLMatrixLike): MLVector = MLVector(internalMult)
}
Both my matrix class and my vector class are extending the trait:
case class MLMatrix(data: SimpleMatrix) extends MLMatrixLike {
def this(rawData: Array[Array[Double]]) = this(new SimpleMatrix(rawData))
def apply(row: Int, col:Int): Double = data.get(row, col)
def transpose(): MLMatrix = MLMatrix(data.transpose())
def invert(): MLMatrix = MLMatrix(data.invert())
def *(implicit that: MLMatrix): MLMatrix = MLMatrix(internalMult)
def *(that: Double): MLMatrix = MLMatrix(data.scale(that))
def -(that: MLMatrix): MLMatrix = MLMatrix(data.minus(that.data))
}
object MLMatrix {
def apply(rawData: Array[Array[Double]]) = new MLMatrix(rawData)
}
case class MLVector(data: SimpleMatrix) extends MLMatrixLike {
def this(rawData: Array[Double]) = {
this(new SimpleMatrix(Array(rawData)).transpose())
}
def apply(index: Int): Double = data.get(index)
def transpose(): MLVector = MLVector(data.transpose())
def -(that: MLVector): MLVector = MLVector(data.minus(that.data))
}
object MLVector {
def apply(rawData: Array[Double]) = new MLVector(rawData)
}
To my mind, this setup is not very good. I would like to define multiply (*) only once, since the SimpleMatrix-call is always the same and I can infer from the type of the parameter "that" whether the return type should be a matrix or a vector. Thus I would like to define a single function in MLMatrixLike along the lines of this (not working) function:
def *[T <: MLMatrixLike](that :T): T = {
new T(data.mult(that.data))
}
Of course, this does not work, since there is no such constructor T, but currently I fail to see, how I can get something similar to work. Returning MLMatrixLike is not correct to my mind, since that way I cannot check during compilation if the correct type is returned.
A similar problem applies to transpose, and minus - here the return type is always the own class.
Thank you very much!
I'm not sure what the benefits of wrapping SimpleMatrix in two other classes are. However, you could solve the duplication problem by making MLMatrixLike generic with its self-type, and defining an abstract constructor.
trait MLMatrixLike[Self <: MLMatrixLike[Self]] {
this: Self =>
def data: SimpleMatrix
def createNew(data: SimpleMatrix): Self
def *[T <: MLMatrixLike[T]](that: T): T = that.createNew(data.mult(that.data))
def *(that: Double): Self = createNew(data.scale(that))
def -(that: Self): Self = createNew(data.minus(that.data))
def transpose: Self = createNew(data.transpose())
}
case class MLMatrix(data: SimpleMatrix) extends MLMatrixLike[MLMatrix] {
this: MLMatrix =>
def this(rawData: Array[Array[Double]]) = this(new SimpleMatrix(rawData))
override def createNew(data: SimpleMatrix): MLMatrix = MLMatrix(data)
def apply(row: Int, col: Int): Double = data.get(row, col)
def invert(): MLMatrix = MLMatrix(data.invert())
}
object MLMatrix {
def apply(rawData: Array[Array[Double]]) = new MLMatrix(rawData)
}
case class MLVector(data: SimpleMatrix) extends MLMatrixLike[MLVector] {
this: MLVector =>
def this(rawData: Array[Double]) = {
this(new SimpleMatrix(Array(rawData)).transpose())
}
override def createNew(data: SimpleMatrix): MLVector = MLVector(data)
def apply(index: Int): Double = data.get(index)
}
object MLVector {
def apply(rawData: Array[Double]) = new MLVector(rawData)
}
By the way, note, that a column vector times a row vector is a matrix, so the signature of the multiplication should probably not return the type of that. However, based on static information (you need to know the dimensions of both arguments) you cannot tell whether a multiplication returns a vector or a matrix, so you may aswell just return a MLMatrixLike.

Scala trouble with casting to generics

I tried to write some function which does different things according to the input type.
For example, I do this:
def Foo[T](inList: List[String]): ArrayBuffer[T] = {
val out: ArrayBuffer[T] = new ArrayBuffer[T]()
inList.map ( x => {
val str = x.substring(1)
out += str.asInstanceOf[T]
})
out
}
but if I call this function with Foo[Long](new List("123","2342")), I get an ArrayBuffer with Strings, not Longs. Sorry for my noob question, i want understand scala and generics.
Scala runs ontop of JVM, that does not know anything about generics, and concrete type of generic is not available at runtime.
So that, runtime equivalent of your code will look like
def Foo(inList: List[String]): (ArrayBuffer[Object]) = {
val out: ArrayBuffer[Object] = new ArrayBuffer[Object]()
inList.map ( x => {
val str=x.substring(1)
out += str.asInstanceOf[Object]
})
(out)
}
asInstanceOf will not convert strings to longs, instead it will throw exception about incompatible types. Instead, you should supply your function with a conversion from strings to another type.
Summing up, your code should look like this:
import scala.collection.mutable.ArrayBuffer
// here we define how convert string to longs
implicit def stringToLong(s: String) = s.toLong
// now this function requires to have converter from string to T in context
def Foo[T](inList: List[String])(implicit f: (String) => T): (ArrayBuffer[T]) = {
val out: ArrayBuffer[T] = new ArrayBuffer[T]()
inList.map { x =>
val str = x.substring(1)
out += f(str) // here we apply converter
}
out
}
// when function is called, appropriate implicit converter from context will be used
Foo[Long](List("51", "42"))
Casting a String to a Long does not make it a Long, it is an error, so you should get a runtime error saying that you cannot cast String to Long. Since T does not place any restrictions on what it can be, you cannot expect to call any method that isn't on all objects (toString is for example). You could provide that function yourself (which is almost the exact signature of map, so you could just use that):
def convert[T](in: List[String])(convert: String => T): List[T] =
in.map(convert)
Or make sure the objects are of a type that you know of the methods on (using a type bound):
trait CanConvertTo[T] {
def convert: T
}
case class Example(value: String) extends CanConvertTo[Long] {
def convert = value.toLong
}
def convert[T](in: List[CanConvertTo[T]]): List[T] = in.map(_.convert)

Accessing class-level values of type parameters in Scala

I have a trait and a case class implementing it. One of the features of the trait that the implementations override is a default value. I can't find a good way to access this default value from a class that is parametrized by a specific implementation of that trait.
This is minimal code, so it doesn't really demonstrate the motivation anymore, but it does demonstrate the error:
import scala.language.implicitConversions
trait Distance[T] {
val Zero: T
def +( that: T ): T
}
case class DoubleDistance( val v: Double ) extends Distance[DoubleDistance] {
val Zero = DoubleDistance( 0.0 )
def +( that: DoubleDistance ) = DoubleDistance( v + that.v )
}
object DistanceImplicits {
implicit def DoubleToDistance( v: Double ) = new DoubleDistance( v )
}
class User[T<:Distance[T]] {
val default: T = T.Zero // This line gives me a compilation error
}
The error I get is
not found: value T
When I needed to construct an Array[T] inside my User class I could get that to work by adding implicit typetag:ClassTag[T] to my arguments, but that doesn't seem to have any effect here.
First, why this doesn't work: consider a different implementation of Distance.
case class DoubleDistance1(val v: Double) extends Distance[DoubleDistance1] {
val Zero = this
def +(that: DoubleDistance1) = ??? // doesn't matter
}
What would you expect DoubleDistance1.Zero to mean? You can make it work using a "type class":
trait DistanceOps[T] {
val zero: T
def add(d1: T, d2: T): T
}
// just to let you write distance1 + distance2
implicit class RichDistance[T](d: T)(implicit ops: DistanceOps[T]) {
def +(other: T) = ops.add(d, other)
}
case class DoubleDistance(v: Double)
object DoubleDistance {
implicit object DoubleDistanceOps extends DistanceOps[DoubleDistance] {
val zero = DoubleDistance(0.0)
def add(d1: DoubleDistance, d2: DoubleDistance) = DoubleDistance(d1.v + d2.v)
}
}
// how to use
class User[T](implicit ops: DistanceOps[T]) {
val default: T = ops.zero
}
This looks like a classic use case for the type class pattern. Rather than associating an instance of the Distance trait with each value of interest, you associate one with each type of interest:
trait Distance[T] {
val Zero: T
def +( a: T, b: T ): T
}
implicit object DoubleDistance extends Distance[Double] {
val Zero = 0.0
def +( a: Double, b: Double ) = a + b
}
class User[T : Distance] {
val default: T = implicitly[Distance[T]].Zero
}
Where is that Zero supposed to come from? Are you looking to do something like this?
class User[T<:Distance[T]] {
self:Distance[T] =>
val default: T = Zero
}

More advanced mathematics with Scala's Numeric and Fractional numbers

Recently I've (finally) started using Scala's Numeric trait, which does wonders. For example:
def square[A](x: A)(implicit num: Numeric[A]): A = num.times(x, x)
Now I can square any number be it Double, Integer, BigDecimal, or what not. Yet what if I want to do some more advanced math? For example, my logistic function for Double numbers looks like this:
def logisticFunction(x: Double): Double = 1.0 / (1.0 + math.exp(-x))
I could do the adding and dividing easily (I'd just have to use trait Fractional instead of Numeric), but what about the exponent? I sure don't want to write my own exp function (or any arbitrary function which takes Double arguments).
So, my question is this: how do I convert my A to Double, do my maths on that, and then convert back to A. Is it even possible?
EDIT:
That's how the signature of my function should look like:
def logisticFunction[A](x: A)(implicit num: Fractional[A]): A =
/* Magic happens here */
I've figured out the part about converting to double, which is as easy as num.toDouble(x). However the problem of converting back to A remains.
I still doubt this approach is really useful. But with your description, you will want something like this:
type FromDouble[A] = Double => A
type ToDouble [A] = A => Double
def logisticFunction[A: FromDouble: ToDouble](x: A): A = 1.0 / (1.0 + math.exp(-x))
logisticFunction(0.5)
implicit def bigDecimalToDouble(b: BigDecimal) = b.toDouble
logisticFunction(BigDecimal(0.5))
Or with dedicated type class:
object FromDouble {
implicit object _Double extends FromDouble[Double] {
def apply(d: Double) = d
}
implicit object _BigDecimal extends FromDouble[BigDecimal] {
def apply(d: Double) = BigDecimal(d)
}
}
trait FromDouble[A] extends (Double => A)
object ToDouble {
implicit object _Double extends ToDouble[Double] {
def apply(d: Double) = d
}
implicit object _BigDecimal extends ToDouble[BigDecimal] {
def apply(b: BigDecimal) = b.toDouble
}
}
trait ToDouble[A] extends (A => Double)
def logisticFunction[A: FromDouble: ToDouble](x: A): A = 1.0 / (1.0 + math.exp(-x))
logisticFunction(0.5)
logisticFunction(BigDecimal(0.5))
You will need a type class that provides trigonometric functions such as exp. Scala's standard library does not go beyond Fractional. You could try to use Spire.
Example:
$ sbt core/console
import spire.math._
import spire.algebra._
import spire.implicits._
def logisticFunction[A](x: A)(implicit m: Field[A], t: Trig[A]): A =
m.one / (m.one + exp(-x))
logisticFunction(0.5)
logisticFunction(BigDecimal(0.5))