2013-07-04 48 views
5

Tôi đang cố tạo ma trận tuần hoàn khối trong R. Cấu trúc của ma trận tuần hoàn khối được đưa ra dưới đây.Tạo ma trận tuần hoàn khối trong R

C0 C1 ... Cn-1 
Cn-1 C0 C1 ... Cn-2 
Cn-2 Cn-1 .... Cn-3 

and so on 

Tôi có khối

C0 .... Cn-1 

cách dễ nhất để tạo ra các ma trận là gì. Có chức năng nào không?

Trả lời

3

Tôi nghĩ rằng những gì bạn đang tìm kiếm là circulant.matrix từ gói lgcp.

Nếu x là một ma trận có các cột là các căn cứ của tiểu khối của một khối ma trận circulant, sau đó chức năng này sẽ trả về khối circulant ma trận quan tâm.

ví dụ

x <- matrix(1:8,ncol=4) 
circulant(x) 
#  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] 
# [1,] 1 2 3 4 5 6 7 8 
# [2,] 2 1 4 3 6 5 8 7 
# [3,] 7 8 1 2 3 4 5 6 
# [4,] 8 7 2 1 4 3 6 5 
# [5,] 5 6 7 8 1 2 3 4 
# [6,] 6 5 8 7 2 1 4 3 
# [7,] 3 4 5 6 7 8 1 2 
# [8,] 4 3 6 5 8 7 2 1 

cách tiếp cận thay thế

Dưới đây là một cách tiếp cận đánh giá cao hiệu quả sử dụng kroneckerReduce

bcirc <- function(list.blocks){ 
    P <- lapply(seq_along(list.blocks), function(x,y) x ==y, x = circulant(seq_along(list.blocks))) 
    Reduce('+',Map(P = P, A=list.blocks, f = function(P,A) kronecker(P,A))) 
    } 

benchmarking với @flodel và @Ben Bolker

lbirary(microbenchmark) 
microbenchmark(bcm(C), bcirc(C), bcMat(C)) 
Unit: microseconds 
    expr  min   lq  median   uq  max neval 
    bcm(C) 10836.719 10925.7845 10992.8450 11141.1240 21622.927 100 
bcirc(C) 444.983 455.7275 479.5790 487.0370 569.105 100 
bcMat(C) 288.558 296.4350 309.8945 348.4215 2190.231 100 
+0

Tôi không thể tìm ra' lgcp :: circulant.matrix' đang làm gì. Có thể sử dụng nó với danh sách 'C' tùy ý không ?? Ví dụ, làm thế nào để sử dụng nó để có được trường hợp ví dụ được hiển thị ở đây (2x2 khối 1, 2, 3)? –

0

Có phải cái gì đó giống như những gì bạn đang tìm kiếm không?

> vec <- 1:4 
> sapply(rev(seq_along(vec)),function(x) c(tail(vec,x),head(vec,-x))) 

    [,1] [,2] [,3] [,4] 
[1,] 1 2 3 4 
[2,] 2 3 4 1 
[3,] 3 4 1 2 
[4,] 4 1 2 3 
+0

đó là một ma trận circulant, không phải là một ma trận khối circulant ... một cái gì đó giống như một sản phẩm Kronecker ('Kronecker ') có thể làm việc, nhưng tôi đã không hoàn toàn tìm ra cách nào được nêu ra –

+0

@BenBolker - Ok - Tôi rõ ràng hiển thị sự thiếu hiểu biết của tôi trong định nghĩa ma trận. Các ký hiệu trong ví dụ của OP không phải là rõ ràng với tôi và tôi không thể tìm thấy bất kỳ ví dụ đơn giản trên google. – thelatemail

+0

@BenBolker - Tôi đã thực hiện một cách tiếp cận không hiệu quả bằng cách sử dụng 'kronecker' – mnel

4

Tôi không biết điều này có hiệu quả đặc biệt hay không, nhưng khi tôi diễn giải câu hỏi của bạn, nó sẽ làm những gì bạn muốn.

rotList <- function(L,n) { 
    if (n==0) return(L) 
    c(tail(L,n),head(L,-n)) 
} 
rowFun <- function(n,matList) do.call(rbind,rotList(matList,n)) 
bcMat <- function(matList) { 
    n <- length(matList) 
    do.call(cbind,lapply(0:(n-1),rowFun,matList)) 
} 

Ví dụ:

bcMat(list(diag(3),matrix(1:9,nrow=3),matrix(4,nrow=3,ncol=3))) 
6

Cảm ơn cho một câu hỏi đầy thách thức! Đây là một giải pháp tổng hợp các sản phẩm kronecker của ma trận của bạn với phụ và siêu diagonals.

dữ liệu mẫu, một danh sách các ma trận:

C <- lapply(1:3, matrix, nrow = 2, ncol = 2) 

Giải pháp của tôi:

bcm <- function(C) { 
    require(Matrix) 
    n <- length(C) 
    Reduce(`+`, lapply((-n+1):(n-1), 
         function(i) kronecker(as.matrix(bandSparse(n, n, -i)), 
              C[[1 + (i %% n)]]))) 
} 
bcm(C) 

#  [,1] [,2] [,3] [,4] [,5] [,6] 
# [1,] 1 1 3 3 2 2 
# [2,] 1 1 3 3 2 2 
# [3,] 2 2 1 1 3 3 
# [4,] 2 2 1 1 3 3 
# [5,] 3 3 2 2 1 1 
# [6,] 3 3 2 2 1 1