Java 中是否有针对(eq. inside)的 Solve 方法?

Is there a Solve method in Java for (eq. inside)?

如果我想从下面的等式中求解变量 (p),其中其他一切都是已知的:

Java 中有什么方法可以让我这样做吗?

我可以用我的计算器来计算,而且我确信那里有适合 Python 的东西 - 所以我知道它是可行的。谢谢。

这是快速参考图:

带圆圈的x值就是满足等式两边的(p)。但是计算所有值,然后检查是否为零并不是执行此操作的最有效方法。

您必须实现给出方程两边差值的函数,然后是某种单变量求解器。由于该方程在正轴上的凸性,所有经典方法,尤其是。正割法,应该可以完美地工作。

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");
    }

  }
}

Apache Commons Math 中有多种用于查找函数根的数值方法。参见documentation for numerical methods。 Java.

中可能还有许多其他现有的数值方法库

至于用符号求解这些方程,我不知道 Java 中的最佳方法。你可以编译一个计算机代数系统,比方说 Maxima, using a JVM-based Lisp (I know of ABCL 但可能还有其他的)。

用符号求解方程很困难,而且 Maxima 的符号求解器也不太强大。但是经过一些哄骗,我得到了以下信息,您在使用它之前需要验证一下:

(1 - alpha) c! = gamma_greek(c + 1, n*p)

其中 gamma_greek 是下不完全伽马函数。因此,如果您实现了下不完全伽马函数的逆函数,则无需调用 root-finding 算法即可解决此问题。 Apache Commons Math 似乎没有,尽管其他库可能有。另见 this question on SO。祝你好运,玩得开心。