y = (2*exp(2)*0.02585/(1-exp(1/0.02585*(1.1-x)))+ 1.125*(x-1.1))*a*(x-1.1)/(8*10^(-9))这个是要建立的函数类型,只含有一个参数a,需要求解,下面是我的实际数据点 x = 0.1:0.1:5; y_data = [-17.07912228, -17.07912228, -16.8427335, -16.6890252, -16.66282283, -16.49643209, -16.46765313, -16.40577772, -16.36655701, -16.2865143, -16.16938895, -16.05982674, -16.04577499, -15.94414234, -15.84806851, -15.7569308, -15.67984072, -15.58160228, -15.51651566, -15.40269786, -15.32736814, -15.22405053, -15.14731673, -15.08847623, -15.01449582, -14.97228176, -14.86533268, -14.79500737, -14.74691493, -14.67235383, -14.60958366, -14.56946988, -14.47909894, -14.4316967, -14.3688958, -14.31803738, -14.26179766, -14.20855315, -14.15800087, -14.0899474, -14.02007772, -13.91533089, -13.80062195, -13.66709055, -13.45783611, -13.1198665, -12.61705293, -11.96705575, -11.22774652, -10.45513517]; y的实际数据点是取了对数的,而函数模型没有取对数,用c或c++用L-M法求解,L-M法需要设立误差函数,误差函数为F=0.5*(f T *f) 写出c语言代码
时间: 2023-09-21 11:13:23 浏览: 121
以下是使用C语言实现L-M法求解的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 50 // 数据点个数
#define M 1 // 待求参数个数
#define IT_MAX 100 // 最大迭代次数
#define EPS 1e-8 // 迭代停止阈值
double x[N] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5.0}; // 数据点的x值
double y[N] = {-17.07912228, -17.07912228, -16.8427335, -16.6890252, -16.66282283, -16.49643209, -16.46765313, -16.40577772, -16.36655701, -16.2865143, -16.16938895, -16.05982674, -16.04577499, -15.94414234, -15.84806851, -15.7569308, -15.67984072, -15.58160228, -15.51651566, -15.40269786, -15.32736814, -15.22405053, -15.14731673, -15.08847623, -15.01449582, -14.97228176, -14.86533268, -14.79500737, -14.74691493, -14.67235383, -14.60958366, -14.56946988, -14.47909894, -14.4316967, -14.3688958, -14.31803738, -14.26179766, -14.20855315, -14.15800087, -14.0899474, -14.02007772, -13.91533089, -13.80062195, -13.66709055, -13.45783611, -13.1198665, -12.61705293, -11.96705575, -11.22774652, -10.45513517}; // 数据点的对数
// 定义待求解的函数模型
double model(double x, double a) {
return (2 * exp(2) * 0.02585 / (1 - exp(1 / 0.02585 * (1.1 - x))) + 1.125 * (x - 1.1)) * a * (x - 1.1) / (8e-9);
}
// 定义误差函数
void error(double *p, double *f, double **J) {
int i, j;
double a = p[0];
for (i = 0; i < N; i++) {
f[i] = log(y[i]) - log(model(x[i], a)); // 残差
for (j = 0; j < M; j++) {
J[i][j] = -1 / (a * (x[i] - 1.1)); // 求解雅可比矩阵
}
}
}
// 定义L-M法的主函数
void lm(double *p, double **J, double *f) {
int i, j, k;
double mu = 1e-3, rho, v[N], p_new[M], f_new[N], **J_new, delta[M], err, err_new;
J_new = (double **) malloc(N * sizeof(double *));
for (i = 0; i < N; i++) {
J_new[i] = (double *) malloc(M * sizeof(double));
}
for (i = 0; i < IT_MAX; i++) {
error(p, f, J);
err = 0;
for (j = 0; j < N; j++) {
err += f[j] * f[j]; // 计算当前误差
}
if (err < EPS) {
break; // 如果误差已经小于阈值,直接退出循环
}
for (j = 0; j < M; j++) {
for (k = 0; k < N; k++) {
v[k] = J[k][j];
}
delta[j] = 0;
for (k = 0; k < N; k++) {
delta[j] += v[k] * f[k];
}
delta[j] /= (mu + 1); // 计算增量
p_new[j] = p[j] + delta[j]; // 更新参数
}
error(p_new, f_new, J_new);
err_new = 0;
for (j = 0; j < N; j++) {
err_new += f_new[j] * f_new[j]; // 计算新的误差
}
if (err_new < err) {
mu /= 2; // 如果新的误差更小,减小步长
for (j = 0; j < M; j++) {
p[j] = p_new[j];
for (k = 0; k < N; k++) {
J[k][j] = J_new[k][j];
}
}
for (j = 0; j < N; j++) {
f[j] = f_new[j];
}
} else {
mu *= 2; // 如果新的误差更大,增加步长
}
}
for (i = 0; i < N; i++) {
free(J_new[i]);
}
free(J_new);
}
int main() {
double a = 1.0; // 待求解参数的初始值
double *p, **J, *f;
int i, j;
// 为参数、雅可比矩阵、残差分配内存
p = (double *) malloc(M * sizeof(double));
J = (double **) malloc(N * sizeof(double *));
for (i = 0; i < N; i++) {
J[i] = (double *) malloc(M * sizeof(double));
}
f = (double *) malloc(N * sizeof(double));
// 初始化参数
p[0] = a;
// 调用L-M法求解
lm(p, J, f);
// 输出结果
printf("a = %lf\n", p[0]);
// 释放内存
free(p);
for (i = 0; i < N; i++) {
free(J[i]);
}
free(J);
free(f);
return 0;
}
```
注意,此处的数据点y是取了对数的,但是在误差函数中需要计算残差,因此需要将模型函数的输出值也取对数。在求解雅可比矩阵时,需要注意除数不能为0的情况。
阅读全文