Java中double到BigDecimal的转换
我编写了一个Java程序来计算的值。在程序内部,我创建了一个库来计算必要的复杂函数,如atan、cos等。两个程序中的所有内容都是通过Java中double到BigDecimal的转换,java,double,bigdecimal,complex-numbers,Java,Double,Bigdecimal,Complex Numbers,我编写了一个Java程序来计算的值。在程序内部,我创建了一个库来计算必要的复杂函数,如atan、cos等。两个程序中的所有内容都是通过double和BigDecimal数据类型访问的。这会在评估Zeta函数的大值时产生重大问题 Zeta函数参考的数值逼近 当s具有较大的复杂形式时,直接以较高的值计算此近似值会产生问题,例如s=(230+30i)。我非常感激能得到这方面的信息。S2.减号(S1)的计算会产生错误,因为我在adaptiveQuad方法中写了一些错误 例如,Zeta(2+3i)通过此
double
和BigDecimal
数据类型访问的。这会在评估Zeta函数的大值时产生重大问题
Zeta函数参考的数值逼近
当s
具有较大的复杂形式时,直接以较高的值计算此近似值会产生问题,例如s=(230+30i)
。我非常感激能得到这方面的信息。S2.减号(S1)
的计算会产生错误,因为我在adaptiveQuad
方法中写了一些错误
例如,Zeta(2+3i)
通过此程序生成
计算形式为Zeta(s)=a+ib的黎曼Zeta函数。
在Riemann Zeta函数中输入[a]的值:2
在Riemann Zeta函数中输入[b]的值:3
Zeta(s)的值为7.9802198581133409e-1-1.137443081631288E-1*i
总时间为0.469秒。
是的
Zeta(100+0i)
计算形式为Zeta(s)=a+ib的黎曼Zeta函数。
在Riemann Zeta函数中输入[a]的值:100
在Riemann Zeta函数中输入[b]的值:0
Zeta的值为1.000000000153236E0
所用总时间为0.672秒。
这与其他方法相比也是正确的。该问题是由标记为adaptiveQuad
的方法内部的某些内容引起的
Zeta(230+30i)
计算形式为Zeta(s)=a+ib的黎曼Zeta函数。
在Riemann Zeta函数中输入[a]的值:230
在Riemann Zeta函数中输入[b]的值:30
Zeta(s)的值是0.999999990909108519845391615339162047254997503854254327939165160684246153982012489787014797711446814567257766441212850988130425915012047816838603847693210844739256205723154167157217280824684724672467499310913504362891191509730873870909918493750428783837552525280693498787878787878787878787878787446900-38.005428584222228490409209292044031338674747488795053570481276480687488780504302949989766663616230972126423385487374863788363786029170239477711991086845577789170147132850500691609991921139705106911047250679664182062256166419533972054228386978638056565656567245197290756021581247961260937154293062734500E-15*i
总时间为1.746秒。
与之相比,虚部有点偏
计算积分的算法称为,并找到了double
Java实现。自适应四元方法应用以下内容
//自适应正交
公共静态双自适应(双a、双b){
双h=b-a;
双c=(a+b)/2.0;
双d=(a+c)/2.0;
双e=(b+c)/2.0;
双Q1=h/6*(f(a)+4*f(c)+f(b));
双Q2=h/12*(f(a)+4*f(d)+2*f(c)+4*f(e)+f(b));
如果(算术平均值(第2季度至第1季度)0.0){
返回formatter.format(re)+“+”+formatter.format(im)
+“*我”;
}
如果(re.doubleValue()!=0.0&&im.doubleValue()<0.0){
返回formatter.format(re)+“-”+formatter.format(im.negate())
+“*我”;
}
如果(im.doubleValue()==0.0){
返回格式化程序。格式化(re);
}
如果(re.doubleValue()==0.0){
返回格式化程序。格式化(im)+“*i”;
}
返回formatter.format(re)+“+i*”+formatter.format(im);
}
}
我正在复习下面的答案
一个问题可能是由于
complenum=(z.multiply(Math.atan(t))).sin();
络合物D1=新络合物(1+t*t).pow(z.divide(TWO));
复数D2=新复数(Math.pow(Math.E,2.0*Math.PI*t)-1.0);
复数den=D1.multiply(D2,MathContext.UNLIMITED);
我没有应用BigDecimal.pow(BigDecimal)
。尽管如此,我不认为这是导致浮点运算产生差异的直接原因
编辑:我尝试了Zeta函数的一种新的积分近似。最后,我将开发一种新方法来计算BigDecimal.pow(BigDecimal)
(1)积分使用AdapterQuad,从区间[0,10]开始。对于a和b=0的值越来越大的z=a+ib,被积函数是一个越来越振荡的函数,仅[0,5]中的零数就与a成正比,对于z=100,被积函数增加到43
因此,从包含一个或多个零的区间开始近似是有风险的,正如发布的程序非常清楚地显示的那样。对于z=100,被积函数在0、5和10处分别为0、-2.08E-78和7.12E-115。因此,将辛普森公式的结果与1E-20进行比较,结果为真,结果绝对错误
(2) AbelPlana方法中的计算涉及两个复数,C1和C2。对于z=a+0i,它们是实数,下表显示了各种a值的值:
a C1 C2
10 5.689E1 1.024E3
20 2.759E4 1.048E6
30 1.851E7 1.073E9
40 1.409E10 1.099E12
60 9.770E15 1.152E18
100 6.402E27 1.267E30
现在我们知道,随着a的增加,ζ(a+0i)的值向1减小。显然,两个大于1E15的值相减时,不可能在一个值附近产生有意义的结果
该表还表明,为了通过使用该算法获得ζ(a+0i)的良好结果,C1和C2*I(I是整数)需要以大约45位有效数字的精度进行计算。(任意精度的数学无法避免(1)中所述的陷阱。)
(3) 请注意,当使用具有任意精度的库时,像E和PI这样的值应该提供比java.lang.Math中的双精度值更好的精度
编辑
(25.5.11)在[0,10]中有与(25.5.12)一样多的零。0处的计算是t
import java.io.PrintWriter;
import org.apfloat.ApcomplexMath;
import org.apfloat.Apcomplex;
import org.apfloat.Apfloat;
import org.apfloat.samples.Pi;
public class ZetaFinder
{
//Number of sig figs accuracy. Note that infinite should be reserved
private static long PRECISION = 40l;
// Convergence criterion for integration
static Apfloat EPSILON = new Apfloat("1e-15",PRECISION);
//Value of PI - enhanced using Apfloat library sample calculation of Pi in constructor,
//Fast enough that we don't need to hard code the value in.
//You could code hard value in for perf enhancement
static Apfloat PI = null; //new Apfloat("3.14159");
//Integration limits - I found too high a value for "infinity" causes integration
//to terminate on first iteration. Plot the integrand to see why...
static Apfloat INFINITE_LIMIT = new Apfloat("40",PRECISION);
static Apfloat ZERO_LIMIT = new Apfloat("1e-16",PRECISION); //You can use zero for the 25.5.12
static Apfloat one = new Apfloat("1",PRECISION);
static Apfloat two = new Apfloat("2",PRECISION);
static Apfloat four = new Apfloat("4",PRECISION);
static Apfloat six = new Apfloat("6",PRECISION);
static Apfloat twelve = new Apfloat("12",PRECISION);
static Apfloat fifteen = new Apfloat("15",PRECISION);
static int counter = 0;
Apcomplex s = null;
public ZetaFinder(Apcomplex s)
{
this.s = s;
Pi.setOut(new PrintWriter(System.out, true));
Pi.setErr(new PrintWriter(System.err, true));
PI = (new Pi.RamanujanPiCalculator(PRECISION+10, 10)).execute(); //Get Pi to a higher precision than integer consts
System.out.println("Created a Zeta Finder based on Abel-Plana for s="+s.toString() + " using PI="+PI.toString());
}
public static void main(String[] args)
{
Apfloat re = new Apfloat("2", PRECISION);
Apfloat im = new Apfloat("3", PRECISION);
Apcomplex s = new Apcomplex(re,im);
ZetaFinder finder = new ZetaFinder(s);
System.out.println(finder.findZeta());
}
private Apcomplex findZeta()
{
Apcomplex retval = null;
//Method currently in question (a.k.a. 25.5.12)
//Apcomplex mult = ApcomplexMath.pow(two, this.s);
//Apcomplex firstterm = (ApcomplexMath.pow(two, (this.s.add(one.negate())))).divide(this.s.add(one.negate()));
//Easier integrand method (a.k.a. 25.5.11)
Apcomplex mult = two;
Apcomplex firstterm = (one.divide(two)).add(one.divide(this.s.add(one.negate())));
Apfloat limita = ZERO_LIMIT;//Apfloat.ZERO;
Apfloat limitb = INFINITE_LIMIT;
System.out.println("Trying to integrate between " + limita.toString() + " and " + limitb.toString());
Apcomplex integral = adaptiveQuad(limita, limitb);
retval = firstterm.add((mult.multiply(integral)));
return retval;
}
private Apcomplex adaptiveQuad(Apfloat a, Apfloat b) {
//if (counter % 100 == 0)
{
System.out.println("In here for the " + counter + "th time");
}
counter++;
Apfloat h = b.add(a.negate());
Apfloat c = (a.add(b)).divide(two);
Apfloat d = (a.add(c)).divide(two);
Apfloat e = (b.add(c)).divide(two);
Apcomplex Q1 = (h.divide(six)).multiply(f(a).add(four.multiply(f(c))).add(f(b)));
Apcomplex Q2 = (h.divide(twelve)).multiply(f(a).add(four.multiply(f(d))).add(two.multiply(f(c))).add(four.multiply(f(e))).add(f(b)));
if (ApcomplexMath.abs(Q2.add(Q1.negate())).compareTo(EPSILON) < 0)
{
System.out.println("Returning");
return Q2.add((Q2.add(Q1.negate())).divide(fifteen));
}
else
{
System.out.println("Recursing with intervals "+a+" to " + c + " and " + c + " to " +d);
return adaptiveQuad(a, c).add(adaptiveQuad(c, b));
}
}
private Apcomplex f(Apfloat x)
{
return integrand2(x);
}
/*
* Simple test integrand (z^2)
*
* Can test implementation by asserting that the adaptiveQuad
* with this function evaluates to z^3 / 3
*/
private Apcomplex integrandTest(Apfloat t)
{
return ApcomplexMath.pow(t, two);
}
/*
* Abel-Plana formulation integrand
*/
private Apcomplex integrand1(Apfloat t)
{
Apcomplex numerator = ApcomplexMath.sin(this.s.multiply(ApcomplexMath.atan(t)));
Apcomplex bottomlinefirstbr = one.add(ApcomplexMath.pow(t, two));
Apcomplex D1 = ApcomplexMath.pow(bottomlinefirstbr, this.s.divide(two));
Apcomplex D2 = (ApcomplexMath.exp(PI.multiply(t))).add(one);
Apcomplex denominator = D1.multiply(D2);
Apcomplex retval = numerator.divide(denominator);
//System.out.println("Integrand evaluated at "+t+ " is "+retval);
return retval;
}
/*
* Abel-Plana formulation integrand 25.5.11
*/
private Apcomplex integrand2(Apfloat t)
{
Apcomplex numerator = ApcomplexMath.sin(this.s.multiply(ApcomplexMath.atan(t)));
Apcomplex bottomlinefirstbr = one.add(ApcomplexMath.pow(t, two));
Apcomplex D1 = ApcomplexMath.pow(bottomlinefirstbr, this.s.divide(two));
Apcomplex D2 = ApcomplexMath.exp(two.multiply(PI.multiply(t))).add(one.negate());
Apcomplex denominator = D1.multiply(D2);
Apcomplex retval = numerator.divide(denominator);
//System.out.println("Integrand evaluated at "+t+ " is "+retval);
return retval;
}
}
import java.io.PrintWriter;
import org.apfloat.ApcomplexMath;
import org.apfloat.Apcomplex;
import org.apfloat.Apfloat;
import org.apfloat.ApfloatMath;
import org.apfloat.samples.Pi;
public class ZetaSeries {
//Number of sig figs accuracy. Note that infinite should be reserved
private static long PRECISION = 100l;
// Convergence criterion for integration
static Apfloat EPSILON = new Apfloat("1e-30",PRECISION);
static Apfloat one = new Apfloat("1",PRECISION);
static Apfloat two = new Apfloat("2",PRECISION);
static Apfloat minus_one = one.negate();
static Apfloat three = new Apfloat("3",PRECISION);
private Apcomplex s = null;
private Apcomplex s_plus_two = null;
public ZetaSeries(Apcomplex s) {
this.s = s;
this.s_plus_two = two.add(s);
}
public static void main(String[] args) {
Apfloat re = new Apfloat("230", PRECISION);
Apfloat im = new Apfloat("30", PRECISION);
Apcomplex s = new Apcomplex(re,im);
ZetaSeries z = new ZetaSeries(s);
System.out.println(z.findZeta());
}
private Apcomplex findZeta() {
Apcomplex series_sum = Apcomplex.ZERO;
Apcomplex multiplier = (one.divide(this.s.add(minus_one)));
int stop_condition = 1;
long n = 1;
while (stop_condition > 0)
{
Apcomplex term_to_add = sum_term(n);
stop_condition = ApcomplexMath.abs(term_to_add).compareTo(EPSILON);
series_sum = series_sum.add(term_to_add);
//if(n%50 == 0)
{
System.out.println("At iteration " + n + " : " + multiplier.multiply(series_sum));
}
n+=1;
}
return multiplier.multiply(series_sum);
}
private Apcomplex sum_term(long n_long) {
Apfloat n = new Apfloat(n_long, PRECISION);
Apfloat n_plus_one = n.add(one);
Apfloat two_n = two.multiply(n);
Apfloat t1 = (n.multiply(n_plus_one)).divide(two);
Apcomplex t2 = (two_n.add(three).add(this.s)).divide(ApcomplexMath.pow(n_plus_one,s_plus_two));
Apcomplex t3 = (two_n.add(minus_one).add(this.s.negate())).divide(ApcomplexMath.pow(n,this.s_plus_two));
return t1.multiply(t2.add(t3.negate()));
}
}