How to find roots of function in Scala? - scala

I'm writing a program in Scala and i want to find the roots of the equation: 2*x^3 + x*(1-2*l + 2*H)-m = 0, where l, H and m are constants, calculated earlier.
In Python, i know there is brentq for such cases but i can't find anything similar in Scala. Is there anything similar or should try find other way of solving this?

There's spire which is a numeric library for Scala. I don't know it very well, but this seems to work in Spire 0.16.0:
scala> val m = 1
m: Int = 1
scala> val l = 2
l: Int = 2
scala> val H = 3
H: Int = 3
scala> import spire.implicits._
import spire.implicits._
scala> import spire.math.Number
import spire.math.Number
scala> val f = poly"2x^3 + ${1-2*l + 2*H}x - $m"
f: spire.math.Polynomial[spire.math.Rational] = (2x³ + 3x - 1)
scala> f.map(Number(_)).roots
res1: spire.math.poly.Roots[spire.math.Number] = Roots(0.3129084094792333580059444668826417)

I do not know of any comprehensive math library in scala. There is one in Java though that you could call from your scala code.
You could have a look at Apache commons math and in particular at section 4.3, root finding.

If l, H and m are constants then this is just
x^3 + ax + b = 0
Where
a = 1/2 - l + H
b = -m/2
There is a very hairy analytical solution to this, see Wolfram Alpha:
https://www.wolframalpha.com/input/?i=solve+x%5E3+%2B+ax+%2B+b+%3D+0
Expressing this in Scala is left as an exercise for the reader :)

As a previous solution commented, use Java's Commons Math! You just import the dependency and you can:
val polynomial: PolynomialFunction = new PolynomialFunction(Array[Double](-m, 1-2*l + 2*H, 2)
val laguerreSolver = new LaguerreSolver()
laguerreSolver.solve(100, polynomial, -100, 100)
This is way faster than spire.

You may also wish to look at Breeze, which I think would also have some routines to help you.

Related

Multi variable assignment in Scala

I am reading a book in scala and one of the exercises is as follows:
Come up with one situation where the assignment x = y = 1 is valid in Scala. (Hint: Pick a suitable type for x.)
The 2 solutions I could come up with are:
val x, y : Int = 1
val x, y = (1, 2)
Have I missed another way that the exercise is looking for?
"valid" and "useful" don't necessarily mean the same thing :)
scala> var y = 2
y: Int = 2
scala> val x = y = 1
x: Unit = ()
scala>

Get objects out of scala interpreter

I spent hours investigating one topic. I am definitely out of my depth here. What I want is to run the scala interpreter programmatically and be able to extract object values from the interpreter. for example, if I send
val a = 1
val b = a + 1
I want to be able to read out b as an Int, not just a string printed out like
b = 2
The source code is dense. So far I don't see any part which would allow such an extraction. Any experts here who can give me a tip or tell me this is utter nonsense?
How do I get typed objects out of the scala interpreter between sessions?
Use JSR 223.
Welcome to Scala version 2.11.7 [...]
scala> import javax.script._
import javax.script._
scala> val engine = (new ScriptEngineManager).getEngineByName("scala")
engine: javax.script.ScriptEngine = scala.tools.nsc.interpreter.IMain#4233e892
scala> engine.eval("val a = 1")
res0: Object = 1
scala> engine.eval("val b = a + 1")
res1: Object = 2
scala> engine.eval("b").asInstanceOf[Int]
res2: Int = 2

Scala Worksheet issues with values and output

Finding quite a big error on the Scala worksheet whilst in Eclipse 3.7.2 downloaded fromTypesafe for a Linux, Ubuntu
Seem to get issues when defining values - something which doesn't happen on my course teachers screen.
Please see as follows:
package week3
object rational2 {
val x = new Rational(1,2) //> x : week3.Rational = week3.Rational#1e9cb75
x.num //> res0: Int = 1
x.den //> res1: Int = 2
val y = new Rational(2,3) //> y : week3.Rational = week3.Rational#1786e64
x.addRationals(y) //> res2: week3.Rational = week3.Rational#197a37c
val z = new Rational(3,2) //> z : week3.Rational = week3.Rational#6e3d60
As you can see it doesn't even tell me what x, y, z are but points to a variable defined as the being within the package.
Previously had a known issue of highlighting errors when there wasn't one, but had to reinstall Eclipse to get rid of these.
Any help appreciated.
EDIT: please note a Rational class has been defined, beneath the object one - I simply didn't paste it as it doesn't show any errors and isn't dealt with by the interactive worksheet
What you're seeing is the toString representation of the Rational class. You haven't defined one so it just goes with the default.
You're probably meant to define Rational as a case class, which will give you a sensible toString representation automatically.

How to explain that "Set(someList : _*)" results the same as "Set(someList).flatten"

I found a piece of code I wrote some time ago using _* to create a flattened set from a list of objects.
The real line of code is a bit more complex and as I didn't remember exactly why was that there, took a bit of experimentation to understand the effect, which is actually very simple as seen in the following REPL session:
scala> val someList = List("a","a","b")
someList: List[java.lang.String] = List(a, a, b)
scala> val x = Set(someList: _*)
x: scala.collection.immutable.Set[java.lang.String] = Set(a, b)
scala> val y = Set(someList).flatten
y: scala.collection.immutable.Set[java.lang.String] = Set(a, b)
scala> x == y
res0: Boolean = true
Just as a reference of what happens without flatten:
scala> val z = Set(someList)
z: scala.collection.immutable.Set[List[java.lang.String]] = Set(List(a, a, b))
As I can't remember where did I get that idiom from I'd like to hear about what is actually happening there and if there is any consequence in going for one way or the other (besides the readability impact)
P.S.: Maybe as an effect of the overuse of underscore in Scala language (IMHO), it is kind of difficult to find documentation about some of its use cases, specially if it comes together with a symbol commonly used as a wildcard in most search engines.
_* is for expand this collection as if it was written here literally, so
val x = Set(Seq(1,2,3,4): _*)
is the same as
val x = Set(1,2,3,4)
Whereas, Set(someList) treats someList as a single argument.
To lookup funky symbols, you could use symbolhound

Scala Tuple Deconstruction

I am new to Scala, and ran across a small hiccup that has been annoying me.
Initializing two vars in parallel works great: var (x,y) = (1,2)
However I can't find a way to assign new values in parallel: (x,y) = (x+y,y-x) //invalid syntax
I end up writing something like this: val xtmp = x+y; y = x-y; x = xtmp
I realize writing functional code is one way of avoiding this, but there are certain situations where vars just make more sense.
I have two questions:
1) Is there a better way of doing this? Am I missing something?
2) What is the reason for not allowing true parallel assignment?
Unfortunately, you cannot do multiple assignments in Scala. But you may use tuples, if they fit your problem:
scala> var xy = (1,2)
xy: (Int, Int) = (1,2)
scala> xy = (xy._1 + xy._2, xy._2 - xy._1)
xy: (Int, Int) = (3,1)
This way, xy is one tuple with two values. The first value can be accessed using xy._1, the second one using xy._2.
Scala has 2 types of variables: vals and vars. Vals are similar to Java's final variables, so as far as I understand from what you're asking, the only way to assign new values in parallel to vals is by:
scala> val (x, y) = (1, 2);
or
scala> val s = (3, 4);
s: (Int, Int) = (3,4)
scala> s._1
res1: Int = 3
scala> s._2
res2: Int = 4