使用R rootSolve :: multiroot数值求解多元方程组时如何避免'奇异矩阵'错误

时间:2018-12-26 10:41:38

标签: r equation-solving

我的方程组包含一个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时适用。
但是,这导致了更频繁的“奇异矩阵”错误。

您对如何避免此问题有任何建议吗?
您对我的函数表述有什么看法吗?

谢谢!

0 个答案:

没有答案