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。祝你好运,玩得开心。
如果我想从下面的等式中求解变量 (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。祝你好运,玩得开心。