これは、Problems with Scala Numeric[T] に関する追加の質問です。
今日、次善のシードのニュートン推定をサポートするために、コードを多少変更しました。A.fromDouble(v)
本当に殺すことができないという事実(?)を除いて、すべて問題ありません。
少し長いサンプルですが、おそらくここにすべてを配置するのが最善です。
import scala.annotation.tailrec
import math.{signum => sign}
import math.Fractional.Implicits._
import Ordering.Implicits._
/*
* 'f' is a "strictly increasing function" (derivative > 0).
* The sweep gives the value at which it gives 'goal' (within '+-bEps' margins).
*/
object NewtonianSweep {
def apply[A: Fractional, B: Fractional](
f: A => B,
fDerivate: A => Double,
goal: B,
bEps: B,
initialSeed: A,
aMin: A,
aMax: A
): A = {
assert( initialSeed >= aMin && initialSeed <= aMax )
// 'goal' is supposed to exist within the range (this also checks that
// the function is increasing - though doesn't (cannot) check "strict increasing",
// we'll just trust the caller.
//
assert( f(aMin) <= goal )
assert( f(aMax) >= goal )
@tailrec
def sweep( _seed: A ): A = {
val seed= _seed.max(aMin).min(aMax) // keep 'seed' within range
val bDiff= goal-f(seed) // >0 for heading higher, <0 for heading lower
if (bDiff.abs < bEps) {
seed // done (within margins)
} else {
val d= fDerivate(seed) // slope at the particular position (dy/dx)
assert( d>0.0 )
// TBD: How to get the calculated 'Double' to be added to 'seed: A'?
//
val aType= implicitly[Fractional[A]]
sweep( aType.plus( seed, aType.fromDouble( d*(bDiff.toDouble) ) ))
}
}
sweep( initialSeed )
}
}
との 2 つのFractional
タイプがあるのは、それらが概念的に異なるためです。通常時です。何でもかまいません。それらに同じタイプを使用する場合、それらは'sであると言えます。A
B
A
B
Double
その前に、誰かがこの問題の欠けているピースを持っているかどうかを確認したかった.