Two matrices A & B, with ncol = 2, nrow = 2 separetly.
A = [a_11 a_12
a_21 a_22]
B = [b_11 b_12
b_21 b_22]
(sorry didnt how to show matrix here...)
Multiply these 2 matrices and aim to obtain a new result matrix as:
c = [a_11*b_11 a_11*b_12 a_12*b_11 a_12*b_12
a_21*b_21 a_21*b_22 a_22*b_21 a_22*b_22]
Obviously, it could be done with some loop, but I'd assume there exist simpler methods
C <- matrix(NA, nrow = nrow(A), ncol = ncol(A)*ncol(B))
for (m in 1 : nrow(C)) {
for (k in 1:ncol(A)) {
C[m, (ncol(B)*(k-1)+1) : (k*ncol(B))] <- d1[m, k] * d2[m,]
}
}
You can do:
cbind(A[, 1]*B, A[,2]*B) # or
matrix(apply(A, 2, function(x) x*B), 2)
data
A <- matrix(1:4, 2)
B <- matrix(11:14, 2)
Related
If I have a function
estimator <- function(A,B) {
A*(B+23)
}
How can I reverse this function to find the value of A for B as a sequence between 0 and 120 (B=1,2,3,4,...,120) that would give a fixed result, say C = 20?
I would use it to map the values for which satisfy the equation A*(B+23)= C = 20 with B being a list b.list between 0 and 120, for c.list, of different C?
b.list <- seq(0,120,by=1)
c.list <- tibble(seq(10,32,by=2))
In the end, I would like to plot the lines of curves of the function for different C using purrr or similar.
I.e.: Given that the height of a tree in metres at age 100 will follow the function, C = A*(B+23), solve for A that will give the result C=10 when B, Age is a list of years between 0 and 120?
Here's a link showing what I'm trying to make!
Here's another one
Many thanks!
For the inverse it is a quick inversion :
A = C/(B+23)
One answer could be :
B <- seq(0, 120)
C <- seq(10, 32, 2)
A <- matrix(0,
nrow = length(B),
ncol = length(C))
for(i in 1:ncol(M)){
A[,i] <- C[i] / (B + 23)
}
matplot(B, A, type ="l", col = "black")
In case of a more complex function indeed you need an automatic solving problem. One way is to see it like an optimisation problem where you want to minimise the distance from C :
B <- seq(1, 120)
C <- seq(10, 32, 2)
A <- matrix(0,
nrow = length(B),
ncol = length(C))
fct <- function(A, B, C){
paramasi <- 25
parambeta<- 7395.6
paramb2 <- -1.7829
refB <- 100
d <- parambeta*(paramasi^paramb2)
r <- (((A-d)^2)+(4*parambeta*A*(B^paramb2)))^0.5
si_est <- (A+d+r)/ (2+(4*parambeta*(refB^paramb2)) / (A-d+r))
return(sum(si_est - C)^2)}
for(c in 1:length(C)){
for(b in 1:length(B)){
# fixe parameters + optimisation
res <- optim(par = 1, fn = fct, B = B[b], C = C[c])
A[b, c] <- res$par
}
}
matplot(B, A, type = "l", col = "black")
You need to be careful because in your case I think that you could find an analytical formula for the inverse which would be better.
Good luck !
I am using R v 3.0.0 (2013-04-03) and RStudio v 1.1.463 under Win-7 64-bit.
In the following source code:
# Problem 1 - Matrix powers in R
#
# R does not have a built-in command for taking matrix powers.
# Write a function matrixpower with two arguments mat and k that
# will take integer powers k of a matrix mat.
matrixMul <- function(mat1)
{
rows <- nrow(mat1)
cols <- ncol(mat1)
matOut = matrix(, nrow = rows, ncol = cols) # empty matrix
for (i in 1:rows)
{
for(j in 1:cols)
{
vec1 <- mat1[i,]
vec2 <- mat1[,j]
mult1 <- vec1 * vec2
matOut[i,j] <- mult1
}
}
return(matOut)
}
matrixpower<-function(mat1, k)
{
matOut <-mat1#empty matix
for (i in k)
{
matOut <- matrixMul(matOut)
}
return(matOut)
}
mat1 <- matrix(c(1,2,3,4,5,6,7,8,9), nrow = 3, ncol=3)
power1 <- matrixMul(mat1)
the declaration
matOut <- matrix(, nrow = rows, ncol = cols) # empty matrix
is giving the following syntax error even before compilation:
missing argument to function call
I am following these instructions.
What am I doing wrong here?
Try this:
matOut = matrix(numeric(rows*cols), nrow = rows, ncol = cols) # empty matrix
I have a list of 40 data sets who all have the same columns. I want to bind the 7th column of each data set. I thought about doing this with a matrix using cbind. This is my code:
RetRates <- function(q) {
q <- matrix(nrow = 766, ncol = length(ListeActions),
data = rep(0, 766), byrow = TRUE)
s <- 0
for (i in 1:length(ListeActions)) {
x <- ListeActions[[i]]
q[,i] <- cbind(q[,i], x[,9]) ## I need the 9th column
}
return(q)
}
Hedi <- matrix(nrow = 766, ncol = length(ListeActions),
data = rep(0, 766), byrow = TRUE)
Hedi <- RetRates(Hedi)
I get these warnings :
Warning messages: 1: In replace(q[, i], 1:766, x[, 9]) : the number
of objects to be replaced is not a multiple of the size of the
replacement !
Let's take a smaller example: cbind the 5th columns of each of these 3 matrices
d1 <- matrix(runif(30), 5, 6)
d2 <- matrix(rnorm(30), 5, 6)
d3 <- matrix(rnorm(30), 5, 6)
First we put the 3 matrices in a list
M <- list(d1=d1, d2=d2, d3=d3)
Then we could use, as in your question, a for loop
res1 <- matrix(NA, nrow=5, ncol=length(M))
for (i in 1:length(M)) {
res1[, i] <- M[[i]][,5]
}
Or we could use some magical R functions to get the result in one slightly more obscure command
res2 <- do.call(cbind, lapply(M, "[",,5))
I have a list of three two-dimensional arrays that contains x, y and z coordinates of some points (to draw a surface from them, I store them in two-dimensional arrays, like surface plots in MATLAB).
Example:
points <- list(x=matrix(c(1, 2, 3, 4), nrow=2),
y=matrix(c(5, 6, 1, 4), nrow=2),
z=matrix(c(1, 9, 2, 3), nrow=2))
This is a representation of points with coordinates (1, 5, 1), (2, 6, 9) and so on (4 points total).
Now I have to multiply every (x, y, z) point with some fixed matrix C (to rotate my surface) and return the result in the same form of list of two-dimensional matrixes.
I can do it in this way with loops:
apply_matrix <- function(C, points) {
x <- points$x
y <- points$y
z <- points$z
n <- nrow(x)
m <- ncol(x)
outx <- matrix(rep(0, n*m), nrow = n)
outy <- matrix(rep(0, n*m), nrow = n)
outz <- matrix(rep(0, n*m), nrow = n)
for (i in 1:nrow(x)) {
for (j in 1:ncol(x)) {
out <- C %*% c(x[i, j], y[i, j], z[i, j])
outx[i,j] <- out[1,]
outy[i,j] <- out[2,]
outz[i,j] <- out[3,]
}
}
list(x=outx,y=outy,z=outz)
}
However, I'm looking for more efficient loop-free solution.
I believe it is possible to convert the list to three-dimensional matrix and then ask R to multiply my matrix C to this three-dimensional matrix using appropriate dimensions, but cannot figure out how to do it.
Here I first convert the list to a three-dimensional array and then also return one:
C <- matrix(rnorm(3 * 3), 3)
ar <- array(unlist(points), c(dim(points[[1]]), 3))
aperm(apply(ar, 1:2, `%*%`, x = t(C)), c(2, 3, 1))
Suppose I have the following code:
X <- model.matrix(~factor(1:2))
beta <- c(1, 2)
I then draw 70 and 40 values from two multivariate normal distributions:
library(MASS)
S1 <- mvrnorm(70, mu = c(0,0), Sigma = matrix(c(10, 3, 3, 2), ncol = 2))
S2 <- mvrnorm(40, mu = c(0,0), Sigma = matrix(c(10, 4, 4, 2), ncol = 2))
As can be easily seen S1 is 70x2 matrix und S2 a 40x2 matrix.
Now I build a for loop in R:
z <- list()
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta + X %*% S1[1,] + X %*% S2[i,] + rnorm(2, mean = 0, sd = 0.45)
Y <- do.call(rbind, z)
}
This gives me a matrix that contains all combinations for the 40 elements in S2 with the 1st element of S1. What I want is to completely cross the two matrices S1 and S2. That is I want the for loop to pick out S1[1,] first, then iterate completely through S2[i,] (e.g. in an inner loop) and store the results in a matrix then pick out S1[2,] iterate again through S2[i,] and store the results in a matrix and so on. If I would need to give a name to what I am looking for I would say "crossed for loops". I find it incredibly hard to come up with R-code that will allow me to do this. Any hints would be appreciated.
Maybe the idea will get clearer with this example:
My idea is equivalent to construction 70 for-loops for every element in S1[i,] and binding the result in a 70*40*2x1 matrix:
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta+X %*% S1[1,]+X %*% S2[i,]+rnorm(2, mean = 0 , sd = sigma)
Y1 <- unname(do.call(rbind, z))
}
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta+X %*% S1[2,]+X %*% S2[i,]+rnorm(2, mean = 0 , sd = sigma)
Y2 <- unname(do.call(rbind, z))
}
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta+X %*% S1[3,]+X %*% S2[i,]+rnorm(2, mean = 0 , sd = sigma)
Y3 <- unname(do.call(rbind, z))
}
.
.
.
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta+X %*% S1[70,]+X %*% S2[i,]+rnorm(2, mean = 0 , sd = sigma)
Y70 <- unname(do.call(rbind, z))
}
Y <- rbind(Y1, Y2, Y3, …, Y70)
What I ideally would want is to do this with for-loops or any other flexible way that can handle different dimensions for S1 and S2.
OK. I might do a few things to make this as efficient as possible. First, we can pre-calculate all the matrix multiplication with
Xb <- X %*% beta
XS1 <- X %*% t(S1)
XS2 <- X %*% t(S2)
Then we can clculate all the combinations of the S1/S2 values with expand.grid
idx <- unname(c(expand.grid(A=1:ncol(XS1), B=1:ncol(XS2))))
Then we can define the transformation
fx<-function(a, b) {
t(Xb + XS1[,a, drop=F] + XS2[,b,drop=F] + rnorm(2, mean = 0, sd = 0.45))
}
we assume we will be passed an index for S1 and an index for S2. Then we combine the data as in your formula. Finally, we use this helper function and the indexes with a set of do.calls
xx <- do.call(rbind, do.call(Map,c(list(fx), idx)))
First we use Map to calculate all the combinations, then we use rbind to merge all the results. This actually produces a 2800x2 matrix. (70*40)*2. The rows are ordered with S1 moving the fastest, then S2.
I realised that this was not a problem with for-loops but with the way I stored the variables. The solution to what I want is:
library(MASS)
z <- list()
y <- list()
for(j in 1:dim(S1)[1]){
for(i in 1:dim(S2)[1]){
z[[i]] <- X %*% beta+X %*% S1[j,]+X %*% S2[i,]+matrix(rnorm(2, mean = 0 , sd = sigma), ncol = 2, nrow = 2)
Z <- unname(do.call(rbind, z))
}
y[[j]] <- Z
Y <- unname(do.call(rbind, y))
}