我的方程组包含一个ifelse
条件;我不知道这是否是导致奇异矩阵问题的原因,因为它有时可行,有时不可行。
这有效:
zf <- function(p,parms) {
with(as.list(c(p,parms)),{
eq = NULL
eq = c(eq,N_A-A-S_AC)
eq = c(eq,N_C-C-S_AC)
eq = c(eq,ifelse(S_AC==0,0,A*C-K_AC))
return(eq)})
}
require(rootSolve)
multiroot(f=zf,start=c(A=0.001,C=0.001,S_AC=0.01),parms=c(N_A=0.0001,N_C=0.01,K_AC=1e-10),positive=TRUE,atol=1.e-50)
#$root
# A C S_AC
#1.010101e-08 9.900010e-03 9.998990e-05
#
#$f.root
#[1] 0.000000e+00 2.981556e-19 6.802063e-17
#
#$iter
#[1] 4
#
#$estim.precis
#[1] 2.277293e-17
我发现它对start
向量的不同值具有相对的容忍度。
另一方面,
zf2 <- function(p,parms) {
with(as.list(c(p,parms)),{
eq = NULL
eq = c(eq,N_A-A-S_AC-S_AK)
eq = c(eq,N_C-C-S_AC)
eq = c(eq,N_K-K-S_AK)
eq = c(eq,ifelse(S_AC==0,0,A*C-K_AC))
eq = c(eq,ifelse(S_AK==0,0,A*K-K_AK))
return(eq)})
}
有时可行:
multiroot(f=zf2,start=c(A=0.001,C=0.001,K=0.0005,S_AC=0.01,S_AK=0.005),parms=c(N_A=0.015,N_C=0.01,N_K=0.005,K_AC=1e-10,K_AK=1e-7),positive=TRUE,atol=1.e-50)
#$root
# A C K S_AC S_AK
#3.247940e-04 2.536305e-05 2.994309e-04 9.974637e-03 4.700569e-03
#
#$f.root
#[1] 0.000000e+00 0.000000e+00 -8.673617e-19 8.137766e-09 -2.746643e-09
#
#$iter
#[1] 4
#
#$estim.precis
#[1] 2.176882e-09
有时会给出错误:
multiroot(f=zf2,start=c(A=0.001,C=0.001,K=0.0005,S_AC=0.01,S_AK=0.005),parms=c(N_A=0.0001,N_C=0.01,N_K=0.005,K_AC=1e-10,K_AK=1e-7),positive=TRUE,atol=1.e-50)
#diagonal element is zero
#[1] 4
#$root
# A C K S_AC S_AK
# 0 0 230465362144 230465362144 0
#
#$f.root
#[1] -2.304654e+11 -2.304654e+11 -2.304654e+11 -1.000000e-10 0.000000e+00
#
#$iter
#[1] 3
#
#$estim.precis
#[1] 138279217286
#
#Warning messages:
#1: In stode(y, times, func, parms = parms, ...) :
# error during factorisation of matrix (dgefa); singular matrix
#2: In stode(y, times, func, parms = parms, ...) : steady-state not reached
从optim
和类似功能的其他帖子中,我似乎了解到初始条件(start
)可能决定矩阵的奇异性。
但是后来我不知道如何选择start
来避免这种问题。
我尝试将ifelse
等式替换为:
max(0,A*C-K_AC)
因为该等式确实仅在A*C
大于K_AC
时适用。
但是,这导致了更频繁的“奇异矩阵”错误。
您对如何避免此问题有任何建议吗?
您对我的函数表述有什么看法吗?
谢谢!