Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

printing matrices and vectors side by side

For tutorial purposes, I'd like to be able to print or display matrices and vectors side-by-side, often to illustrate the result of a matrix equation, like $A x = b$.

I could do this using SAS/IML, where the print statement takes an arbitrary collection of (space separated) expressions, evaluates them and prints the result, e.g.,

print A ' * ' x '=' (A * x) '=' b;

                    A                     X   #TEM1001       B
                    1     1    -4  *  0.733 =        2 =     2
                    1    -2     1     -0.33          1       1
                    1     1     1      -0.4          0       0

Note that quoted strings are printed as is.

I've searched, but can find nothing like this in R. I imagine something like this could be done by a function showObj(object, ...) taking its list of arguments, formatting each to a block of characters, and joining them side-by-side.

Another use of this would be a compact way of displaying a 3D array as the side-by-side collection of its slices.

Does this ring a bell or does anyone have a suggestion for getting started?

like image 772
user101089 Avatar asked Sep 09 '16 20:09

user101089


People also ask

How do you print two matrices side by side?

printf(" + "); for (i; i < width2; i++) { if (i != 0) { if (i % width2 == 0) { printf(" |\n| "); } } printf("%d ", row2[i]); //row2 has second matrix (right) array values } } sec++; //Just another integer variable to have some control over loop process, didnt succeed much though } printf(" |\n\n");

How do you print a matrix code?

MATRIX PRINT CODE simply what you need to add is: put //printf("\n"); in loop,that is responsible of printing of ROWS.so that, \n:it will change the row after complition of each row.

How do you add a vector to a matrix in R?

To convert a vector into matrix, just need to use matrix function. We can also define the number of rows and columns, if required but if the number of values in the vector are not a multiple of the number of rows or columns then R will throw an error as it is not possible to create a matrix for that vector.


1 Answers

I have created a very simple function that can print matrices and vectors with arbitrary character strings (typically operators) in between. It allows for matrices with different numbers of rows and treats vectors as column matrices. It is not very elaborate, so I fear there are many examples where it fails. But for an example as simple as the one in your question, it should be enough.

format() is used to convert the numbers to characters. This has the advantage that all the rows of the matrix have the same width and are thus nicely aligned when printed. If needed, you could add some of the arguments of format() also as arguments mat_op_print() to make the configurable. As an example, I have added the argument width that can be used to control the minimal width of the columns.

If the matrices and vectors are name in the function call, these names are printed as headers in the first line. Otherwise, only the numbers are printed.

So, this is the function:

mat_op_print <- function(..., width = 0) {

  # get arguments
  args <- list(...)
  chars <- sapply(args, is.character)

  # auxilliary function to create character of n spaces
  spaces <- function(n) paste(rep(" ", n), collapse = "")

  # convert vectors to row matrix
  vecs <- sapply(args, is.vector)
  args[vecs & !chars] <- lapply(args[vecs & !chars], function(v) matrix(v, ncol = 1))

  # convert all non-characters to character with format
  args[!chars] <- lapply(args[!chars], format, width = width)

  # print names as the first line, if present
  arg_names <- names(args)
  if (!is.null(arg_names)) {
    get_title <- function(x, name) {
      if (is.matrix(x)) {
        paste0(name, spaces(sum(nchar(x[1, ])) + ncol(x) - 1 - nchar(name)))
      } else {
        spaces(nchar(x))
      }
    }
  cat(mapply(get_title, args, arg_names), "\n")
  }

  # auxiliary function to create the lines
  get_line <- function(x, n) {
    if (is.matrix(x)) {
      if (nrow(x) < n) {
       spaces(sum(nchar(x[1, ])) + ncol(x) - 1)
      } else {
        paste(x[n, ], collapse = " ")
      }
    } else if (n == 1) {
      x
    } else {
      spaces(nchar(x))
    }
  }

  # print as many lines as needed for the matrix with most rows
  N <- max(sapply(args[!chars], nrow))
  for (n in 1:N) {
    cat(sapply(args, get_line, n), "\n")
  }
}

And this is an example of how it works:

A = matrix(c(0.5, 1, 3, 0.75, 2.8, 4), nrow = 2)
x = c(0.5, 3.7, 2.3)
y = c(0.7, -1.2)
b = A %*% x - y
mat_op_print(A = A, " * ", x = x, " - ", y = y, " = ", b = b, width = 6)
## A                        x          y          b      
##   0.50   3.00   2.80  *     0.5  -     0.7  =  17.090 
##   1.00   0.75   4.00        3.7       -1.2     13.675 
##                             2.3    

Also printing the slices of a 3-dimensional array side-by-side is possible:

A <- array(1:12, dim = c(2, 2, 3))
mat_op_print(A1 = A[, , 1], " | ", A2 = A[, , 2], " | ", A3 = A[, , 3])
## A1      A2      A3    
## 1 3  |  5 7  |   9 11 
## 2 4     6 8     10 12
like image 84
Stibu Avatar answered Sep 29 '22 11:09

Stibu