如果我想从下面的等式求解变量(p),其他一切都是已知的:
Java中是否有一种方法可以让我这样做?
我可以用我的计算器来完成它,我相信Python有一些东西 - 所以我知道它是可行的。谢谢。
这是快速参考图:
带圆的x值是满足等式两边的(p)。但是计算所有值,然后检查零将不是最有效的方法。
答案 0 :(得分:1)
你必须实现函数,给出方程两边的差异,然后是某种单变量求解器。由于这个方程在正轴上的凸性,所有经典方法,尤其是割线方法应该完美无缺。
class myfunc {
public myfunc(int nn, int cc, double aalpha) {...}
public double eval(double p) {
double sum = 1;
double term = 1;
for(int i = 1; i<=c; i++) {
term *= (n*p)/i;
sum += term;
}
return sum*Math.exp(-n*p) - alpha;
}
}
..............
public double secant(myfunc f, double a, double b) {
double fa = f.eval(a);
double fb = f.eval(b);
while(Math.abs(b-a)>1e-10) {
double c = (a*fb-b*fa)/(fb-fa);
a=b; fa = fb;
b=c; fb = f.eval(b);
}
return b;
}
你会用
之类的东西来称呼它p = secant(new myfunc(n,c,alpha), 0, 0.1);
事实证明,割线方法不稳定,使用修改后的规则falsi
import java.lang.*;
interface RealFunc {
public double eval(double x);
}
class myfunc implements RealFunc {
int c,n;
double alpha;
public myfunc(int nn, int cc, double aalpha) {
c=cc; n=nn; alpha = aalpha;
}
public double eval(double p) {
double sum = 1;
double term = 1;
for(int i = 1; i<=c; i++) {
term *= (n*p)/i;
sum += term;
}
return sum*Math.exp(-n*p) - alpha;
}
}
public class SecantSolverSO34980366 {
static public double illinois(RealFunc f, double a, double b) {
double fa = f.eval(a);
double fb = f.eval(b);
while(Math.abs(b-a) > 1e-10) {
//System.out.printf("a:f(%16.12f) = %16.12f | b: f(%16.12f) = %16.12f \n ",a,fa,b,fb);
double c = (a*fb-b*fa)/(fb-fa);
double fc = f.eval(c);
if( fa*fc < 0 ) {
fa *= 0.5;
} else {
a = b; fa = fb;
}
b = c; fb = fc;
}
return b;
}
public static void main(String[] args) {
int n = 1;
for(double alpha = 0.2; alpha <=1.0001; alpha += 0.1) {
System.out.printf("alpha=%4.2f: ", alpha);
for(int c = 2; c < 15; c+=2) {
double p = illinois(new myfunc(n,c,alpha), 0.,(c+13.0)/n);
System.out.printf("(c=%2d):%12.9f ",c,p);
}
System.out.printf("\n");
}
}
}
答案 1 :(得分:1)
Apache Commons Math中有几种数值方法可用于查找函数的根。请参阅documentation for numerical methods。 Java中可能还有许多其他现有的数值方法库。
至于象征性地解决这些方程式,我不知道在Java中使用它的最佳方法。你可以编译一个计算机代数系统,让我们说Maxima,使用基于JVM的Lisp(我知道ABCL,但可能有其他人)。
象征性地解决方程是困难的,而Maxima的符号求解器并不太强大。但是通过一些哄骗,我得到以下内容,您在使用之前需要验证:
(1 - alpha) c! = gamma_greek(c + 1, n*p)
其中gamma_greek
是较低的不完整伽玛函数。因此,如果您具有较低不完整伽玛函数的逆的实现,则可以在不调用根查找算法的情况下解决此问题。似乎Apache Commons Math没有,尽管其他库可能。另见this question on SO。祝你好运,玩得开心。