Converting Array[(Double,Double)] to Seq[Seq[Double]] - arrays

I am fairly new to Scala and I have to use a function which takes as argument of type Seq[Seq[Double]]. However, my data has the type Array[(Double,Double)].
I tried using .toSeq to convert the data, but that doesn't work.
Any fixes in this regard would be highly appreciated. Thanks!

val input: Array[(Double, Double)] = ...
val output: Seq[Seq[Double]] = input.map { case (x, y) => Seq(x, y) }
Unfortunately, there is no generic way to type-safely convert a tuple to a list in the standard library. shapeless, however, does provide this functionality:
import shapeless.syntax.std.tuple._
val input: Array[(Double, Double)] = ...
val output: Seq[Seq[Double]] = input.map(_.toList)
Shapeless is smart enough to compute a lowest upper bound in case your tuple contains components of different types:
val input: Array[(Double, Int)] = ...
// AnyVal is the closest type which both Double and Int are subtypes of
val output: Seq[Seq[AnyVal]] = input.map(_.toList)
Finally, there is a non-type-safe way to do this using only the standard library tools. You can rely on the fact that all tuples in Scala implement the Product trait and therefore are iterable as collections of Any:
val input: Array[(Double, Double)] = ...
val output: Seq[Seq[Double]] = input.map(_.productIterator.toSeq.asInstanceOf[Seq[Double]])
This is safe as long as you're careful, but it does require an explicit cast and it is more verbose.
If you have fixed-length tuples of relatively small size, then I'd say it is better to use the partial function-based approach. Otherwise, it is up to you, but I'd use shapeless because it is type safe, and I also use shapeless in many of my projects for other things as well, so it is kind of free for me :)

Related

What's the fastest way of finding the index of the maximum value in an array?

I have a 2D array of type f32 (from ndarray::ArrayView2) and I want to find the index of the maximum value in each row, and put the index value into another array.
The equivalent in Python is something like:
import numpy as np
for i in range (0, max_val, batch_size):
sims = xp.dot(batch, vectors.T)
# sims is the dot product of batch and vectors.T
# the shape is, for example, (1024, 10000)
best_rows[i: i+batch_size] = sims.argmax(axis = 1)
In Python, the function .argmax is very fast, but I don't see any function like that in Rust. What's the fastest way of doing so?
Consider the easy case of a general Ord type: The answer will differ slightly depending on whether you know the values are Copy or not, but here's the code:
fn position_max_copy<T: Ord + Copy>(slice: &[T]) -> Option<usize> {
slice.iter().enumerate().max_by_key(|(_, &value)| value).map(|(idx, _)| idx)
}
fn position_max<T: Ord>(slice: &[T]) -> Option<usize> {
slice.iter().enumerate().max_by(|(_, value0), (_, value1)| value0.cmp(value1)).map(|(idx, _)| idx)
}
The basic idea is that we pair [a reference to] each item in the array (really, a slice - it doesn't matter if it's a Vec or an array or something more exotic) with its index, use std::iter::Iterator functions to find the maximum value according to the value only (not the index), then return just the index. If the slice is empty None will be returned. Per the documentation, the rightmost index will be returned; if you need the leftmost, do rev() after enumerate().
rev(), enumerate(), max_by_key(), and max_by() are documented here; slice::iter() is documented here (but that one needs to be on your shortlist of things to recall without documentation as a rust dev); map is Option::map() documented here (ditto). Oh, and cmp is Ord::cmp but most of the time you can use the Copy version which doesn't need it (e.g. if you're comparing integers).
Now here's the catch: f32 isn't Ord because of the way IEEE floats work. Most languages ignore this and have subtly wrong algorithms. The most popular crate to provide a total order on Ord (by declaring all NaN to be equal, and greater than all numbers) seems to be ordered-float. Assuming it's implemented correctly it should be very very lightweight. It does pull in num_traits but this is part of the most popular numerics library so might well be pulled in by other dependencies already.
You'd use it in this case by mapping ordered_float::OrderedFloat (the "constructor" of the tuple type) over the slice iter (slice.iter().map(ordered_float::OrderedFloat)). Since you only want the position of the maximum element, no need to extract the f32 afterward.
The approach from #David A is cool, but as mentioned, there's a catch: f32 & f64 do not implement Ord::cmp. (Which is really a pain in your-know-where.)
There are multiple ways of solving that: You can implement cmp yourself, or you can use ordered-float, etc..
In my case, this is a part of a bigger project and we are very careful about using external packages. Besides, I am pretty sure we don't have any NaN values. Therefore I would prefer using fold, which, if you take a close look at the max_by_key source code, is what they have been using too.
for (i, row) in matrix.axis_iter(Axis(1)).enumerate() {
let (max_idx, max_val) =
row.iter()
.enumerate()
.fold((0, row[0]), |(idx_max, val_max), (idx, val)| {
if &val_max > val {
(idx_max, val_max)
} else {
(idx, *val)
}
});
}

Scala overloading operators with generic types

I am doing a project in scala and i am struggling with a certain thing. I am making a matrix DSL so i am overloading some operators like +,- or * so that i can do :
matrixMult = matrix1*matrix2
The thing is i made this class where the matrix was represented as a Array[Array[Double]] type but i would like to make it generic: Array[Array[T]]
The thing is i do not know how to handle this in the class methods since for operations like +,- and *. It should work for doubles or ints, but strings should throw an error. Here is my current code:
def +(other : Matrix[Double]): Matrix[Double] = {
var array = new Array[Array[Double]](rows)
for (i <- 0 to (rows - 1)) {
var arrayRow = new Array[Double](columns)
for (j <- 0 to (columns - 1)) {
arrayRow(j) = this.array(i)(j) + other.array(i)(j)
}
array(i) = arrayRow
}
return new Matrix(array)
}
I get an error on the arrayRow(j) =... line which is normal because it does not know what type the "this" object is.
What should i do to make this work? Like i would like this method only to be accessible to doubles (or ints) and not strings, if this method was to be invoked on a Matrix[String] object it should throw an error. I tried pattern matching with isInstanceOf() but that doesn't remove the error and i can't compile.
If kind of have the same issue with all of my methods in my class, so i'd like a generic answer if possible.
Any help is appreciated,
Thank you very much!
Not sure which version of Scala you are using, but if you're on 2.8, I found this thread on Scala-lang, and it looks like you may be able to use T:Numerics to limit it to Int, Long, Float, Double.
A little farther down in the thread, to limit it to JUST a subset of those (like Int, Double), they say to define your own generic Trait.
https://www.scala-lang.org/old/node/4787
Answer can be found in comments:
Matrix addition has been asked, and answered, before. Even though the question posses a different matrix implementation, I believe the answer from the redoubtable Rex Kerr is still applicable. – jwvh

Range of an Array or List in Kotlin when it does not have to accommodate the empty case

I'm looking to calculate the range of a list or array and was frustrated by not being able to simply take the difference of the max() and min() functions due to null safety feature of Kotlin.
I came up with this solution which is forcing me to deal with the case of an ifEmpty() even if I know that is not possible in with this immutable array. I wonder if there is something simpler without the extra characters.
val array=arrayOf(1,2,3,4,5)
// doesn't compile... val range = array.max()-array.min()
val range = (array.max() ?: 0) - (array.min() ?: 0)
This isn't much different, but since you know that it isn't empty, you can use !! (the Hold My Beer operator), to tell Kotlin to ignore the nullability of the types.
val range = if(array.isEmpty()) 0 else array.max()!! - array.min()!!
It might also be handy to define an extension if you anticipate doing this a lot:
fun Array<Int>.range(): Int =
if(isEmpty()) 0 else max()!! - min()!!
// Usage
val range = array.range()

Obtaining array element in Scala works only with explicit apply method

Accessing collection elements in Scala is done by apply method. Having said that I tried to read numbers from standard input and get the second one as int in just one line.
def main(args: Array[String]): Unit = {
val number = StdIn.readLine().split(" ").map(_.toInt)(1)
}
IntelliJ marks this 1 and show the error (the same is shown after the compilation attempt):
Error:(11, 60) type mismatch; found : Int(1) required:
scala.collection.generic.CanBuildFrom[Array[String],Int,?]
val number = StdIn.readLine().split(" ").map(_.toInt)(1)
Folding the expression in the parentheses dosn't help as well. However, when I split mapping input to int array and getting the element to other lines, everything works fine.
def main(args: Array[String]): Unit = {
val numbers = StdIn.readLine().split(" ").map(_.toInt)
numbers(1)
}
The explicit invocation of apply also does the job:
val number = StdIn.readLine().split(" ").map(_.toInt).apply(1)
Why does this weird behaviour happens? Obtaining element via array(5) is just a shortcut for array.apply(5), isn't it?
As compiler already pointed out, map is defined with two arg lists. second one containing a single implicit param: implicit bf: CanBuildFrom[Repr, B, That]
For a vast majority of scenarios, the users don't worry about specifying the second arg. Specifically, in your case this is what the compiler "figures out":
StdIn.readLine().split(" ").map(_.toInt)(Array.canBuildFrom[Int])
So, if writing out apply is not desired then the following is the only choice:
StdIn.readLine().split(" ").map(_.toInt)(Array.canBuildFrom[Int])(1)
It's a bit counter-intuitive that adding a set of parentheses still doesn't quite do the trick:
( StdIn.readLine().split(" ").map(_.toInt) )(1) //does not compile, same error
Perhaps it's best to demonstrate what's going with a simpler example. Consider the following function:
def add(x:Int)(y:Int) = x + y
The type of add(2) is Int => Int (since we haven't specified y). Note that adding a set of parentheses around it doesn't change the return type, i.e. (add(2)) still has a type Int => Int. Similarly, (Array("1").map(_.toInt))(1) still requires an instance of CanBuildFrom before using shorthand for apply.
Suggested reading about Scala collections:
The Architecture of Scala Collections
Getting to know CanBuildFrom (without a PhD)
and implicit scope:
Scala Specification <- as comprehensive as it gets
Where does Scala look for implicits?
You're getting a collision with an implicit argument to map. This is one of the cases apply needs to be invoked explicitly.
Here's some REPL that replicates the error:
scala> class Foo {
def apply() { println("bar") }
}
scala> def makeFoo(): Foo = new Foo
scala> makeFoo()()
bar // got the println from the apply here
scala> def makeFooImplicit()(implicit x: Int): Foo = new Foo
scala> implicit val x = 5
scala> makeFooImplicit()()
<console>:11: error: not enough arguments for method makeFooImplicit:(implicit x: Int)Foo.
Unspecified value parameter x.
makeFooImplicit()()

How do I compare two arrays in scala?

val a: Array[Int] = Array(1,2,4,5)
val b: Array[Int] = Array(1,2,4,5)
a==b // false
Is there a pattern-matching way to see if two arrays (or sequences) are equivalent?
From Programming Scala:
Array(1,2,4,5).sameElements(Array(1,2,4,5))
You need to change your last line to
a.deep == b.deep
to do a deep comparison of the arrays.
a.corresponds(b){_ == _}
Scaladoc: true if both sequences have
the same length and p(x, y) is true
for all corresponding elements x of
this wrapped array and y of that,
otherwise false
For best performance you should use:
java.util.Arrays.equals(a, b)
This is very fast and does not require extra object allocation. Array[T] in scala is the same as Object[] in java. Same story for primitive values like Int which is java int.
As of Scala 2.13, the deep equality approach doesn't work and errors out:
val a: Array[Int] = Array(1,2,4,5)
val b: Array[Int] = Array(1,2,4,5)
a.deep == b.deep // error: value deep is not a member of Array[Int]
sameElements still works in Scala 2.13:
a sameElements b // true
It didn't look like most of the provided examples work with multidimensional arrays. For example
val expected = Array(Array(3,-1,0,1),Array(2,2,1,-1),Array(1,-1,2,-1),Array(0,-1,3,4))
val other = Array(Array(3,-1,0,1),Array(2,2,1,-1),Array(1,-1,2,-1),Array(0,-1,3,4))
assert(other.sameElements(expected))
returns false, throws an assertion failure
deep doesn't seem to be a function defined on Array.
For convenience I imported scalatest matchers and it worked.
import org.scalatest.matchers.should.Matchers._
other should equal(expected)

Resources