Scala中的优化过程(布伦特方法)

时间:2015-03-31 17:08:45

标签: function scala statistics solver

我正在尝试在Scala中构建一个功耗分析工具。特别是,我正在尝试创建一个函数,它确实返回所需的样本大小给定一些限制(统计功效,效果大小,两个样本大小之间的比率,显着性水平和我们想要运行的假设检验的类型)

我写了以下代码:

import org.apache.commons.math3.analysis.UnivariateFunction
import org.apache.commons.math3.analysis.solvers.BrentSolver
import org.apache.commons.math3.distribution.NormalDistribution
import scala.math._

object normal_sample_size extends App {

  val theta1 = 0.0025
  val theta2 = theta1 * 1.05
  val split = 0.50
  val power = 0.80
  val significance = 0.05
  val alternative = "two sided"

  val result = requiredSizeCalculationNormal(effectSizeCalculation(theta1, theta2), split, power, significance, alternative)
  println(result)

  def effectSizeCalculation(mu1: Double, mu2: Double): Double = {
    2 * math.asin(math.sqrt(mu1)) - 2 * math.asin(math.sqrt(mu2))
  }

  def requiredSizeCalculationNormal(effect_size: Double, split_ratio: Double, power: Double, significance: Double, alternative: String): Unit = {

    if (alternative == "two sided") {

      val z_score = new NormalDistribution().inverseCumulativeProbability(significance / 2.0)
      val func = new UnivariateFunction {def value(n: Double) = (1 - new NormalDistribution().cumulativeProbability(z_score.abs - effect_size * sqrt(n * split_ratio * n * (1 - split_ratio)))) +
        new NormalDistribution().cumulativeProbability(z_score - effect_size * sqrt(n * split_ratio * n * (1 - split_ratio)))}
      val solver = new BrentSolver()
      try {solver.solve(500, func, 0.001, 1000000)} catch {case _:Throwable => None}

    } else if (alternative == "less") {

      //val z_score = new NormalDistribution().inverseCumulativeProbability(significance)
      //new NormalDistribution().cumulativeProbability(z_score - effect_size * sqrt(n * split_ratio * n * (1 - split_ratio)))

    } else if (alternative == "greater") {

      //val z_score = new NormalDistribution().inverseCumulativeProbability(significance).abs
      //1 - new NormalDistribution().cumulativeProbability(z_score - effect_size * sqrt(n * split_ratio * n * (1 - split_ratio)))

    } else {

      println("Error message: Specify the right alternative. Possible values are 'two sided', 'less', 'greater'")

    }
  }
}

requiredSizeCalculationNormal()识别哪种类型的假设检验正在处理(“双面”,“更大”或“更少”),然后计算所需的样本量。最后一点是我在努力的地方!使用Brent的方法(来自math3库)我想找到解决函数的n的值。

通过代码,只关注我的函数的“双面”部分(我将在第二阶段完成“更大”和“更少”),我试图创建一个名为{{1的函数}}。然后使用命令func我试图使用最多500次迭代并在区间(0.001,1000000)内解决它。不幸的是,该命令既不返回结果也不返回错误消息。

编辑:我已从try {solver.solve(500, func, 0.001, 1000000)} catch {case _:Throwable => None}上面引用的代码中删除了(无论如何都是多余的)。这段代码实际上是捕获所有异常并且不对它们执行任何操作。 我看到运行代码的例外是:

//catch {case _:Throwable => None}

所以问题似乎是函数在指定的时间间隔内没有改变符号。

0 个答案:

没有答案