'Creating a 3 by 1 matrix from three columns in a data frame and multiplying by a 2*3 in the correct order and applying to all the rows

I have a 23 constant complex matrix and create a 31 matric created from 3 columns of a data frame(this should be done for each row) and the result is going to be a 2*1 matric called N. This should be applied to all of the rows so I define a while loop. Then N[1,1] and N[2,1] are used to calculate the final thing, but I am not getting the result I want, I calculated Q from each row!!! I put Q like Q[i] inside the loop and still not the result I wanted.

library(dplyr)
library(tidyr)
library(readxl)
library(Matrix)
library(matlib)
library(readxl)
library(MASS)
c1 <- c(2+3i,1+2i,3+4i)
c2 <- c(1+4i,4+6i,7+1i)
c3 <- c(4+5i,2+2i,3+4i)
c4=2
df <- data.frame(c1,c2,c3)
print(df)
a1 <- matrix(c(1+2i,2+4i,5+1i,1+2i,5+4i,2+2i),nrow=3,ncol=2, byrow=T)
a_inv <- ginv(a1)
print(a_inv)
i <-1
while(i <= nrow(df)){
  C <- matrix(c(df$c1[1],df$c2[1],df$c3[1]), nrow=3, ncol=1)
  N <- a_inv %*% C
  N1 <- N[1,1]
  N2 <- N[2,1]
  i=i+1
}
Q <-((N1+N2)*c4)
print(Q)
r


Solution 1:[1]

I would make a couple of empty lists to receive the while loop iteration results, made outside the loop:

N <- list()
lst_31_2 <- list() # your C
i = 1
 while (i <= nrow(df)) {
lst_31_2[[i]] = matrix(c(df$c1[i], df$c2[i], df$c3[i]), nrow=3, ncol=1)
N[[i]] = a_inv %*% lst_31_2[[i]]
i= i+1
}
> str(N)
List of 3
 $ : cplx [1:2, 1] 0.386+0.338i 0.781-0.169i
 $ : cplx [1:2, 1] 0.393+0.602i 0.413-0.568i
 $ : cplx [1:2, 1] 0.81+0.157i 0.452-0.351i

Then using the N values, a for loop:

Q <- list()
for (j in 1:nrow(df)) {
+ Q[[j]] <- (N[[j]][1,1] + N[[j]][2,1]) * c4
+ }
Q
[[1]]
[1] 2.333981+0.337864i

[[2]]
[1] 1.61165+0.067961i

[[3]]
[1] 2.524272-0.38835i
# or
unlist(Q)
[1] 2.333981+0.337864i 1.611650+0.067961i 2.524272-0.388350i
> unlist(Q)[1]
[1] 2.333981+0.337864i
> unlist(Q)[2]
[1] 1.61165+0.067961i
> unlist(Q)[3]
[1] 2.524272-0.38835i

Note the [[ to extract list values and [ for matrix. And I'll still say my best guess as I don't know what the expected value should be. The above 'while' could also be a for loop, which would simplify to one loop, this assuming df and a_inv in environment and C and Q lists:

for(k in 1:nrow(df)) {
 lst_31_2[[k]] = matrix(c(df$c1[k], df$c2[k], df$c3[k]), nrow=3, ncol=1)
 N[[k]] = a_inv %*% lst_31_2[[k]]
 Q[[k]] <- (N[[k]][1,1] + N[[k]][2,1]) * c4
 df$Q[k] <- Q[[k]]
 }
> df
    c1   c2   c3                  Q
1 2+3i 1+4i 4+5i 2.333981+0.337864i
2 1+2i 4+6i 2+2i 1.611650+0.067961i
3 3+4i 7+1i 3+4i 2.524272-0.388350i
> Q
[[1]]
[1] 2.333981+0.337864i

[[2]]
[1] 1.61165+0.067961i

[[3]]
[1] 2.524272-0.38835i

ls()
 [1] "a_inv"    "a1"       "c1"       "c2"       "c3"       "c4"      
 [7] "df"       "k"        "lst_31_2" "N"        "Q"

Because the objects were initialized as empty, outside the loop, they are all available after processing and can be removed rm(Q) if they are cluttering up your workspace.

And I find building the steps like this, getting each part returning reasonably expected numbers, then next, then combining easier to later debug errors in my logic. So I first try to do it in the simplest base way I can.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1