Оптимизировать расчет корреляционной матрицы - PullRequest
1 голос
/ 27 февраля 2012

Приведенный ниже код вычисляет матрицу корреляции по ковариационной матрице.Как я могу написать это лучше?Проблема заключается в том, что этот раздел кода будет запускаться тысячи раз на матрицах, размеры которых составляют около 100 x 100.

// Copy upper triangle of covariance matrix to correlation matrix
for(i = 0; i < rows; i++){
  for(j = i; j < rows; j++){
    corrmatrix.array[i * rows + j] = covmatrix.array[i * rows + j];
  }
}

// Calculate upper triangle of corr matrix
for(i = 0; i < rows; i++){

  root = sqrt(covmatrix.array[(i * rows) + i]);    

  for(j = 0; j <= i; j++){ // Move down 
    corrmatrix.array[ j * rows + i ] /= root;
  }

  k = i * rows;

  for(j = i; j < rows; j++){ // Move across
    corrmatrix.array[ k + j ] /= root;
  }

}

// Copy upper triangle to lower triangle
for(i = 0; i < rows; i++){
  k = i * rows;
  for(j = i; j < rows; j++){
    corrmatrix.array[ (j * rows) + i ] = corrmatrix.array[ k + j ];
  }
}

Я проверил, что строки и столбцы равны и т. Д., Поэтому я просто использую строкивезде.Я хочу оптимизировать скорость (значительно).

PS:

  1. Матрицы хранятся в плотном формате строк
  2. Я не использую упакованное хранилище.

Спасибо

1 Ответ

1 голос
/ 27 февраля 2012

Первое, что бросается в глаза, это то, что вы делаете деление на одно и то же число во внутренних циклах.

Не делайте этого. Деление медленное.

Вместо этого вы должны умножить на обратную величину root вместо того, чтобы делить ее на несколько раз:

inv_root = 1. / sqrt(covmatrix.array[(i * rows) + i]);

for(j = 0; j <= i; j++){ // Move down 
    corrmatrix.array[ j * rows + i ] *= inv_root;
}

k = i * rows;

for(j = i; j < rows; j++){ // Move across
    corrmatrix.array[ k + j ] *= inv_root;
}

Хотя эта оптимизация может показаться очевидной для компилятора, она не может бытьпозволил сделать эту оптимизацию из-за строгости с плавающей точкой.Вы можете попытаться ослабить настройки с плавающей точкой с помощью -ffast-math (в GCC) или чего-то подобного.

...