简体   繁体   English

使用C语言的GNU科学库进行线性拟合

[英]Linear fitting with GNU Scientific Library in C

I have two arrays of 64-bit integers (one for the x and one for the y values) I want to fit with a straight line starting from the origin. 我有两个64位整数数组(一个用于x,一个用于y值),我想用一条从原点开始的直线拟合。 They both have length num . 它们都有长度num

I made a previous parsing of the two arrays so that they're both starting when they're zero, so I have to shift one of the two arrays, according to the value of result , either by pos1 or by pos2 . 我对这两个数组进行了先前的解析,以便它们都在零时都开始。因此,我必须根据result的值,将两个数组之一移到pos1pos2

Now, as I said, the arrays are 64-bit integer-sized, so I cast them as double. 现在,正如我所说的,数组是64位整数大小的,所以我将它们强制转换为double。 But whenever I call the following piece of code, the program crashes. 但是,每当我调用以下代码时,程序就会崩溃。 c1 , cov11 and sumsq are defined outside as pointers to doubles. c1cov11sumsq在外部定义为双精度指针。

if(result > 0)  
gsl_fit_mul((double *) array1 + pos2, 1,(double *) array2, 1, (num - pos2 - 1) * sizeof(uint64_t), c1, cov11, sumsq);
else
gsl_fit_mul((double *) array1, 1, (double *) array2 + pos1, 1, (num - pos2 - 1) * sizeof(uint64_t), c1, cov11, sumsq);

I tried reading the documentation , but it's actully not so clear, and I think the problem is in the call to the arrays. 我尝试阅读文档 ,但实际上并不清楚,我认为问题出在对数组的调用中。

Thank you in advance. 先感谢您。


EDIT: I changed approach. 编辑:我改变了方法。 I wrote this function 我写了这个功能

void findFit(uint64_t *array1, uint64_t *array2, uint64_t num, double c1){
    double *array1_parallel = malloc(num * sizeof(double)), *array2_parallel = malloc(num * sizeof(double));

    for(uint64_t i = 0; i < num; i++){
        array1_parallel[i] = (double) array1[i];
        array2_parallel[i] = (double) array2[i];
    }

    double *cov11, *sumsq;

    gsl_fit_mul(array1_parallel, 1, array2_parallel, 1, num, &c1, cov11, sumsq);

    free(array2_parallel);
    free(array1_parallel);

    return;
}

passing to it the already shifted and parsed arrays, but it's still not working... 传递给它已经移位和解析的数组,但仍然无法正常工作...

Casting in C can be confusing. 使用C进行转换可能会造成混淆。 You're not casting the individual values, you're casting the pointer to those values. 您不是在投射单个值,而是在将指针投射到这些值。 Which isn't what you want. 这不是你想要的。

So, you're telling gsl_fit_mul() - "here's an array of doubles, not the array of ints that the compiler thinks it is." 因此,您要告诉gsl_fit_mul()-“这是双精度数组,而不是编译器认为是的整数数组。” But they really are ints, so that's not going to work. 但是它们确实整数,所以这行不通。

You need to create a second array of doubles and cast each of the ints to convert your ints into doubles. 您需要创建第二个双精度数组并转换每个int才能将您的int转换为双精度。

so: 所以:

double* double_array1, *double_array2;
size_t i;

double_array1 = malloc(sizeof(double)*num);
double_array2 = malloc(sizeof(double)*num);
for (i=0; i < num; ++i) {
    double_array1[i] = array1[i];
    double_array2[i] = array2[i];
}


...
gsl_fit_mul(double_array1 + ..., double_array2, ...)
...
free(double_array1);
free(double_array2);

(Be sure to call free() on those arrays after you're done. If you know a maximum value for num at compile time, those arrays can be declared statically and you don't need to malloc/free them). (一定要在完成后在这些数组上调用free()。​​如果在编译时知道num的最大值,则可以静态声明这些数组,而无需malloc / free它们)。

Also, I don't know this library at all, but I doubt that the 'n' parameter should be the size in bytes of the input arrays (which is what you're getting when you multiply by sizeof(uint64_t)). 另外,我一点也不了解这个库,但是我怀疑'n'参数是否应该是输入数组的字节大小(当您乘以sizeof(uint64_t)时会得到什么)。 Just pass in the number of elements (num - minus your offsetting magic). 只需传入元素的数量(num-减去抵消的魔力)即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM