[R] Fit NLE - was: computer algebra in R

Ivan Krylov kry|ov@r00t @end|ng |rom gm@||@com
Sun Dec 10 09:59:48 CET 2023


В Fri, 8 Dec 2023 08:21:16 +0100
Konrad via R-help <r-help using r-project.org> пишет:

> My problem is how to replicate the Eliminate function in R.

While R does invite the user to "compute on the language", i.e. take R
expressions and function calls and work with them as with ordinary
variables [*], so far nobody wrote a complete computer algebra system in
R. Interfaces for other CASes do exist, but I haven't tried them.

> Or is it possible to solely solve the system numerically?

While it's less efficient to do so, it must be possible. For example,
the https://CRAN.R-project.org/package=nleqslv package does exactly
that.

> h0 = h + hd + hg,
> d0 = d + hd,
> ga0 = ga + hg,
> kga = hg/(h*ga),
> kd = hd/(h*d)
 
> The aim is to fit a non-linear equation in the form: signal ~ I0 +
> IHD * hd + ID * d.

> The parameters which should be identified/optimized are: I0, ID, IHD
> and kd. However, the only information known is kga (33600.0), h0 
> (0.0000208), d0 (0.000079) and the guest concentration (= ga0).

This doesn't quite agree with

> 0 = h + hd + hga,
> 33600. = d + hd,
> 0.000079 = hga/(ga*h),

...that you gave to Mathematica. Is it d0 = d + hd or kga = 33600. = d +
hd? kga = hg/(h*ga) or d0 = 0.000079 = hga/(ga*h)? What other equations
are missing?

The general approach is to take all the equations and write them down
as a vector of expressions that should be evaluate to 0 at solution,
then substitute() in the values of the constants and x[i] for
sequential values of `i` for variables:

fn <- function(x) NULL
body(fn) <- substitute(
 c( # equations go here
  h0  - h + hd + hg,
  d0  - d + hd,
  ga0 - ga + hg,
  kga - hg/(h*ga),
  kd  - hd/(h*d),
  # ...more equations...
  signal - I0 + IHD * hd + ID * d
 ),
 list(
  # knowns
  kga = 33600.0,
  h0 = 0.0000208,
  d0 = 0.000079,
  # assuming two more knowns live in same-named variables
  ga0 = ga0,
  signal = signal,
  # variables named so far
  I0 = quote(x[1]), ID = quote(x[2]),
  IHD = quote(x[3]), kd = quote(x[4])
  # ...more variables...
 )
)

The resulting function fn() takes a vector of variables and should
return a vector of zeroes at the solution. Try to solve it using
nleqslv::nleqslv(starting_guess, fn) or some of the functions from the
BB package.

-- 
Best regards,
Ivan

[*] For example, see this R package automatically differentiate
expressions when solving nonlinear least squares problems:
https://cran.r-project.org/package=nlsr/vignettes/nlsr-derivs.pdf



More information about the R-help mailing list