Use R to implement an algorithm to compute the LU factorization of banded matrices (you can ignore pivoting). The inputs to your function should be a matrix A and its bandwidth w (your algorithm does not need to determine the bandwidth, you can assume it will be provided by the user). The outputs should be a list of two matrices L and U .
使用R实现一个算法来计算带状矩阵的LU分解(您可以忽略旋转)。您的函数的输入应该是一个矩阵A及其带宽w(您的算法不需要确定带宽,您可以假设它将由用户提供)。输出应该是两个矩阵L和U的列表。
lu_with_bandwidth <- function(A, bandwidth) {
n <- nrow(A)
L <- diag(n)
U <- matrix(0, nrow = n, ncol = n)
for (i in 1:n) {
start_col <- max(1, i - bandwidth)
end_col <- min(n, i + bandwidth)
U[i, i:end_col] <- A[i, i:end_col]
if (start_col <= end_col) {
L[start_col:end_col, i] <- A[start_col:end_col, i] / U[i, i]
if (i < n) {
A[(i+1):end_col, (i+1):end_col] <- A[(i+1):end_col, (i+1):end_col] - L[(i+1):end_col, i] %*% U[i, (i+1):end_col]
}
}
}
return(list(L = L, U = U))
}
B <- matrix (c(3,1,4,0,0,0,1,5,9,2,0,0,6,5,3,5,8,0,0,9,7,9,3,2,0,0,3,8,4,6,0,0,0,2,6,4), nrow=6)
print(lu_with_bandwidth(B,2))
Output error: Error in A[(i + 1):end_col, (i + 1):end_col] - L[(i + 1):end_col, i] %*% :
non-conformable arrays
输出错误:A[(i+1):END_COOL,(I+1):END_COOL]-L[(I+1):END_COOL,I]%*%:不一致数组
here is the algorithm i follow.
algorithm
以下是我遵循的算法。演算法
更多回答
You should add code to print the dimensions of all the matrices at each step just before the error-generating line. That A matrix looks to be square but L and U look to be row and column matrices.
您应该添加代码,以便在每个步骤中在错误生成行之前打印所有矩阵的维度。A矩阵看起来是正方形的,但L和U看起来是行矩阵和列矩阵。
@IRTFM I tried to add this earlier, cat("Dimensions of L[start_col:end_col, i]:", dim(L[start_col:end_col, i]), "\n") cat("Dimensions of U[i, (i+1):end_col]:", dim(U[i, (i+1):end_col]), "\n") but I still have no clue
@IRTFM我之前试着添加这个,cat(“Dimensions of L[Start_Col:End_Col,I]:”,Dim(L[Start_Col:End_Col,I]),“\n”)cat(“Dimensions of U[i,(i+1):End_Col]:”,Dim(U[i,(i+1):End_Col]),“\n”),但我仍然不知道
If you don’t give the results of your efforts at debugging, then we also “have no clue”.
如果你不给出你努力调试的结果,那么我们也“一无所知”。
@IRTFM So, I added those two lines after if (i < n) {, and it gave me Dimensions of L[start_col:end_col, i]: Dimensions of U[i, (i+1):end_col]: Error in A[(i + 1):end_col, (i + 1):end_col] - L[(i + 1):end_col, i] %*% : non-conformable arrays. It didn't even give me the dimension, which I was not sure why.
@IRTFM所以,我在if(i < n){之后添加了这两行,它给了我L的尺寸[start_col:end_col,i]:U的尺寸[i,(i+1):end_col]:A中的错误[(i + 1):end_col,(i +1):end_col] - L[(i + 1):end_col,i] %*%:non-conformable arrays。它甚至没有给我维度,我不知道为什么。
This version of your question has already received an answer. If you have a different but related question you can ask a new one. If you have found an answer to this question you can "Post Your Answer" by clicking the button at the bottom of the page.
此版本的您的问题已收到答复。如果你有一个不同但相关的问题,你可以问一个新的问题。如果你找到了这个问题的答案,你可以通过点击页面底部的按钮来“张贴你的答案”。
If you add the drop=FALSE parameter to the indexing of L and U you will get further. R's [
function will drop dimensions for single column or row matrices.
如果将DROP=FALSE参数添加到L和U的索引中,则会得到进一步的结果。R‘s[函数将删除单列或单行矩阵的维度。
... - L[(i+1):end_col, i, drop=FALSE] %*% U[i, (i+1):end_col, drop=FALSE]
#no prettying screen scraping:
> lu_with_bandwidth <- function(A, bandwidth) {
+ n <- nrow(A)
+ L <- diag(n)
+ U <- matrix(0, nrow = n, ncol = n)
+
+ for (i in 1:n) {
+ start_col <- max(1, i - bandwidth)
+ end_col <- min(n, i + bandwidth)
+
+ U[i, i:end_col] <- A[i, i:end_col]
+
+ if (start_col <= end_col) {
+ L[start_col:end_col, i] <- A[start_col:end_col, i] / U[i, i]
+ if (i < n) {cat("starting")
+ A[(i+1):end_col, (i+1):end_col] <- A[(i+1):end_col, (i+1):end_col] - L[(i+1):end_col, i, drop=FALSE] %*% U[i, (i+1):end_col, drop=FALSE]
+ }
+ }
+ }
+
+ return(list(L = L, U = U))
+ }
> B <- matrix (c(3,1,4,0,0,0,1,5,9,2,0,0,6,5,3,5,8,0,0,9,7,9,3,2,0,0,3,8,4,6,0,0,0,2,6,4), nrow=6)
> print(lu_with_bandwidth(B,2))
startingstartingstartingstartingstarting$L
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1.0000000 0.2142857 -0.6043165 0.0000000 0.0000000 0.0000000
[2,] 0.3333333 1.0000000 -0.3021583 4.0354839 0.0000000 0.0000000
[3,] 1.3333333 1.6428571 1.0000000 -3.4910138 0.1514658 0.0000000
[4,] 0.0000000 0.4285714 -0.3741007 1.0000000 0.4605723 0.6269144
[5,] 0.0000000 0.0000000 -0.8057554 -1.4677419 1.0000000 2.8008919
[6,] 0.0000000 0.0000000 0.0000000 0.8967742 -0.1100977 1.0000000
$U
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 1.000000 6.000000 0.000000 0.000000 0.000000
[2,] 0 4.666667 3.000000 9.000000 0.000000 0.000000
[3,] 0 0.000000 -9.928571 -7.785714 3.000000 0.000000
[4,] 0 0.000000 0.000000 2.230216 9.122302 2.000000
[5,] 0 0.000000 0.000000 0.000000 19.806452 8.935484
[6,] 0 0.000000 0.000000 0.000000 0.000000 3.190228
But I don't know if that is correct or not. (It does have a banded structure so it might be.)
但我不知道这是否正确。(It它有一个带状结构,所以它可能是。)
更多回答
the code is almost correct. It tackles the error and actually produce the right U. However, now I am confused because for the L factor, it should be a lower triangular matrix. Honestly the value for the lower triangular are all correct. I jus not sure why there are value filled in the upper triangular part
代码几乎是正确的。它解决了错误,实际上产生了正确的U。然而,现在我感到困惑,因为对于L因子,它应该是一个下三角矩阵。老实说,下三角形的值都是正确的。我只是不确定为什么上面的三角形部分会有值填充
You were making assignments to rectangular sub matrices of L. Perhaps you should have indexed that assignment with lower.tri
? Where is the algorithm you are following?
您正在对L的矩形子矩阵进行赋值。也许您应该用lower.tri对该赋值进行索引?您正在遵循的算法在哪里?
the algorithm is too long to put in the comment, i update my prompt instead. it should be similar to LU factorization, but i only want to work with nonzero element as it is a banded matrix.
算法太长,不能放在评论中,我更新了提示符。它应该类似于LU因式分解,但我只想使用非零元素,因为它是带状矩阵。
The algorithm should have been put in the body of the question as should have been any code or results. I’m willing to look at this again only if you do so.
算法应该放在问题正文中,任何代码或结果都应该放在正文中。我愿意再看一遍,除非你这样做。
Yes, I have been put my algorithm in the body of the question. It is a link that lead you to a picture (algorithm in blue). Here for easy reference: i.stack.imgur.com/WJftx.png
是的,我已经把我的算法放在了问题的正文中。它是一个链接,可以将您带到一张图片(蓝色算法)。这里方便参考:i.stack.imgur.com/WJftx.png
我是一名优秀的程序员,十分优秀!