带if条件的R-外部
使用R,我定义了一个矩阵M,除了对角线带if条件的R-外部,r,if-statement,matrix,R,If Statement,Matrix,使用R,我定义了一个矩阵M,除了对角线M(I,I)和M(I,I-1)和M(I,I+1)元素之外,它用0填充 因为这个矩阵可能很大,所以我想使用外部函数。 但是,如果我这样定义makeM函数: makeM <- function(j,k,n,s){ a=j*(n-j)*(1.0-s)/n^2 b=j*(n-j)*(1.0)/n^2 if(j==(k+1)){ return(a)} if(j==(k-1)){ return(b)} if(j==k){ r
M(I,I)
和M(I,I-1)
和M(I,I+1)
元素之外,它用0填充
因为这个矩阵可能很大,所以我想使用外部函数。
但是,如果我这样定义makeM
函数:
makeM <- function(j,k,n,s){
a=j*(n-j)*(1.0-s)/n^2
b=j*(n-j)*(1.0)/n^2
if(j==(k+1)){ return(a)}
if(j==(k-1)){ return(b)}
if(j==k){ return(1-b-a)}
return(0)
}
我得到了wring结果,即应该为null的元素不是,就好像“if”条件在外部不起作用一样
为了检查,我用蛮力做了同样的操作:
s=0.1
N=100
M=matrix(rep(0,N*N),ncol=N,nrow=N)
for(i in 1:N)
{
for(j in 1:N)
{
M[i,j]=makeM(i,j,N,s)
}
}
这就行了,我得到了正确的矩阵。因此,makeM
函数是正常的。
因此,问题似乎确实在于我的“如果”条件的矢量化。但是,我不明白为什么。有人能解释一下原因吗?以及在外部函数中传递if
语句的方法
提前感谢。外部使用矢量化函数,因此您只需将函数矢量化即可
VecFun <- Vectorize(makeM)
N=100
M=outer(seq(1, N), seq(1,N), VecFun,n=N,s=0.1)
VecFun我建议您创建一个稀疏矩阵
你的蛮力方法具有较低的n:
s=0.1
N=6
M=matrix(rep(0,N*N),ncol=N,nrow=N)
for(i in 1:N)
{
for(j in 1:N)
{
M[i,j]=makeM(i,j,N,s)
}
}
现在是创建稀疏矩阵的解决方案。注意我是如何用相应的顺序替换j
:
library(Matrix)
j <- seq_len(N) #sequence 1:N
M1 <- bandSparse(N, N, k = -1:1, diag= list(
(j+1) *(N - (j+1))*(1.0-s)/N^2, #j offset by 1
1-j*(N-j)*(1.0)/N^2-j *(N - j)*(1.0-s)/N^2,
j*(N-j)*(1.0)/N^2
), symmetric = FALSE)
库(矩阵)
j或者更好,以一种使其矢量化的方式编写函数。然后这会更快。谢谢,这确实是一个简单的破解。我还按照@Roland的建议直接对函数进行了矢量化:makeMbis对此表示感谢,没有直接回答我的问题,但它可能会派上用场。@z_飞开,如果n变得足够大,这是唯一不会很快耗尽内存的解决方案。
library(Matrix)
j <- seq_len(N) #sequence 1:N
M1 <- bandSparse(N, N, k = -1:1, diag= list(
(j+1) *(N - (j+1))*(1.0-s)/N^2, #j offset by 1
1-j*(N-j)*(1.0)/N^2-j *(N - j)*(1.0-s)/N^2,
j*(N-j)*(1.0)/N^2
), symmetric = FALSE)
M2 <- as.matrix(M1)
dimnames(M2) <- NULL
all.equal(M, M2)
#[1] TRUE