Matrix by Vector division: Cannot (in one case) find implicit value for parameter

53 views
Skip to first unread message

Mark Blokpoel

unread,
Dec 12, 2017, 2:49:11 PM12/12/17
to Scala Breeze
Hi,

I've recently started exploring Scala and Breeze because I want to implement some Bayesian computations for agent based simulations. I am using IntelliJ (worksheet) and I'm aware that the issue I am encountering might be related to the IDE, but I'd like to know for sure I'm not doing anything wrong.

I've written two normalization methods, one that normalizes by rows and one that does so by columns:

def normalizeRows(mapping: DenseMatrix[Double]) : DenseMatrix[Double] = {
val rowSums :DenseVector[Double] = sum(mapping(*,::))
var res : DenseMatrix[Double] = mapping(::,*) / rowSums
return res
}

def normalizeColumns(mapping: DenseMatrix[Double]) : DenseMatrix[Double] = {
val columnSums = sum(mapping(::,*))
var res : DenseMatrix[Double] = mapping(*,::) / columnSums
return res
}

For some reason, compilation errors on the normalizeColumns method with the following message:

Error:(26, 52) could not find implicit value for parameter op: breeze.linalg.operators.OpDiv.Impl2[breeze.linalg.BroadcastedRows[breeze.linalg.DenseMatrix[Double],breeze.linalg.DenseVector[Double]],breeze.linalg.Transpose[breeze.linalg.DenseVector[Double]],That]
    var res : DenseMatrix[Double] = mapping(*,::) / columnSums
                                                  ^
Error:(26, 52) not enough arguments for method /: (implicit op: breeze.linalg.operators.OpDiv.Impl2[breeze.linalg.BroadcastedRows[breeze.linalg.DenseMatrix[Double],breeze.linalg.DenseVector[Double]],breeze.linalg.Transpose[breeze.linalg.DenseVector[Double]],That])That.
Unspecified value parameter op.
    var res : DenseMatrix[Double] = mapping(*,::) / columnSums
                                                  ^
But normalizeRows works just fine if I comment out normalizeColumns. I did my best to add as many types explicitly, but my Scala skills are still quite limited so perhaps I overlooked something? Hope someone can help me out, because I'm really enthusiastic about Scala but for my project I do need a matrix library like Breeze. Thanks!!

Best,
Mark

David Hall

unread,
Dec 12, 2017, 2:58:08 PM12/12/17
to scala-...@googlegroups.com
The short answer to your question is to use breeze.linalg.normalize:

// 1.0 is the L1 norm, default is 2.0
// row normalize:
normalize(dm(*, ::), 1.0) 

// column normalize:
normalize(dm(::, *), 1.0) 

The longer answer is that `sum(mapping(::, *))` returns a row vector Transpose[DenseVector[Double]] and the compiler is telling you it doesn't know how to divide a broadcasted rows DM by a transposed Vector. you need to untranspose it to apply the operation, so just use .t:

var res : DenseMatrix[Double] = mapping(*,::) / columnSums.t

Breeze is unfortunately highly inconsistent about when row-y things are DenseVectors or Transpose[DenseVector] . But usually you can just transpose your way through the problem

-- David


--
You received this message because you are subscribed to the Google Groups "Scala Breeze" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-breeze+unsubscribe@googlegroups.com.
To post to this group, send email to scala-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/scala-breeze/0b84aa0f-4790-4225-adc6-345554339670%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mark Blokpoel

unread,
Dec 14, 2017, 1:43:53 AM12/14/17
to Scala Breeze
Thanks for the help David! I figured out that transposing solved the problem, but the normalize method is much cleaner. Good stuff.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-breeze...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages