feat: normal distribution
This commit is contained in:
45
src/main/java/me/hatter/math/NormalDistribution.java
Normal file
45
src/main/java/me/hatter/math/NormalDistribution.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package me.hatter.math;
|
||||||
|
|
||||||
|
import me.hatter.math.util.MathUtil;
|
||||||
|
import me.hatter.tools.commons.string.StringUtil;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NormalDistribution {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
BigDecimal mu = BigDecimal.valueOf(0);
|
||||||
|
BigDecimal sigma = MathUtil.sqrt(BigDecimal.valueOf(0.2), 100);
|
||||||
|
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
list.add("G = Graphics()");
|
||||||
|
for (int i = -200; i <= 200; i++) {
|
||||||
|
double x = ((double) i) / 100;
|
||||||
|
BigDecimal fx = nd(mu, sigma, BigDecimal.valueOf(x)).setScale(10, RoundingMode.HALF_UP);
|
||||||
|
// System.out.println(Arrays.asList(x, fx.toPlainString()));
|
||||||
|
list.add("G += point((" + x + ", " + fx.toPlainString() + "), color='blue', size=10)");
|
||||||
|
}
|
||||||
|
list.add("G += line([(-2, 0), (2, 0)], color='black')");
|
||||||
|
list.add("G += line([(0, -0.1), (0, 1.1)], color='black')");
|
||||||
|
list.add("show(G, xmin=-2, xmax=2, ymin=-0.1, ymax=1.1, aspect_ratio=1)");
|
||||||
|
System.out.println(StringUtil.join(list, "\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BigDecimal nd(BigDecimal mu, BigDecimal sigma, BigDecimal x) {
|
||||||
|
// \frac{1}{\sigma \times \sqrt{2\times \pi}}
|
||||||
|
BigDecimal pa = BigDecimal.ONE.divide(
|
||||||
|
sigma.multiply(MathUtil.sqrt(BigDecimal.valueOf(2).multiply(MathUtil.PI), 100))
|
||||||
|
, 100, RoundingMode.HALF_UP
|
||||||
|
);
|
||||||
|
// \frac{(x-\mu)^2}{2\times \sigma^2}
|
||||||
|
BigDecimal pb = x.subtract(mu).pow(2).divide(
|
||||||
|
BigDecimal.valueOf(2).multiply(sigma.pow(2))
|
||||||
|
, 100, RoundingMode.HALF_UP
|
||||||
|
);
|
||||||
|
return pa.multiply(MathUtil.pow(MathUtil.E, BigDecimal.ZERO.subtract(pb)))
|
||||||
|
.setScale(100, RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -87,4 +87,33 @@ public class MathUtil {
|
|||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 泰勒级数展开(Generated By Qwen3-Coder)
|
||||||
|
public static BigDecimal pow(BigDecimal base, BigDecimal exponent) {
|
||||||
|
if (exponent.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
|
return BigDecimal.ONE;
|
||||||
|
}
|
||||||
|
if (base.compareTo(BigDecimal.ONE) == 0) {
|
||||||
|
return BigDecimal.ONE;
|
||||||
|
}
|
||||||
|
if (exponent.compareTo(BigDecimal.ONE) == 0) {
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
// 使用公式: a^b = e^(b * ln(a))
|
||||||
|
BigDecimal lnBase = ln(base);
|
||||||
|
BigDecimal exponentLnBase = exponent.multiply(lnBase);
|
||||||
|
return exp(exponentLnBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这里需要实现自然对数的计算,可以使用泰勒级数
|
||||||
|
// 简化处理:使用Math.log转换
|
||||||
|
public static BigDecimal ln(BigDecimal x) {
|
||||||
|
return BigDecimal.valueOf(Math.log(x.doubleValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 指数函数的近似计算(简化版)
|
||||||
|
// 简化处理:使用Math.exp转换
|
||||||
|
public static BigDecimal exp(BigDecimal x) {
|
||||||
|
return BigDecimal.valueOf(Math.exp(x.doubleValue()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user