Santiago Burone
2017-May-10 18:20 UTC
[R] Solve system of non linear equations using nasted loops
Hello, I'm new at R and I would like to use it in order to solve a system of non linear equations. I have the code that works but im not able to save the results. My system has three equations and i would like to solve this using three nested loops, becouse i need solutions for all the values combinations. The code im using is this: library(nleqslv) #x3 es gamma #x2 es alpha #x1 es beta MA <- c(50000, 43600, 40000, 38800, 37600, 34400, 31600, 27200, 24400, 20000) MI <- c(10000, 21800, 20000, 19400, 18800, 17200, 15800, 13600, 12200, 10000) ME <- c(30000, 32700, 30000, 29100, 28200, 25800, 23700, 20400, 18300, 15000) DE <- c(0.384900179, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009) for (i in 1:9) { for (j in 1:9){ for (k in 1:9){ df.names <- paste("SociedadB",1:10,sep="") fun <- function(x) { f <- numeric(length(x)) # read as: f[1] <- 1*x[3] - (log(ME[1+i]/ME[1])+(1*x[1]+1*x[2])*(2)*(log((MA[1]-ME[1])/(MA[i+1]-ME[i+1]))))/(log(0.19245009/0.384900179)) f[2] <- 1*x[3] - (log(MI[1+j]/MI[1])-(1*x[2])*(2)*(log((MA[1+j]-MI[1+j])/(MA[1]-MI[1]))))/(log(0.19245009/0.384900179)) f[3] <- 1*x[3] - (log(MA[1+k]/MA[1])-(1*x[1])*(2)*(log((MI[1+k]-MA[1+k])/(MI[1]-MA[1]))))/(log(0.19245009/0.384900179)) f } startx <- c(1,1,1) answers<-as.data.frame(nleqslv(startx,fun)) d.frame <- (answers$x) assign(df.names[k+20], d.frame) despejes<- data.frame(SociedadB2, SociedadB3, SociedadB4, SociedadB5, SociedadB6, SociedadB7, SociedadB8, SociedadB9, SociedadB10) } } } despejes<- data.frame(SociedadB2, SociedadB3, SociedadB4, SociedadB5, SociedadB6, SociedadB7, SociedadB8, SociedadB9, SociedadB10) If im not wrong i should have 1000 different solutions but the data frame only save 10 results. I tried copying the last part of the code between the last two brackets (changing the name of the data frame despejes for despejes 1, 2 and 3 but i only get three data frames with exactly the same results. I dont know how could i save all the results of every combination. I mean, i need to solve for i=1, j=1 and the 9 diferent values of k and save those results, then i=1, j=2 and the 9 values of k.. I know this might be a easy question but i have not been able to find a solution in the last days. Thanks in advance if you can help me. Santiago. [[alternative HTML version deleted]]
David Winsemius
2017-May-10 20:55 UTC
[R] Solve system of non linear equations using nasted loops
> On May 10, 2017, at 11:20 AM, Santiago Burone <santiagoburone at icloud.com> wrote: > > Hello, > > I'm new at R and I would like to use it in order to solve a system of non linear equations. I have the code that works but im not able to save the results. > > > > My system has three equations and i would like to solve this using three nested loops, becouse i need solutions for all the values combinations. > > > > > > The code im using is this: > > > > library(nleqslv) > #x3 es gamma > #x2 es alpha > #x1 es beta > MA <- c(50000, 43600, 40000, 38800, 37600, 34400, 31600, 27200, 24400, 20000) > MI <- c(10000, 21800, 20000, 19400, 18800, 17200, 15800, 13600, 12200, 10000) > ME <- c(30000, 32700, 30000, 29100, 28200, 25800, 23700, 20400, 18300, 15000) > DE <- c(0.384900179, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009) > for (i in 1:9) { > for (j in 1:9){ > for (k in 1:9){I got an error on the first pass through the loop.> df.names <- paste("SociedadB",1:10,sep="")# seems kind of excessive to repeat that process 9*9*9 times # Maybe this should be done outside the loop?> > fun <- function(x) { > f <- numeric(length(x)) # read as: > f[1] <- 1*x[3] - (log(ME[1+i]/ME[1])+(1*x[1]+1*x[2])*(2)*(log((MA[1]-ME[1])/(MA[i+1]-ME[i+1]))))/(log(0.19245009/0.384900179)) > f[2] <- 1*x[3] - (log(MI[1+j]/MI[1])-(1*x[2])*(2)*(log((MA[1+j]-MI[1+j])/(MA[1]-MI[1]))))/(log(0.19245009/0.384900179)) > f[3] <- 1*x[3] - (log(MA[1+k]/MA[1])-(1*x[1])*(2)*(log((MI[1+k]-MA[1+k])/(MI[1]-MA[1]))))/(log(0.19245009/0.384900179)) > f > }# So you need 9*9*9 different functions?> startx <- c(1,1,1) > answers<-as.data.frame(nleqslv(startx,fun))> d.frame <- (answers$x) > assign(df.names[k+20], d.frame)# I don't think that df.names[k+20] would be anything other than NA since it only has 10 elements> despejes<- data.frame(SociedadB2, SociedadB3, SociedadB4, SociedadB5, SociedadB6, SociedadB7, SociedadB8, SociedadB9, SociedadB10) > > } > } > } > > despejes<- data.frame(SociedadB2, SociedadB3, SociedadB4, SociedadB5, SociedadB6, SociedadB7, SociedadB8, SociedadB9, SociedadB10) >The error message is: Error in data.frame(SociedadB2, SociedadB3, SociedadB4, SociedadB5, SociedadB6, : object 'SociedadB2' not found That's because column names are not first class data-objects in R.> > > If im not wrong i should have 1000 different solutions but the data frame only save 10 results. I tried copying the last part of the code between the last two brackets (changing the name of the data frame despejes for despejes 1, 2 and 3 but i only get three data frames with exactly the same results. I dont know how could i save all the results of every combination. I mean, i need to solve for i=1, j=1 and the 9 diferent values of k and save those results, then i=1, j=2 and the 9 values of k.. >If you need to save separate results for each combination of i,j,k , then you need at a minimum an array (possibly with a further 4th dimension if you are storing numerical vectors) or possibly a list if these items are more complicated than an atomic vector.> > > I know this might be a easy question but i have not been able to find a solution in the last days. > > > > Thanks in advance if you can help me. > > > Santiago. > [[alternative HTML version deleted]]Rhelp is a plain text list although you don't seem to have run into trouble on that account. You should however determine how your mail client can be setup to just send pain text to this mailing list.> > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.David Winsemius Alameda, CA, USA
Bert Gunter
2017-May-10 22:51 UTC
[R] Solve system of non linear equations using nasted loops
I haven't gone through your code carefully, but I believe this can be done in a tiny fraction of the time you are taking by eschewing loops. See ?expand.grid to get started. In general,nested loops should be avoided if possible. I also suggest you spend some time with a good R tutorial to learn how to write good R code instead of recapitulating C (or whatever) in R. All languages have their own coding paradigms(R's is functional) and you will do better in the long run if you spend the time to learn R's. Cheers, Bert On May 10, 2017 1:20 PM, "Santiago Burone" <santiagoburone at icloud.com> wrote: Hello, I'm new at R and I would like to use it in order to solve a system of non linear equations. I have the code that works but im not able to save the results. My system has three equations and i would like to solve this using three nested loops, becouse i need solutions for all the values combinations. The code im using is this: library(nleqslv) #x3 es gamma #x2 es alpha #x1 es beta MA <- c(50000, 43600, 40000, 38800, 37600, 34400, 31600, 27200, 24400, 20000) MI <- c(10000, 21800, 20000, 19400, 18800, 17200, 15800, 13600, 12200, 10000) ME <- c(30000, 32700, 30000, 29100, 28200, 25800, 23700, 20400, 18300, 15000) DE <- c(0.384900179, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009) for (i in 1:9) { for (j in 1:9){ for (k in 1:9){ df.names <- paste("SociedadB",1:10,sep="") fun <- function(x) { f <- numeric(length(x)) # read as: f[1] <- 1*x[3] - (log(ME[1+i]/ME[1])+(1*x[1]+1* x[2])*(2)*(log((MA[1]-ME[1])/(MA[i+1]-ME[i+1]))))/(log(0. 19245009/0.384900179)) f[2] <- 1*x[3] - (log(MI[1+j]/MI[1])-(1*x[2])*( 2)*(log((MA[1+j]-MI[1+j])/(MA[1]-MI[1]))))/(log(0.19245009/0.384900179)) f[3] <- 1*x[3] - (log(MA[1+k]/MA[1])-(1*x[1])*( 2)*(log((MI[1+k]-MA[1+k])/(MI[1]-MA[1]))))/(log(0.19245009/0.384900179)) f } startx <- c(1,1,1) answers<-as.data.frame(nleqslv(startx,fun)) d.frame <- (answers$x) assign(df.names[k+20], d.frame) despejes<- data.frame(SociedadB2, SociedadB3, SociedadB4, SociedadB5, SociedadB6, SociedadB7, SociedadB8, SociedadB9, SociedadB10) } } } despejes<- data.frame(SociedadB2, SociedadB3, SociedadB4, SociedadB5, SociedadB6, SociedadB7, SociedadB8, SociedadB9, SociedadB10) If im not wrong i should have 1000 different solutions but the data frame only save 10 results. I tried copying the last part of the code between the last two brackets (changing the name of the data frame despejes for despejes 1, 2 and 3 but i only get three data frames with exactly the same results. I dont know how could i save all the results of every combination. I mean, i need to solve for i=1, j=1 and the 9 diferent values of k and save those results, then i=1, j=2 and the 9 values of k.. I know this might be a easy question but i have not been able to find a solution in the last days. Thanks in advance if you can help me. Santiago. [[alternative HTML version deleted]] ______________________________________________ R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. [[alternative HTML version deleted]]
Berend Hasselman
2017-May-11 08:12 UTC
[R] Solve system of non linear equations using nasted loops
Your code looks needlessly complicated and inefficient in my view. Even if you don't need or use nested for loops it can still be simplified. 1: First define some new constants to avoid the the M? stuff in your function <code> pME <- ME[2:9]/ME[1] pMI <- MI[2:9]/MI[1] pMA <- MA[2:9]/MA[1] pMAE <- (MA[1]-ME[1])/(MA[2:9]-ME[2:9]) pMAI <- (MA[2:9]-MI[2:9])/(MA[1]-MI[1]) pMIA <- (MI[2:9]-MA[2:9])/(MI[1]-MA[1]) </code> 2. Redefine your function and avoid silly and unnecessary use of 1* and 2* and use a constant for log(.../...) The vector pXX is a vector consisting of elements from the vector pME etc. <code> fun <- function(x,pXX) { f <- numeric(length(x)) # read as: pME <- pXX[1] pMI <- pXX[2] pMA <- pXX[3] pMAE <- pXX[4] pMAI <- pXX[5] pMIA <- pXX[6] const <- log(0.19245009/0.384900179) f[1] <- x[3] - (log(pME)+(x[1]+x[2])*2*(log(pMAE)))/const f[2] <- x[3] - (log(pMI)-(x[2])*2*(log(pMAI)))/const f[3] <- x[3] - (log(pMA)-(x[1])*2*(log(pMIA)))/const f } </code> This can be simplified further by doing the log(pXX) beforehand. 3. I'm not going to have a go at using expand.grid. Too lazy and more involved to get everything correct. So use a nested loop as follows: - prepare a result matrix of correct dimensions with7 columns: one for nleaslv termination code, 3 for the result x-vales and another 3 to store i,j,k. - storing the termination code is a must to see if convergence was obtained. - and before invoking nleqslv test if fun(startx) contains NA values. If it does fill the appropriate row of Result with NA. - use an index counter (indx) to store the results in the rows of Result <code> Result <- matrix(0,nrow=9*9*9,ncol=7) indx <- 1 for (i in 1:9) { for (j in 1:9) { for (k in 1:9) { pXXijk <- c(pME[i],pMI[j],pMA[k],pMAE[i],pMAI[j],pMIA[k]) f.startx <- fun(startx,pXXijk) if(anyNA(f.startx)) { Result[indx,1:4] <- NA } else { z <- nleqslv(startx,fun,pXX=pXXijk) Result[indx,1:4] <- c(z$termcd,z$x) } Result[indx,5:7] <- c(i,j,k) indx <- indx+1 } } } </code> And now you can inspect Result, which contains 729 rows (and not 1000) and continue to make a data.frame with column names. The rest is up to you. Berend On 10 May 2017, at 20:20, Santiago Burone <santiago burone at icloud.com> wrote:> > Hello, > > I'm new at R and I would like to use it in order to solve a system of non linear equations. I have the code that works but im not able to save the results. > > > > My system has three equations and i would like to solve this using three nested loops, becouse i need solutions for all the values combinations. > > > > > > The code im using is this: > > > > library(nleqslv) > #x3 es gamma > #x2 es alpha > #x1 es beta > MA <- c(50000, 43600, 40000, 38800, 37600, 34400, 31600, 27200, 24400, 20000) > MI <- c(10000, 21800, 20000, 19400, 18800, 17200, 15800, 13600, 12200, 10000) > ME <- c(30000, 32700, 30000, 29100, 28200, 25800, 23700, 20400, 18300, 15000) > DE <- c(0.384900179, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009, 0.19245009) > for (i in 1:9) { > for (j in 1:9){ > for (k in 1:9){ > df.names <- paste("SociedadB",1:10,sep="") > > fun <- function(x) { > f <- numeric(length(x)) # read as: > f[1] <- 1*x[3] - (log(ME[1+i]/ME[1])+(1*x[1]+1*x[2])*(2)*(log((MA[1]-ME[1])/(MA[i+1]-ME[i+1]))))/(log(0.19245009/0.384900179)) > f[2] <- 1*x[3] - (log(MI[1+j]/MI[1])-(1*x[2])*(2)*(log((MA[1+j]-MI[1+j])/(MA[1]-MI[1]))))/(log(0.19245009/0.384900179)) > f[3] <- 1*x[3] - (log(MA[1+k]/MA[1])-(1*x[1])*(2)*(log((MI[1+k]-MA[1+k])/(MI[1]-MA[1]))))/(log(0.19245009/0.384900179)) > f > } > startx <- c(1,1,1) > answers<-as.data.frame(nleqslv(startx,fun)) > d.frame <- (answers$x) > assign(df.names[k+20], d.frame) > despejes<- data.frame(SociedadB2, SociedadB3, SociedadB4, SociedadB5, SociedadB6, SociedadB7, SociedadB8, SociedadB9, SociedadB10) > > } > } > } > > despejes<- data.frame(SociedadB2, SociedadB3, SociedadB4, SociedadB5, SociedadB6, SociedadB7, SociedadB8, SociedadB9, SociedadB10) > > > > If im not wrong i should have 1000 different solutions but the data frame only save 10 results. I tried copying the last part of the code between the last two brackets (changing the name of the data frame despejes for despejes 1, 2 and 3 but i only get three data frames with exactly the same results. I dont know how could i save all the results of every combination. I mean, i need to solve for i=1, j=1 and the 9 diferent values of k and save those results, then i=1, j=2 and the 9 values of k.. > > > > I know this might be a easy question but i have not been able to find a solution in the last days. > > > > Thanks in advance if you can help me. > > > Santiago. > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.