Here's my solution adapted from work I've done in the past. method = "BFGS"
generally works best for me.
library(tidyverse)
# model
my_model <- function(p, x) {
y <- p["A"] * x^2 + p["B"] * x + p["C"] + p["D"] / x # just the numerator
return(y)
}
# real values
p <- c(A = 1, B = 2, C = 3, D = 4)
# simulated data
# make x order 1 otherwise some model terms will dominate
my_data <- tibble(
x = seq(0.5, 1.5, .001),
y = my_model(p, x) # + 0.01 + runif(length(x))
)
with(my_data, qplot(x, y))

# objective fn
calc_obj <- function(p, model, df) {
resid <- model(p, df$x) - df$y
return(sqrt(sum(resid^2)))
}
# initial guess
p0 <- c(A = 1.1, B = 2.2, C = 3.3, D = 4.4)
# try to recover the real values through nonlinear opt
soln <- optim(
par = p0,
fn = calc_obj,
method = "BFGS",
control = list(trace = 5, REPORT = TRUE),
model = my_model,
df = my_data
)
#> initial value 33.193450
#> iter 2 value 5.247466
#> iter 3 value 4.227183
#> iter 4 value 1.328340
#> iter 5 value 0.789765
#> iter 6 value 0.344899
#> iter 7 value 0.155544
#> iter 8 value 0.109454
#> iter 9 value 0.084487
#> iter 10 value 0.040555
#> iter 11 value 0.035276
#> iter 12 value 0.017175
#> iter 13 value 0.007212
#> iter 14 value 0.006679
#> iter 15 value 0.006320
#> iter 16 value 0.005695
#> iter 17 value 0.005051
#> iter 17 value 0.005051
#> iter 18 value 0.004443
#> iter 19 value 0.004018
#> iter 20 value 0.002721
#> iter 21 value 0.002691
#> iter 21 value 0.002691
#> iter 22 value 0.002289
#> iter 23 value 0.002194
#> iter 24 value 0.001797
#> iter 24 value 0.001797
#> iter 25 value 0.001328
#> iter 26 value 0.001268
#> iter 27 value 0.001174
#> iter 28 value 0.001153
#> iter 29 value 0.001147
#> iter 30 value 0.001145
#> iter 31 value 0.001145
#> iter 32 value 0.001145
#> iter 33 value 0.001145
#> iter 34 value 0.000906
#> iter 35 value 0.000877
#> iter 35 value 0.000877
#> iter 36 value 0.000766
#> iter 37 value 0.000746
#> iter 38 value 0.000688
#> iter 38 value 0.000688
#> iter 39 value 0.000637
#> iter 40 value 0.000637
#> iter 40 value 0.000637
#> iter 41 value 0.000615
#> iter 42 value 0.000615
#> iter 43 value 0.000598
#> iter 44 value 0.000598
#> iter 45 value 0.000597
#> iter 45 value 0.000597
#> iter 46 value 0.000591
#> iter 47 value 0.000585
#> iter 48 value 0.000580
#> iter 49 value 0.000577
#> iter 49 value 0.000577
#> iter 50 value 0.000574
#> iter 51 value 0.000569
#> iter 52 value 0.000569
#> iter 53 value 0.000569
#> iter 53 value 0.000569
#> iter 54 value 0.000566
#> iter 55 value 0.000563
#> iter 56 value 0.000546
#> iter 57 value 0.000546
#> iter 58 value 0.000546
#> iter 58 value 0.000546
#> iter 59 value 0.000540
#> iter 60 value 0.000537
#> iter 61 value 0.000534
#> iter 62 value 0.000533
#> iter 62 value 0.000533
#> iter 63 value 0.000511
#> iter 64 value 0.000511
#> iter 65 value 0.000510
#> iter 66 value 0.000509
#> iter 67 value 0.000509
#> iter 68 value 0.000509
#> iter 69 value 0.000509
#> iter 69 value 0.000509
#> iter 70 value 0.000507
#> iter 71 value 0.000503
#> iter 72 value 0.000502
#> iter 73 value 0.000502
#> iter 74 value 0.000502
#> iter 75 value 0.000502
#> iter 76 value 0.000502
#> iter 76 value 0.000502
#> iter 77 value 0.000496
#> iter 78 value 0.000496
#> iter 79 value 0.000492
#> iter 79 value 0.000492
#> iter 80 value 0.000488
#> iter 81 value 0.000481
#> iter 82 value 0.000479
#> iter 83 value 0.000476
#> iter 84 value 0.000475
#> iter 84 value 0.000475
#> iter 85 value 0.000472
#> iter 86 value 0.000468
#> iter 87 value 0.000468
#> iter 88 value 0.000467
#> iter 88 value 0.000467
#> iter 89 value 0.000458
#> iter 90 value 0.000449
#> iter 91 value 0.000443
#> iter 92 value 0.000436
#> iter 92 value 0.000436
#> iter 93 value 0.000434
#> iter 94 value 0.000430
#> iter 95 value 0.000424
#> iter 96 value 0.000424
#> iter 96 value 0.000424
#> iter 97 value 0.000421
#> iter 98 value 0.000416
#> iter 99 value 0.000415
#> iter 100 value 0.000413
#> final value 0.000413
#> stopped after 100 iterations
# results
tibble(
name = names(p),
true_value = p,
guess = p0,
solution = soln$par
) %>%
print()
#> # A tibble: 4 x 4
#> name true_value guess solution
#> <chr> <dbl> <dbl> <dbl>
#> 1 A 1 1.1 0.999
#> 2 B 2 2.2 2.00
#> 3 C 3 3.3 3.00
#> 4 D 4 4.4 4.00
Created on 2022-01-28 by the reprex package (v2.0.1)