Nothing
#::::::::::
# drkl
#::::::::::
subroutine drkl (cd, nxis, qdrs, nqd, nt, bwt, qdwt, wt0, mchpr, prec, maxiter,
jpvt, wk, info)
integer nxis, nqd, nt, maxiter, jpvt(*), info
double precision cd(*), qdrs(nqd,*), bwt(*), qdwt(nt,*), wt0(*), mchpr, prec, wk(*)
integer imrs, iwt, iwtsum, imu, imuwk, iv, ivwk, icdnew, iwtnew, iwtnewsum
imrs = 1
iwt = imrs + nxis
iwtsum = iwt + nt*nqd
imu = iwtsum + nt
imuwk = imu + nxis
iv = imuwk + nxis
ivwk = iv + nxis*nxis
icdnew = ivwk + nxis*nxis
iwtnew = icdnew + nxis
iwtnewsum = iwtnew + nt*nqd
call drkl1 (cd, nxis, qdrs, nqd, nt, bwt, qdwt, wt0, mchpr, prec, maxiter,
wk(imrs), wk(iwt), wk(iwtsum), wk(imu), wk(imuwk), wk(iv), wk(ivwk),
jpvt, wk(icdnew), wk(iwtnew), wk(iwtnewsum), info)
return
end
#::::::::::
# drkl1
#::::::::::
subroutine drkl1 (cd, nxis, qdrs, nqd, nt, bwt, qdwt, wt0, mchpr, prec, maxiter,
mrs, wt, wtsum, mu, muwk, v, vwk, jpvt, cdnew, wtnew, wtnewsum,
info)
integer nxis, nqd, nt, maxiter, jpvt(*), info
double precision cd(*), qdrs(nqd,*), bwt(*), qdwt(nt,*), wt0(*), mchpr, mrs(*),
wt(nt,*), wtsum(*), mu(*), muwk(*), v(nxis,*), vwk(nxis,*),
cdnew(*), wtnew(nt,*), wtnewsum(*), prec
integer i, j, k, m, iter, flag, idamax, infowk
double precision tmp, ddot, rkl, rklnew, mumax, disc
# Initialization
info = 0
call dset (nxis, 0.d0, mrs, 1)
for (m=1;m<=nt;m=m+1) {
for (i=1;i<=nqd;i=i+1) wt(m,i) = qdwt(m,i) * wt0(i)
for (i=1;i<=nxis;i=i+1) muwk(i) = ddot (nqd, qdrs(1,i), 1, wt(m,1), nt)
call daxpy (nxis, bwt(m), muwk, 1, mrs, 1)
wtsum(m) = 0.d0
}
for (i=1;i<=nqd;i=i+1) {
tmp = dexp (ddot (nxis, qdrs(i,1), nqd, cd, 1))
for (m=1;m<=nt;m=m+1) {
wt(m,i) = qdwt(m,i) * tmp
wtsum(m) = wtsum(m) + wt(m,i)
}
}
rkl = 0.d0
for (m=1;m<=nt;m=m+1) {
tmp = 0.d0
for (i=1;i<=nqd;i=i+1) {
disc = wt0(i) * qdwt(m,i)
tmp = tmp + dlog (disc/wt(m,i)) * disc
}
rkl = rkl + bwt(m) * (tmp + dlog (wtsum(m)))
}
iter = 0
flag = 0
# Iteration
repeat {
iter = iter + 1
# Calculate hessian and gradient
call dset(nxis, 0.d0, mu, 1)
call dset(nxis*nxis, 0.d0, v, 1)
for (m=1;m<=nt;m=m+1) {
for (i=1;i<=nxis;i=i+1)
muwk(i) = - ddot (nqd, wt(m,1), nt, qdrs(1,i), 1) / wtsum(m)
for (i=1;i<=nxis;i=i+1) {
for (j=i;j<=nxis;j=j+1) {
vwk(i,j) = 0.d0
for (k=1;k<=nqd;k=k+1)
vwk(i,j) = vwk(i,j) + wt(m,k) * qdrs(k,i) * qdrs(k,j)
vwk(i,j) = vwk(i,j) / wtsum(m) - muwk(i) * muwk(j)
}
}
call daxpy (nxis, bwt(m), muwk, 1, mu, 1)
call daxpy (nxis*nxis, bwt(m), vwk, 1, v, 1)
}
call daxpy (nxis, 1.d0, mrs, 1, mu, 1)
mumax = dabs(mu(idamax(nxis, mu, 1)))
# Cholesky factorization
for (i=1;i<=nxis;i=i+1) jpvt(i) = 0
call dmcdc (v, nxis, nxis, muwk, jpvt, infowk)
# Update coefficients
repeat {
call dcopy (nxis, mu, 1, cdnew, 1)
call dprmut (cdnew, nxis, jpvt, 0)
call dtrsl (v, nxis, nxis, cdnew, 11, infowk)
call dtrsl (v, nxis, nxis, cdnew, 01, infowk)
call dprmut (cdnew, nxis, jpvt, 1)
call daxpy (nxis, 1.d0, cd, 1, cdnew, 1)
call dset (nt, 0.d0, wtnewsum, 1)
for (i=1;i<=nqd;i=i+1) {
tmp = ddot (nxis, qdrs(i,1), nqd, cdnew, 1)
if (tmp>3.d2) {
flag = flag + 1
break
}
for (m=1;m<=nt;m=m+1) {
wtnew(m,i) = qdwt(m,i) * dexp (tmp)
wtnewsum(m) = wtnewsum(m) + wtnew(m,i)
}
}
rklnew = 0.d0
for (m=1;m<=nt;m=m+1) {
tmp = 0.d0
for (i=1;i<=nqd;i=i+1) {
disc = wt0(i) * qdwt(m,i)
tmp = tmp + dlog (disc/wtnew(m,i)) * disc
}
rklnew = rklnew + bwt(m) * (tmp + dlog (wtnewsum(m)))
}
if (flag==1) {
# Reset iteration with uniform starting value
call dset (nxis, 0.d0, cd, 1)
call dcopy (nt*nqd, qdwt, 1, wt, 1)
call dset (nt, 0.d0, wtsum, 1)
for (m=1;m<=nt;m=m+1) {
for (i=1;i<=nqd;i=i+1) wtsum(m) = wtsum(m) + wt(m,i)
}
rkl = 0.d0
for (m=1;m<=nt;m=m+1) {
tmp = 0.d0
for (i=1;i<=nqd;i=i+1)
tmp = tmp + dlog (wt0(i)) * wt0(i) * qdwt(m,i)
rkl = rkl + bwt(m) * (tmp + dlog (wtsum(m)))
}
iter = 0
break
}
if (rklnew-rkl<1.d1*(1.d0+dabs(rkl))*mchpr) break
call dscal (nxis, .5d0, mu, 1)
if (dabs(mu(idamax(nxis, mu, 1))/mumax)<1.d1*mchpr) break
}
if (flag==1) {
flag = 2
next
}
if (flag==3) {
info = 1
return
}
# Calculate convergence criterion
disc = 0.d0
for (i=1;i<=nqd;i=i+1){
for (m=1;m<=nt;m=m+1)
disc = dmax1 (disc, dabs(wt(m,i)-wtnew(m,i))/(1.d0+dabs(wt(m,i))))
}
disc = dmax1 (disc, (mumax/(1.d0+rkl))**2)
disc = dmax1 (disc, dabs(rkl-rklnew)/(1.d0+dabs(rkl)))
# Check convergence
if (disc<prec) break
# Set to new values
call dcopy (nxis, cdnew, 1, cd, 1)
call dcopy (nt*nqd, wtnew, 1, wt, 1)
call dcopy (nt, wtnewsum, 1, wtsum, 1)
rkl = rklnew
if (iter<maxiter) next
if (flag==0) {
# Reset iteration with uniform starting value
call dset (nxis, 0.d0, cd, 1)
call dcopy (nt*nqd, qdwt, 1, wt, 1)
call dset (nt, 0.d0, wtsum, 1)
for (m=1;m<=nt;m=m+1) {
for (i=1;i<=nqd;i=i+1) wtsum(m) = wtsum(m) + wt(m,i)
}
rkl = 0.d0
for (m=1;m<=nt;m=m+1) {
tmp = 0.d0
for (i=1;i<=nqd;i=i+1)
tmp = tmp + dlog (wt0(i)) * wt0(i) * qdwt(m,i)
rkl = rkl + bwt(m) * (tmp + dlog (wtsum(m)))
}
iter = 0
flag = 2
}
else {
info = 2
break
}
}
# return projection density on the mesh
for (i=1;i<=nqd;i=i+1) wt0(i) = dexp (ddot (nxis, qdrs(i,1), nqd, cd, 1))
return
end
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.