[R] non-linear regression and root finding
Troels Ring
tr|ng @end|ng |rom gvdnet@dk
Mon Nov 6 17:53:49 CET 2023
Dear friends - I have a function for the charge in a fluid (water)
buffered with HEPES and otherwise only containing Na and Cl so that [Na]
- [Cl] = SID (strong ion difference) goes from -1 mM to 1 mM. With known
SID and total HEPES concentration I can calculate accurately the pH if I
know 3 pK values for HEPES by finding the single root with uniroot
Now, the problem is that there is some disagreement in the literature
what is the correct value for the 3 pKs. I know the 3 pK values have the
relationship pK1 < pK2 <- pK3 and for the most common formulation of
HEPES I know the charge on fully protonated species is 2. Hence I can
generate a huge number of pK values from uniform distribution by taking
sort(runif(3,-1,9) and make sure there are no ties and then run all
those triplets of pK values to find pH values and thereby find the
lowest deviation vis a vis measured values. That works but requires many
triplets and is not satisfying. Hence I wonder if I could somehow have
non linear regression to find the 3 pK values. Below is HEPESFUNC which
delivers charge in the fluid for known pKs, HEPTOT and SID. Is it
possible to have root-finding in the formula with nls? (I know the
precision asked for is extreme but it has worked well in really many
applications).
All best wishes
Troels Ring, MD
Aalborg, Denmark
HEPESFUNC <-
function(H,SID,HEPTOT,pK1,pK2,pK3) {
XX <- (H^3/(10^-pK3*10^-pK2*10^-pK1)+H^2/(10^-pK3*10^-pK2)+H/(10^-pK3))
IV <- HEPTOT/(1+XX)
I <- IV*H^3/(10^-pK3*10^-pK2*10^-pK1)
II <- IV*H^2/(10^-pK3*10^-pK2)
III <- IV*H/10^-pK3
H - kw/H + SID + I*2 + II - IV
}
HEPTOT <- 0.050
SID <- c(-seq(10,1)*1e-4,0,seq(1,10)*1e-4)
pHobs <- c(4.63,4.68,4.72,4.77,4.83,4.9,4.96,5.04,5.12,5.21,5.3,
5.39,5.48,5.55,5.63,5.69,5.74,5.8,5.85,5.89,5.93)
pK1 <- -1; pK2 <- 3; pK3 <- 7.55 # literature values
pK3 <- 7.6; pK2 <- 2.96 # values eye-balled to be better
pH <- c()
for (i in 1:length(SID)) {
pH[i] <- -log10(uniroot(HEPESFUNC,c(1e-20,1),tol=1e-20,maxiter=1e4,
HEPTOT=HEPTOT,SID = SID[i],
pK1=pK1,pK2=pK2,pK3=pK3)$root)
}
plot(SID,pH)
points(SID,pHobs,col="red")
More information about the R-help
mailing list