我有一个函数可以计算一些估计并将其打印到文件中。该程序在多个线程中调用,以针对不同的初始条件进行计算。每个线程创建单独的文件来写入值,因此不涉及文件冲突。这些值以科学记数法打印。我的问题是,在打印时,即使大多数值都正确打印,但有些(一两个)打印时缺少指数部分中的“e”,有一些 -ve 符号,或者通常会破坏格式。虽然这看起来并不重要,但它破坏了管道的其余部分,因为使用这些文件作为输入的程序无法正确解析它。下面给出了准系统代码。调用该函数的循环。
调用函数的循环。
for (int i = 0; i < 12; i++) {
void* args[2] = {clock_pairs[i], Q_matrices[i]};
pthread_create(&K_threads[i], NULL, calculate_kalman, (void*)args);
printf("thread no %d ran \n",i);
}
for (int i = 0; i < 12; i++) {
pthread_join(K_threads[i], NULL);
}
这会将初始条件传递给一个函数,该函数组合参数并传递给计算值的函数。
void Calculate_Kalman(const char *filename, const char *filename1, double** processNoise)
{
char kalman_filename[256];
sprintf(kalman_filename, "K_%s_%s", filename, filename1);
FILE *kalman_file = fopen(kalman_filename, "w");
if (!kalman_file)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
char Error_filename[256];
sprintf(Error_filename, "E_%s_%s", filename, filename1);
FILE *E_file = fopen(Error_filename, "w");
if (!E_file)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
for (int i = 0; i < SampleSize; i++)
{
kf.z = diff[i] + normalRandom(0,pow(measurementNoise,0.5));
Kalman(&kf); // Kalman function call.
// Print the current state estimate
fprintf(kalman_file, "%e, %e\n", gsl_matrix_get(kf.x, 0, 0), gsl_matrix_get(kf.x, 1, 0));
fprintf(E_file, "%e,%e\n", gsl_matrix_get(kf.S, 0, 0), gsl_matrix_get(kf.S, 1, 0));
// Add kf.S values to the dynamic matrix
double row[NUM_VARS] = {gsl_matrix_get(kf.S, 0, 0), gsl_matrix_get(kf.S, 1, 0)};
addRow(&matrix, row);
}
fclose(kalman_file);}
我删除了初始化系统的代码,因为它与问题无关。卡尔曼函数接收结构体 {kf} 并更新其中的值。循环中的 fprintf 命令应该将行打印到文件中。 kf 结构体定义如下
typedef struct
{
gsl_matrix *x; // State estimate (3x1 matrix)
gsl_matrix *P; // Error covariance (3x3 matrix)
gsl_matrix *Q; // Process noise covariance (3x3 matrix)
double R; // Measurement noise covariance (scalar)
gsl_matrix *K; // Kalman gain (3x1 matrix)
gsl_matrix *Phi; // State transition matrix (3x3 matrix)
gsl_matrix *S; // Noise vector (3x1 matrix)
gsl_matrix *H;
double z;
} KalmanFilter;
我尝试使用不同的格式样式(le而不是e),但它没有改变任何东西。事实上,这些错误在完全随机的文件中完全随机地出现也无济于事。
正常输出是这样的
-3.257449e-15, -1.437916e-18
8.742356e-11, 5.662028e-14
-1.929949e-10, -1.779626e-13
1.927338e-10, 2.305067e-13
-8.744399e-11, -1.284666e-13
........................
........................
但是一些不好的输出值看起来像这样
-3.0.049398e-13
1.-12
- -1.922051e-13
我在网上搜索,但找不到任何人提到类似的问题,我希望有人能对此有所启发。
您需要刷新有关变量的范围和生命周期的知识。
for (int i = 0; i < 12; i++) {
void* args[2] = {clock_pairs[i], Q_matrices[i]};
pthread_create(&K_threads[i], NULL, calculate_kalman, (void*)args);
printf("thread no %d ran \n",i);
}
在此代码中,在任何给定时间都只有 1 个数组
args
,并且在离开循环后,该变量根本不再有效。
这意味着,如果当您仍在循环中时执行其中一个线程(不能保证),它只会看到最后存储的内容。
如果线程在循环已经离开后执行,则内存不再有效并且读取内容会导致未定义的行为。
您必须使用静态内存。定义具有静态生存期的变量或使用动态内存分配:
void* args[12][2];
for (int i = 0; i < 12; i++) {
args[i][0] = clock_pairs[i];
args[i][1] = Q_matrices[i];
pthread_create(&K_threads[i], NULL, calculate_kalman, (void*)args[i]);
printf("thread no %d ran \n",i);
}