scala's spire framework : I am unable to operate on a group - scala

I try to use spire, a math framework, but I have an error message:
import spire.algebra._
import spire.implicits._
trait AbGroup[A] extends Group[A]
final class Rationnel_Quadratique(val n1: Int = 2)(val coef: (Int, Int)) {
override def toString = {
coef match {
case (c, i) =>
s"$c + $i√$n"
}
}
def a() = coef._1
def b() = coef._2
def n() = n1
}
object Rationnel_Quadratique {
def apply(coef: (Int, Int),n: Int = 2)= {
new Rationnel_Quadratique(n)(coef)
}
}
object AbGroup {
implicit object RQAbGroup extends AbGroup[Rationnel_Quadratique] {
def +(a: Rationnel_Quadratique, b: Rationnel_Quadratique): Rationnel_Quadratique = Rationnel_Quadratique(coef=(a.a() + b.a(), a.b() + b.b()))
def inverse(a: Rationnel_Quadratique): Rationnel_Quadratique = Rationnel_Quadratique((-a.a(), -a.b()))
def id: Rationnel_Quadratique = Rationnel_Quadratique((0, 0))
}
}
object euler66_2 extends App {
val c = Rationnel_Quadratique((1, 2))
val d = Rationnel_Quadratique((3, 4))
val e = c + d
println(e)
}
the program is expected to add 1+2√2 and 3+4√2, but instead I have this error:
could not find implicit value for evidence parameter of type spire.algebra.AdditiveSemigroup[Rationnel_Quadratique]
val e = c + d
^
I think there is something essential I have missed (usage of implicits?)

It looks like you are not using Spire correctly.
Spire already has an AbGroup type, so you should be using that instead of redefining your own. Here's an example using a simple type I created called X.
import spire.implicits._
import spire.algebra._
case class X(n: BigInt)
object X {
implicit object XAbGroup extends AbGroup[X] {
def id: X = X(BigInt(0))
def op(lhs: X, rhs: X): X = X(lhs.n + rhs.n)
def inverse(lhs: X): X = X(-lhs.n)
}
}
def test(a: X, b: X): X = a |+| b
Note that with groups (as well as semigroups and monoids) you'd use |+| rather than +. To get plus, you'll want to define something with an AdditiveSemigroup (e.g. Semiring, or Ring, or Field or something).
You'll also use .inverse and |-| instead of unary and binary - if that makes sense.
Looking at your code, I am also not sure your actual number type is right. What will happen if I want to add two numbers with different values for n?
Anyway, hope this clears things up for you a bit.
EDIT: Since it seems like you're also getting hung up on Scala syntax, let me try to sketch a few designs that might work. First, there's always a more general solution:
import spire.implicits._
import spire.algebra._
import spire.math._
case class RQ(m: Map[Natural, SafeLong]) {
override def toString: String = m.map {
case (k, v) => if (k == 1) s"$v" else s"$v√$k" }.mkString(" + ")
}
object RQ {
implicit def abgroup[R <: Radical](implicit r: R): AbGroup[RQ] =
new AbGroup[RQ] {
def id: RQ = RQ(Map.empty)
def op(lhs: RQ, rhs: RQ): RQ = RQ(lhs.m + rhs.m)
def inverse(lhs: RQ): RQ = RQ(-lhs.m)
}
}
object Test {
def main(args: Array[String]) {
implicit val radical = _2
val x = RQ(Map(Natural(1) -> 1, Natural(2) -> 2))
val y = RQ(Map(Natural(1) -> 3, Natural(2) -> 4))
println(x)
println(y)
println(x |+| y)
}
}
This allows you to add different roots together without problem, at the cost of some indirection. You could also stick more closely to your design with something like this:
import spire.implicits._
import spire.algebra._
abstract class Radical(val n: Int) { override def toString: String = n.toString }
case object _2 extends Radical(2)
case object _3 extends Radical(3)
case class RQ[R <: Radical](a: Int, b: Int)(implicit r: R) {
override def toString: String = s"$a + $b√$r"
}
object RQ {
implicit def abgroup[R <: Radical](implicit r: R): AbGroup[RQ[R]] =
new AbGroup[RQ[R]] {
def id: RQ[R] = RQ[R](0, 0)
def op(lhs: RQ[R], rhs: RQ[R]): RQ[R] = RQ[R](lhs.a + rhs.a, lhs.b + rhs.b)
def inverse(lhs: RQ[R]): RQ[R] = RQ[R](-lhs.a, -lhs.b)
}
}
object Test {
def main(args: Array[String]) {
implicit val radical = _2
val x = RQ[_2.type](1, 2)
val y = RQ[_2.type](3, 4)
println(x)
println(y)
println(x |+| y)
}
}
This approach creates a fake type to represent whatever radical you are using (e.g. √2) and parameterizes QR on that type. This way you can be sure that no one will try to do additions that are invalid.
Hopefully one of these approaches will work for you.

Related

Generating random/sample json based on a schema in Scala

I need to generate some radom json sample, compliant to a schema dynamically. Meaning that the input would be a schema (e.g. json-schema) and the output would a json that complies to it.
I'm looking for pointers. Any suggestions ?
This is not complete solution, but you can get it from here.
Let's assume we have our domain objects we want to generate:
case class Dummy1(foo: String)
case class Dummy11(foo: Dummy1)
If we do this:
object O {
implicit def stringR: Random[String] = new Random[String] {
override def generate(): String = "s"
}
implicit def intR: Random[Int] = new Random[Int] {
override def generate(): Int = 1
}
implicit def tupleR[T1: Random, T2: Random]: Random[(T1, T2)] = new Random[(T1, T2)] {
override def generate(): (T1, T2) = {
val t1: T1 = G.random[T1]()
val t2: T2 = G.random[T2]()
(t1, t2)
}
}
}
object G {
def random[R: Random](): R = {
implicitly[Random[R]].generate()
}
}
then we will be able to generate some primitive values:
import O._
val s: String = G.random[String]()
val i: Int = G.random[Int]()
val t: (Int, String) = G.random[(Int, String)]()
println("s=" + s)
println("i=" + i)
println("t=" + t)
Now to jump to custom type we need to add
def randomX[R: Random, T](f: R=>T): Random[T] = {
val value: Random[R] = implicitly[Random[R]]
new Random[T] {
override def generate(): T = f.apply(value.generate())
}
}
to our G object.
Now we can
import O._
val d1: Dummy1 = G.randomX(Dummy1.apply).generate()
println("d1=" + d1)
and with some extra effort even
import O._
implicit val d1Gen: Random[Dummy1] = G.randomX(Dummy1.apply)
val d11: Dummy11 = G.randomX(Dummy11.apply).generate()
println("d11=" + d11)
Now you need to extend it to all primitive you have, add real implementation of random and support classes with more then 1 field and you ready to go.
You may even make some fancy library out of it.

why scala compiler says type arguments does not conform to bounds?

I created Combiner trait with subclasses Complex and IntCombiner and my objective is to make Matrix work with both Complex and Int. But some reason it dosen't compile saying that
[com.implicits.TestImplicits1.IntCombiner] do not conform to class Matrix's type parameter bounds [T <: com.implicits.TestImplicits1.Combiner[T]]
val m1 = new Matrix[IntCombiner](3, 3)((1 to 9).sliding(3).map {
But as my understanding goes as IntContainer is the subclass of Combiner it should work. Why such an error please explain ?
object TestImplicits1 {
trait Combiner[T] {
def +(b: T): T
def *(b: T): T
}
class Complex(r: Double, i: Double) extends Combiner[Complex] {
val real = r
val im = i
override def +(b: Complex): Complex = {
new Complex(real + b.real, im + b.im)
}
override def *(b: Complex): Complex = {
new Complex((real * b.real) - (im * b.im), real * b.im + b.real * im)
}
}
class IntCombiner(a: Int) extends Combiner[Int] {
val v = a
override def *(b: Int): Int = v * b
override def +(b: Int): Int = v + b
}
class Matrix[T <: Combiner[T]](x1: Int, y1: Int)(ma: Seq[Seq[T]]) {
self =>
val x: Int = x1
val y: Int = y1
def dot(v1: Seq[T], v2: Seq[T]): T = {
v1.zip(v2).map { t: (T, T) => {
t._1 * t._2
}
}.reduce(_ + _)
}
}
object MatrixInt extends App {
def apply[T <: Combiner[T]](x1: Int, y1: Int)(s: Seq[Seq[T]]) = {
new Matrix[T](x1, y1)(s)
}
val m1 = new Matrix[IntCombiner](3, 3)((1 to 9).sliding(3).map {
x => x map { y => new IntCombiner(y) }
}.toSeq)
}
}
F-bounded polymorphism cannot be added to an existing Int class, because Int is just what it is, it does not know anything about your Combiner traits, so it cannot extend Combiner[Int]. You could wrap every Int into something like an IntWrapper <: Combiner[IntWrapper], but this would waste quite a bit of memory, and library design around F-bounded polymorphism tends to be tricky.
Here is a proposal based on ad-hoc polymorphism and typeclasses instead:
object TestImplicits1 {
trait Combiner[T] {
def +(a: T, b: T): T
def *(a: T, b: T): T
}
object syntax {
object combiner {
implicit class CombinerOps[A](a: A) {
def +(b: A)(implicit comb: Combiner[A]) = comb.+(a, b)
def *(b: A)(implicit comb: Combiner[A]) = comb.*(a, b)
}
}
}
case class Complex(re: Double, im: Double)
implicit val complexCombiner: Combiner[Complex] = new Combiner[Complex] {
override def +(a: Complex, b: Complex): Complex = {
Complex(a.re + b.re, a.im + b.im)
}
override def *(a: Complex, b: Complex): Complex = {
Complex((a.re * b.re) - (a.im * b.im), a.re * b.im + b.re * a.im)
}
}
implicit val intCombiner: Combiner[Int] = new Combiner[Int] {
override def *(a: Int, b: Int): Int = a * b
override def +(a: Int, b: Int): Int = a + b
}
class Matrix[T: Combiner](entries: Vector[Vector[T]]) {
def frobeniusNormSq: T = {
import syntax.combiner._
entries.map(_.map(x => x * x).reduce(_ + _)).reduce(_ + _)
}
}
}
I don't know what you attempted with dot there, your x1, x2 and ma seemed to be completely unused, so I added a simple square-of-Frobenius-norm example instead, just to show how the typeclasses and the syntactic sugar for operators work together. Please don't expect anything remotely resembling "high performance" from it - JVM traditionally never cared about rectangular arrays and number crunching (at least not on a single compute node; Spark & Co is a different story). At least your code won't be automatically transpiled to optimized CUDA code, that's for sure.

Using a double value in a Fractional[T] method

I have the following function which generates a Uniform distributed value between 2 bounds:
def Uniform(x: Bounded[Double], n: Int): Bounded[Double] = {
val y: Double = (x.upper - x.lower) * scala.util.Random.nextDouble() + x.lower
Bounded(y, x.bounds)
}
and Bounded is defined as follows:
trait Bounded[T] {
val underlying: T
val bounds: (T, T)
def lower: T = bounds._1
def upper: T = bounds._2
override def toString = underlying.toString + " <- [" + lower.toString + "," + upper.toString + "]"
}
object Bounded {
def apply[T : Numeric](x: T, _bounds: (T, T)): Bounded[T] = new Bounded[T] {
override val underlying: T = x
override val bounds: (T, T) = _bounds
}
}
However, I want Uniform to work on all Fractional[T] values so I wanted to add a context bound:
def Uniform[T : Fractional](x: Bounded[T], n: Int): Bounded[T] = {
import Numeric.Implicits._
val y: T = (x.upper - x.lower) * scala.util.Random.nextDouble().asInstanceOf[T] + x.lower
Bounded(y, x.bounds)
}
This works swell when doing a Uniform[Double](x: Bounded[Double]), but the other ones are impossible and get a ClassCastException at runtime because they can not be casted. Is there a way to solve this?
I'd suggest defining a new type class that characterizes types that you can get random instances of:
import scala.util.Random
trait GetRandom[A] {
def next(): A
}
object GetRandom {
def instance[A](a: => A): GetRandom[A] = new GetRandom[A] {
def next(): A = a
}
implicit val doubleRandom: GetRandom[Double] = instance(Random.nextDouble())
implicit val floatRandom: GetRandom[Float] = instance(Random.nextFloat())
// Define any other instances here
}
Now you can write Uniform like this:
def Uniform[T: Fractional: GetRandom](x: Bounded[T], n: Int): Bounded[T] = {
import Numeric.Implicits._
val y: T = (x.upper - x.lower) * implicitly[GetRandom[T]].next() + x.lower
Bounded(y, x.bounds)
}
And use it like this:
scala> Uniform[Double](Bounded(2, (0, 4)), 1)
res15: Bounded[Double] = 1.5325899033654382 <- [0.0,4.0]
scala> Uniform[Float](Bounded(2, (0, 4)), 1)
res16: Bounded[Float] = 0.06786823 <- [0.0,4.0]
There are libraries like rng that provide a similar type class for you, but they tend to be focused on purely functional ways to work with random numbers, so if you want something simpler you're probably best off writing your own.

Can a partially applied function be extracted or interrogated for the applied parameter value

Is there a way to extract or interrogate a partially applied function to get the applied value.
For example, can the value 3 be extracted from reduceBy3 in the code below.
def subtract(x:Int, y:Int) = x-y
val reduceBy3 = subtract(3,_:Int)
I have experimented with creating an extractor has shown in the example below however the unapply method must accept an (Int=>Int) function that requires interrogation.
class ReduceBy(y: Int) {
val amt = y
def subtract(y: Int, x: Int) = x - y
}
object ReduceBy extends Function1[Int, Int => Int] {
def apply(y: Int) = {
val r = new ReduceBy(y)
r.subtract(y, _: Int)
}
def unapply(reduceBy: ReduceBy): Option[Int] = Some(reduceBy.amt)
}
object ExtractPartialApplied extends App {
val r3 = ReduceBy(3)
val extract = r3 match {
case ReduceBy(x) => ("reduceBy", x)
case x: ReduceBy => ("reduceBy", x.amt)
case _ => ("No Match", 0)
}
println(extract)
val z = r3(5)
println(z)
}
You can have your subtract method receive the first parameter, and then return a function-like object which will then take the second parameter, similarly to a multiple-argument-list function, but which you can then extend however you wish.
This doesn't look very elegant though, and needs a bit of manual boilerplate.
class ReduceBy(val amt: Int) {
def subtract(x: Int) = {
val xx = x // avoid shadowing
new Function[Int, Int] {
def x = xx
def apply(y: Int) = x - y
}
}
}
A solution adapting the answer by danielkza is to have the companion object do the extraction and return a ReduceBy function that holds onto the the initial value.
object ReduceBy {
def apply(y: Int) = new ReduceBy(y)
def unapply(reduceBy: ReduceBy): Option[Int] = Some(reduceBy.amt)
}
class ReduceBy(val amt: Int) extends Function[Int, Int] {
def apply(y: Int) = y - amt
}
object ExtractPartialApplied extends App {
val reduceBy3 = ReduceBy(3)
val extract = reduceBy3 match {
case ReduceBy(x) => ("ReduceBy(x)", x)
case x: ReduceBy => ("ReduceBy", x.amt)
case _ => ("No Match", 0)
}
println(extract)
println(reduceBy3(5))
}

scala: adding a method to List?

I was wondering how to go about adding a 'partitionCount' method to Lists, e.g.:
(not tested, shamelessly based on List.scala):
Do I have to create my own sub-class and an implicit type converter?
(My original attempt had a lot of problems, so here is one based on #Easy's answer):
class MyRichList[A](targetList: List[A]) {
def partitionCount(p: A => Boolean): (Int, Int) = {
var btrue = 0
var bfalse = 0
var these = targetList
while (!these.isEmpty) {
if (p(these.head)) { btrue += 1 } else { bfalse += 1 }
these = these.tail
}
(btrue, bfalse)
}
}
and here is a little more general version that's good for Seq[...]:
implicit def seqToRichSeq[T](s: Seq[T]) = new MyRichSeq(s)
class MyRichList[A](targetList: List[A]) {
def partitionCount(p: A => Boolean): (Int, Int) = {
var btrue = 0
var bfalse = 0
var these = targetList
while (!these.isEmpty) {
if (p(these.head)) { btrue += 1 } else { bfalse += 1 }
these = these.tail
}
(btrue, bfalse)
}
}
You can use implicit conversion like this:
implicit def listToMyRichList[T](l: List[T]) = new MyRichList(l)
class MyRichList[T](targetList: List[T]) {
def partitionCount(p: T => Boolean): (Int, Int) = ...
}
and instead of this you need to use targetList. You don't need to extend List. In this example I create simple wrapper MyRichList that would be used implicitly.
You can generalize wrapper further, by defining it for Traversable, so that it will work for may other collection types and not only for Lists:
implicit def listToMyRichTraversable[T](l: Traversable[T]) = new MyRichTraversable(l)
class MyRichTraversable[T](target: Traversable[T]) {
def partitionCount(p: T => Boolean): (Int, Int) = ...
}
Also note, that implicit conversion would be used only if it's in scope. This means, that you need to import it (unless you are using it in the same scope where you have defined it).
As already pointed out by Easy Angel, use implicit conversion:
implicit def listTorichList[A](input: List[A]) = new RichList(input)
class RichList[A](val source: List[A]) {
def partitionCount(p: A => Boolean): (Int, Int) = {
val partitions = source partition(p)
(partitions._1.size, partitions._2.size)
}
}
Also note that you can easily define partitionCount in terms of partinion. Then you can simply use:
val list = List(1, 2, 3, 5, 7, 11)
val (odd, even) = list partitionCount {_ % 2 != 0}
If you are curious how it works, just remove implicit keyword and call the list2richList conversion explicitly (this is what the compiler does transparently for you when implicit is used).
val (odd, even) = list2richList(list) partitionCount {_ % 2 != 0}
Easy Angel is right, but the method seems pretty useless. You have already count in order to get the number of "positives", and of course the number of "negatives" is size minus count.
However, to contribute something positive, here a more functional version of your original method:
def partitionCount[A](iter: Traversable[A], p: A => Boolean): (Int, Int) =
iter.foldLeft ((0,0)) { ((x,y), a) => if (p(a)) (x + 1,y) else (x, y + 1)}