Finding area under the curve(Integration) in Scala from Array of values - scala

Hi does anyone know of a standard library that can do what is specified in the title. Ideally the usage should be something like this: https://docs.scipy.org/doc/numpy/reference/generated/numpy.trapz.html
I researched quite a lot and couldn't finding anything similar.
Everything used apache PolynomialFunction class which takes as inputs the polynomial parameters and not the y-coordinates

Using Breeze you can write any type of function that type checks and pass it to trapezoid, you can just include the mapping in the function:
val f = (x: Double) => {
val xToY = Map(1.0 -> 1.0 , 2.0 -> 2.0, 3.0 -> 3.0)
xToY(x)
}
scala> import breeze.integrate._
scala> trapezoid(f, 1, 3, 3)
res0: Double = 4.0
Although it has restricted use, as it needs the mapping not to have gaps between the range it defined.

Related

Scala .map() Information Loss (Since return type is same as elements: Set)

I am using this piece of code to get the weighted sum of a map of elements:
val wSum = elements.map(element=>
weights(element) * values(element))
.sum
While testing, if I pass
weights = Map(1 -> 1.0, 2 -> 1.0, 3 -> 1.0)
values = Map(1 -> 0.2, 2 -> 0.6, 3 -> 0.4)
It returns 1.2 as expected. On the other hand, if I pass
weights = Map(1 -> 1.0, 2 -> 1.0, 3 -> 1.0)
values = Map(1 -> 0.5, 2 -> 0.5, 3 -> 0.5)
This returns 0.5. This seems like dangerously wrong, am I missing a commonly used alternative instead?
The code is behaving correctly, so it isn't really wrong, and certainly not dangerously so.
If you are actually trying to compute weights*values for each element and then sum the result, there are two common ways of doing this:
The simplest is just
elements.toList.map(element=>
weights(element) * values(element))
.sum
The other option is to compute the sum in one pass using foldLeft:
elements.foldLeft(0.0){
case (prev, element) => prev + weights(element) * values(element)
}
To understand the behaviour in the original code you need to understand what map does:
The map method on a collection creates a new collection of the same type by applying a function to each element of the old collection and adding it to the new collection.
The key point is that the collection type is not changed, so any rules that apply to the old collection also apply to the new collection. If the collection is ordered then the ordering is retained. If the collection is self-sorting then the new collection will be sorted. If the collection has set-like properties then duplicate elements will not be added to the new collection.
In this question the problem is made more complicated by using Java classes in Scala code. The behaviour of a Java collection might be different from the Scala behaviour, so the correct approach is to convert all Java collections to Scala collections using asScala from JavaConverters.
So mapping over a set returns a set. Seems logical to me. IIRC, preserving return type of the original collection was a big part of scala collections library. Your immediate fix would be to call elements.toSeq before mapping.
However, I'd go with a case class to encapsulate Elements:
case class Element(weight: Double, value: Double) {
def weightedValue = weight * value
}
val elements = Map(1 -> Element(1.0, 0.5), 2 -> Element(1.0, 0.5))
elements.values.map(_.weightedValue).sum
The resulting Set from the Set.map() call is collapsing repeated values, like Sets are supposed to do...

Mixing Space and Dot Notation on method chaining in Scala

This question is not about the recommended practices for notation in method chaining, its about understanding this particular case.
I am learning Scala and Play for about 2 weeks now. I have prior one month learning experience in scala sometime in 2011.
I am having trouble understanding why this line is not working
List(1,2,3) map {x=>x*2}.filter((x:Int)=>x==2)
But this one is working
List(1,2,3).map{x=>x*2}.filter((x:Int)=>x==2)
One reason that I can think of is that the filter is being called upon the function value rather than the resulting collection.
Why is it still not working when Space and Dot notation are mixed? If I keep pure Space or Dot notation then it works otherwise not.
I would have not got confused if I only saw pure notation everywhere. I have seen mixed notation especially in the Play codebase. What am I missing?
It works as expected.
This line:
List(1,2,3) map {x=>x*2}.filter((x:Int)=>x==2)
means
List(1,2,3) map ( {x=>x*2}.filter((x:Int)=>x==2) )
It is definitely a error, but you could use it like this:
val f1 = (x: Int) => x * 2
val f2 = (x: Int) => x + 2
List(1,2,3) map f1.andThen(f2) // List(1,2,3).map( f1.andThen(f2) )
//List[Int] = List(4, 6, 8)
This code creates new function as composition of 2 functions: {(x: Int)=>x*2}.andThen((x:Int)=> x + 2) and then applies map method to it.
You could mix Space or Dot notations, but you should know that "priority" of dot is higher.

Scala - Enforcing size of Vector at compile time

Is it possible to enforce the size of a Vector passed in to a method at compile time? I want to model an n-dimensional Euclidean space using a collection of points in the space that looks something like this (this is what I have now):
case class EuclideanPoint(coordinates: Vector[Double]) {
def distanceTo(desination: EuclieanPoint): Double = ???
}
If I have a coordinate that is created via EuclideanPoint(Vector(1, 0, 0)), it is a 3D Euclidean point. Given that, I want to make sure the destination point passed in a call to distanceTo is of the same dimension.
I know I can do this by using Tuple1 to Tuple22, but I want to represent many different geometric spaces and I would be writing 22 classes for each space if I did it with Tuples - is there a better way?
It is possible to do this in a number of ways that all look more or less like what Randall Schulz has described in a comment. The Shapeless library provides a particularly convenient implementation, which lets you get something pretty close to what you want like this:
import shapeless._
case class EuclideanPoint[N <: Nat](
coordinates: Sized[IndexedSeq[Double], N] { type A = Double }
) {
def distanceTo(destination: EuclideanPoint[N]): Double =
math.sqrt(
(this.coordinates zip destination.coordinates).map {
case (a, b) => (a - b) * (a - b)
}.sum
)
}
Now you can write the following:
val orig2d = EuclideanPoint(Sized(0.0, 0.0))
val unit2d = EuclideanPoint(Sized(1.0, 1.0))
val orig3d = EuclideanPoint(Sized(0.0, 0.0, 0.0))
val unit3d = EuclideanPoint(Sized(1.0, 1.0, 1.0))
And:
scala> orig2d distanceTo unit2d
res0: Double = 1.4142135623730951
scala> orig3d distanceTo unit3d
res1: Double = 1.7320508075688772
But not:
scala> orig2d distanceTo unit3d
<console>:15: error: type mismatch;
found : EuclideanPoint[shapeless.Nat._3]
required: EuclideanPoint[shapeless.Nat._2]
orig2d distanceTo unit3d
^
Sized comes with a number of nice features, including a handful of collections operations that carry along static guarantees about length. We can write the following for example:
val somewhere = EuclideanPoint(Sized(0.0) ++ Sized(1.0, 0.0))
And have an ordinary old point in three-dimensional space.
You could do something your self by doing a type level encoding of the Natural Numbers like: http://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/. Then just parametrizing your Vector by a Natural. Would not require the extra dependency, but would probably be more complicated then using Shapeless.

How do I scale a Matrix by a Double with breeze

I am using the Breeze library's math part and have the following Matrix:
val matrix = breeze.linalg.DenseMatrix((1.0,2.0),(3.0,4.0))
I want to scale this by a scalar Double (and add the result to another Matrix) using one
of the *= and :*= operators:
val scale = 2.0
val scaled = matrix * scale
This works just fine (more details in my answer below).
Update This code does work in isolation. I seem to have a problem elsewhere. Sorry for wasting your bandwidth...
Update 2 However, the code fails to compile if I specifically assign the type Matrix to the variable matrix:
val matrix: Matrix[Double] = breeze.linalg.DenseMatrix((1.0,2.0),(3.0,4.0))
val scaled = matrix * scale // does not compile
The compiler keeps complaining that it "could not find implicit value for parameter op".
Can anyone explain this please? Is this a bug in Breeze or intentional? TIA.
For those of you who struggle with Scala and the Breeze library, I would like to detail some of the functions / operators available for Matrix instances here.
Our starting point is a simple Double matrix (Matrix and the related operations also support Float and Int):
scala> val matrix = breeze.linalg.DenseMatrix((1.0,2.0),(3.0,4.0))
You can easily pretty-print this using
scala> println(matrix)
1.0 2.0
3.0 4.0
Breeze supports operators that leave the left operand intact and those that modify the left operand - e.g. * and *=:
scala> val scaled1 = matrix * 2.0 // returns new matrix!
scala> println(matrix)
1.0 2.0
3.0 4.0
scala> println(scaled1)
2.0 4.0
6.0 8.0
scala> println(matrix == scaled1)
false
scala> val scaled2 = matrix *= 2.0 // modifies and returns matrix!
scala> println(matrix)
2.0 4.0
6.0 8.0
scala> println(scaled2)
2.0 4.0
6.0 8.0
scala> println(matrix == scaled2) // rough equivalent of calling Java's equals()
true
The hash codes of both variables indicate that they actually point to the same object (which true according to the javadoc and can be verified by looking at the sources):
scala> println(matrix.##)
12345678
scala> println(scaled2.##)
12345678
This is further illustrated by:
scala> val matrix2 = breeze.linalg.DenseMatrix((2.0,4.0),(6.0,8.0))
scala> println(matrix == matrix2)
true
scala> println(matrix2.##)
34567890

Named parameters lead to maintenance problems and inferior readability?

With named parameters like
def f(x : Int = 1, y : Int = 2) = x * y
your parameter names become part of the interface
f(x=3)
Now if you want to change the parameter names locally, you are forced to perserve the public name of the parameter:
def f(x : Int = 1, y : Int = 2) = {
val (a,b) = (x,y)
a * b
}
If this a real problem? Is there a syntax to support this directly? Who do other languages handle this?
A small illustration of the problems you can run into if you switch parameter names, as suggested by Jon.
trait X{ def f(x : Int, y : Int) }
class A extends X{
override def f(y : Int, x : Int) = println("" + y + x)
}
val a = new A
scala> a.f(x = 1, y = 2)
21
scala> (a : X).f(x = 1, y = 2)
12
Yes, the parameter name is effectively part of the public interface. This is a "problem" for any language which has named arguments - or indeed produces code which is consumed by languages supporting named arguments. Sometimes this isn't well understood.
For example, C# 3 doesn't support named arguments - but VB does. So if you create a library in C# 3, someone builds against it in VB, then changing parameter names counts as a breaking change.
Ultimately some of this will be handled by refactoring tools, but it boils down to the same sort of caution as with any other aspect of a public API... you need to be very cautious.
You should also be very cautious when overriding a method with parameters - use the same parameter names as the original method, or you could cause some very subtle issues. (In particular, switching round the names of parameters would be very evil...)
I don't know about the "inferior readability" part of your title. The few times I used named parameters, it was to provide default values like increment:Int = 100000, maxCount:Int = 1000000. I think it helps readability when you have to changed on value where you call the function.