a的初始值为10^(-16) y = (2exp(2)0.02585/(1-exp(1/0.02585(1.1-x)))+ 1.125(x-1.1))a(x-1.1)/(810^(-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-20 15:12:01 浏览: 112
以下是使用L-M法求解的C语言代码,其中包括了误差函数和L-M法的主要代码逻辑:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// 定义常量
#define N 50
#define M 1
#define EPS 1e-8
#define MAX_ITERATION 1000
// 定义全局变量
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};
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 a[M] = {1e-16};
double lambda = 0.001;
double mu = 10.0;
// 定义函数原型
void func(double x[], double y[], double a[], double f[]);
void jacobian(double x[], double a[], double J[][M]);
double error(double f[]);
void LM(double x[], double y[], double a[], int n, int m);
int main()
{
LM(x, y, a, N, M);
printf("a = %lf\n", a[0]);
return 0;
}
void func(double x[], double y[], double a[], double f[])
{
double p, q;
for (int i = 0; i < N; i++)
{
p = 2 * exp(2) * 0.02585 / (1 - exp(1 / 0.02585 * (1.1 - x[i]))) + 1.125 * (x[i] - 1.1);
q = a[0] * (x[i] - 1.1) / (810e-9);
f[i] = p * q;
}
}
void jacobian(double x[], double a[], double J[][M])
{
double p, q;
for (int i = 0; i < N; i++)
{
p = 2 * exp(2) * 0.02585 / (1 - exp(1 / 0.02585 * (1.1 - x[i]))) + 1.125 * (x[i] - 1.1);
q = (x[i] - 1.1) / (810e-9);
J[i][0] = p * q;
}
}
double error(double f[])
{
double e = 0.0;
for (int i = 0; i < N; i++)
{
e += pow(f[i] - y[i], 2);
}
return e / 2.0;
}
void LM(double x[], double y[], double a[], int n, int m)
{
double f[N], J[N][M], delta[M], e, e1, e2;
int k = 0;
func(x, y, a, f);
e = error(f);
while (k < MAX_ITERATION)
{
jacobian(x, a, J);
for (int i = 0; i < m; i++)
{
double sum = 0.0;
for (int j = 0; j < n; j++)
{
sum += J[j][i] * J[j][i];
}
delta[i] = 0.0;
delta[i] = (sum + lambda) * mu;
}
for (int i = 0; i < m; i++)
{
a[i] += delta[i];
}
func(x, y, a, f);
e1 = error(f);
if (e1 < e)
{
lambda /= 10.0;
e = e1;
}
else
{
lambda *= 10.0;
for (int i = 0; i < m; i++)
{
a[i] -= delta[i];
}
}
e2 = error(f);
if (fabs(e2 - e) < EPS)
{
break;
}
k++;
}
}
```
其中,函数`func`用于计算函数值,函数`jacobian`用于计算雅可比矩阵,函数`error`用于计算误差,函数`LM`是L-M法的主要实现逻辑。
在`LM`函数中,首先计算初始误差`e`和初始函数值`f`,然后进入迭代过程,每次迭代分别计算雅可比矩阵和增量`delta`,根据增量更新参数`a`,然后计算新的函数值和误差,根据误差判断是否接受更新,如果接受则将阻尼因子`lambda`减小,否则将其增大,直到满足收敛条件。最终输出求解得到的参数`a`的值。
注意,由于函数中存在除数为0的情况,需要特别注意计算时的精度和取值范围。
阅读全文