
breeze.linalg.operators.VectorBuilderOps.scala Maven / Gradle / Ivy
package breeze.linalg.operators
import breeze.macros.expand
import breeze.generic.UFunc.{UImpl2, InPlaceImpl2}
import breeze.math._
import breeze.storage.Zero
import spire.syntax.cfor._
import scala.reflect.ClassTag
import breeze.linalg._
trait VectorBuilderOps { this: VectorBuilder.type =>
@expand
@expand.valify
implicit def canOpInto_V_S[@expand.args(OpMulScalar, OpDiv) Op,
@expand.args(Double, Long, Float, Int) T](implicit @expand.sequence[Op]((_ * _), (_ / _)) op: Q): Op.InPlaceImpl2[VectorBuilder[T], T] = {
new Op.InPlaceImpl2[VectorBuilder[T], T] {
def apply(a: VectorBuilder[T], b: T) {
var i = 0
while(i < a.activeSize) {
a.data(i) = op(a.data(i), b)
i += 1
}
}
}
}
implicit def canMulInto_V_S[T:Semiring:ClassTag]: OpMulScalar.InPlaceImpl2[VectorBuilder[T], T] = {
new OpMulScalar.InPlaceImpl2[VectorBuilder[T], T] {
val sr = implicitly[Semiring[T]]
def apply(a: VectorBuilder[T], b: T) {
var i = 0
while(i < a.activeSize) {
a.data(i) = sr.*(a.data(i), b)
i += 1
}
}
}
}
implicit def canDivInto_V_S[T:Field:ClassTag]: OpDiv.InPlaceImpl2[VectorBuilder[T], T] = {
new OpDiv.InPlaceImpl2[VectorBuilder[T], T] {
val f = implicitly[Field[T]]
def apply(a: VectorBuilder[T], b: T) {
var i = 0
while(i < a.activeSize) {
a.data(i) = f./(a.data(i), b)
i += 1
}
}
}
}
@expand
@expand.valify
implicit def canOpInto_V_V[@expand.args(OpAdd, OpSub) Op,
@expand.args(Double, Long, Float, Int) T](implicit @expand.sequence[Op]((x => x), (- _)) op: Q): Op.InPlaceImpl2[VectorBuilder[T], VectorBuilder[T]] = {
new Op.InPlaceImpl2[VectorBuilder[T], VectorBuilder[T]] {
def apply(a: VectorBuilder[T], b: VectorBuilder[T]) {
require(a.length < 0 || b.length < 0 || a.length == b.length, "Dimension mismatch!")
a.reserve(a.activeSize + b.activeSize)
var i = 0
// read once here in case we're doing a += a
val bActiveSize = b.activeSize
while(i < bActiveSize) {
a.add(b.index(i), op(b.data(i)))
i += 1
}
}
}
}
@expand
implicit def canOpInto_V_V[@expand.args(OpAdd, OpSub) Op,
T:Ring:ClassTag](implicit @expand.sequence[Op]((x => x), {r.negate(_)}) op: Q): Op.InPlaceImpl2[VectorBuilder[T], VectorBuilder[T]] = {
new Op.InPlaceImpl2[VectorBuilder[T], VectorBuilder[T]] {
val r = implicitly[Ring[T]]
def apply(a: VectorBuilder[T], b: VectorBuilder[T]) {
require(a.length < 0 || b.length < 0 || a.length == b.length, "Dimension mismatch!")
a.reserve(a.activeSize + b.activeSize)
var i = 0
// read once here in case we're doing a += a
val bActiveSize = b.activeSize
while(i < bActiveSize) {
a.add(b.index(i), op(b.data(i)))
i += 1
}
}
}
}
@expand
implicit def canOpInto_V_S[@expand.args(OpAdd, OpSub) Op,
T:Ring:ClassTag](implicit @expand.sequence[Op]((x => x), {r.negate(_)}) op: Q): Op.InPlaceImpl2[VectorBuilder[T], T] = {
new Op.InPlaceImpl2[VectorBuilder[T], T] {
val r = implicitly[Ring[T]]
def apply(a: VectorBuilder[T], b: T) {
var i = 0
// read once here in case we're doing a += a
while(i < a.activeSize) {
a.add(i, op(b))
i += 1
}
}
}
}
@expand
@expand.valify
implicit def canSet[@expand.args(Double, Long, Float, Int) T]: OpSet.InPlaceImpl2[VectorBuilder[T], VectorBuilder[T]] = {
new OpSet.InPlaceImpl2[VectorBuilder[T], VectorBuilder[T]] {
def apply(a: VectorBuilder[T], b: VectorBuilder[T]) {
if(a eq b) return
a.clear()
a.reserve(b.activeSize)
var i = 0
while(i < b.activeSize) {
a.add(b.index(i), b.data(i))
i += 1
}
}
}
}
implicit def canSet[T]: OpSet.InPlaceImpl2[VectorBuilder[T], VectorBuilder[T]] = {
new OpSet.InPlaceImpl2[VectorBuilder[T], VectorBuilder[T]] {
def apply(a: VectorBuilder[T], b: VectorBuilder[T]) {
if(a eq b) return
a.clear()
a.reserve(b.activeSize)
var i = 0
while(i < b.activeSize) {
a.add(b.index(i), b.data(i))
i += 1
}
}
}
}
implicit def opFromCopyAndUpdate[Op, V, Other](implicit op: InPlaceImpl2[Op, VectorBuilder[V], Other],
semi: Semiring[V],
dev: Zero[V],
classTag: ClassTag[V]): UImpl2[Op, VectorBuilder[V], Other, VectorBuilder[V]] = {
BinaryOp.fromCopyAndUpdate[VectorBuilder[V], Other, Op](op, canCopyBuilder[V])
}
@expand
@expand.valify
implicit def canAxpy[@expand.args(Double, Long, Float, Int) T]: scaleAdd.InPlaceImpl3[VectorBuilder[T], T, VectorBuilder[T]] = {
new scaleAdd.InPlaceImpl3[VectorBuilder[T], T, VectorBuilder[T]] {
def apply(a: VectorBuilder[T], s: T, b: VectorBuilder[T]) {
require(a.length < 0 || b.length < 0 || a.length == b.length, "Dimension mismatch!")
if(a eq b) {
a :*= (1+s)
} else {
val bActiveSize: Int = b.activeSize
a.reserve(bActiveSize + a.activeSize)
var i = 0
val bd = b.data
while(i < bActiveSize) {
a.add(b.index(i), s * bd(i))
i += 1
}
}
}
}
}
implicit def canAxpy[T:Semiring:ClassTag]: scaleAdd.InPlaceImpl3[VectorBuilder[T], T, VectorBuilder[T]] = {
new scaleAdd.InPlaceImpl3[VectorBuilder[T], T, VectorBuilder[T]] {
val sr = implicitly[Semiring[T]]
def apply(a: VectorBuilder[T], s: T, b: VectorBuilder[T]) {
require(a.length < 0 || b.length < 0 || a.length == b.length, "Dimension mismatch!")
if(a eq b) {
a :*= sr.+(sr.one,s)
} else {
val bActiveSize: Int = b.activeSize
a.reserve(bActiveSize + a.activeSize)
var i = 0
val bd = b.data
while(i < bActiveSize) {
a.add(b.index(i), sr.*(s, bd(i)))
i += 1
}
}
}
}
}
implicit def space[T:Field:ClassTag]: MutableModule[VectorBuilder[T], T] = {
MutableModule.make[VectorBuilder[T], T] ({ (a:VectorBuilder[T], b: VectorBuilder[T], tolerance: Double) =>
val aHV = a.toHashVector
implicit val hvSpace:MutableVectorField[HashVector[T],T] = HashVector.space[T]
import hvSpace._
val diff: Double = norm(a.toHashVector - b.toHashVector)
diff < tolerance
})
}
// operations involving vectors:
implicit def canAddInto_V_VB[V, Vec](implicit ev: Vec <:
var i = 0
val bd = b.data
while(i < b.iterableSize) {
if(b.isActive(i))
a.add(b.indexAt(i), bd(i))
i += 1
}
case _ =>
a.reserve(a.activeSize + b.activeSize)
require(a.length == b.length, "Dimension mismatch!")
for( (i,v) <- b.activeIterator) {
a.add(i, v)
}
}
}
}
}
implicit def canSubInto_VV_V[V, Vec](implicit ev: Vec <:
var i = 0
val bd = b.data
while(i < b.iterableSize) {
if(b.isActive(i))
a.add(b.indexAt(i), ring.negate(bd(i)))
i += 1
}
case _ =>
a.reserve(a.activeSize + b.activeSize)
require(a.length == b.length, "Dimension mismatch!")
for( (i,v) <- b.activeIterator) {
a.add(i, ring.negate(v))
}
}
}
}
}
implicit def canDot_V_VB[Vec, V](implicit ev: Vec <:
axpy(b.data(i), a(::, b.index(i)), result)
}
result
}
}
}
implicit def canMulDMVB_Semi[T:ClassTag](implicit semi: Semiring[T]): OpMulMatrix.Impl2[DenseMatrix[T], VectorBuilder[T], DenseVector[T]] = {
new OpMulMatrix.Impl2[DenseMatrix[T], VectorBuilder[T], DenseVector[T]] {
def apply(a: DenseMatrix[T], b: VectorBuilder[T]): DenseVector[T] = {
val result = DenseVector.zeros[T](a.rows)
cforRange(0 until b.activeSize) { i =>
axpy(b.data(i), a(::, b.index(i)), result)
}
result
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy