openlang

MATLAB 스크립트를 R로 옮겼더니 결과 하나가 행렬로 나왔다

짧은 MATLAB 스크립트를 R로 다시 짜 보는 중인데, MATLAB은 거의 써 본 적이 없어요. 대부분은 무난하게 옮겨졌는데 한 줄만 다른 숫자를 내요.

A = [2 0; 1 3];
w = [0.5; 0.25];
s = A * w;
B = A .* A;
A <- matrix(c(2, 0, 1, 3), nrow = 2, byrow = TRUE)
w <- c(0.5, 0.25)
s <- A * w
B <- A * A
s
#>      [,1] [,2]
#> [1,] 1.00 0.00
#> [2,] 0.25 0.75

B는 MATLAB과 같아요. s는 MATLAB에서 1과 1.25 두 숫자인데, R에서는 2행 2열 행렬이 통째로 나오고 오류도 경고도 없어요. A가 양쪽에서 똑같이 출력되는 건 확인했으니 byrow 문제는 아니에요. R에는 .*가 없는 것 같아서 점을 전부 그냥 뺐어요. 거기서 잘못된 걸까요, 아니면 w를 만든 방식 때문일까요?

영어에서 번역원문 보기

이어지는 대화 7

서로의 근거를 따라
  1. 고유 링크

    순서가 반대입니다. MATLAB에서 .*가 행렬 곱이고 *는 R의 *처럼 원소별 곱이니, s는 쓴 그대로 일치해야 합니다. 그보다 w를 봐야 합니다. c()는 열이 아니라 평범한 벡터를 만들고, R은 그것을 행렬 전체에 재활용합니다.

    영어에서 번역원문 보기
  2. 고유 링크

    반대다. MATLAB에서 행렬 사이의 *는 행렬 곱이고 .*가 원소별 곱이다. R은 거꾸로다. *가 원소별이고 %*%가 행렬 곱이다.

    s <- A %*% w
    s
    #>      [,1]
    #> [1,] 1.00
    #> [2,] 1.25

    w는 평범한 벡터여도 된다. %*%는 모양이 맞도록 그것을 열로 취급한다. B가 맞은 건 A .* A와 A * A가 둘 다 원소별이라서일 뿐이다. 점을 뺀 게 그 줄에서는 맞았고 다른 줄에서는 틀렸다.

    영어에서 번역원문 보기
  3. 고유 링크

    맞습니다, 제가 둘을 바꿔 기억하고 있었습니다. 점은 MATLAB의 원소별 표시이고, 그래서 R에는 애초에 필요가 없었습니다. 그래도 c() 이야기는 유효합니다. 평범한 벡터에는 방향이 없고 %*%가 대신 정해 줍니다.

    영어에서 번역원문 보기
  4. 고유 링크

    R의 그 줄은 엉터리가 아니라 MATLAB의 A * w와는 다른 식을 계산합니다. R은 w를 각 열을 따라 재활용하므로 i행에 w[i]가 곱해집니다. 이는 w가 열일 때 MATLAB의 A .* w입니다. 2행 2열 결과는 그 식에 대해서는 맞습니다.

    영어에서 번역원문 보기
  5. 고유 링크

    길이가 나누어떨어지니 아무 말 없이 그렇게 한다. 재활용은 긴 쪽 길이가 짧은 쪽의 배수가 아닐 때만 경고하는데, 원소 넷에 가중치 둘이면 딱 나누어떨어진다. 원소가 세 개인 w였다면 적어도 경고는 나왔을 것이다. 가중치가 정말 행마다 따로라면 나는 sweep(A, 1, w, "*")로 써서 의도를 코드에 드러내는 쪽을 택한다.

    영어에서 번역원문 보기
  6. 고유 링크

    같은 함정에 기호만 더 많다. MATLAB의 A^2는 행렬 거듭제곱, 곧 A * A다. R의 A^2는 원소마다 제곱한다. MATLAB의 A'는 전치이고, 실수 행렬이면 R에서는 t(A)다. MATLAB의 A \ b는 연립방정식을 푼다. R에서는 solve(A, b)다. MATLAB에서 행렬 사이의 /도 방정식을 푸는 연산인데, R은 원소별로 나눈다. 스크립트를 훑어 양쪽에 행렬이 있는 *, ^, /를 하나씩 확인하라.

    영어에서 번역원문 보기
  7. 고유 링크

    바로 그거였어요, 고마워요. 이제 s <- A %*% w가 1과 1.25를 내요. 2행 1열 행렬로 나오니까 데이터 프레임에 넣기 전에 drop()을 거치게 했어요. 전체 스크립트 아래쪽에 A^2도 있었는데, pgr의 목록 덕분에 다음 수수께끼가 되기 전에 잡았어요.

    영어에서 번역원문 보기

같은 질문의 다른 갈래

  1. 전부 NA인 그룹에 na.rm = TRUE

    그룹별 합계를 tapply(x, g, sum, na.rm = TRUE)로 냈더니 한 그룹이 0으로 나왔다. 그 그룹의 값은 전부 NA다. 측정값이 하나도 없는데 표에는 합계가 0이라고 적혀 있다. 하나씩 보면 다 변명할 수…

    답글 5r
  2. 행이 하나인 행렬의 sum(X)

    관측 행렬을 받아 각 열을 X ./ sum(X)로 정규화하는 함수가 있다. 행은 관측, 열은 특성이다. 오래 문제없이 돌았다. 그러다 행이 하나뿐인 입력이 들어왔다. sum은 크기가 1이 아닌 첫 번째 차원을 따라 더한다.…

    답글 6matlab
  3. 열마다 새로 할당하던 루프

    Julia에서 슬라이싱은 복사를 해요. 알고 있었는데 루프 안에서는 깜빡했어요. 행렬의 열을 돌면서 j마다 s += sum(A[:, j])를 하는 함수를 예로 들어 볼게요. A[:, j]가 매번 새 벡터를 만들고, 더하고,…

    답글 4julia