R - Выполнить функцию для значений матрицы, используя расположение значений - PullRequest
0 голосов
/ 20 марта 2019

Я создаю программное обеспечение, которое использует матричные вычисления R для построения тепловой карты. Предполагая, что в качестве стартовой матрицы у меня есть следующее:

        -1.8784 -1.8783 -1.8782
53.5919       0       0       0
53.592        0      50       0
53.5921       0       0       0

Как бы я превратил это в следующее?

        -1.8784 -1.8783 -1.8782
53.5919       0    12.5       0
53.592     12.5      25    12.5
53.5921       0    12.5       0

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

Я пытался использовать apply, но я не могу понять, как передать местоположение текущего обрабатываемого индекса в функцию. Для циклов, очевидно, вариант, но они классно медленны в R, и я очень хотел бы иметь некоторый уровень оптимизации для этого.

Есть ли более элегантное решение, чем перебирать каждое значение в матрице?

1 Ответ

0 голосов
/ 20 марта 2019

Следующие могут делать то, что вы хотите.Это, конечно, возможно более элегантно, я верю.Но моя линейная алгебра слишком далека, чтобы сделать это на макушке головы.

Сначала я строю некоторые игрушечные данные.

Матрица для "сглаживания":

x <- 0*diag(10)  
x[8,4] <- x[6,7] <- x[3,3] <- 50
print(x)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    0    0    0    0    0    0    0    0     0
 [2,]    0    0    0    0    0    0    0    0    0     0
 [3,]    0    0   50    0    0    0    0    0    0     0
 [4,]    0    0    0    0    0    0    0    0    0     0
 [5,]    0    0    0    0    0    0    0    0    0     0
 [6,]    0    0    0    0    0    0   50    0    0     0
 [7,]    0    0    0    0    0    0    0    0    0     0
 [8,]    0    0    0   50    0    0    0    0    0     0
 [9,]    0    0    0    0    0    0    0    0    0     0
[10,]    0    0    0    0    0    0    0    0    0     0

Далее мы определяем вспомогательную матрицу, которую можно использовать при умножении матрицы на матрицу:

b <- 0*diag(10)
b[col(b) == row(b) + 1] <- 0.5
b[col(b) == row(b) - 1] <- 0.5
print(b)  # A symmetric matrix with the first off-diagonal set to 0.5
       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]  0.0  0.5  0.0  0.0  0.0  0.0  0.0  0.0  0.0   0.0
 [2,]  0.5  0.0  0.5  0.0  0.0  0.0  0.0  0.0  0.0   0.0
 [3,]  0.0  0.5  0.0  0.5  0.0  0.0  0.0  0.0  0.0   0.0
 [4,]  0.0  0.0  0.5  0.0  0.5  0.0  0.0  0.0  0.0   0.0
 [5,]  0.0  0.0  0.0  0.5  0.0  0.5  0.0  0.0  0.0   0.0
 [6,]  0.0  0.0  0.0  0.0  0.5  0.0  0.5  0.0  0.0   0.0
 [7,]  0.0  0.0  0.0  0.0  0.0  0.5  0.0  0.5  0.0   0.0
 [8,]  0.0  0.0  0.0  0.0  0.0  0.0  0.5  0.0  0.5   0.0
 [9,]  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.5  0.0   0.5
[10,]  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.5   0.0

Выполните вычисление:

res <- x %*% b + b %*% x + x
res
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    0    0    0    0    0    0    0    0     0
 [2,]    0    0   25    0    0    0    0    0    0     0
 [3,]    0   25   50   25    0    0    0    0    0     0
 [4,]    0    0   25    0    0    0    0    0    0     0
 [5,]    0    0    0    0    0    0   25    0    0     0
 [6,]    0    0    0    0    0   25   50   25    0     0
 [7,]    0    0    0   25    0    0   25    0    0     0
 [8,]    0    0   25   50   25    0    0    0    0     0
 [9,]    0    0    0   25    0    0    0    0    0     0
[10,]    0    0    0    0    0    0    0    0    0     0

Редактировать Это дает то же самое:

d <- 0.5*diag(10)
d[col(d) == row(d) + 1] <- 0.5
d[col(d) == row(d) - 1] <- 0.5

res2 <- x %*% d + d %*% x  # or crossprod(d, x) + tcrossprod(x, d)
print(res2)
...