# Other Nonlinear Model Fitting Algorithms

Author

Derek H. Ogle

The von Bertalanffy Growth Function (VBGF) was introduced and methods for fitting the function were illustrated in Chapter 12 of Ogle (2016). The nls() function demonstrated in Ogle (2016) uses the Gauss-Newton algorithm by default. However, there are many other algorithms for fitting nonlinear functions. Two of the several algorithms coded in R are demonstrated in this supplement.

# Setup

## Packages

Functions used in this supplement require the following packages.

library(FSA)        # for headtail(), vbFuns(), vbStarts()
library(dplyr)      # for select(), filter()
library(nlstools)   # for nlsBoot()
library(minpack.lm) # for nlsLM()

## Data

The male Black Drum data.1 used in Ogle (2016) are also used in this supplement. As in Ogle (2016) a few unneeded variables are removed for simplicity, only males are examined, and a single old fish is removed by retaining only fish with an otolith age less than 50.

• bdm <- read.csv("https://raw.githubusercontent.com/fishR-Core-Team/FSAdata/main/data-raw/BlackDrum2001.csv") |>
select(-c(spname,day,weight)) |>
filter(sex=="male",otoage<50)
headtail(bdm)
#R|     year agid month     tl  sex otoage
#R|  1  2001    1     4  787.5 male      6
#R|  2  2001    2     5  700.0 male      5
#R|  3  2001    8     5 1140.0 male     23
#R|  72 2001  122     5 1175.0 male     39
#R|  73 2001  125     6  590.0 male      4
#R|  74 2001  127     6  530.0 male      3

# Levenberg-Marquardt Algorithm

The Levenberg-Marquardt (L-M) algorithm is a powerful and common method that switches between two other algorithms depending on when those algorithms perform most optimally . Most practically, the L-M algorithm appears to be quite robust to “poor” starting values.

The L-M algorithm is implemented in nlsLM() from minpack.lm and uses the same main arguments as nls(). For example, the “Typical” VBGF is fit (and parameter estimates, bootstrapped confidence intervals, and predictions are extracted) to the male Black Drum data below using the L-M algorithm.2

• 2 This code is the same as used in Ogle (2016), except that nlsLM() replaced nls().

• vbTyp <- vbFuns()
svTyp <- list(Linf=1193,K=0.13,t0=-2.0)
fitLM <- nlsLM(tl~vbTyp(otoage,Linf,K,t0),data=bdm,start=svTyp)
bootLM <- nlsBoot(fitLM)
cbind(Ests=coef(fitLM),confint(bootLM))
#R|               Ests      95% LCI      95% UCI
#R|  Linf 1196.7193453 1180.7583403 1215.3277659
#R|  K       0.1418266    0.1245746    0.1614129
#R|  t0     -1.5943403   -2.4861941   -0.8246865
predict(bootLM,vbTyp,t=3)
#R|       t   Median  95% LCI  95% UCI
#R|  [1,] 3 573.6826 534.7676 608.3075

# Using Parameter Constraints

In some instances, the user may want to constrain the model fitting algorithms to only consider parameter values within a certain range. For example, the user may want to constrain the $$L_{\infty}$$ and $$K$$ parameters of the “Typical” VBGF to be positive.

Warning

Parameter constraints may substantively effect the results of the model fitting. Thus, they should be used rarely and, when used, set liberally.

Parameter constraints can be used with at least two algorithms in R. In either case, the lower and upper bounds for each parameter are entered into separate named vectors in the same order as the list used for starting values. Infinite bounds are the default ,but may be specifically defined for some parameters with Inf and -Inf (where Inf represents infinity). For example, vectors that define constraints for the parameters in the “Typical” VBGF are defined below, with $$L_\infty$$ and $$K$$ constrained to be positive values and $$t_{0}$$ left unconstrained.

clwr <- c(Linf=1,  K=0.0001,t0=-Inf)
cupr <- c(Linf=Inf,K=Inf,   t0=Inf)

These constraints may be provided to lower= and upper=, respectively, of nlsLM(). In this instance, these bounds had no noticeable effect until bootstapping, where there were fewer instances of lack of convergence.

fitLM1 <- nlsLM(tl~vbTyp(otoage,Linf,K,t0),data=bdm,start=svTyp,
lower=clwr,upper=cupr)
bootLM1 <- nlsBoot(fitLM1)
cbind(Ests=coef(fitLM1),confint(bootLM1))
#R|               Ests      95% LCI      95% UCI
#R|  Linf 1196.7193453 1180.4433085 1214.9203900
#R|  K       0.1418266    0.1228016    0.1619365
#R|  t0     -1.5943403   -2.5765079   -0.8162231

Parameter constraints may be used similarly with nls(), but the “Port” optimization algorithm must be used with algorithm="port".

fitP <- nls(tl~vbTyp(otoage,Linf,K,t0),data=bdm,start=svTyp,
algorithm="port",lower=clwr,upper=cupr)
bootP <- nlsBoot(fitP)
cbind(Ests=coef(fitP),confint(bootP))
#R|               Ests      95% LCI      95% UCI
#R|  Linf 1196.7188171 1178.3021069 1216.2244935
#R|  K       0.1418273    0.1230324    0.1629955
#R|  t0     -1.5943092   -2.5654540   -0.7327735

# Other Algorithms

Still other algorithms are found in nlxb() from nlmrt and nls2() from nls2 .

## References

Elzhov, T. V., K. M. Mullen, A.-N. Spiess, and B. M. Bolker. 2013. Minpack.lm: R Interface to the Levenberg-Marquardt Nonlinear Least-Squares Algorithm Found in MINPACK, Plus Support for Bounds.
Grothendieck, G. 2013. nls2: Non-Linear Regression with Brute Force.
Motulsky, H. J., and L. A. Ransnas. 1987. Fitting curves to data using nonlinear regression: A practical and nonmathematical review. The Federation of American Societies for Experimental Biology Journal 1:365–374.
Nash, J. C. 2014. Nlmrt: Functions for Nonlinear Least Squares Solutions.
Ogle, D. H. 2016. Introductory Fisheries Analyses with R. CRC Press, Boca Raton, FL.