Function Scala中的优化程序(Brent法)
我正在尝试在Scala中构建一个电源分析工具。特别是,我试图创建一个函数,在给定一些限制条件(统计能力、效应大小、两个样本大小之间的比率、显著性水平和我们希望运行的假设检验类型)的情况下,该函数确实返回所需的样本大小 我编写了以下代码: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
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是的,这就是我要做的。我把问题缩短了,直截了当地说。