Использование функций GSL lib для данных в struct C - PullRequest
0 голосов
/ 15 января 2019

Многие функции GSl принимают аргументы в виде значений типа double или массивов значений типа double. Однако большая часть моих данных вместо этого вложена в массивы структур. Скажите как массивы:

struct A
{
  double a;
  int b;
};

Я мог бы написать оболочку, которая копирует данные в массив чистых двойных или целых чисел. Но мне было интересно что-то более элегантное, чтобы обойти это.

Ответы [ 2 ]

0 голосов
/ 16 января 2019

"... большая часть моих данных вместо этого вложена в массивы структур. ... Я может написать обертку, которая копирует данные в массив чистого удваивает или увеличивает Но мне было интересно что-то более элегантное, чтобы получить вокруг этого. "

Нет необходимости писать оболочку для копирования данных в массив чистых double или int. Тот факт, что у вас есть массив-структуры , уже обеспечивает удобный прямой доступ к каждому сохраненному значению. С массивом-структурой , доступным к каждому индивидууму struct в пределах массива, является простым делом индексации структуры, которую вы хотите, например, array[n] где n - искомый элемент в массиве.

В вашем примере array[n].a обеспечивает прямой доступ к значению double в элементе a, а array[n].b обеспечивает прямой доступ к int элементу b для каждого действительного индекса в вашем массиве.

Краткий пример этой индексации для прямого доступа к каждому члену каждой структуры в массиве может помочь. Следующее инициализирует array с пятью структурами с показанными значениями double и int. Значения int затем увеличиваются на 1 в цикле перед выводом каждого члена каждой структуры, например,

#include <stdio.h>

typedef struct A {  /* struct A (with a typedef for convenience) */
    double a;
    int b;
} A;

int main (void) {

    /* array of struct A */
    A array[] = {{1.1, 1}, {2.2, 2}, {3.3, 3}, {4.4, 4}, {5.5, 5}};
    size_t nelem = sizeof array / sizeof *array;    /* no. elements */

    for (size_t i = 0; i < nelem; i++) { 
        array[i].b++;   /* increment int/output stored values */
        printf ("array[%zu]: {%3.1f, %d}\n", i, array[i].a, array[i].b);
    }
}

Пример использования / Вывод

Обратите внимание, как целочисленное значение, хранящееся в каждом struc в массиве структуры , увеличивается на 1, прежде чем значения в каждом struct с массивом будут непосредственно использоваться в качестве параметра выводится printf:

$ ./bin/arraystruct
array[0]: {1.1, 2}
array[1]: {2.2, 3}
array[2]: {3.3, 4}
array[3]: {4.4, 5}
array[4]: {5.5, 6}

Ваш доступ к каждому члену независимо от того, как вы хотите его использовать, будет одинаковым. Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 15 января 2019

Не тот ответ, который вы хотите. Но так как вы не можете изменить интерфейс GSL, если вы ищете производительность, я думаю, что вашим лучшим решением, вероятно, будет выбор структур данных, которые соответствуют заданию с самого начала. Так что, может быть, что-то вроде структуры, содержащей массивы двойников.

Если и интерфейс GSL, и ваша исходная структура данных находятся вне вашего контроля, то, вероятно, единственным вариантом будет оболочка, о которой вы думаете.

Если библиотечные функции, которые вы используете, могут принимать аргумент 'шага', вы могли бы рассмотреть упаковку и заполнение структуры. (Но это все равно не превратит ваши целые числа в двойные.)

...