1

这是关于 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 )
  }
}

我有两种Fractional类型A和的原因B是它们在概念上是不同的。A通常是时间。B可以是任何东西。如果我要为它们使用相同的类型,我也可以说它们是Double's。

在我这样做之前,我想检查是否有人有这个问题的缺失部分。

4

1 回答 1

0

我不确定我是否理解您在A和之间的区别B。但是既然你有f: A => B,我认为它们可以以某种方式相互转换?然后看代码,我的印象是A主类型,那为什么不把所有B类型的东西都转换成A而不是反过来呢?

然后你可以节省任何转换为Double​​ ,无论如何这似乎不是一个好主意。

/*
* '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 => A, 
    goal: B, 
    bEps: B, 
    initialSeed: A, 
    aMin: A, 
    aMax: A 
  )(f: B => 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.
    //
    val aGoal = f(goal)
    val aEps  = f(bEps)

    assert(aMin <= aGoal)
    assert(aMax >= aGoal)

    val aType = implicitly[Fractional[A]]

    @tailrec
    def sweep(_seed: A): A = {
      val seed = _seed.max(aMin).min(aMax)   // keep 'seed' within range

      val aDiff = aGoal - seed    // >0 for heading higher, <0 for heading lower

      if (aDiff.abs < aEps) {
        seed                        // done (within margins)
      } else {
        val d = fDerivate(seed)      // slope at the particular position (dy/dx)
        assert(d > aType.zero)
        val prod = d * aDiff
        sweep(seed + prod)
      }
    }

    sweep(initialSeed)
  }
}
于 2013-06-16T20:28:36.843 回答