You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言实现多维函数梯度(偏导数)计算问题求助

参考截图1
参考截图2
我尝试实现梯度计算算法,但无法判断程序是否运行正确,因为我甚至不知道如何手动计算梯度。
我附上了参考实现的相关资料,若有人能给出输入数据示例和对应的预期输出结果,我将十分感激,我很想弄懂相关原理。同时我也想知道我的程序编写存在哪些错误。
提前感谢大家的帮助,我真的卡在这个问题上毫无进展。
参考截图3

初始版本代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <locale.h>
double f(double x)
{
    return (x * x );
}
int main(int argc, char** argv) {
    double del = 0.1;
    int n;
    scanf_s("%d", &n);
    double* x;
    x = (double*)malloc(n * sizeof(double));
    double* y;
    y = (double*)malloc(n * sizeof(double));
    double* fx;
    fx = (double*)malloc(n * sizeof(double));
    double* fy;
    fy = (double*)malloc(n * sizeof(double));
    double* grad;
    grad = (double*)malloc(n * sizeof(double));
    int i = 0;
    for (i = 0; i < n; i++)
    {
        printf("x[%d] = ", i);
        scanf_s("%lf", &x[i]);
        y[i] = x[i];
        fx[i] = f(x[i]);
    }
    double a = 1 / del;
    for (i = 0; i < n; i++) {
        y[i] = y[i] + del;
        fy[i] = f(y[i]);
        grad[i] = a * (fy[i] - fx[i]);
        y[i] = x[i];

    }
    for (i = 0; i < n; i++) {
    printf("%lf ", grad[i]);
    }

}
更新版本代码
double f(double arr[], int size)
{
    int a = sizeof(arr);
    for (int i = 0; i < size; i++) {
        arr[i] = arr[i] * arr[i];
    }
    return *arr;
}
int main(int argc, char** argv) {
    double del = 0.1;
    int n;
    scanf_s("%d", &n);
    double* x;
    x = (double*)malloc(n * sizeof(double));
    double* y;
    y = (double*)malloc(n * sizeof(double));
    double* fx;
    fx = (double*)malloc(n * sizeof(double));
    double* fy;
    fy = (double*)malloc(n * sizeof(double));
    double* grad;
    grad = (double*)malloc(n * sizeof(double));
    int i = 0;
    for (i = 0; i < n; i++)
    {
        printf("x[%d] = ", i);
        scanf_s("%lf", &x[i]);
        y[i] = x[i];
        fx[i] = f(x,n);
    }
    double a = 1 / del;
    for (i = 0; i < n; i++) {
        y[i] = y[i] + del;
        fy[i] = f(y,n);
        grad[i] = a * (fy[i] - fx[i]);
        y[i] = x[i];

    }
    for (i = 0; i < n; i++) {
    printf("%lf ", grad[i]);
    }

}

解答

梯度计算基础逻辑

你使用的前向差分法数值梯度计算公式为:梯度分量 ≈ (f(x+Δ) - f(x))/Δ,你设置的Δ为0.1。如果测试函数为f(x)=x²,精确梯度为2x,前向差分计算的近似值为2x+0.1。


初始版本问题与测试用例

初始版本实现的是多个独立单变量函数的导数计算,逻辑可运行,但不属于多元函数梯度计算。
测试输入:

2
1
2

预期输出:2.100000 4.100000


更新版本错误与修正

更新后的版本存在3处核心错误:

  1. 函数f直接修改了传入的原数组,每次调用后原数组所有元素都会被平方,后续计算全部错误
  2. sizeof(arr) 获取的是指针的字节长度,不是数组元素长度,该写法无效
  3. 函数仅返回数组第一个元素的平方值,不符合多元函数梯度计算要求,常规测试用多元函数为所有输入变量的平方和

修正后的函数示例:

// 计算多元函数f = sum(x_i²),不修改原数组
double f(double arr[], int size)
{
    double sum = 0;
    for (int i = 0; i < size; i++) {
        sum += arr[i] * arr[i];
    }
    return sum;
}

修正后测试输入:

2
1
2

计算过程:

  • 原函数值:1² + 2² = 5
  • 第一个变量加0.1后的函数值:1.1² + 2² = 5.21,对应梯度分量为(5.21-5)/0.1 = 2.1
  • 第二个变量加0.1后的函数值:1² + 2.1² = 5.41,对应梯度分量为(5.41-5)/0.1 = 4.1

预期输出:2.100000 4.100000


内容的提问来源于stack exchange,提问作者user14554338

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 20:15:03