I figured that the error messages that one gets using solnp
mostly refer to inadequate constrains. Also, as it is stated in the documentation, it is required to put all the parameters in one vector. After appropriate adjustments to the code, I was able to implement my constrains of y(t)_c > y(t)_b > y(t)_a > 0
directly, without any need for altering the problem. The most convenient way is to use matrix formation for the solver.
Using the data above, I've got the following:
Results shown here
library(data.table)
library(Rsolnp)
t<-as.vector(10:20)
DT<-cbind.data.frame(A,B,C)
tlogDT<-transpose(log(DT))
# min[log(y)'- Ax-b]
# Arr = [A1 A2 .. An b1 b2 .. bn]
gofn = function(arrin)
{
arr = cbind(arrin[1:3],arrin[4:6])
sum(
(as.matrix(arr[,1])%*%t + arr[,2] - tlogDT)^2
)
}
nocross=t #defines the times where the curves are not allowed to intersect
ineqfn2=function(arrin)
{
#constrains:
# 0<f_a(t)<f_b(t)<f_c(t), for some t,
arr = cbind(arrin[1:3],arrin[4:6])
nextarr=as.matrix(rbind(rep(0,2),arr[1:(length(arr[,1])-1),]))
ineqmat=as.matrix(arr[,1])%*%nocross+arr[,2]-nextarr[,1]%*%nocross-nextarr[,2]
as.vector(t(ineqmat))
}
#lines should be aligned with the first startvalue
eqfn = function(arrin)
{
arr = cbind(arrin[1:3],arrin[4:6])
arr[,1]*t[1]+arr[,2]-tlogDT[,1]
}
#start values:
An=c(1,1,1)
bn=tlogDT[,1]
vstart=c(An,bn)
r <- solnp(
vstart, gofn,
eqfun = eqfn, eqB= c(0,0,0),
ineqfun = ineqfn2,
ineqLB = rep(0,length(DT[1,])*length(nocross)),
ineqUB = rep(5000,length(DT[1,])*length(nocross))
)
r$pars[1]
line1 = exp(r$pars[4]+r$pars[1]*t)
line2 = exp(r$pars[5]+r$pars[2]*t)
line3 = exp(r$pars[6]+r$pars[3]*t)
plot(t, DT[,3],log = "y")
points(t, DT[,2],col="green")
points(t, DT[,1],col="blue")
lines(t, line1,lwd=2, col = "blue", xlab = "Time (s)", ylab = "Counts")
lines(t, line2,lwd=2, col = "green", xlab = "Time (s)", ylab = "Counts")
lines(t, line3,lwd=2, col = "black", xlab = "Time (s)", ylab = "Counts")