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

在C语言中对矩阵应用梯形积分法的实现疑问

对随r变化的2x2矩阵应用梯形积分法的C语言实现

问题背景

我有一个名为one_elect的2x2矩阵,它是变量r的函数。作为C语言入门学习者,不清楚如何对该矩阵应用梯形积分法,也不知道如何针对变量r循环处理矩阵。以下是我编写的代码和梯形积分法示例代码:

原代码(存在问题)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define Z 1
#define BASISFUN 2
#define UPPER 100 // 积分上限
#define LOWER 0   // 积分下限
#define SUBINT 50 // 积分区间数

void makingmatrix(double a[][BASISFUN], double d[][BASISFUN], double alpha_coeff[BASISFUN], double d_coeff[BASISFUN]){
    
    for (int i = 0; i < BASISFUN; i++){
        for (int j = 0; j < BASISFUN; j++){
            a[i][j] = alpha_coeff[j];
            d[i][j] = d_coeff[j];
        }
    }

    printf("\nAlpha 2x2 Coefficient Matrix is:\n");
    for (int i = 0; i < BASISFUN; i++){
        for (int j = 0; j < BASISFUN; j++){
            printf("%.4f\t", a[i][j]);
        }
        printf("\n");
    }

   printf("\nD 2x2 Coefficient Matrix is:\n");
    for (int i = 0; i < BASISFUN; i++){
        for (int j = 0; j < BASISFUN; j++){
            printf("%.4f\t", d[i][j]);
        }
        printf("\n");    
    }
    printf("\n------------------------------------------------------------------\n");
};

void one_ele(double a[][BASISFUN], double d[][BASISFUN], double r, double one_electron[][BASISFUN]){

    double i_step = (UPPER-LOWER)/SUBINT;

    for (int i = 0; i < BASISFUN; i++){
            for (int j = 0; j < BASISFUN; j++){
                
                if (i != j){
                    one_electron[i][j] = (0.5) * (-2 * a[i][j] * r * exp(-a[i][j] * pow(r, 2))) * (-2 * a[j][i] * r * exp(-a[j][i] * pow(r, 2))) + (Z / r);
                } 
                
                else{
                    one_electron[i][i] = (0.5) * (-2 * a[i][i] * r * exp(-a[i][i] * pow(r, 2))) * (-2 * a[i][i] * r * exp(-a[i][i] * pow(r, 2))) + (Z / r);
                }
            }
    }
 printf("\nOne Electron Hamiltonian Elements are\n");
    for (int i = 0; i < BASISFUN; i++){
        for (int j = 0; j < BASISFUN; j++){
            printf("%.4f\t", one_electron[i][j]);
        }
        printf("\n");
    }

    printf("\n------------------------------------------------------------------\n");
}

int main(){
    double A1 = 0.532149, A2 = 4.097728, D1 = 0.82559, D2 = 0.28317;
    double r;
    
    double alpha_coeff[BASISFUN] = {A1, A2};
    double d_coeff[BASISFUN] = {D1, D2};
    double a[BASISFUN][BASISFUN], d[BASISFUN][BASISFUN];
    
    makingmatrix(a, d, alpha_coeff, d_coeff);
    one_ele(a, d, r, one_electron);
    
    return 0;
}

梯形积分示例代码(存在问题)

#include <stdio.h>
#include <math.h>

#define BASISFUN 2 
#define Z 1.0
#define UPPER 100 // 积分上限
#define LOWER 0   // 积分下限
#define SUBINT 50 // 积分区间数

double f(double r) {
    // 定义函数
    return (0.5) * (-2 * a[i][j] * r * exp(-a[i][j] * pow(r, 2))) * (-2 * a[i][j] * r * exp(-a[i][j] * pow(r, 2))) + (Z / r);
}

int main() {
    double stepSize = (UPPER - LOWER) / SUBINT;
    double integral = f(a) + f(b);

    for (int i = 1; i < SUBINT; i++) {
        double r = a + i * stepSize;
        integral += 2 * f(r);
    }

    integral *= stepSize / 2.0;

    printf("Required value of integration is: %.3f\n", integral);
    return 0;
}

修正后的完整实现

核心思路:对矩阵的每个元素单独执行梯形积分,因为每个元素都是r的函数。同时修复原代码中的变量未声明、奇点(r=0时除以0)等问题。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define Z 1
#define BASISFUN 2
#define UPPER 100.0   // 积分上限
#define LOWER 1e-6    // 修改为极小值避免r=0的奇点
#define SUBINT 500    // 增加区间数提升精度

// 生成系数矩阵
void makingmatrix(double a[][BASISFUN], double d[][BASISFUN], double alpha_coeff[BASISFUN], double d_coeff[BASISFUN]){
    for (int i = 0; i < BASISFUN; i++){
        for (int j = 0; j < BASISFUN; j++){
            a[i][j] = alpha_coeff[j];
            d[i][j] = d_coeff[j];
        }
    }

    printf("\nAlpha 2x2 Coefficient Matrix:\n");
    for (int i = 0; i < BASISFUN; i++){
        for (int j = 0; j < BASISFUN; j++){
            printf("%.6f\t", a[i][j]);
        }
        printf("\n");
    }

    printf("\nD 2x2 Coefficient Matrix:\n");
    for (int i = 0; i < BASISFUN; i++){
        for (int j = 0; j < BASISFUN; j++){
            printf("%.6f\t", d[i][j]);
        }
        printf("\n");    
    }
    printf("\n---------------------------------------------------------\n");
}

// 计算指定(i,j)位置的矩阵元素在r处的值
double compute_matrix_element(double a[][BASISFUN], int i, int j, double r){
    double term1, term2;
    if (i != j) {
        term1 = (-2 * a[i][j] * r * exp(-a[i][j] * pow(r, 2)));
        term2 = (-2 * a[j][i] * r * exp(-a[j][i] * pow(r, 2)));
    } else {
        term1 = (-2 * a[i][i] * r * exp(-a[i][i] * pow(r, 2)));
        term2 = term1; // 对角元素两个项相同
    }
    return 0.5 * term1 * term2 + (Z / r);
}

// 对整个矩阵应用梯形积分,结果存入integrated_matrix
void trapz_integrate_matrix(double a[][BASISFUN], double integrated_matrix[][BASISFUN]){
    double step_size = (UPPER - LOWER) / SUBINT;

    // 初始化积分矩阵
    for (int i = 0; i < BASISFUN; i++){
        for (int j = 0; j < BASISFUN; j++){
            // 梯形积分第一步:上下限的函数值之和
            integrated_matrix[i][j] = compute_matrix_element(a, i, j, LOWER) + compute_matrix_element(a, i, j, UPPER);
        }
    }

    // 遍历中间区间
    for (int k = 1; k < SUBINT; k++){
        double r = LOWER + k * step_size;
        for (int i = 0; i < BASISFUN; i++){
            for (int j = 0; j < BASISFUN; j++){
                integrated_matrix[i][j] += 2 * compute_matrix_element(a, i, j, r);
            }
        }
    }

    // 乘以步长的一半完成积分
    for (int i = 0; i < BASISFUN; i++){
        for (int j = 0; j < BASISFUN; j++){
            integrated_matrix[i][j] *= step_size / 2.0;
        }
    }
}

// 打印矩阵
void print_matrix(double mat[][BASISFUN], const char* name){
    printf("\n%s:\n", name);
    for (int i = 0; i < BASISFUN; i++){
        for (int j = 0; j < BASISFUN; j++){
            printf("%.6f\t", mat[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

int main(){
    double A1 = 0.532149, A2 = 4.097728, D1 = 0.82559, D2 = 0.28317;
    
    double alpha_coeff[BASISFUN] = {A1, A2};
    double d_coeff[BASISFUN] = {D1, D2};
    double a[BASISFUN][BASISFUN], d[BASISFUN][BASISFUN];
    double integrated_one_elect[BASISFUN][BASISFUN]; // 积分后的矩阵

    makingmatrix(a, d, alpha_coeff, d_coeff);
    trapz_integrate_matrix(a, integrated_one_elect);
    print_matrix(integrated_one_elect, "Integrated One-Electron Hamiltonian Matrix");

    return 0;
}

关键修改说明

  • 修复奇点问题:将积分下限从0改为1e-6,避免Z/r在r=0时出现除以0的错误。
  • 拆分功能函数:
    • compute_matrix_element:单独计算矩阵某个位置(i,j)在特定r下的值,便于在积分循环中重复调用。
    • trapz_integrate_matrix:对矩阵每个元素应用梯形积分,外层循环遍历r的子区间,内层循环遍历矩阵的每个元素。
  • 修正变量错误:原代码中main函数未声明one_electron变量,示例代码中a、b、i、j未定义,均已修复。
  • 提升精度:将子区间数从50改为500,平衡计算速度和积分精度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 05:14:57