'Solve non-linear equations using "nleqslv" package

I tried to solve the these non-linear equations by using nleqslv. However it does not work well. I do know the reason why it does not because I didn't separate the two unknowns to different sides of the equation.

My questions are: 1, Are there any other packages that could solve this kind of equations? 2, Is there any effective way in R that could help me rearrange the equation so that it meets the requirement of the package nleqslv?

Thank you guys.

Here are the codes and p[1] and p[2] are the two unknowns I want to solve.

   dslnex<-function(p){
   p<-numeric(2)
   0.015=sum(exp(Calib2$Median_Score*p[1]+p[2])*weight_pd_bad)

   cum_dr<-0 
   for (i in 1:length(label)){
   cum_dr[i]<-exp(Calib2$Median_Score*p[1]+p[2][1:i]*weight_pd_bad[1:i]/0.015
   }

   mid<-0
   for (i in 1:length(label)){
   mid[i]<-sum(cum_dr[1:i])/2
   }

   0.4=(sum(mid*weight_pd_bad)-0.5)/(0.5*(1-0.015))

   }

   pstart<-c(-0.000679354,-4.203065891)
   z<- nleqslv(pstart, dslnex, jacobian=TRUE,control=list(btol=.01))


Solution 1:[1]

Following up on my comment I have rewritten your function as follows correcting errors and inefficiencies. Errors and other changes are given as inline comments.

# no need to use dslnex as name for your function
# dslnex <- function(p){
# any valid name will do

f <- function(p) {
    # do not do this
    # you are overwriting p as passed by nleqslv
    # p<-numeric(2)

    # declare retun vector
    y <- numeric(2)

    y[1] <- 0.015 - (sum(exp(Calib2$Median_Score*p[1]+p[2])*weight_pd_bad))

    # do not do this
    # cum_dr is initialized as a scalar and will be made into a vector
    # which will be grown as a new element is inserted (can be very inefficient)
    # cum_dr<-0 
    # so declare cum_dr to be a vector with length(label) elements

    cum_dr <- numeric(length(label))
    for (i in 1:length(label)){
        cum_dr[i]<-exp(Calib2$Median_Score*p[1]+p[2][1:i]*weight_pd_bad[1:i]/0.015
    }

    # same problem as above
    # mid<-0
    mid <- numeric(length(label))
    for (i in 1:length(label)){
        mid[i]<-sum(cum_dr[1:i])/2
    }

    y[2] <- 0.4 - (sum(mid*weight_pd_bad)-0.5)/(0.5*(1-0.015))

    # return vector y
    y
}

pstart <-c(-0.000679354,-4.203065891)
z <- nleqslv(pstart, dslnex, jacobian=TRUE,control=list(btol=.01))

nleqslv is intended for solving systems of equations of the form f(x) = 0 which must be square. So a function must return a vector with the same size as the x-vector.

You should now be able to proceed provided your system of equations has a solution. And provided there are no further errors in your equations. I have my doubles about the [1:i] in the expression for cum_dr and the expression for mid[i]. The loop calculating mid possibly can be written as a single statement: mid <- cumsum(cum_dr)/2. Up to you.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1