2

私は a に型エイリアスを持っています。私は、myを Breeze のいくつかの組み込み関数、特に関数andSortedMap[Int, Double]に渡すことができる暗黙的なものを持ちたいと思っています。SortedMapbreeze.stats._variancestddev

これは、暗黙のない実際の例です。

package com.soquestion

import breeze.linalg._
import breeze.stats._
import scala.collection.SortedMap
import scala.language.implicitConversions

object proof {
  type Series = SortedMap[Int, Double]

  def example: Double = {
    val s: Series = SortedMap(1 -> 9.0, 2 -> 2.0, 3 -> 5.0, 4 -> 4.0, 5 -> 12.0, 6 -> 7.0, 7 -> 8.0, 8 -> 11.0, 9 -> 9.0, 10 -> 3.0, 11 -> 7.0, 12 -> 4.0, 13 -> 12.0, 14 -> 5.0, 15 -> 4.0, 16 -> 10.0, 17 -> 9.0, 18 -> 6.0, 19 -> 9.0, 20 -> 4.0)

    stddev(s.values)
  }
}

走り込むsbt console

scala> com.soquestion.proof.example
res0: Double = 3.0607876523260447

私が望むのは、 and を指定する必要はなく、単にand.valuesを呼び出すことです。stddev(s)variance(s)

これが私が試したものです

package com.soquestion

import breeze.linalg._
import breeze.stats._
import scala.collection.SortedMap
import scala.language.implicitConversions

object proof {
    // Implicitly convert the SortedMap, or any map, to a DenseVector[Double]
  implicit def series2DenseVector(s: Traversable[(Int, Double)]): DenseVector[Double] = {
    DenseVector(s.map(_._2).toArray)
  }
  type Series = SortedMap[Int, Double]

  def example: Double = {
    val s: Series = SortedMap(1 -> 9.0, 2 -> 2.0, 3 -> 5.0, 4 -> 4.0, 5 -> 12.0, 6 -> 7.0, 7 -> 8.0, 8 -> 11.0, 9 -> 9.0, 10 -> 3.0, 11 -> 7.0, 12 -> 4.0, 13 -> 12.0, 14 -> 5.0, 15 -> 4.0, 16 -> 10.0, 17 -> 9.0, 18 -> 6.0, 19 -> 9.0, 20 -> 4.0)

    stddev(s) // <--- compiler error here
  }
}

しかし、私はコンパイルエラーが発生します

could not find implicit value for parameter impl: breeze.stats.stddev.Impl[com.soquestion.proof.Series,VR]

簡単なドキュメントを調べても、提供する必要がある暗黙的なものの良い例を見つけることができませんでした。stdev理想的には、複数の Implicit を使用せずに両方を呼び出せるようにする 1 つの Implicit を作成したいと考えていますvariance

Scala Breeze DenseVector Implicit failureという質問を見ましたが、このシナリオにどのように適用されるかわかりません。

将来誰かが必要になった場合に備えて、以下の@dlwの回答に基づいて完全にフォーマットされた回答

package com.soquestion

import breeze.linalg.support._
import breeze.linalg.support.CanTraverseValues._
import breeze.stats._
import scala.annotation.tailrec
import scala.collection.SortedMap
import scala.language.implicitConversions

object proof {
  type Series = SortedMap[Int, Double]

  def example: Double = {
    // ideally this implicit would go in a scope higher up so it could be
    // brought in wherever it's needed, but this works for a sample
    implicit object SeriesIter extends CanTraverseValues[Series, Double] {
      def isTraversableAgain(from: Series) = true
      def traverse(from: Series, fn: ValuesVisitor[Double]): Unit = {
        @tailrec def traverser(idx: Int, t: Array[Double]): Unit = {
          if (idx == 1) fn.visit(t.head)
          else {
            fn.visit(t.head)
            traverser(idx - 1, t.tail)
          }
        }
        val v: Array[Double] = from.values.toArray
        fn.zeros(0, 0d)
        traverser(v.size, v)
      }
    }

    val s: Series = SortedMap(1 -> 9.0, 2 -> 2.0, 3 -> 5.0, 4 -> 4.0, 5 -> 12.0, 6 -> 7.0, 7 -> 8.0, 8 -> 11.0, 9 -> 9.0, 10 -> 3.0, 11 -> 7.0, 12 -> 4.0, 13 -> 12.0, 14 -> 5.0, 15 -> 4.0, 16 -> 10.0, 17 -> 9.0, 18 -> 6.0, 19 -> 9.0, 20 -> 4.0)
    stddev(s)
  }
}
4

1 に答える 1

2

これについては、ドキュメントの方がはるかに優れている可能性があります。エラー メッセージをより役立つものにできればと思います。

stddevのソースを見ると、 の実装が必要であることがわかります。variance.Implこれには が必要です。これは、暗黙的meanAndVariance.Implな型を持つ任意の型に提供できます。CanTraverseValues[T, Double]デフォルトでは、CanTraverseValues暗黙の for コレクションがありますが、含まれている型のみであり、scala のMap型の値ではありません。CanTraverseValues と CanMapValues を実装すると、ほとんどの簡単な UFuncs が有効になります。

Scala は通常、暗黙を「連鎖」しません。そのため、proof例が機能しませんでした。

于 2015-11-20T19:07:53.293 に答える