scala - Array.map returns ArraySeq? -


i making small example of linear algebra sequential , parallel implementations. below current code:

import util.random import system.currenttimemillis import actors.futures._ import numeric.implicits._  object parallel extends app{    val rnd = new random(1337)//seeded rng    //create 2 matrices dimension nxn   val n = 550   val a:array[array[double]] = array.fill(n,n){ rnd.nextdouble }   val b:array[array[double]] = array.fill(n,n){ rnd.nextdouble }    //time call-by-name block , return milli-seconds   def time(b: => unit):long = {     val start = currenttimemillis     b     currenttimemillis-start   }     val sequentialprogram = new linearalgebra sequentiallinearalgebra {     println("sequential time: "+time { * b } )   }    val parcolprogram = new linearalgebra parcollinearalgebra {     println("parcol time: "+time { * b } )   }    val futureprogram = new linearalgebra futurelinearalgebra {     println("future time: "+time { * b } )   }  }  //interface, knows nothing implementation trait linearalgebra{    type vector[t] = array[t]   type matrix[t] = vector[vector[t]]    implicit class vectorops[t:numeric](v:vector[t]){     def dot(that:vector[t]):t = innerprod(v,that)   }   implicit class matrixops[t:numeric](m:matrix[t]){     def *(that:matrix[t]):matrix[t] = matmul(m,that)   }    //functionality deferred implementing traits   def innerprod[t:numeric](a:vector[t],b:vector[t]):t   def matmul[t:numeric](a:matrix[t],b:matrix[t]):matrix[t] }  //implements linearalgebra interface in sequential fashion trait sequentiallinearalgebra extends linearalgebra {    def innerprod[t:numeric](a:vector[t],b:vector[t]) =     ((a,b).zipped map (_*_)).sum    def matmul[t:numeric](a:matrix[t],b:matrix[t]) = {       val bt = b.transpose             a.map(row => bt.map(col => row dot col))      }  }  //implements linearalgebra interface using parallel collections trait parcollinearalgebra extends linearalgebra {    def innerprod[t:numeric](a:vector[t],b:vector[t]) =     ((a,b).zipped map (_*_)).sum    def matmul[t:numeric](a:matrix[t],b:matrix[t]) = {     val bt = b.transpose     (a.par map (row => bt map (col => row dot col))).toarray   }  }  //implements linearalgebra interface using futures, i.e. explicit workload distribution trait futurelinearalgebra extends linearalgebra {    def innerprod[t:numeric](a:vector[t],b:vector[t]) =     ((a,b).zipped map (_*_)).sum    def matmul[t:numeric](a:matrix[t],b:matrix[t]) = {       val bt = b.transpose       val res = map ( row => future {bt map (col => row dot col)})        res.map(_.apply)     }  } 

the code seems correct me, following errors:

fsc parallel.scala /home/felix/documents/teaching/2014/dm509/scala/parallel.scala:61: error: type mismatch;  found   : array[scala.collection.mutable.arrayseq[t]]  required: sequentiallinearalgebra.this.matrix[t]     (which expands to)  array[array[t]]       a.map(row => bt.map(col => row dot col))             ^ /home/felix/documents/teaching/2014/dm509/scala/parallel.scala:71: error: type mismatch;  found   : array[scala.collection.mutable.arrayseq[t]]  required: parcollinearalgebra.this.matrix[t]     (which expands to)  array[array[t]]     (a.par map (row => bt map (col => row dot col))).toarray                                                      ^ /home/felix/documents/teaching/2014/dm509/scala/parallel.scala:82: error: type mismatch;  found   : array[scala.collection.mutable.arrayseq[t]]  required: futurelinearalgebra.this.matrix[t]     (which expands to)  array[array[t]]       res.map(_.apply)              ^ 3 errors found 

the problem seems array.map returns arrayseq oppposed expected array. if search-replace array , list, program works expected. reason moving array wish compare efficiency imperative implementation, i.e., need efficient random access. can explain behaviour?

the context bound makes difference:

scala> val = array.tabulate(10,10)((x,y)=>y) as: array[array[int]] = array(array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))  scala> map (x => x.sum) res0: array[int] = array(45, 45, 45, 45, 45, 45, 45, 45, 45, 45)  scala> def f[a: numeric](as: array[array[a]]) = map (x => x.sum) f: [a](as: array[array[a]])(implicit evidence$1: numeric[a])scala.collection.mutable.arrayseq[a]  scala> def f[a](as: array[array[a]]) = map (x => 42) f: [a](as: array[array[a]])array[int] 

presumably uses fallback canbuildfrom yields seq.

edit: fix it, supply reflect.classtag[t] can create array[t] want.

you'll need on:

def matmul[t:numeric](a:matrix[t],b:matrix[t])(implicit ev1: classtag[t]) 

and

implicit class matrixops[t:numeric](m:matrix[t])(implicit ev1: classtag[t]) 

Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -