多倍長ライブラリの一部を更新しました。以下の資料をご覧下さい。実際には5乗根の計算と0.2乗の計算は似たような速度でしたが計算桁数の関係で平方根以外は逆数乗で計算しています。
多倍長ライブラリの作り方と高次方程式の解の計算方法
通常の多倍長ライブラリです。回転行列を軸の回転に統一しました。
package jp.wshounen;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
public class BigMath {
public static int precision = 20;
public static MathContext context = new MathContext(24,
RoundingMode.HALF_EVEN);
public static BigDecimal PI = atan(BigDecimal.ONE).multiply(
new BigDecimal(4));
public static BigDecimal E = exp(BigDecimal.ONE);
public static BigDecimal round(final BigDecimal in, final int precision) {
return in.round(new MathContext(precision, RoundingMode.HALF_EVEN));
}
public static BigDecimal round(final BigDecimal in) {
return in.setScale(0, RoundingMode.HALF_EVEN);
}
public static BigDecimal degToRad(final BigDecimal arcsec) {
return arcsec.multiply(PI).divide(new BigDecimal(180), context);
}
public static BigDecimal radToDeg(final BigDecimal rad) {
return rad.multiply(new BigDecimal(180)).divide(PI, context);
}
public static BigDecimal floor(final BigDecimal in) {
return in.setScale(0, RoundingMode.FLOOR);
}
public static BigDecimal ceil(final BigDecimal in) {
return in.setScale(0, RoundingMode.CEILING);
}
public static void setPrecision(final int prec) {
if (prec >= 20 && prec != precision) {
precision = prec;
setContext((int) Math.ceil(Math.log10(prec) * 3) + prec,
RoundingMode.HALF_EVEN);
}
}
public static void setContext(final int prec, final RoundingMode mode) {
if (prec >= precision && prec != context.getPrecision()) {
context = new MathContext(prec, mode);
if (PI.precision() < prec) {
E = exp(BigDecimal.ONE);
PI = atan(BigDecimal.ONE).multiply(new BigDecimal(4));
}
}
}
public static BigDecimal asin(final BigDecimal in) {
int num = in.abs().compareTo(BigDecimal.ONE);
if (num == 0) {
return PI.divide(new BigDecimal(in.signum() * 2));
} else if (num == -1) {
BigDecimal bi = atan(in.divide(
root(in.pow(2).negate().add(BigDecimal.ONE), 2).add(
BigDecimal.ONE), context));
return bi.add(bi, context);
} else if (round(in.abs(), precision).compareTo(BigDecimal.ONE) == 0) {
return PI.divide(new BigDecimal(in.signum() * 2));
} else {
return null;
}
}
public static BigDecimal acos(final BigDecimal in) {
if (in.round(context).compareTo(BigDecimal.ONE) == 0) {
return BigDecimal.ZERO;
}
BigDecimal bi = asin(in);
if (bi == null) {
return bi;
} else {
return PI.add(bi.add(bi).negate()).divide(new BigDecimal(2));
}
}
public static BigDecimal atan(final BigDecimal in) {
int num = in.signum();
if (num == 0) {
return BigDecimal.ZERO;
}
BigDecimal bd1 = in.abs(context);
BigDecimal bd2 = BigDecimal.ZERO;
BigDecimal perfive = new BigDecimal(2).scaleByPowerOfTen(-1);
if (bd1.compareTo(perfive) == 1) {
BigDecimal perfiveat = atan(perfive);
while (bd1.signum() == 1) {
bd1 = perfive
.negate()
.add(bd1)
.divide(bd1.multiply(perfive).add(BigDecimal.ONE),
context);
bd2 = bd2.add(perfiveat);
}
}
if (num == -1) {
bd1 = bd1.negate();
bd2 = bd2.negate();
}
BigDecimal coef = bd1.plus();
BigDecimal[] temp = new BigDecimal[] { coef.add(bd2, context) };
num = 1;
bd1 = bd1.pow(2, context).negate();
do {
num += 2;
bd2 = new BigDecimal(num);
coef = coef.multiply(bd1, context);
temp = new BigDecimal[] {
temp[0].multiply(bd2).add(coef).divide(bd2, context),
temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0];
}
public static BigDecimal root(final BigDecimal in, final int index) {
BigDecimal bd = in.round(context);
int num = bd.signum();
if (num == 0) {
return BigDecimal.ZERO;
} else if (num == -1 || index <= 0) {
return null;
} else if (bd.compareTo(BigDecimal.ONE) == 0 || index == 1) {
return bd;
}
int i = index;
while (i % 2 == 0) {
i /= 2;
bd = sqrt(bd);
}
if (i > 2) {
bd = pow(bd, BigDecimal.ONE.divide(new BigDecimal(i), context));
}
return bd;
}
public static BigDecimal sqrt(final BigDecimal in) {
BigDecimal bd = in.round(context);
int num = bd.signum();
if (num == 0) {
return BigDecimal.ZERO;
} else if (num == -1) {
return null;
} else if (bd.compareTo(BigDecimal.ONE) == 0) {
return bd;
}
BigDecimal[] temp = new BigDecimal[] { bd };
do {
temp = new BigDecimal[] {
temp[0].multiply(temp[0]).add(bd)
.divide(temp[0].add(temp[0]), context), temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0];
}
public static BigDecimal log(BigDecimal in) {
if (in.signum() < 1) {
return null;
}
BigDecimal bd1 = in.round(context);
int num = bd1.compareTo(BigDecimal.ONE);
BigDecimal coef, bd2;
if (num == 0) {
return BigDecimal.ZERO;
} else if (num == -1) {
coef = BigDecimal.ONE;
} else {
bd1 = BigDecimal.ONE.divide(bd1, context);
coef = new BigDecimal(-1);
}
bd2 = BigDecimal.ZERO;
do {
bd1 = bd1.multiply(E, context);
bd2 = bd2.add(BigDecimal.ONE);
} while (bd1.compareTo(BigDecimal.ONE) == -1);
if (num == -1) {
bd2 = bd2.negate();
}
while (bd1.pow(16).compareTo(E) == 1) {
bd1 = sqrt(bd1);
coef = coef.add(coef);
}
bd1 = BigDecimal.ONE.add(new BigDecimal(-1).divide(bd1, context));
coef = coef.multiply(bd1, context);
BigDecimal[] temp = new BigDecimal[] { coef.add(bd2, context) };
num = 1;
do {
num++;
coef = coef.multiply(bd1, context);
bd2 = new BigDecimal(num);
temp = new BigDecimal[] {
temp[0].multiply(bd2).add(coef).divide(bd2, context),
temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0];
}
public static BigDecimal sin(final BigDecimal in) {
BigDecimal bd1, bd2;
bd2 = PI.add(PI);
bd1 = in.remainder(bd2);
int num = bd1.signum();
if (num == 0) {
return BigDecimal.ZERO;
} else if (num < 0) {
return sin(bd1.negate()).negate();
}
if (bd1.compareTo(PI) > -1) {
return sin(bd1.add(PI)).negate();
} else if (bd1.compareTo(PI.divide(new BigDecimal(4))) > 0) {
bd2 = PI.divide(new BigDecimal(2));
if (bd1.compareTo(bd2) > 0) {
return sin(bd1.negate().add(PI));
} else {
return cos(bd1.negate().add(bd2));
}
}
bd1 = bd1.divide(new BigDecimal(3), context);
BigDecimal[] temp = new BigDecimal[] { bd1.plus() };
BigDecimal coef = temp[0].plus();
bd1 = bd1.pow(2, context);
num = 0;
do {
num++;
coef = coef.multiply(bd1).divide(
new BigDecimal(-2 * num * (2 * num + 1)), context);
temp = new BigDecimal[] { temp[0].add(coef, context), temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0].multiply(temp[0]).multiply(new BigDecimal(-4))
.add(new BigDecimal(3)).multiply(temp[0], context);
}
public static BigDecimal cos(final BigDecimal in) {
BigDecimal bd1, bd2;
bd2 = PI.add(PI);
bd1 = in.remainder(bd2);
int num = bd1.signum();
if (num == 0) {
return BigDecimal.ONE;
} else if (num < 0) {
return cos(bd1.negate());
}
if (bd1.compareTo(PI) > -1) {
return cos(bd1.add(PI)).negate();
} else if (bd1.compareTo(PI.divide(new BigDecimal(4))) > 0) {
bd2 = PI.divide(new BigDecimal(2));
if (bd1.compareTo(bd2) > 0) {
return cos(bd1.negate().add(PI)).negate();
} else {
return sin(bd1.negate().add(bd2));
}
}
bd1 = bd1.pow(2).divide(new BigDecimal(9), context);
BigDecimal[] temp = new BigDecimal[] { BigDecimal.ONE };
BigDecimal coef = temp[0].plus();
num = 0;
do {
num++;
coef = coef.multiply(bd1).divide(
new BigDecimal(-2 * num * (2 * num - 1)), context);
temp = new BigDecimal[] { temp[0].add(coef, context), temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0].multiply(temp[0]).multiply(new BigDecimal(4))
.add(new BigDecimal(-3)).multiply(temp[0], context);
}
public static BigDecimal tan(final BigDecimal in) {
BigDecimal bd = cos(in);
if (bd.add(BigDecimal.ONE, context).compareTo(BigDecimal.ONE) == 0) {
return null;
} else {
return sin(in).divide(bd, context);
}
}
public static BigDecimal exp(final BigDecimal in) {
int num = in.signum();
BigDecimal coef = BigDecimal.ONE;
BigDecimal bi;
if (num == 0) {
return BigDecimal.ONE;
} else if (num == 1) {
bi = in.negate(context);
} else {
bi = in.round(context);
}
if (bi.compareTo(new BigDecimal(-1)) != 0) {
while (bi.signum() == -1) {
bi = bi.add(BigDecimal.ONE);
coef = coef.multiply(E, context);
}
}
if (num == 1) {
bi = bi.negate();
} else {
coef = BigDecimal.ONE.divide(coef, context);
}
BigDecimal[] temp = new BigDecimal[] { coef.round(context) };
num = 0;
do {
num++;
coef = coef.multiply(bi).divide(new BigDecimal(num), context);
temp = new BigDecimal[] { temp[0].add(coef, context), temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0];
}
public static BigDecimal pow(final BigDecimal in, final BigDecimal index) {
BigDecimal bi = log(in);
if (bi == null) {
return null;
} else {
return exp(bi.multiply(index));
}
}
/**
* Matrix of rotation Z to Y. R1(rad).
*/
public static BigDecimal[][] rotX(final BigDecimal rad) {
BigDecimal Cos = cos(rad);
BigDecimal Sin = sin(rad);
return new BigDecimal[][] {
{ BigDecimal.ONE, BigDecimal.ZERO, BigDecimal.ZERO },
{ BigDecimal.ZERO, Cos, Sin.negate() },
{ BigDecimal.ZERO, Sin, Cos } };
}
/**
* Matrix of rotation X to Z. R2(rad).
*/
public static BigDecimal[][] rotY(final BigDecimal rad) {
BigDecimal Cos = cos(rad);
BigDecimal Sin = sin(rad);
return new BigDecimal[][] { { Cos, BigDecimal.ZERO, Sin },
{ BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.ZERO },
{ Sin.negate(), BigDecimal.ZERO, Cos } };
}
/**
* Matrix of rotation Y to X. R3(rad).
*/
public static BigDecimal[][] rotZ(final BigDecimal rad) {
BigDecimal Cos = cos(rad);
BigDecimal Sin = sin(rad);
return new BigDecimal[][] { { Cos, Sin.negate(), BigDecimal.ZERO },
{ Sin, Cos, BigDecimal.ZERO },
{ BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ONE } };
}
/**
* Matrix of rotation Y to X. R(rad).
*/
public static BigDecimal[][] rot2(final BigDecimal rad) {
BigDecimal Cos = cos(rad);
BigDecimal Sin = sin(rad);
return new BigDecimal[][] { { Cos, Sin.negate() }, { Sin, Cos } };
}
/**
* Rotation (1,0,0) to A[0] = (x,y,z). Rotation (0,1,0) to A[1] = (x,y,z).
* Rotation (0,0,1) to A[2] = (x,y,z). Ar = rotA(A,r).
*/
public static BigDecimal[] rotA(final BigDecimal[][] A,
final BigDecimal[] star) {
if (star.length != A.length) {
return null;
} else {
for (int i = 1; i < A.length; i++) {
if (A[i].length != A[0].length) {
return null;
}
}
}
BigDecimal[] res = new BigDecimal[A[0].length];
for (int i = 0; i < A[0].length; i++) {
res[i] = BigDecimal.ZERO;
for (int j = 0; j < star.length; j++) {
res[i] = res[i].add(star[j].multiply(A[j][i]));
}
}
return res;
}
/**
* AB = (rotA(A,B[0]),rotA(A,B[1]),rotA(A,B[2])).
*/
public static BigDecimal[][] rotAB(final BigDecimal[][] A,
final BigDecimal[][] B) {
BigDecimal[][] res = new BigDecimal[B.length][];
for (int i = 0; i < B.length; i++) {
res[i] = rotA(A, B[i]);
}
return res;
}
}
暦計算用の定数付き20桁精度のライブラリです。
package jp.wshounen;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
public class DEMath {
public static final int precision = 20;
public final static MathContext context = new MathContext(24,
RoundingMode.HALF_EVEN);
public static final BigDecimal au = new BigDecimal(149597870691l)
.scaleByPowerOfTen(-3);
public static final BigDecimal emrat = new BigDecimal(8130056)
.scaleByPowerOfTen(-5);
public static final BigDecimal clight = new BigDecimal(2997922458l)
.scaleByPowerOfTen(-4);
public static final BigDecimal jultimeOfJ2000 = new BigDecimal(2451545);
public static final BigDecimal equatorialRadius = new BigDecimal(6378137)
.scaleByPowerOfTen(-3);
public static final BigDecimal polarRadius = new BigDecimal(6356752)
.scaleByPowerOfTen(-3);
public static final BigDecimal solarRadius = new BigDecimal(696000);
public static final BigDecimal lunarRadius = new BigDecimal(1738091)
.scaleByPowerOfTen(-3);
public static final BigDecimal PI = atan(BigDecimal.ONE).multiply(
new BigDecimal(4));
public static final BigDecimal E = exp(BigDecimal.ONE);
public static final BigDecimal[][] icrfRot = rotAB(
rotAB(rotX(arcsecToRad(new BigDecimal(-68192).scaleByPowerOfTen(-7))),
rotY(arcsecToRad(new BigDecimal(-166170)
.scaleByPowerOfTen(-7)))),
rotZ(arcsecToRad(new BigDecimal(146).scaleByPowerOfTen(-4))));
public static final BigDecimal obliquityArcsecOfJ2000 = new BigDecimal(
84381406).scaleByPowerOfTen(-3);
public static BigDecimal round(final BigDecimal in, final int precision) {
return in.round(new MathContext(precision, RoundingMode.HALF_EVEN));
}
public static long divideToFloor(final long value, final long divisor) {
long remainder = value % divisor;
return ((remainder < 0 && divisor > 0) || (remainder > 0 && divisor < 0)) ? (value - remainder)
/ divisor - 1
: (value - remainder) / divisor;
}
public static BigDecimal round(final BigDecimal in) {
return in.setScale(0, RoundingMode.HALF_EVEN);
}
public static BigDecimal arcsecToRad(final BigDecimal arcsec) {
return arcsec.multiply(PI).divide(new BigDecimal(648000), context);
}
public static BigDecimal radToArcsec(final BigDecimal rad) {
return rad.multiply(new BigDecimal(648000)).divide(PI, context);
}
public static BigDecimal floor(final BigDecimal in) {
return in.setScale(0, RoundingMode.FLOOR);
}
public static BigDecimal ceil(final BigDecimal in) {
return in.setScale(0, RoundingMode.CEILING);
}
public static BigDecimal asin(final BigDecimal in) {
int num = in.abs().compareTo(BigDecimal.ONE);
if (num == 0) {
return PI.divide(new BigDecimal(in.signum() * 2));
} else if (num == -1) {
BigDecimal bi = atan(in.divide(
root(in.pow(2).negate().add(BigDecimal.ONE), 2).add(
BigDecimal.ONE), context));
return bi.add(bi, context);
} else if (round(in.abs(), precision).compareTo(BigDecimal.ONE) == 0) {
return PI.divide(new BigDecimal(in.signum() * 2));
} else {
return null;
}
}
public static BigDecimal acos(final BigDecimal in) {
if (in.round(context).compareTo(BigDecimal.ONE) == 0) {
return BigDecimal.ZERO;
}
BigDecimal bi = asin(in);
if (bi == null) {
return bi;
} else {
return PI.add(bi.add(bi).negate()).divide(new BigDecimal(2));
}
}
public static BigDecimal atan(final BigDecimal in) {
int num = in.signum();
if (num == 0) {
return BigDecimal.ZERO;
}
BigDecimal bd1 = in.abs(context);
BigDecimal bd2 = BigDecimal.ZERO;
BigDecimal perfive = new BigDecimal(2).scaleByPowerOfTen(-1);
if (bd1.compareTo(perfive) == 1) {
BigDecimal perfiveat = atan(perfive);
while (bd1.signum() == 1) {
bd1 = perfive
.negate()
.add(bd1)
.divide(bd1.multiply(perfive).add(BigDecimal.ONE),
context);
bd2 = bd2.add(perfiveat);
}
}
if (num == -1) {
bd1 = bd1.negate();
bd2 = bd2.negate();
}
BigDecimal coef = bd1.plus();
BigDecimal[] temp = new BigDecimal[] { coef.add(bd2, context) };
num = 1;
bd1 = bd1.pow(2, context).negate();
do {
num += 2;
bd2 = new BigDecimal(num);
coef = coef.multiply(bd1, context);
temp = new BigDecimal[] {
temp[0].multiply(bd2).add(coef).divide(bd2, context),
temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0];
}
public static BigDecimal root(final BigDecimal in, final int index) {
BigDecimal bd = in.round(context);
int num = bd.signum();
if (num == 0) {
return BigDecimal.ZERO;
} else if (num == -1 || index <= 0) {
return null;
} else if (bd.compareTo(BigDecimal.ONE) == 0 || index == 1) {
return bd;
}
int i = index;
while (i % 2 == 0) {
i /= 2;
bd = sqrt(bd);
}
if (i > 2) {
bd = pow(bd, BigDecimal.ONE.divide(new BigDecimal(i), context));
}
return bd;
}
public static BigDecimal sqrt(final BigDecimal in) {
BigDecimal bd = in.round(context);
int num = bd.signum();
if (num == 0) {
return BigDecimal.ZERO;
} else if (num == -1) {
return null;
} else if (bd.compareTo(BigDecimal.ONE) == 0) {
return bd;
}
BigDecimal[] temp = new BigDecimal[] { bd };
do {
temp = new BigDecimal[] {
temp[0].multiply(temp[0]).add(bd)
.divide(temp[0].add(temp[0]), context), temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0];
}
public static BigDecimal log(BigDecimal in) {
if (in.signum() < 1) {
return null;
}
BigDecimal bd1 = in.round(context);
int num = bd1.compareTo(BigDecimal.ONE);
BigDecimal coef, bd2;
if (num == 0) {
return BigDecimal.ZERO;
} else if (num == -1) {
coef = BigDecimal.ONE;
} else {
bd1 = BigDecimal.ONE.divide(bd1, context);
coef = new BigDecimal(-1);
}
bd2 = BigDecimal.ZERO;
do {
bd1 = bd1.multiply(E, context);
bd2 = bd2.add(BigDecimal.ONE);
} while (bd1.compareTo(BigDecimal.ONE) == -1);
if (num == -1) {
bd2 = bd2.negate();
}
while (bd1.pow(16).compareTo(E) == 1) {
bd1 = sqrt(bd1);
coef = coef.add(coef);
}
bd1 = BigDecimal.ONE.add(new BigDecimal(-1).divide(bd1, context));
coef = coef.multiply(bd1, context);
BigDecimal[] temp = new BigDecimal[] { coef.add(bd2, context) };
num = 1;
do {
num++;
coef = coef.multiply(bd1, context);
bd2 = new BigDecimal(num);
temp = new BigDecimal[] {
temp[0].multiply(bd2).add(coef).divide(bd2, context),
temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0];
}
public static BigDecimal sin(final BigDecimal in) {
BigDecimal bd1, bd2;
bd2 = PI.add(PI);
bd1 = in.remainder(bd2);
int num = bd1.signum();
if (num == 0) {
return BigDecimal.ZERO;
} else if (num < 0) {
return sin(bd1.negate()).negate();
}
if (bd1.compareTo(PI) > -1) {
return sin(bd1.add(PI)).negate();
} else if (bd1.compareTo(PI.divide(new BigDecimal(4))) > 0) {
bd2 = PI.divide(new BigDecimal(2));
if (bd1.compareTo(bd2) > 0) {
return sin(bd1.negate().add(PI));
} else {
return cos(bd1.negate().add(bd2));
}
}
bd1 = bd1.divide(new BigDecimal(3), context);
BigDecimal[] temp = new BigDecimal[] { bd1.plus() };
BigDecimal coef = temp[0].plus();
bd1 = bd1.pow(2, context);
num = 0;
do {
num++;
coef = coef.multiply(bd1).divide(
new BigDecimal(-2 * num * (2 * num + 1)), context);
temp = new BigDecimal[] { temp[0].add(coef, context), temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0].multiply(temp[0]).multiply(new BigDecimal(-4))
.add(new BigDecimal(3)).multiply(temp[0], context);
}
public static BigDecimal cos(final BigDecimal in) {
BigDecimal bd1, bd2;
bd2 = PI.add(PI);
bd1 = in.remainder(bd2);
int num = bd1.signum();
if (num == 0) {
return BigDecimal.ONE;
} else if (num < 0) {
return cos(bd1.negate());
}
if (bd1.compareTo(PI) > -1) {
return cos(bd1.add(PI)).negate();
} else if (bd1.compareTo(PI.divide(new BigDecimal(4))) > 0) {
bd2 = PI.divide(new BigDecimal(2));
if (bd1.compareTo(bd2) > 0) {
return cos(bd1.negate().add(PI)).negate();
} else {
return sin(bd1.negate().add(bd2));
}
}
bd1 = bd1.pow(2).divide(new BigDecimal(9), context);
BigDecimal[] temp = new BigDecimal[] { BigDecimal.ONE };
BigDecimal coef = temp[0].plus();
num = 0;
do {
num++;
coef = coef.multiply(bd1).divide(
new BigDecimal(-2 * num * (2 * num - 1)), context);
temp = new BigDecimal[] { temp[0].add(coef, context), temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0].multiply(temp[0]).multiply(new BigDecimal(4))
.add(new BigDecimal(-3)).multiply(temp[0], context);
}
public static BigDecimal tan(final BigDecimal in) {
BigDecimal bd = cos(in);
if (bd.add(BigDecimal.ONE, context).compareTo(BigDecimal.ONE) == 0) {
return null;
} else {
return sin(in).divide(bd, context);
}
}
public static BigDecimal exp(final BigDecimal in) {
int num = in.signum();
BigDecimal coef = BigDecimal.ONE;
BigDecimal bi;
if (num == 0) {
return BigDecimal.ONE;
} else if (num == 1) {
bi = in.negate(context);
} else {
bi = in.round(context);
}
if (bi.compareTo(new BigDecimal(-1)) != 0) {
while (bi.signum() == -1) {
bi = bi.add(BigDecimal.ONE);
coef = coef.multiply(E, context);
}
}
if (num == 1) {
bi = bi.negate();
} else {
coef = BigDecimal.ONE.divide(coef, context);
}
BigDecimal[] temp = new BigDecimal[] { coef.round(context) };
num = 0;
do {
num++;
coef = coef.multiply(bi).divide(new BigDecimal(num), context);
temp = new BigDecimal[] { temp[0].add(coef, context), temp[0] };
} while (temp[0].compareTo(temp[1]) != 0);
return temp[0];
}
public static BigDecimal pow(final BigDecimal in, final BigDecimal index) {
BigDecimal bi = log(in);
if (bi == null) {
return null;
} else {
return exp(bi.multiply(index));
}
}
/**
* Matrix of rotation Y to Z. R1(-rad).
*/
public static BigDecimal[][] rotX(final BigDecimal rad) {
BigDecimal Cos = cos(rad);
BigDecimal Sin = sin(rad);
return new BigDecimal[][] {
{ BigDecimal.ONE, BigDecimal.ZERO, BigDecimal.ZERO },
{ BigDecimal.ZERO, Cos, Sin },
{ BigDecimal.ZERO, Sin.negate(), Cos } };
}
/**
* Matrix of rotation X to Z. R2(rad).
*/
public static BigDecimal[][] rotY(final BigDecimal rad) {
BigDecimal Cos = cos(rad);
BigDecimal Sin = sin(rad);
return new BigDecimal[][] { { Cos, BigDecimal.ZERO, Sin },
{ BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.ZERO },
{ Sin.negate(), BigDecimal.ZERO, Cos } };
}
/**
* Matrix of rotation X to Y. R3(-rad).
*/
public static BigDecimal[][] rotZ(final BigDecimal rad) {
BigDecimal Cos = cos(rad);
BigDecimal Sin = sin(rad);
return new BigDecimal[][] { { Cos, Sin, BigDecimal.ZERO },
{ Sin.negate(), Cos, BigDecimal.ZERO },
{ BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ONE } };
}
/**
* Matrix of rotation X to Y. R(-rad).
*/
public static BigDecimal[][] rot2(final BigDecimal rad) {
BigDecimal Cos = cos(rad);
BigDecimal Sin = sin(rad);
return new BigDecimal[][] { { Cos, Sin }, { Sin.negate(), Cos } };
}
/**
* Rotation (1,0,0) to A[0] = (x,y,z). Rotation (0,1,0) to A[1] = (x,y,z).
* Rotation (0,0,1) to A[2] = (x,y,z). Ar = rotA(A,r).
*/
public static BigDecimal[] rotA(final BigDecimal[][] A,
final BigDecimal[] star) {
if (star.length != A.length) {
return null;
} else {
for (int i = 1; i < A.length; i++) {
if (A[i].length != A[0].length) {
return null;
}
}
}
BigDecimal[] res = new BigDecimal[A[0].length];
for (int i = 0; i < A[0].length; i++) {
res[i] = BigDecimal.ZERO;
for (int j = 0; j < star.length; j++) {
res[i] = res[i].add(star[j].multiply(A[j][i]));
}
}
return res;
}
/**
* AB = (rotA(A,B[0]),rotA(A,B[1]),rotA(A,B[2])).
*/
public static BigDecimal[][] rotAB(final BigDecimal[][] A,
final BigDecimal[][] B) {
BigDecimal[][] res = new BigDecimal[B.length][];
for (int i = 0; i < B.length; i++) {
res[i] = rotA(A, B[i]);
}
return res;
}
public static BigDecimal[] getApproximation(final BigDecimal[] y,
final BigDecimal unit) {
if (y == null || y.length == 0) {
return null;
} else if (y.length == 1) {
return new BigDecimal[] { y[0].plus() };
} else if (unit == null || unit.signum() == 0) {
return new BigDecimal[] { y[(y.length + 1) / 2].plus() };
}
BigDecimal[] res = new BigDecimal[y.length];
for (int i = 0; i < y.length; i++) {
res[i] = BigDecimal.ZERO;
}
for (int i = 0; i < y.length; i++) {
ArrayList<BigDecimal> temp = new ArrayList<BigDecimal>(0);
temp.add(y[i].plus());
for (int j = 0; j < y.length; j++) {
if (i != j) {
BigDecimal dif = new BigDecimal(j - (y.length + 1) / 2)
.multiply(unit);
temp.add(0, temp.get(0).multiply(dif));
for (int k = 1; k < temp.size() - 1; k++) {
temp.set(k,
temp.get(k + 1).multiply(dif).add(temp.get(k)));
}
dif = new BigDecimal(j - i).multiply(unit);
for (int k = 0; k < temp.size(); k++) {
temp.set(k, temp.get(k).divide(dif, DEMath.context));
}
}
}
for (int j = 0; j < y.length; j++) {
res[j] = res[j].add(temp.get(j));
}
}
return res;
}
public static BigDecimal approximationR(final BigDecimal[] coef,
final BigDecimal x) {
if (coef == null || coef.length == 0) {
return BigDecimal.ZERO;
} else if (x == null || x.signum() == 0) {
return coef[0].plus();
}
BigDecimal y = coef[coef.length - 1].plus();
for (int i = coef.length - 2; i >= 0; i--) {
y = y.multiply(x).add(coef[i]);
}
return y;
}
public static BigDecimal approximationV(final BigDecimal[] coef,
final BigDecimal x) {
if (coef == null || coef.length <= 1) {
return BigDecimal.ZERO;
} else if (x == null || x.signum() == 0) {
return coef[1].plus();
}
BigDecimal y = new BigDecimal(coef.length - 1)
.multiply(coef[coef.length - 1]);
for (int i = coef.length - 2; i >= 1; i--) {
y = y.multiply(x).add(new BigDecimal(i).multiply(coef[i]));
}
return y;
}
}
最近のコメント