Умножить каждый элемент массива на число в C

Я пытаюсь оптимизировать часть моего кода на C, который намного больше, чем фрагмент ниже. Исходя из Python, я задаюсь вопросом, можете ли вы просто умножить весь массив на число, как я делаю ниже.

очевидно, это не работает так, как я делаю это ниже. Есть ли другой способ достичь того же, или мне нужно пройти через весь массив, как в цикле for?

void main()
{
    int i;
    float data[] = {1.,2.,3.,4.,5.};

    //this fails
    data *= 5.0;

    //this works
    for(i = 0; i < 5; i++) data[i] *= 5.0;

}

4 ответов


нет короткого пути, который вы должны пройти через каждый элемент массива.

обратите внимание, однако, что в вашем примере вы можете достичь ускорения с помощью int, а не float для ваших данных и множителя.


если вы хотите, вы можете делать то, что вы хотите через Блас, основные подпрограммы линейной алгебры, которые оптимизированы. Это не в стандарте C, это пакет, который вы должны установить самостоятельно.

пример кода для достижения того, что вы хотите:

#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
int main () {            
    int limit =10;
    float *a =  calloc( limit, sizeof(float));
    for ( int i = 0; i < limit ; i++){
        a[i] = i;
    }
    cblas_sscal( limit , 0.5f, a, 1); 

    for ( int i = 0; i < limit ; i++){
        printf("%3f, " , a[i]);
    }
    printf("\n");
}

имена функций не очевидны, но, читая рекомендации, вы можете начать догадываться, что Блас функции. sscal() можно разделить на s для один и scal на scale, что означает, что эта функция работает на поплавках. Та же функция для двойной точности называется dscal().

Если вам нужно масштабировать вектор с константой и добавлять его в другой, BLAS получил функцию для этого:

saxpy()
s      a x p y
float  a*x + y
y[i] += a*x

как вы могли догадаться есть daxpy() тоже, который работает на doubles.


боюсь, что в C вам придется использовать for(i = 0; i < 5; i++) data[i] *= 5.0;. Python допускает гораздо больше "ярлыков"; однако в C вы должны получить доступ к каждому элементу, а затем манипулировать этими значениями.

использование for-loop будет самым коротким способом выполнить то, что вы пытаетесь сделать с массивом.

EDIT: если у вас есть большой объем данных, есть более эффективные (с точки зрения времени выполнения) способы умножить 5 на каждое значение. Проверьте цикл плитки, например.


data *= 5.0;

здесь сведения - это адрес массива, который является постоянным. если вы хотите умножить первое значение в этом массиве, используйте оператор*, как показано ниже.

*data *= 5.0;