I am still new to Scala (still learning it). I have the following assignment, but am having problems running it due to the error "overloaded method value converged with alternatives:"
Full Error:
\KMeans.scala:101:8: overloaded method value converged with alternatives:
(eta: Double,oldMeans: scala.collection.parallel.ParSeq[kmeans.Point],newMeans: scala.collection.parallel.ParSeq[kmeans.Point])Boolean <and>
(eta: Double,oldMeans: scala.collection.Seq[kmeans.Point],newMeans: scala.collection.Seq[kmeans.Point])Boolean
cannot be applied to (Double)
if (!converged(eta)(means, newMeans))
Can you please help?
The full class is:
package kmeans
import scala.annotation.tailrec
import scala.collection.{Map, Seq, mutable}
import scala.collection.parallel.CollectionConverters._
import scala.collection.parallel.{ParMap, ParSeq}
import scala.util.Random
import org.scalameter._
class KMeans extends KMeansInterface {
def generatePoints(k: Int, num: Int): Seq[Point] = {
val randx = new Random(1)
val randy = new Random(3)
val randz = new Random(5)
(0 until num)
.map({ i =>
val x = ((i + 1) % k) * 1.0 / k + randx.nextDouble() * 0.5
val y = ((i + 5) % k) * 1.0 / k + randy.nextDouble() * 0.5
val z = ((i + 7) % k) * 1.0 / k + randz.nextDouble() * 0.5
new Point(x, y, z)
}).to(mutable.ArrayBuffer)
}
def initializeMeans(k: Int, points: Seq[Point]): Seq[Point] = {
val rand = new Random(7)
(0 until k).map(_ => points(rand.nextInt(points.length))).to(mutable.ArrayBuffer)
}
def findClosest(p: Point, means: IterableOnce[Point]): Point = {
val it = means.iterator
assert(it.nonEmpty)
var closest = it.next()
var minDistance = p.squareDistance(closest)
while (it.hasNext) {
val point = it.next()
val distance = p.squareDistance(point)
if (distance < minDistance) {
minDistance = distance
closest = point
}
}
closest
}
def classify(points: Seq[Point], means: Seq[Point]): Map[Point, Seq[Point]] = {
means.map{(_, Seq())}.toMap ++ points.groupBy(findClosest(_, means))
}
def classify(points: ParSeq[Point], means: ParSeq[Point]): ParMap[Point, ParSeq[Point]] = {
means.map{(_, ParSeq())}.toMap ++ points.groupBy(findClosest(_, means))
}
def findAverage(oldMean: Point, points: Seq[Point]): Point = if (points.isEmpty) oldMean else {
var x = 0.0
var y = 0.0
var z = 0.0
points.foreach { p =>
x += p.x
y += p.y
z += p.z
}
new Point(x / points.length, y / points.length, z / points.length)
}
def findAverage(oldMean: Point, points: ParSeq[Point]): Point = if (points.isEmpty) oldMean else {
var x = 0.0
var y = 0.0
var z = 0.0
points.seq.foreach { p =>
x += p.x
y += p.y
z += p.z
}
new Point(x / points.length, y / points.length, z / points.length)
}
def update(classified: Map[Point, Seq[Point]], oldMeans: Seq[Point]): Seq[Point] = {
oldMeans.par.map(oldMean => findAverage(oldMean, classified(oldMean)))
}
def update(classified: ParMap[Point, ParSeq[Point]], oldMeans: ParSeq[Point]): ParSeq[Point] = {
oldMeans.par.map(oldMean => findAverage(oldMean, classified(oldMean)))
}
def converged(eta: Double, oldMeans: Seq[Point], newMeans: Seq[Point]): Boolean = {
(oldMeans zip newMeans)
.forall(entry => entry._1.squareDistance(entry._2) <= eta)
}
def converged(eta: Double, oldMeans: ParSeq[Point], newMeans: ParSeq[Point]): Boolean = {
(oldMeans zip newMeans)
.forall(entry => entry._1.squareDistance(entry._2) <= eta)
}
#tailrec
final def kMeans(points: Seq[Point], means: Seq[Point], eta: Double): Seq[Point] = {
val meansClassification = classify(points, means)
val newMeans = update(meansClassification, means)
if (!converged(eta)(means, newMeans))
kMeans(points, newMeans, eta)
else
newMeans
}
#tailrec
final def kMeans(points: ParSeq[Point], means: ParSeq[Point], eta: Double): ParSeq[Point] = {
val meansClassification = classify(points, means)
val newMeans = update(meansClassification, means)
if (!converged(eta)(means, newMeans))
kMeans(points, newMeans, eta)
else
newMeans
}
}
/** Describes one point in three-dimensional space.
*
* Note: deliberately uses reference equality.
*/
class Point(val x: Double, val y: Double, val z: Double) {
private def square(v: Double): Double = v * v
def squareDistance(that: Point): Double = {
square(that.x - x) + square(that.y - y) + square(that.z - z)
}
private def round(v: Double): Double = (v * 100).toInt / 100.0
override def toString = s"(${round(x)}, ${round(y)}, ${round(z)})"
}
object KMeansRunner {
val standardConfig = config(
Key.exec.minWarmupRuns -> 20,
Key.exec.maxWarmupRuns -> 40,
Key.exec.benchRuns -> 25,
Key.verbose -> true
) withWarmer(new Warmer.Default)
def main(args: Array[String]): Unit = {
val kMeans = new KMeans()
val numPoints = 500000
val eta = 0.01
val k = 32
val points = kMeans.generatePoints(k, numPoints)
val means = kMeans.initializeMeans(k, points)
val seqtime = standardConfig measure {
kMeans.kMeans(points, means, eta)
}
val parPoints = points.par
val parMeans = means.par
val partime = standardConfig measure {
kMeans.kMeans(parPoints, parMeans, eta)
}
// Additional `println` to avoid bad interaction with JLine output
println()
println()
println()
println()
println(s"sequential time: $seqtime")
println(s"parallel time: $partime")
println(s"speedup: ${seqtime.value / partime.value}")
println()
println()
println()
}
// Workaround Dotty's handling of the existential type KeyValue
implicit def keyValueCoerce[T](kv: (Key[T], T)): KeyValue = {
kv.asInstanceOf[KeyValue]
}
}
The interface:
package kmeans
import scala.collection.{Map, Seq}
import scala.collection.parallel.{ParMap, ParSeq}
/**
* The interface used by the grading infrastructure. Do not change signatures
* or your submission will fail with a NoSuchMethodError.
*/
trait KMeansInterface {
def classify(points: Seq[Point], means: Seq[Point]): Map[Point, Seq[Point]]
def classify(points: ParSeq[Point], means: ParSeq[Point]): ParMap[Point, ParSeq[Point]]
def update(classified: Map[Point, Seq[Point]], oldMeans: Seq[Point]): Seq[Point]
def update(classified: ParMap[Point, ParSeq[Point]], oldMeans: ParSeq[Point]): ParSeq[Point]
def converged(eta: Double, oldMeans: Seq[Point], newMeans: Seq[Point]): Boolean
def converged(eta: Double, oldMeans: ParSeq[Point], newMeans: ParSeq[Point]): Boolean
def kMeans(points: Seq[Point], means: Seq[Point], eta: Double): Seq[Point]
def kMeans(points: ParSeq[Point], means: ParSeq[Point], eta: Double): ParSeq[Point]
}
The method should be called as converged(eta, means, newMeans) not converged(eta)(means, newMeans). If you look, both def converged are defined with a single parameter list (with 3 parameters), not with two.
The most relevant part of this error is not the part you quoted but
cannot be applied to (Double)
Related
I have the following program:
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
def this(n: Int) = this(n, 1)
def this(s: String) = {
val regex: Regex = "^([+-]?(\\d+|\\d*\\.?\\d+)|\\d*\\/?\\d+)$".r
if (!regex.matches(s)) throw new NumberFormatException()
val input: Array[String] = s.split("\\.|\\/")
val num: Int = input(0).toInt
if (input.length equals 1)
this(num, 1) // problem here
else
this(num, input(1).toInt) // problem here
}
}
I tried to create the constructor with some logic. However, I cannot due to
'Rational' does not take parameters
What's the problem?
Try to introduce a helper method
import scala.util.matching.Regex
def gcd(i: Int, i1: Int): Int = BigInt(i).gcd(BigInt(i1)).toInt
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
def this(n: Int) = this(n, 1)
def this(s: String) = {
this(Rational.transformStr(s)._1, Rational.transformStr(s)._2)
}
}
object Rational {
// helper method
def transformStr(s: String): (Int, Int) = {
val regex: Regex = "^([+-]?(\\d+|\\d*\\.?\\d+)|\\d*\\/?\\d+)$".r
if (!regex.matches(s)) throw new NumberFormatException()
val input: Array[String] = s.split("\\.|\\/")
val num: Int = input(0).toInt
if (input.length equals 1)
(num, 1)
else
(num, input(1).toInt)
}
}
or better, factory methods (because constructors have many limitations)
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
}
object Rational {
// factory methods
def apply(n: Int) = new Rational(n, 1)
def apply(s: String): Rational = {
val regex: Regex = "^([+-]?(\\d+|\\d*\\.?\\d+)|\\d*\\/?\\d+)$".r
if (!regex.matches(s)) throw new NumberFormatException()
val input: Array[String] = s.split("\\.|\\/")
val num: Int = input(0).toInt
if (input.length equals 1)
new Rational(num, 1)
else
new Rational(num, input(1).toInt)
}
}
Executing code in overloaded constructor prior to calling this()
By the way, you can also use default values
class Rational(n: Int, d: Int = 1 /*default*/ ) {
// ...
}
object Rational {
def apply(s: String): Rational = ???
}
here is an interesting puzzle that I can not solve for a few days.
A class takes a function and gives out a string. Main thing is that it puts parentheses when a priority of an argument becomes negative. The goal is to find such a relationship of value, literal and operation, that the parentheses will be at initial place
Known is that:
literal * variable is e.g 2X and not 2 * X
Priority of X (or any other variable) is 5
Priority of 42 (e.g 42.lit or 4.lit * 2.lit which one is unknown) is 4
Priority of X * Y * 2 is 3
Priority of -X * Y * 3 is 1
object Main {
trait Expr[T] {
def literalInt(value: Int): T
def variable(name: String): T
def times(x: T, y: T): T
def plus(x: T, y: T): T
def minus(x: T, y: T): T = plus(x, negate(y))
def negate(x: T): T = times(x, literalInt(-1))
}
object exprSyntax {
def literalInt[T](value: Int)(implicit expr: Expr[T]): T = expr.literalInt(value)
def X[T](implicit expr: Expr[T]): T = expr.variable("x")
def Y[T](implicit expr: Expr[T]): T = expr.variable("y")
def Z[T](implicit expr: Expr[T]): T = expr.variable("z")
implicit class IntToExpr[T](x: Int)(implicit expr: Expr[T]) {
def lit: T = expr.literalInt(x)
}
implicit class NumOps[T](val x: T) extends AnyVal {
def +(y: T)(implicit expr: Expr[T]): T = expr.plus(x, y)
def -(y: T)(implicit expr: Expr[T]): T = expr.minus(x, y)
def *(y: T)(implicit expr: Expr[T]): T = expr.times(x, y)
def unary_-(implicit expr: Expr[T]): T = expr.negate(x)
}
}
final case class Print(s: String, priority: Int, isLit: Boolean = false) {
def print(outer: Int = 0) = if (outer <= priority) s else s"($s)"
}
// interesting starts from here
object Expr {
implicit val stringOrderExpr: Expr[Print] = new Expr[Print] {
override def literalInt(value: Int): Print = Print(value.toString, priority = ???, isLit = true)
override def variable(name: String): Print = Print(name.toUpperCase, priority = ???)
override def times(x: Print, y: Print): Print = {
if (x.isLit){
val print = Print(s"${x.s}${y.s}", priority = ???).print()
Print(print, priority = ???)
}
else {
val print = Print(s"${x.s}*${y.s}", priority = ???).print()
Print(print, priority = ???)
}
}
override def plus(x: Print, y: Print): Print = {
val print = Print(s"${x.s}+${y.s}".toUpperCase, priority = ???).print()
Print(print, y.priority - x.priority)
}
override def minus(x: Print, y: Print): Print = {
val print = Print(s"${x.s}-${y.s}", priority = ???).print()
Print(print, priority = ???)
}
override def negate(x: Print): Print = {
val print = Print(s"-${x.s}", priority = ???).print()
Print(print, priority = ???)
}
}
}
def main(args: Array[String]): Unit = {
import Main.exprSyntax._
def function[T: Main.Expr]: T = X * X + 2.lit * (Y + Z * X * 2.lit) - 7.lit * Z + 4.lit
println(function[Main.Print].priority) // X*X+2(Y+Z*X*2)-7Z+4
}
}
I'm trying to understand how to leverage monads in scala to solve simple problems as way of building up my familiarity. One simple problem is estimating PI using a functional random number generator. I'm including the code below for a simple stream based approach.
I'm looking for help in translating this to a monadic approach. For example, is there an idiomatic way convert this code to using the state (and other monads) in a stack safe way?
trait RNG {
def nextInt: (Int, RNG)
def nextDouble: (Double, RNG)
}
case class Point(x: Double, y: Double) {
val isInCircle = (x * x + y * y) < 1.0
}
object RNG {
def nonNegativeInt(rng: RNG): (Int, RNG) = {
val (ni, rng2) = rng.nextInt
if (ni > 0) (ni, rng2)
else if (ni == Int.MinValue) (0, rng2)
else (ni + Int.MaxValue, rng2)
}
def double(rng: RNG): (Double, RNG) = {
val (ni, rng2) = nonNegativeInt(rng)
(ni.toDouble / Int.MaxValue, rng2)
}
case class Simple(seed: Long) extends RNG {
def nextInt: (Int, RNG) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL
val nextRNG = Simple(newSeed)
val n = (newSeed >>> 16).toInt
(n, nextRNG)
}
def nextDouble: (Double, RNG) = {
val (n, nextRNG) = nextInt
double(nextRNG)
}
}
}
object PI {
import RNG._
def doubleStream(rng: Simple):Stream[Double] = rng.nextDouble match {
case (d:Double, next:Simple) => d #:: doubleStream(next)
}
def estimate(rng: Simple, iter: Int): Double = {
val doubles = doubleStream(rng).take(iter)
val inside = (doubles zip doubles.drop(3))
.map { case (a, b) => Point(a, b) }
.filter(p => p.isInCircle)
.size * 1.0
(inside / iter) * 4.0
}
}
// > PI.estimate(RNG.Simple(10), 100000)
// res1: Double = 3.14944
I suspect I'm looking for something like replicateM from the Applicative monad in cats but I'm not sure how to line up the types or how to do it in a way that doesn't accumulate intermediate results in memory. Or, is there a way to do it with a for comprehension that can iteratively build up Points?
Id you want to iterate using monad in a stack safe way, then there is a tailRecM method implemented in Monad type class:
// assuming random generated [-1.0,1.0]
def calculatePi[F[_]](iterations: Int)
(random: => F[Double])
(implicit F: Monad[F]): F[Double] = {
case class Iterations(total: Int, inCircle: Int)
def step(data: Iterations): F[Either[Iterations, Double]] = for {
x <- random
y <- random
isInCircle = (x * x + y * y) < 1.0
newTotal = data.total + 1
newInCircle = data.inCircle + (if (isInCircle) 1 else 0)
} yield {
if (newTotal >= iterations) Right(newInCircle.toDouble / newTotal.toDouble * 4.0)
else Left(Iterations(newTotal, newInCircle))
}
// iterates until Right value is returned
F.tailRecM(Iterations(0, 0))(step)
}
calculatePi(10000)(Future { Random.nextDouble }).onComplete(println)
It uses by-name param because you could try to pass there something like Future (even though the Future is not lawful), which are eager, so you would end up with evaluating the same thing time and time again. With by name param at least you have the chance of passing there a recipe for side-effecting random. Of course, if we use Option, List as a monad holding our "random" number, we should also expect funny results.
The correct solution would be using something that ensures that this F[A] is lazily evaluated, and any side effect inside is evaluated each time you need a value from inside. For that you basically have to use some of Effects type classes, like e.g. Sync from Cats Effects.
def calculatePi[F[_]](iterations: Int)
(random: F[Double])
(implicit F: Sync[F]): F[Double] = {
...
}
calculatePi(10000)(Coeval( Random.nextDouble )).value
calculatePi(10000)(Task( Random.nextDouble )).runAsync
Alternatively, if you don't care about purity that much, you could pass side effecting function or object instead of F[Int] for generating random numbers.
// simplified, hardcoded F=Coeval
def calculatePi(iterations: Int)
(random: () => Double): Double = {
case class Iterations(total: Int, inCircle: Int)
def step(data: Iterations) = Coeval {
val x = random()
val y = random()
val isInCircle = (x * x + y * y) < 1.0
val newTotal = data.total + 1
val newInCircle = data.inCircle + (if (isInCircle) 1 else 0)
if (newTotal >= iterations) Right(newInCircle.toDouble / newTotal.toDouble * 4.0)
else Left(Iterations(newTotal, newInCircle))
}
Monad[Coeval].tailRecM(Iterations(0, 0))(step).value
}
Here is another approach that my friend Charles Miller came up with. It's a bit more direct since it uses RNG directly but it follows the same approach provided by #Mateusz Kubuszok above that leverages Monad.
The key difference is that it leverages the State monad so we can thread the RNG state through the computation and generate the random numbers using the "pure" random number generator.
import cats._
import cats.data._
import cats.implicits._
object PICharles {
type RNG[A] = State[Long, A]
object RNG {
def nextLong: RNG[Long] =
State.modify[Long](
seed ⇒ (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL
) >> State.get
def nextInt: RNG[Int] = nextLong.map(l ⇒ (l >>> 16).toInt)
def nextNatural: RNG[Int] = nextInt.map { i ⇒
if (i > 0) i
else if (i == Int.MinValue) 0
else i + Int.MaxValue
}
def nextDouble: RNG[Double] = nextNatural.map(_.toDouble / Int.MaxValue)
def runRng[A](seed: Long)(rng: RNG[A]): A = rng.runA(seed).value
def unsafeRunRng[A]: RNG[A] ⇒ A = runRng(System.currentTimeMillis)
}
object PI {
case class Step(count: Int, inCircle: Int)
def calculatePi(iterations: Int): RNG[Double] = {
def step(s: Step): RNG[Either[Step, Double]] =
for {
x ← RNG.nextDouble
y ← RNG.nextDouble
isInCircle = (x * x + y * y) < 1.0
newInCircle = s.inCircle + (if (isInCircle) 1 else 0)
} yield {
if (s.count >= iterations)
Right(s.inCircle.toDouble / s.count.toDouble * 4.0)
else
Left(Step(s.count + 1, newInCircle))
}
Monad[RNG].tailRecM(Step(0, 0))(step(_))
}
def unsafeCalculatePi(iterations: Int) =
RNG.unsafeRunRng(calculatePi(iterations))
}
}
Thanks Charles & Mateusz for your help!
How do I run the refint1 function? I've triedvar x = new RefInt(5) and then doing scala> argpass.refint1(x)but get a found: RefInt, required : argpass.RefInt => Unit error in the console.
object argpass{
class RefInt (initial : Int) {
private var n : Int = initial
def get () : Int = n
def set (m : Int) : Unit = { n = m}
}
def refint1 ( f: RefInt => Unit) : (Int, Int, Int) = {
var x = new RefInt(5)
val first = f(x)
val firstget = x.get
val sec = f(x)
val secget = x.get
val third = f(x)
val thirdget = x.get
(firstget, secget, thirdget)
}
//How do i run the refint1 function?
As Luis said in the comments, f returns Unit, which is basically void. This should solve your problem:
class RefInt(initial: Int) {
var n: Int = initial
def get(): Int = n
def set(m: Int): Unit = { n = m }
}
def refint1(f: RefInt => Unit): (Int, Int, Int) = {
var x = new RefInt(5)
f(x)
val firstget = x.get
f(x)
val secget = x.get
f(x)
val thirdget = x.get
(firstget, secget, thirdget)
}
That being said, I think you can improve your design a little bit. Here's a different approach to solve the same problem:
case class RefInt(initial: Int)
def refInt1(initial: RefInt, f: RefInt => RefInt) : (Int, Int, Int) = {
val x0 = f(initial)
val x1 = f(x0)
val x2 = f(x1)
(x0.initial, x1.initial, x2.initial)
}
println(refInt1(RefInt(5), ri => ri.copy(ri.initial * 2)))
Code:
object Integral {
def approx(start: Double, end: Double, nIntervals: Int)(f: Double => Double): Double = {
val delta = (end - start) / nIntervals
val halfDelta = delta / 2
val xs = start until end by delta
xs.map(x => f(x + halfDelta) * delta).sum
}
def approx(startEnd: Array[Double], nIntervas: Int)(f: Double => Double): Double = {
require(startEnd.length == 2)
val startEndSorted = startEnd.sorted
val res = approx(startEndSorted(0), startEndSorted(1), nIntervas)(f)
if(startEndSorted == startEnd) res else (-res)
}
}
object IntegralTest {
def f1(x: Double) = {
math.pow(x, 3) - 6 * x
}
println(Integral.approx(0, 3, 6)(f1))
println(Integral.approx(0, 1, 60000)(f1))
def f2(x: Double) = {
math.sqrt(1 - x * x)
}
println(Integral.approx(0, 1, 60000)(f2))
println(math.Pi / 4)
println(Integral.approx(0, 3, 60000)({
(x: Double) => x - 1
}))
println(Integral.approx(1, 2, 5)({
(x: Double) => 1 / x
}))
// test the exponential function
println(Integral.approx(1, 3, 60000)(math.exp))
println(math.exp(3) - math.exp(1))
}
I want to make approx(start: Double, end: Double, nIntervals: Int)(f: Double => Double): Double private and change all the reference to it to approx(startEnd: Array[Double], nIntervas: Int)(f: Double => Double): Double, is there a way to do this safely and hassle-free in intellij?
Update
I soon realized that for this specific case I could have handled it in a better way (by recursion):
def approx(start: Double, end: Double, nIntervals: Int)(f: Double => Double): Double = {
if(start > end) {
-approx(end, start, nIntervals)(f)
} else {
val delta = (end - start) / nIntervals
val halfDelta = delta / 2
val xs = start until end by delta
xs.map(x => f(x + halfDelta) * delta).sum
}
}
But I am still interested in finding out how to refactor the old problematic code because it might be useful in the future.
I don't know if the fact you use it for Scala changes anything, but you should be able to right-click on a function, and Change method signature to the one you want (so you wouldn't replace function1 by function2 per se, but rather modify f1 to match f2).
Edit: This won't work as per Ben comment. Leaving anyway for the sake of mentioning the functionality.