*! version 2.3 11Nov2018 /* Notes: PS changed to mdl: indicates the variables in the model, but we can treat mdl as 1 variable. Changed stpm2cr_main to stpm2cr_state */ //clear all version 14.1 /* Label variable types */ local structName string scalar local delayedEntry real scalar local numObs real scalar local numCauses real scalar local causeList real scalar local firstDerivCols real scalar local deathIndicator real matrix mata: mata clear struct stpm2cr_state { // Define the structure/box which we may need in the likelihood function real colvector t, t0, d real matrix xb, dxb, expxb, ht, st, ft, Ft, xb0, expxb0, Ft0, prod `numCauses' nCauses `causeList' cList `delayedEntry' delentry `numObs' nObs `deathIndicator' di, D `firstDerivCols' ScoreCols } void stpm2cr_setup(`structName' temp) // this is the setup function to create the global struct stpm2cr_state { struct stpm2cr_state scalar mdl pointer scalar p // memory address rmexternal(temp) p = crexternal(temp) touse = st_local("touse_obs") scale = st_local("scale") mdl.delentry = strtoreal(st_local("del_entry")) mdl.nObs = strtoreal(st_local("nobs")) mdl.nCauses = strtoreal(st_local("nCauses")) mdl.ScoreCols = 2:*(mdl.nCauses) :+ ((mdl.delentry:==1):*(mdl.nCauses)) mdl.cList = strtoreal(tokens(st_local("causelist"))) // data mdl.d = st_data(.,"_d",touse) mdl.t = st_data(.,"_t",touse) if (mdl.delentry) mdl.t0 = st_data(.,"_t0",touse) mdl.D = st_data(.,"i._status",touse) //mdl.di = J(mdl.nObs,mdl.nCauses,0) //"p1" //mdl.di = mdl.di + mdl.D[,2::mdl.nCauses+1] // death indicator for each of the causes mdl.di = mdl.D[,2::mdl.nCauses+1] //"p2" // equations mdl.xb = J(mdl.nObs,mdl.nCauses,.) // nObs rows, ncauses column of missing values (.) mdl.dxb = J(mdl.nObs,mdl.nCauses,.) mdl.ft = J(mdl.nObs,mdl.nCauses,.) if(scale=="hazard" | scale=="odds") { mdl.expxb = J(mdl.nObs,mdl.nCauses,.) if (mdl.delentry) { mdl.xb0 = mdl.expxb0 = J(mdl.nObs,mdl.nCauses,.) mdl.Ft0 = J(mdl.nObs,mdl.nCauses,0) } } if(scale=="hazard") { mdl.st = J(mdl.nObs,mdl.nCauses,.) mdl.ht = J(mdl.nObs,mdl.nCauses,.) mdl.Ft = J(mdl.nObs,mdl.nCauses,.) mdl.prod = J(mdl.nObs,mdl.nCauses,.) } if(scale=="odds") { mdl.Ft = J(mdl.nObs,mdl.nCauses,.) } //Done swap((*p), mdl) } /* Hazard scale */ void stpm2cr_ml_hazard(transmorphic scalar M, real scalar todo, real rowvector b, real colvector lnfj, real matrix S, real matrix H) { pointer(struct stpm2cr_state scalar) scalar mdl mdl = &moptimize_util_userinfo(M,1) for (j=1; j<=cols((*mdl).xb); j++) { mdl-> xb[,j] = moptimize_util_xb(M,b,j) k = j :+ (*mdl).nCauses mdl-> dxb[,j] = moptimize_util_xb(M,b,k) } if ((*mdl).delentry) { sumFt0 = J((*mdl).nObs,1,1) delent = J((*mdl).nObs,1,0) for (j=1; j<=cols((*mdl).xb); j++) { l = (((*mdl).nCauses) :* 2) :+ j mdl-> xb0[,j] = moptimize_util_xb(M,b,l) mdl-> Ft0[,j] = ((*mdl).t0:>0) :* (1 :- exp(-exp((*mdl).xb0[,j]))) sumFt0 = sumFt0 :- (*mdl).Ft0[,j] } delent = ln(sumFt0) } mdl-> expxb = exp((*mdl).xb) denSum = J((*mdl).nObs,1,0) sumFt = J((*mdl).nObs,1,1) for (j=1; j<=cols((*mdl).xb); j++) { mdl-> ht[,j] = (*mdl).dxb[,j] :* (*mdl).expxb[,j] mdl-> st[,j] = exp(-exp((*mdl).xb[,j])) mdl-> Ft[,j] = 1 :- exp(-exp((*mdl).xb[,j])) mdl-> ft[,j] = (*mdl).ht[,j] :* (*mdl).st[,j] mdl-> prod[,j] = (*mdl).expxb[,j]:*(*mdl).st[,j] sumFt = sumFt :- (*mdl).Ft[,j] denSum = denSum :+ ((*mdl).di[,j] :* ln((*mdl).ft[,j])) } lnfj = denSum :+ ((1 :- (*mdl).d) :* ln(sumFt)) if ((*mdl).delentry) { lnfj = lnfj :- delent } if (todo==0) return S = J((*mdl).nObs,(*mdl).ScoreCols,.) for (j=1; j<=cols((*mdl).xb); j++) { S[,j] = (*mdl).di[,j]:*(1 :- (*mdl).expxb[,j]) :- (1 :- (*mdl).d):*(((*mdl).expxb[,j] :* (*mdl).st[,j])) :/ (sumFt) k = j :+ (*mdl).nCauses S[,k] = (*mdl).di[,j]:/(*mdl).dxb[,j] } if ((*mdl).delentry) { for (j=1; j<=cols((*mdl).xb); j++) { l = (((*mdl).nCauses) :* 2) :+ j S[,l] = ((*mdl).t0:>0):*((exp((*mdl).xb0[,j]):*exp(-exp((*mdl).xb0[,j]))) :/ sumFt0) } } if (todo==1) return for (j=1; j<=cols((*mdl).xb); j++) { k = j :+ (*mdl).nCauses H[|moptimize_util_eq_indices(M, j, j)|] = moptimize_util_matsum(M,j,j,-1:*(*mdl).di[,j]:*((*mdl).expxb[,j]) :- ( ((1 :- (*mdl).d):*(*mdl).expxb[,j]:*(*mdl).st[,j]) :/ (sumFt) ) :+ ( ((1 :- (*mdl).d):*((*mdl).expxb[,j]:^2):*(*mdl).st[,j]) :/ (sumFt) ) :- ( (((1 :- (*mdl).d):*((*mdl).expxb[,j]:^2):*((*mdl).st[,j]):^2)) :/ ((sumFt):^2) ),lnfj[1]) H[|moptimize_util_eq_indices(M, k, k)|] = moptimize_util_matsum(M,k,k,-1:*((*mdl).di[,j] :/ ((*mdl).dxb[,j]):^2),lnfj[1]) } if ((*mdl).delentry) { for (k=(*mdl).nCauses:+1; k<=2:*(*mdl).nCauses; k++) { for (j=1; j<=(*mdl).ScoreCols; j++) { if(k != j) { H[|moptimize_util_eq_indices(M, k, j)|] = moptimize_util_matsum(M,k,j,0,lnfj[1]) } } } for (k=(2:*(*mdl).nCauses):+1; k<=(*mdl).ScoreCols; k++) { for (j=1; j<=2:*(*mdl).nCauses; j++) { H[|moptimize_util_eq_indices(M, k, j)|] = moptimize_util_matsum(M,k,j,0,lnfj[1]) } } l = (*mdl).nCauses:*2 for (k=1; k<=(*mdl).nCauses; k++) { l = l :+ 1 H[|moptimize_util_eq_indices(M, l, l)|] = moptimize_util_matsum(M,l,l,((*mdl).t0:>0) :* ((exp((*mdl).xb0[,k]):*exp(-exp((*mdl).xb0[,k])):* ( sumFt0 :* (1:-exp((*mdl).xb0[,k])):+exp((*mdl).xb0[,k]):*exp(-exp((*mdl).xb0[,k])) )) :/ (sumFt0):^2 ) ,lnfj[1]) } for (i=(2:*(*mdl).nCauses):+1; i<=(*mdl).ScoreCols; i++) { c1 = i :- (*mdl).nCauses:*2 for (j=(2:*(*mdl).nCauses):+1; j<=(*mdl).ScoreCols; j++) { c2 = j :- (*mdl).nCauses:*2 if(i != j) { H[|moptimize_util_eq_indices(M, i, j)|] = moptimize_util_matsum(M,i,j,((*mdl).t0:>0):*((exp((*mdl).xb0[,c1]):*exp(-exp((*mdl).xb0[,c1])):*exp((*mdl).xb0[,c2]):*exp(-exp((*mdl).xb0[,c2]))):/(sumFt0):^2),lnfj[1]) } } } } else { for (k=(*mdl).nCauses; k<=2:*(*mdl).nCauses; k++) { for (j=1; j<=2:*(*mdl).nCauses; j++) { if(k != j) { H[|moptimize_util_eq_indices(M, k, j)|] = moptimize_util_matsum(M,k,j,0,lnfj[1]) } } } } for (i=1; i<=(*mdl).nCauses; i++) { for (j=1; j<=(*mdl).ScoreCols; j++) { if((i != j) & j <= (*mdl).nCauses) { H[|moptimize_util_eq_indices(M, i, j)|] = moptimize_util_matsum(M,i,j,-1:*( ((1 :- (*mdl).d):*(*mdl).prod[,i]:*(*mdl).prod[,j]) :/ ((sumFt):^2) ),lnfj[1]) } if((i != j) & j > (*mdl).nCauses) { H[|moptimize_util_eq_indices(M, i, j)|] = moptimize_util_matsum(M,i,j,0,lnfj[1]) } } } } /* Odds scale */ void stpm2cr_ml_odds(transmorphic scalar M, real scalar todo, real rowvector b, real colvector lnfj, real matrix S, real matrix H) { pointer(struct stpm2cr_state scalar) scalar mdl mdl = &moptimize_util_userinfo(M,1) for (j=1; j<=cols((*mdl).xb); j++) { mdl-> xb[,j] = moptimize_util_xb(M,b,j) k = j + (*mdl).nCauses mdl-> dxb[,j] = moptimize_util_xb(M,b,k) } mdl-> expxb = exp((*mdl).xb) denSum = J((*mdl).nObs,1,0) sumFt = J((*mdl).nObs,1,0) for (j=1; j<=cols((*mdl).xb); j++) { mdl-> Ft[,j] = (*mdl).expxb[,j] :/ (1 :+ (*mdl).expxb[,j]) mdl-> ft[,j] = ((*mdl).dxb[,j]:*(*mdl).expxb[,j]) :/ (1 :+ (*mdl).expxb[,j]):^2 sumFt = sumFt :+ (*mdl).Ft[,j] denSum = denSum :+ ((*mdl).di[,j] :* ln((*mdl).ft[,j])) } mFt = 1 :- (sumFt) //mFt = (mFt:<0.0000000001):*0.0000000001 :+ (mFt:>0.0000000001):*mFt /* if ((*mdl).delentry) { mdl->xb0 = moptimize_util_xb(M,b,3) mdl->expxb0 = exp((*mdl).xb0) } */ lnfj = denSum :+ ((1 :- (*mdl).d) :* ln(mFt)) /*if ((*mdl).delentry) lnfj = lnfj :+ ((*mdl).t0:>0):* (*mdl).expxb0*/ if (todo==0) return S = J((*mdl).nObs,(*mdl).ScoreCols,.) for (j=1; j<=cols((*mdl).xb); j++) { S[,j] = (*mdl).di[,j] :* ((1 :- (*mdl).expxb[,j]) :/ (1 :+ (*mdl).expxb[,j])) :+ (1 :- (*mdl).d) :* ( ((*mdl).Ft[,j]:^2 :- (*mdl).Ft[,j]) :/ mFt) k = j + (*mdl).nCauses S[,k] = (*mdl).di[,j]:/(*mdl).dxb[,j] } /*if ((*mdl).delentry) S[,3] = ((*mdl).t0:>0):*(*mdl).expxb0 */ if (todo==1) return for (j=1; j<=cols((*mdl).xb); j++) { k = j + (*mdl).nCauses H[|moptimize_util_eq_indices(M, j, j)|] = moptimize_util_matsum(M,j,j, -2:*(*mdl).di[,j]:*((*mdl).expxb[,j]:/(1 :+ (*mdl).expxb[,j]):^2) :+ (1 :- (*mdl).d):*((-1:*(*mdl).Ft[,j] :+ 3:*((*mdl).Ft[,j]):^2 :- 2:*((*mdl).Ft[,j]):^3):/mFt) :- (1 :- (*mdl).d):*((((*mdl).Ft[,j]):^2 :- (*mdl).Ft[,j]):^2:/(mFt):^2), lnfj[1]) H[|moptimize_util_eq_indices(M, k, k)|] = moptimize_util_matsum(M,k,k, -1:*((*mdl).di[,j] :/ ((*mdl).dxb[,j]):^2),lnfj[1]) } for (j=1; j<=2:*(*mdl).nCauses; j++) { for (k=1; k<=2:*(*mdl).nCauses; k++) { if(j != k) { H[|moptimize_util_eq_indices(M, j, k)|] = moptimize_util_matsum(M,j,k,0,lnfj[1]) H[|moptimize_util_eq_indices(M, k, j)|] = moptimize_util_matsum(M,k,j,0,lnfj[1]) } } } /*if ((*mdl).delentry) { real matrix H13, H23, H33 H33 = moptimize_util_matsum(M,3,3,((*mdl).t0:>0):* (-(*mdl).expxb0),lnfj[1]) H13 = moptimize_util_matsum(M,1,3,0,lnfj[1]) H23 = moptimize_util_matsum(M,2,3,0,lnfj[1]) H = -1*(H11, H12, H13 \ H12', H22, H23 \ H13', H23', H33) } else*/ //H = -1*(H11,H12 \ H12',H22) //H = h } end mata mata mlib create lstpm2cr, replace mata mata mlib add lstpm2cr stpm2cr_state() stpm2cr_setup() stpm2cr_ml_hazard() stpm2cr_ml_odds()