diff --git a/src/main/java/me/hatter/math/NormalDistribution.java b/src/main/java/me/hatter/math/NormalDistribution.java new file mode 100644 index 0000000..e90034a --- /dev/null +++ b/src/main/java/me/hatter/math/NormalDistribution.java @@ -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 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); + } +} diff --git a/src/main/java/me/hatter/math/util/MathUtil.java b/src/main/java/me/hatter/math/util/MathUtil.java index 1bf94e2..5b87d06 100644 --- a/src/main/java/me/hatter/math/util/MathUtil.java +++ b/src/main/java/me/hatter/math/util/MathUtil.java @@ -87,4 +87,33 @@ public class MathUtil { 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())); + } }