openlang

Ported a short MATLAB script to R and one result came back as a matrix

Trying to redo a short MATLAB script in R, and I've barely touched MATLAB before. Most of it came over fine, except for a single line that gives different numbers.

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 agrees with MATLAB. s in MATLAB is two numbers, 1 and 1.25, and in R it's a whole 2 by 2 matrix with no error and no warning. I checked that A prints the same in both, so byrow isn't the problem. R didn't seem to have .*, so I just dropped the dot everywhere. Is that where it went wrong, or is it something about how I built w?

后续讨论 7

顺着彼此的依据读下去
  1. 固定链接

    You have them the wrong way round. MATLAB's .* is the matrix product and * is elementwise, same as R's *, so s should match as written. Look at w instead. c() gives a plain vector, not a column, and R recycles it across the matrix.

  2. 固定链接

    Backwards. In MATLAB * between matrices is the matrix product and .* is elementwise. R has it the other way round. * is elementwise and %*% is the product.

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

    w is fine as a plain vector. %*% treats it as a column when that's what makes the shapes fit. B matched only because A .* A and A * A are both elementwise. Dropping the dot was right for that line and wrong for the other.

  3. 固定链接

    The R line computes something real, just not MATLAB's A * w. R recycles w down each column, so row i is multiplied by w[i]. That is MATLAB's A .* w with w as a column. Your 2 by 2 result is correct for that expression.

  4. 固定链接

    And it does that without a word because the lengths divide. Recycling warns only when the longer length isn't a multiple of the shorter one, and four elements over two weights divides evenly. A three-element w would at least have complained. When the weights really are per row I'd rather write sweep(A, 1, w, "*") and have the intent on the page.

  5. 固定链接

    Same trap, more symbols. MATLAB A^2 is the matrix power, A * A. R A^2 squares each element. MATLAB A' transposes, t(A) in R for a real matrix. MATLAB A \ b solves the system, solve(A, b) in R, and / between matrices is a solve in MATLAB too, while R divides element by element. Go through the script and check every *, ^ and / with a matrix on both sides.

  6. 固定链接

    That was it, thank you. s <- A %*% w gives 1 and 1.25 now. It comes back as a 2 by 1 matrix, so it goes through drop() before landing in the data frame. The full script has an A^2 further down too, and pgr's list caught it before it could become the next mystery.

同一个问题的其他角度

  1. na.rm = TRUE on a group that is all NA

    Per-group totals with tapply(x, g, sum, na.rm = TRUE), and one group came back as 0. Every value in that group is NA. Not a s…

    回复 5最近活动 r
  2. A loop that allocated a column at a time

    Slicing in Julia copies, which I knew and then forgot inside a loop. Take a function that walks the columns of a matrix and d…

    回复 4最近活动 julia
  3. sum(X) on a matrix with one row

    A function takes a matrix of observations, rows are observations and columns are features, and normalizes each column with X…

    回复 6最近活动 matlab