多变量函数数值微分实现求助:带精度控制的差分计算如何实现?
修正后的完整实现
import java.util.Scanner; public class Cmath { // 多变量函数定义:测试用函数为 f(x₁,x₂...xₙ) = x₁² + x₂² + ... +xₙ² public static double function(double[] variables) { double out = 0; for (double var : variables) { out += Math.pow(var, 2); } return out; } // 计算第index个变量的中心差分偏导 public static double calPartialDer(int index, double[] variables, double delta) { // 构造仅第index个变量加delta的数组 double[] plusVar = variables.clone(); plusVar[index] += delta; // 构造仅第index个变量减delta的数组 double[] minusVar = variables.clone(); minusVar[index] -= delta; // 中心差分公式计算 return (function(plusVar) - function(minusVar)) / (2 * delta); } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("输入变量个数:"); int varNum = scanner.nextInt(); System.out.println("依次输入各变量的取值:"); double[] variables = new double[varNum]; for (int i = 0; i < varNum; i++) { variables[i] = scanner.nextDouble(); } System.out.println("输入计算精度epsilon:"); double epsilon = scanner.nextDouble(); scanner.close(); double[] resultDer = new double[varNum]; // 逐变量迭代计算偏导 for (int i = 0; i < varNum; i++) { double delta = 0.1; double prevDer = Double.MAX_VALUE; double currentDer = 0; // 迭代直到满足精度要求 while (true) { currentDer = calPartialDer(i, variables, delta); if (Math.abs(currentDer - prevDer) < epsilon) { break; } prevDer = currentDer; delta *= 0.5; } resultDer[i] = currentDer; } // 输出结果 System.out.println("各变量的偏导数计算结果:"); for (int i = 0; i < varNum; i++) { System.out.printf("对第%d个变量的偏导:%.10f%n", i+1, resultDer[i]); } } }
核心修改说明
- 修复多变量函数适配:将原单变量入参的
function改为接收完整变量数组,符合多变量函数计算要求 - 修正偏导计算逻辑:计算单个变量的偏导时固定其余所有变量取值,仅修改当前变量的delta偏移,符合偏导数定义
- 新增精度控制流程:支持键盘输入epsilon,每次迭代将delta缩小为原来的1/2,直到前后两次偏导计算结果的差值绝对值小于epsilon后停止
- 移除原代码中逻辑错误的嵌套循环和冗余变量
结果验算方法
当前测试用函数的解析偏导公式为:对第i个变量x_i的偏导 = 2 * x_i,直接将数值计算结果和该解析值对比,差值在你设置的epsilon范围内即为计算正确。
举例:输入变量数为2,变量取值分别为3、4,最终计算的偏导结果应接近6、8,误差小于输入的epsilon。
内容的提问来源于stack exchange,提问作者user17059077
相关产品推荐
相关产品推荐

