解决一个由50个非线性方程组成的系统-fn(par,...)中的错误:缺少参数

时间:2019-05-19 09:59:54

标签: r nonlinear-functions

我正在尝试解决由50个非线性方程组成的系统,如下所示:

给出一个包含49个不同值的向量y,我想将这49个值转换为另一个向量(例如x)中稍有不同的值,例如:

>>> from operator import gt
>>> gt(1, 2.5)
False

为清楚起见,在上述公式中,log(x[1], y[1]) = n ... log(x[49], y[49]) = n x[1] + ... + x[49] = 1 是对数的底。

我编写了以下代码,但是似乎不起作用:

y[i]

我希望它可以解决library(xlsx) rm(list=ls()) setwd("C:/Users/.../folder") my_data <- read.xlsx("samplefile.xlsx", 1) y <- matrix(0:0, nrow=49,ncol=1) for(i in 1:49) { if(my_data[i,1]!=0) { y[i,1] = 1/my_data[i,1] } } for(i in 1:49) { fn <- function(x,n) { dummy1 <- log(x[i],y[i])-n dummy2 <- sum(x[1:49])-1 return(c(dummy1,dummy2)) } } guess <- matrix(0.5:0.5, nrow = 50, ncol = 1) nleqslv(guess,fn) x[i]的问题。但是,我收到以下错误消息:

“ fn(par,...)中存在错误:缺少参数“ n”,没有默认值”

编辑:格式化

1 个答案:

答案 0 :(得分:0)

有两种解决问题的方法。

第一个函数使用nleqslv来求解包含50个变量和50个变量的系统: x[1]x[49]nnleqslv要解析的函数必须返回一个包含50个元素的向量;方程组必须是正方形。

第二个将您的问题简化为n中的单个方程式。

第一个解决方案:

library(nleqslv)
fn <- function(z,y) {

    x <- z[1:49]
    n <- z[50]

    f <- numeric(50)

    for( k in 1:49 ) f[k] <- log(x[k],y[k]) - n
    f[50] <- sum(x) - 1
    f
}

生成y的一些值以及xn的起始值,然后尝试求解

y <- rep(2,49)
guess <- c( rep(.5,49), 1)

res <- nleqslv(guess,fn,y=y)
res

检查结果:

# this should sum to 1
sum(res$x[1:49])
# value of n
res$x[50]

第二个解决方案:

利用log(a,b) = n暗示a <- b^n的事实。 因此log(x[k],y[k])=n等效于x[k]=y[k]^n。 因此x[1:49]可以立即计算出来。我们只需要根据n的元素之和为1的限制来确定x。 这意味着一个简单的功能

f2 <- function(n,y) {
    x <- y^n  # gives values for x
    sum(x) - 1
}

现在使用uniroot这样,假设n的值在-10和10之间,并且端点处f2的符号具有相反的符号。

uniroot(f2,c(-10,10), y=y)

您可以按照给定的方式运行此代码,并检查nleqslvunirootn给出的结果是否相同。

这是否对您的数据有效取决于您的发现。