Function Scala中的优化程序(Brent法)

Function Scala中的优化程序(Brent法),function,scala,statistics,solver,Function,Scala,Statistics,Solver,我正在尝试在Scala中构建一个电源分析工具。特别是,我试图创建一个函数,在给定一些限制条件(统计能力、效应大小、两个样本大小之间的比率、显著性水平和我们希望运行的假设检验类型)的情况下,该函数确实返回所需的样本大小 我编写了以下代码: import org.apache.commons.math3.analysis.UnivariateFunction import org.apache.commons.math3.analysis.solvers.BrentSolver import org

我正在尝试在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的值

在浏览代码时,只关注函数的“双面”部分(我将在第二阶段完成“更大”和“更少”),我尝试创建一个名为
func
的函数。然后使用命令
try{solver.solve(500,func,0.001,1000000)}catch{case\uuux:Throwable=>None}
我尝试使用最多500次迭代并在间隔(0.001,1000000)内求解它。不幸的是,该命令既不返回结果也不返回错误消息

编辑:我已经从上面引用的代码中删除了
//catch{case\uuwable=>None}
(没有一个是多余的)。这段代码实际上捕获了所有异常,并且对它们不做任何处理。 我在运行代码时看到的例外情况有:

Exception in thread "main" org.apache.commons.math3.exception.NoBracketingException: function values at endpoints do not have different signs, endpoints: [2, 10,000,000], values: [0.05, 1]
    at org.apache.commons.math3.analysis.solvers.BrentSolver.doSolve(BrentSolver.java:118)
    at org.apache.commons.math3.analysis.solvers.BaseAbstractUnivariateSolver.solve(BaseAbstractUnivariateSolver.java:190)
    at org.apache.commons.math3.analysis.solvers.BaseAbstractUnivariateSolver.solve(BaseAbstractUnivariateSolver.java:195)
    at normal_sample_size$.requiredSizeCalculationNormal(normal_sample_size.scala:46)
    at normal_sample_size$.delayedEndpoint$normal_sample_size$1(normal_sample_size.scala:31)
    at normal_sample_size$delayedInit$body.apply(normal_sample_size.scala:22)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.App$class.main(App.scala:76)
    at normal_sample_size$.main(normal_sample_size.scala:22)
    at normal_sample_size.main(normal_sample_size.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

Process finished with exit code 1

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

tldr;您是否在问如何使用commons math(可能来自Scala)的Brent解算器?如果是这样,您应该删除所有与问题无关的其他信息。@ziggystar是的,这就是我要做的。我把问题缩短了,直截了当地说。