Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sparse matrix equality efficient #480

Merged
34 changes: 29 additions & 5 deletions math/src/main/scala/breeze/linalg/Matrix.scala
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,35 @@ trait Matrix[@spec(Double, Int, Float, Long) V] extends MatrixLike[V, Matrix[V]]

def flatten(view: View=View.Prefer): Vector[V]

override def equals(p1: Any) = p1 match {
case x: Matrix[_] =>
this.rows == x.rows && this.cols == x.cols &&
keysIterator.forall(k => this(k) == x(k))
case _ => false
override def equals(p1: Any) : Boolean = (this, p1) match {
case (x: CSCMatrix[V], y: CSCMatrix[V]) =>
if(x.rows != y.rows || x.cols != y.cols){
return false
} else {
val xIter = x.activeIterator
val yIter = y.activeIterator

while(xIter.hasNext && yIter.hasNext){
var xkeyval = xIter.next()
var ykeyval = yIter.next()
while(xkeyval._2 == 0 && xIter.hasNext) xkeyval = xIter.next()
while(ykeyval._2 == 0 && yIter.hasNext) ykeyval = yIter.next()
if(xkeyval != ykeyval) return false
}
if(xIter.hasNext == true && yIter.hasNext == false){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd rather (xIter.hasNext && !yIter.hasNext) (and on the next one)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed with latest commit

while(xIter.hasNext) if(xIter.next()._2 != 0) return false
}

if(xIter.hasNext == false && yIter.hasNext == true){
while(yIter.hasNext) if(yIter.next()._2 != 0) return false
}
}
return true
case (x: Matrix[V], y: Matrix[_]) =>
x.rows == y.rows && x.cols == y.cols &&
keysIterator.forall(k => x(k) == y(k))
case _ =>
return false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh this should be super.==(p1)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh - this is in Matrix.scala not CSCMatrix.scala so I am not sure you want to use the equals method of the super class. Do you want to override the equals method in CSCMatrix? It doesn't have an explicit implementation in CSCMatrix.scala

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, blah, sorry. maybe move the CSC/CSC check to CSC itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

}
Expand Down
20 changes: 20 additions & 0 deletions math/src/test/scala/breeze/linalg/MatrixTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,26 @@ class MatrixTest extends FunSuite with Checkers {
assert(v.hashCode == v2.hashCode)
}

test("Sparse equality") {
val v: CSCMatrix[Int] = {
val mt = new CSCMatrix.Builder[Int](5, 1)
mt.add(1, 0, 2)
mt.add(4, 0, 3)
mt.result
}
val v2: CSCMatrix[Int] = CSCMatrix(0, 2, 0, 0, 3)
val diff = v - v2
val zeros = CSCMatrix.zeros[Int](5, 1)
val v4 = v2.copy
v4.update(1, 0, 0)
v4.update(4, 0, 0)
assert(v == v2) // similar matrices are same
assert(diff == zeros) // automatic removal of explicit zeros
assert(diff.activeSize == 0)
assert(zeros == v4) // implicit vs explicit
assert(v4 == zeros) // explicit vs implicit
assert(zeros != v)
}

// test("MapValues") {
// val a : Matrix[Int] = Matrix((1,0,0),(2,3,-1))
Expand Down