** Find the Phi_p optimal design for LINEXP model: eta(x,theta)=theta1+theta2*exp(theta3*x)+theta4*x; ** A quasi-Newton algorithm using BFGS update is implemented to find the critical point, which gives the optimal design; ** You need to change the fisher information function and settings about the parameters, design boundary, etc, to accommodate other models in the paper; proc iml; ** p=0 meand D-optimality, p=1 means A-optimality; p=1; ** WB is the matrix of interested parameters; WB=i(4); ** theta is the value of parameter; theta={1 0.5 -1 1}; ** space is the design space; space={0 1}; ** x1 and x4 are fixed design points, by complete class result; x1=space[1]; x4=space[2]; ** find z=(x2,x3,w2,w3,w4) to minimize the variance-covariance matrix, z0 is the starting point for the search; z0={0.1,0.2,0.3,0.3,0.2}; ** lb, ub are the lower bound, upper bound for z, respectively; lb={0,0,0,0,0}; ub={1,1,1,1,1}; ** z is under the constraint of constr_A*z0.000000001*grad0`*grad0) ); delta=-invhess*grad; newz=z+delta; ** adjust the step so that newz is within the bounds and constraint is satisfied; do while ( (any(newz-lb<0) | any(newz-ub>0) | constr_A*newz>1 ) ); delta=delta/2; newz=z+delta; end; delta=delta/2; newz=z+delta; diff=phi_value(p,newz,theta,wb)-phi_value(p,z,theta,wb); ** further adjust the step so that we don't overstep; do while ( diff>0.001*grad`*delta ); delta=delta/2; newz=z+delta; diff=phi_value(p,newz,theta,wb)-phi_value(p,z,theta,wb); end; ** update; old_grad=grad; z=newz ; grad=gradient(p,z,theta,wb); gamma=grad-old_grad; ** BFGS estimate of the inverse hessian; if (delta`*gamma>0) then do; c1=delta`*gamma; c2=(1+gamma`*invhess*gamma/c1)/c1; dd=delta*delta`; dg=delta*gamma`; gd=gamma*delta`; M=c2*dd-(dg*invhess+invhess*gd)/c1; invhess=invhess+M; end; else invhess=i(nvar); iter=iter+1; end; print iter; return (z); finish; ** Now everything is defined, and we can call QNewton_BFGS function to find the critical point; crit_pt=QNewton_BFGS(p,z0,theta,wb,lb, ub,constr_A,constr_b,max_iter); value=phi_value(p,crit_pt,theta,wb); print crit_pt value; quit;