inline void computeU(const Eigen::Matrix<double,xDim,1> & x, Eigen::Matrix<double,uDim,1> & u) { _x = x; computeU(); u = _u; }
void computeU(const double *x, int xLen, double *u, int uLen) { assert(xLen == xDim && uDim == uLen); setX(x, xLen); computeU(); getU(u, uLen); }
void removeUV() { computeU(); int u; for(u=0; u<NUSERS; u++) { int base0=useridx[u][0]; unsigned int *ent=&userent[base0]; int d012=UNALL(u); int i; double sUu=sU[u]; for(i=0; i<d012; i++) { err[base0+i]-=sUu*sV[ent[i]&USER_MOVIEMASK]; } } }
double T2model(pulsar *psr,int p,int ipos,int param,int arr) { double an; double pb,omdot; double rad2deg = 180.0/M_PI; double SUNMASS = 4.925490947e-6; longdouble tt0,t0,ct,t0asc; double m2,x,ecc,er,xdot,edot,dr,dth,eth; double pbdot,xpbdot,phase,u,gamma; double orbits; int norbits; double cu,onemecu=0,cae,sae,ae,omega,omz,sw,cw,alpha,beta,bg,dre,drep,drepp, anhat,su=0; double sqr1me2,cume,brace,si,dlogbr,ds,da,a0,b0,d2bar,torb; double csigma,ce,cx,comega,cgamma,cdth,cm2,csi, ckom, ckin; double eps1,eps2,eps1dot,eps2dot; double ceps1,ceps2; double shapmax,cshapmax,sdds; int com,com1,com2; int allTerms=1; /* = 0 to emulate BT model */ double dpara; double pmra,pmdec; double sin_omega,cos_omega,ki; double mtot,m1,xk,xomdot,afac,kom; longdouble DK011,DK012, DK021, DK022, DK031,DK032, DK041,DK042,C,S; longdouble DK013, DK014, DK023, DK024, DK033, DK034, DK043, DK044; longdouble DAOP=longdouble(0.0), DSR=longdouble(0.0); longdouble DOP=longdouble(0.0); // Orbital parallax time delay double daop;// DAOP is the time delay due to annual orbital // parallax. daop is the aop distance. longdouble h3,h4,stig; longdouble lgf,TrueAnom; longdouble lsc, fs; int nharm=4; int mode = -1; // See ELL1Hmodel.C torb = 0.0; const char *CVS_verNum = "$Id: d5e412cf859761421154f47be2a083ae696d674f $"; if (displayCVSversion == 1) CVSdisplayVersion("T2model.C","T2model()",CVS_verNum); if (param==-1) { com1 = 0; com2 = psr[p].nCompanion; } else { com1 = arr; com2 = arr+1; } // printf("Number of companions = %d %d\n",com1,com2); for (com = com1; com < com2;com++) { /* Obtain Keplerian parameters */ getKeplerian(&psr[p],com,&pb,&t0,&ecc,&omz,&x,&eps1,&eps2,&t0asc, &shapmax,&kom,&ki); /* Now add in the jumps */ addKeplerianJumps(&psr[p],ipos,&torb,&x,&ecc,&omz,&pb); /* Parameters derived from the Keplerian parameters */ deriveKeplerian(pb,kom,&an,&sin_omega,&cos_omega); /* Obtain post-Keplerian parameters */ getPostKeplerian(&psr[p],com,an,&si,&m2,&mtot,&omdot,&gamma,&xdot,&xpbdot, &pbdot,&edot,&pmra,&pmdec,&dpara,&dr,&dth,&a0,&b0, &xomdot,&afac,&eps1dot,&eps2dot,&daop); /* If the beta-prime parameters are set then omdot, gamma, si, dr, er, dth, a0 and b0 can be calculated from the beta-prime values * - see papers of Taylor, Wolszczan, Damour & Weisberg 1992 - Nature * Damour & Taylor 1992 - Phys Rev D */ if (psr[p].param[param_bp].paramSet[0]==1 && psr[p].param[param_bpp].paramSet[0]==1) { /* useBeta(psr[p]); */ printf("Beta model not implemented yet\n"); } /* If general relativity is assummed to be correct and * the total system mass has been determined then the values * of dr,dth,er, eth, sini, gamma and pbdot can be calculated */ if (psr[p].param[param_mtot].paramSet[com]==1) { calcGR(mtot,m2,x,ecc,an,afac,(double)psr[p].param[param_f].val[0], &dr,&dth,&er,ð,&xk,&si,&gamma,&pbdot,&a0,&b0); omdot = xomdot + xk; } /* Derive parameters from the post-Keplerian parameters */ derivePostKeplerian(mtot,m2,dr,dth,ecc,&m1,&er,ð); /* Obtain delta T */ ct = psr[p].obsn[ipos].bbat; if (psr[p].param[param_t0].paramSet[com]==1) tt0 = (ct-t0)*SECDAY; else if( psr[p].param[param_tasc].paramSet[com]==1) tt0 = (ct-t0asc)*SECDAY; else { printf("ERROR [T2] T0 or TASC needs to be set in the parameter file\n"); exit(1); } // logdbg("going to update Parameters"); /* Update parameters with their time derivatives */ updateParameters(edot,xdot,eps1dot,eps2dot,tt0,&ecc,&x,&eps1,&eps2); // logdbg("updated parameters"); /* Do some checks */ if (ecc < 0.0 || ecc > 1.0) { displayMsg(1,"BIN2","Eccentricity of orbit < 0, setting to 0","", psr[p].noWarnings); psr[p].param[param_ecc].val[com]=0.0; ecc = 0.0; } /* Obtain number of orbits in tt0 */ orbits = tt0/pb - 0.5*(pbdot+xpbdot)*pow(tt0/pb,2); norbits = (int)orbits; if (orbits<0.0) norbits--; /* Obtain phase of orbit */ phase=2.0*M_PI*(orbits-norbits); // ld_printf("Orbit phase = %.15Lf %.15g\n",psr[p].obsn[ipos].bbat,phase); if (psr[p].param[param_ecc].paramSet[com]==1) { // logdbg("going to compute U"); /* Compute eccentric anomaly u by iterating Kepler's equation */ computeU(phase,ecc,&u); // logdbg("computed U"); /* DD equations 17b and 17c */ su=sin(u); cu=cos(u); onemecu=1.0-ecc*cu; cae=(cu-ecc)/onemecu; /* Equation 17b */ sae=sqrt(1.0-pow(ecc,2))*su/onemecu; /* Equation 17c */ ae=atan2(sae,cae); if(ae<0.0) ae=ae+2.0*M_PI; ae=2.0*M_PI*orbits + ae - phase; omega=omz/rad2deg + omdot*ae; sw=sin(omega); cw=cos(omega); // logdbg("In the middle of DD"); /* DD equations 26, 27, 57: */ sqr1me2=sqrt(1-pow(ecc,2)); cume=cu-ecc; // logdbg("going to Kopeikin"); /* Update parameters due to proper motion - Kopeikin 1996 */ /* And annual-orbital and orbital parallax - Kopeikin 1995 */ if (psr[p].param[param_kin].paramSet[com]==1 && psr[p].param[param_kom].paramSet[com]==1 && (psr[p].param[param_pmra].paramSet[com]==1 || psr[p].param[param_pmdec].paramSet[com]==1)) { // logdbg("going to do KopeikinTerms"); KopeikinTerms(&psr[p],ipos,ki,pmra,sin_omega,pmdec,cos_omega,tt0, dpara,daop,si,&x,&DK011,&DK012,&DK021,&DK022, &DK031,&DK032,&DK041,&DK042,&DK013,&DK014,&DK023, &DK024,&DK033,&DK034,&DK043,&DK044); // logdbg("did KopeikinTerms"); C = (longdouble)(cw*(cu-er)-sqrt(1.0-pow(eth,2.0))*sw*su); S = (longdouble)(sw*(cu-er)+cw*sqrt(1.0-pow(eth,2.0))*su); DAOP = (DK011+DK012)*C-(DK021+DK022)*S; DSR = (DK031+DK032)*C+(DK041+DK042)*S; DOP = dpara/AULTSC/2.0*pow(x,2.0)* ( pow( sin( ki ), -2.0 ) - 0.5 + 0.5 * pow( ecc, 2.0 ) * ( 1 + pow( sw, 2.0 ) - 3.0 / pow( sin( ki ), 2.0 ) ) - 2.0 * ecc * ( pow( sin( ki ), -2.0 ) - pow( sw, 2.0 ) ) * cume - sqr1me2 * 2 * sw * cw * su * cume + 0.5 * ( cos( 2.0 * omega ) + pow( ecc, 2.0 ) * ( pow( sin( ki ), -2.0 ) + pow( cu, 2.0 ) ) ) * cos( 2.0 * u ) ); // printf("T2model: %g DAOP = %g DSR = %g DOP = %g\n",(double)psr[p].obsn[ipos].bbat,(double)DAOP,(double)DSR,(double)DOP); // logdbg("DAOP is %g and DSR is %g\n", (double)DAOP, (double)DSR); // logdbg("DAOP is %g, DK011 and DK021 are %f and %f\n", // (double)DAOP,(double)DK011,(double)DK021); } if (psr[p].param[param_shapmax].paramSet[com]==1) /* DDS model */ { sdds = 1.0 - exp(-1.0*shapmax); brace = onemecu-sdds*(sw*cume+sqr1me2*cw*su); } else brace=onemecu-si*(sw*cume+sqr1me2*cw*su); da=a0*(sin(omega+ae) + ecc*sw) + b0*(cos(omega+ae) + ecc*cw); /* Equation 27 */ /* DD equations 46 to 51 */ alpha=x*sw; /* Equation 46 */ beta=x*sqrt(1-pow(eth,2))*cw; /* Equation 47 */ bg=beta+gamma; dre=alpha*(cu-er) + bg*su; /* Equation 48 */ drep=-alpha*su + bg*cu; /* Equation 49 */ drepp=-alpha*cu - bg*su; /* Equation 50 */ anhat=an/onemecu; /* Equation 51 */ dlogbr=log(brace); ds=-2*m2*dlogbr; /* Equation 26 */ } else if (psr[p].param[param_eps1].paramSet[com]==1) /* ELL1 model */ { dre = x*(sin(phase)-0.5*(eps1*cos(2.0*phase)-eps2*sin(2.0*phase))); drep = x*cos(phase); drepp=-x*sin(phase); // logdbg("going to Kopeikin"); /* Update parameters due to proper motion - Kopeikin 1996 */ if (psr[p].param[param_kin].paramSet[com]==1 && psr[p].param[param_kom].paramSet[com]==1 && (psr[p].param[param_pmra].paramSet[com]==1 || psr[p].param[param_pmdec].paramSet[com]==1)) { S = (sin(phase)-0.5*(eps1*cos(2.0*phase)-eps2*sin(2.0*phase))); C = cos(phase)+0.5*(eps2*cos(2.0*phase)+eps1*sin(2.0*phase)); KopeikinTerms(&psr[p],ipos,ki,pmra,sin_omega,pmdec,cos_omega,tt0, dpara,daop,si,&x,&DK011,&DK012,&DK021,&DK022, &DK031,&DK032,&DK041,&DK042,&DK013,&DK014,&DK023, &DK024,&DK033,&DK034,&DK043,&DK044); DAOP = (DK011+DK012)*C-(DK021+DK022)*S; DSR = (DK031+DK032)*C+(DK041+DK042)*S; } brace=1-si*sin(phase); da=a0*sin(phase)+b0*cos(phase); anhat = an; ecc = 0.0; /* Shapiro delay */ if ( psr[p].param[param_h3].paramSet[0] * psr[p].param[param_stig].paramSet[0] == 1 || psr[p].param[param_h3].paramSet[0] * psr[p].param[param_h4].paramSet[0] == 1){ // printf("Using the Friere & Wex formalism for the Shapiro delay\n"); // Based on ELL1Hmodel.C //h3 = psr[p].param[param_h3].val[0]; h3 = getParameterValue( &psr[p], param_h3, 0 ); // Determine fw10 mode if( psr[p].param[param_h4].paramSet[0] == 1 ){ // h4 = psr[p].param[param_h4].val[0]; h4 = getParameterValue( &psr[p], param_h4, 0 ); // mode 2 or 3 take preference over mode 1 as they are more stable if( psr[p].param[param_nharm].paramSet[0] == 1 ){ nharm = (int)psr[p].param[param_nharm].val[0]; //nharm = (int)getParameterValue( &psr[p], param_nharm, 0 ); if( nharm > 4 ) mode = 3; else mode = 2; } if( psr[p].param[param_stig].paramSet[0] == 1 ){ // Conflict. Unsure whether to select mode 1 or modes 2/3, so will default // to the most stable one. logerr("You specified both H4 and STIG - Ignoring STIG"); logmsg( "WARNING! You specified both H4 and STIG." ); logmsg( "We will ignore STIG and perform the approx. H4 fit instead." ); logmsg( "If you want to perform the exact fit for H3 and STIG, then " ); logmsg( "please remove H4 from your parameter file."); } // Have H3, H4, but no NHARM mode = 2; }else{ // Have H3, but no H4 if( psr[p].param[param_stig].paramSet[0] == 1 ){ // stig = psr[p].param[param_stig].val[0]; stig = getParameterValue( &psr[p], param_stig, 0 ); mode = 1; }else{ mode = 0; h4 = 0; nharm = 3; } }// fw10 mode determined. // Define sin(i) and m2 for calculation of the orbital phases etc. if( mode == 1 ){ // fw10, Eq. 22: si = 2.0 * stig / ( 1.0 + pow( stig, 2.0 ) ); // fw10, Eq. 20: m2 = h3 / pow( stig, 3.0 ); // Shapiro r, not just M2. if( si > 1.0 ){ displayMsg(1,"BIN1", "SIN I > 1.0, setting to 1: should probably use DDS model", "",psr[p].noWarnings); si = 1.0; psr[p].param[param_sini].val[0] = longdouble(1.0); } }else if( mode == 2 || mode == 3 ){ // fw10, Eq. 25: si = 2.0 * h3 * h4 / ( h3 * h3 + h4 * h4 ); // fw10, Eq. 26: m2 = pow( h3, 4.0 ) / pow( h4, 3.0 ); if( si > 1.0 ){ displayMsg(1,"BIN1", "SIN I > 1.0, setting to 1: should probably use DDS model", "",psr[p].noWarnings); si = 1.0; psr[p].param[param_sini].val[0] = longdouble(1.0); } }else if( mode == 0 ){ // Cannot determine m2 and/or sini. Will have to determine the // Shapiro delay based on h3 alone. }else{ printf( "This should not be possible. Go Away.\n" ); printf( "And tell someone about it: [email protected], e.g.\n" ); } brace=1-si*sin(phase); dlogbr=log(brace); ecc = sqrt( eps1 * eps1 + eps2 * eps2 ); TrueAnom = phase; //TrueAnom = 2.0 * atan2( sqrt( 1.0 + ecc ) * sin( phase / 2.0 ), // sqrt( 1.0 - ecc ) * cos( phase / 2.0 ) ); omega = atan2( eps1, eps2 ); //lgf = log( 1.0 + stig * stig - 2.0 * stig * sin( TrueAnom + omega ) ); fs = 1.0 + stig * stig - 2.0 * stig * sin( TrueAnom ); lgf = log( fs ); lsc = lgf + 2.0 * stig * sin( TrueAnom ) - stig * stig * cos( 2.0 * TrueAnom ); if( mode == 0 ){ // mode 0: only h3 is known. ds = -4.0 / 3.0 * h3 * sin( 3.0 * TrueAnom ); }else if( mode == 1 ){ ds = -2.0 *m2* lsc; //ds = -2.0 * m2 * dlogbr; }else{ // modes 2 and 3 ds = calcDH( TrueAnom, h3, h4, nharm, 0 ); } } else{ dlogbr=log(brace); ds=-2*m2*dlogbr; /* Equation 26 */ } } else { printf("Require eccentricity set or EPS1/EPS2 parameters for companion %d\n",com+1); exit(1); } // printf("T2: %g %g %g %g %g %g %g\n",brace,phase,a0,b0,dlogbr,ds,m2); /* Now compute d2bar, the orbital time correction in DD equation 42. */ /* Equation 52 */ if (onemecu != 0.0) { d2bar=dre*(1-anhat*drep+allTerms*pow(anhat,2)* (pow(drep,2) + 0.5*dre*drepp - 0.5*ecc*su*dre*drep/onemecu)) + allTerms*(ds+da+DAOP+DSR + DOP); } else { d2bar=dre*(1-anhat*drep+allTerms*pow(anhat,2)* (pow(drep,2) + 0.5*dre*drepp)) + allTerms*(ds+da+DAOP+DSR+DOP); } // printf("T2a: %g %g %g %g %g drepp=%g ecc=%g su =%g ome =%g ds = %g da = %g %g %g\n",(double)d2bar,(double)dre,(double)anhat,(double)drep,(double)allTerms,(double)drepp,(double)ecc,(double)su,(double)onemecu,(double)ds,(double)da,(double)DAOP,(double)DSR); torb-=d2bar; /* Equation 42 */ if (param==-1 && com == psr[p].nCompanion-1) return torb; else if (param!=-1 && com==arr) { // Now we need the partial derivatives. Use DD equations 62a - 62k. if (psr[p].param[param_ecc].paramSet[com]==1) { csigma=x*(-sw*su+sqr1me2*cw*cu)/onemecu; /* Equation 62a */ ce=su*csigma-x*sw-ecc*x*cw*su/sqr1me2; /* Equation 62c */ cx=sw*cume+sqr1me2*cw*su; /* Equation 62d */ comega=x*(cw*cume-sqr1me2*sw*su); /* Equation 62e */ cgamma=su; /* Equation 62g */ cdth=-ecc*ecc*x*cw*su/sqr1me2; /* Equation 62i */ cm2=-2*dlogbr; /* Equation 62j */ if (psr[p].param[param_shapmax].paramSet[com]==1) cshapmax = 2*m2*(sw*cume+sqr1me2*cw*su)/brace * (1.0-sdds); else if (psr[p].param[param_sini].nLinkTo>0){ csi= 2*m2*(sw*cume+sqr1me2*cw*su)*cos(ki)/brace; } else csi=2*m2*(sw*cume+sqr1me2*cw*su)/brace; /* Equation 62k */ } else if (psr[p].param[param_eps1].paramSet[com]==1) /* ELL1 model */ { csigma = x*cos(phase); cx = sin(phase); ceps1 = -0.5*x*cos(2*phase); ceps2 = 0.5*x*sin(2*phase); cm2 = -2*dlogbr; csi = 2*m2*sin(phase)/brace; } if (param==param_pb) return -csigma*an*SECDAY*tt0/pb; else if (param==param_a1) return cx; else if (param==param_ecc) return ce; else if (param==param_edot) return ce*tt0; else if (param==param_om) return comega; else if (param==param_omdot) return ae*comega/(an*360.0/(2.0*M_PI)*365.25*SECDAY); else if (param==param_t0) return -csigma*an*SECDAY; else if (param==param_pbdot){ if(psr[p].param[param_pbdot].nLinkFrom>0){ return 0.5*tt0*(-csigma*an*SECDAY*tt0/(pb*SECDAY)); /*- SPEED_LIGHT/(getParameterValue(&psr[p],param_pb,0)*SECDAY* (pow(getParameterValue(&psr[p],param_pmra,0)*MASYR2RADS,2)+ pow(getParameterValue(&psr[p],param_pmdec,0)*MASYR2RADS,2))* getParameterValue(&psr[p],param_daop,0))* (C*(-DK011-DK012)+S*(DK021+DK022));*/ } else return 0.5*tt0*(-csigma*an*SECDAY*tt0/(pb*SECDAY)); } else if (param==param_sini) return csi; else if (param==param_gamma) return cgamma; else if (param==param_m2) return cm2*SUNMASS; else if (param==param_a1dot) return cx*tt0; else if (param==param_eps1) return ceps1; else if (param==param_eps1dot) return ceps1*tt0; else if (param==param_eps2dot) return ceps2*tt0; else if (param==param_eps2) return ceps2; else if (param==param_tasc) return -csigma*an*SECDAY; else if (param==param_shapmax) return cshapmax; else if (param==param_stig){ return( -2.0 * m2 / stig * ( 1.0 - 3.0 * lgf - ( 1.0 - stig * stig ) / fs ) + 2.0 * m2 * ( 4.0 * sin( TrueAnom ) - stig * cos( 2.0 * TrueAnom ) ) ); } else if (param==param_h3) { if( mode == 0 || mode == 2) return( -4.0 / 3.0 * sin( 3.0 * TrueAnom ) ); else if( mode == 1 ){ return( -2.0 * lsc / pow( stig, 3.0 ) ); //return( 2.0 / pow( stig, 3.0 ) * // ( lgf + 2.0 * stig * sin( TrueAnom ) - stig * stig * cos( TrueAnom ) ) ); }else if( mode == 3 ) return( calcDH( TrueAnom, h3, h4, nharm, 3 ) ); else{ printf( "ERROR in ELLH model in T2. This really shouldn't happen.\n" ); } }else if( param == param_h4 ){ if( mode == 2 ) return( cos( 4.0 * TrueAnom ) ); else return( calcDH( TrueAnom, h3, h4, nharm, 4 ) ); } else if (param==param_kom){ ckom = C* (DK033+DK034+DK013+DK014) + S*(DK043+DK044+DK023+DK024); return ckom; } else if (param==param_kin){ ckin = C/sin(ki)*(DK043+DK044+DK023+DK024)- S/sin(ki)*(DK013+DK014+DK033+DK034); if( psr[p].param[param_ecc].paramSet[com]== 1 ) ckin += dpara/AULTSC/2.0*pow( x, 2.0 ) * cos( ki ) * pow( sin( ki ), -3.0 ) * ( pow( ecc, 2.0 ) * ( 3.0 - cos( 2.0 * u ) ) + 4.0 * ecc * cume - 2.0 ); if(psr[p].param[param_kin].nLinkFrom>0) ckin += csi; // * cos( ki ); return ckin; } /* Update the binary parameter jumps */ if (psr[p].param[param_bpjep].paramSet[arr]==1 && psr[p].obsn[ipos].bbat > psr[p].param[param_bpjep].val[arr]) { if (param==param_bpjph) return 1.0/psr[p].param[param_f].val[0]; else if (param==param_bpja1) return cx; else if (param==param_bpjec) return ce; else if (param==param_bpjom) return comega; else if (param==param_bpjpb) return -csigma*an*SECDAY*tt0/(pb*SECDAY); } else return 0.0; } } return 0.0; }
int score_train(int loop) { double lrate=0.0001; double lrate_lambda=LAMBDA*lrate; double penalty = (0.88 + ((double)loop)/100.0); if ( penalty > 1.0 ) penalty = 1.0; double rmse_targ; double vcavg=0.0; { int count=0; int u; double rmse=0.0; int m; for(m=0; m<NMOVIES; m++) sVCnt[m] = 0; for(u=0; u<NUSERS; u++) { int base0=useridx[u][0]; float *e=&err[base0]; unsigned int *ent=&userent[base0]; int d0=UNTRAIN(u); int j; for(j=0; j<d0; j++) { m=(*ent++)&USER_MOVIEMASK; double t = (*e++); rmse+=t*t; count++; //sUCnt[u]++; sVCnt[m]++; vcavg++; } } rmse=sqrt(rmse/count); vcavg /= NMOVIES; int i; double goal = 3.5; //printf("GOAL: %f\n", goal); for (i=0; i< loop; i++) goal *= 0.80; goal = 1.0 - goal/1000.0; printf("GOAL: %f\n", goal); rmse_targ = rmse*goal; printf("RMSE GOAL: %f\n", rmse_targ); /* if ( loop < 4 ) { rmse_targ = rmse*0.997; } else if ( loop < 6 ) { rmse_targ = rmse*0.997; } else if ( loop < 12 ) { rmse_targ = rmse*0.998; } else if ( loop < 18 ) { rmse_targ = rmse*0.9985; } else { rmse_targ = rmse*0.999; } */ //if ( loop > 0 ) { //lrate_lambda = LRATE_LAMBDA_ORIG/(loop+19.0/20.0); //lrate = LRATE_ORIG/(loop+19.0/20.0); //} } if(fpV && fpW) { int nV=fread(sV,sizeof(double),NMOVIES,fpV); int nW=fread(sW,sizeof(double),NMOVIES,fpW); if(!nV && !nW) { fclose(fpV); fclose(fpW); fpV=NULL; fpW=NULL; } else if(nV!=NMOVIES) error("Failed to read %s %d",fnameVNS1,nV); else if(nW!=NMOVIES) error("Failed to read %s %d",fnameWNS1,nW); else { removeUV(); return 1; } } /* Initial estimation for current feature */ { int m; for(m=0; m<NMOVIES; m++) { sV[m]=0.1; sW[m]=0.1; } } /* Optimize current feature */ { int epoch; double rmse, last_rmse; double uavg=0.0, vavg=0.0; for(last_rmse=1.e20,epoch=0; epoch<MAX_EPOCHS; epoch++) { clock_t t0=clock(); computeU(); rmse=0.; int ntrain=0; double vslope[NMOVIES]; ZERO(vslope); double wslope[NMOVIES]; ZERO(wslope); int u; for(u=0; u<NUSERS; u++) { uavg += sU[u]; } uavg /= NUSERS; int mm; for(mm=0; u<NMOVIES; mm++) { vavg += sV[mm]; } vavg /= NMOVIES; //int uucount=0; for(u=0; u<NUSERS; u++) { int base0=useridx[u][0]; float *e=&err[base0]; unsigned int *ent=&userent[base0]; int d0=UNTRAIN(u); int j; double s=0.; double sUu=sU[u]; double lsUu = sUu; //lsUu += (uavg-sUu) * 0.05; double uslope=0; for(j=0; j<d0; j++) { int m=(*ent++)&USER_MOVIEMASK; double sVm=sV[m]; //sVm += (vavg-sVm) * 0.05; double ssVm; int svcnt = sVCnt[m]; if ( svcnt > vcavg*100 ) ssVm = sVm / 4.0; else if ( svcnt > vcavg*10 ) ssVm = sVm ; else ssVm = sVm*4.0; //double t = penalty*(*e++) - sUu*sVm; // New estimation error double t = (*e++) - lsUu*sVm; // New estimation error rmse+=t*t; vslope[m]+=t*lsUu; uslope+=t*ssVm; //if ( (uucount++ % 1000000) == 0 ) { //printf("%d v bef:%f\tdsyg:%f\tu bef:%f t:%f vslope:%f\n", uucount, //sUu, //sUu, //sVm, t, t*(sUu)); //} } ntrain+=d0; uslope*=unorm[u]; ent=&userent[base0]; d0=UNTOTAL(u); for(j=0; j<d0; j++) wslope[(*ent++)&USER_MOVIEMASK]+=uslope; } rmse=sqrt(rmse/ntrain); /* early stopping */ if( epoch >= 18 && rmse>last_rmse) break; int m; for(m=0; m<NMOVIES; m++) { sV[m] += lrate*vslope[m] - lrate_lambda*sV[m]; sW[m] += lrate*wslope[m] - lrate_lambda*sW[m]; } lg("%d %f %f\t\r",epoch,rmse,(clock()-t0)/(double)CLOCKS_PER_SEC); double deltar = last_rmse-rmse; if( epoch >= 27 && (deltar < ((1.0/penalty)*0.0000001) || rmse <= rmse_targ) ) break; //if( epoch > 10 && deltar < ((1.0/penalty)*0.000002) ) break; last_rmse=rmse; } } /* Perform a final iteration in which the errors are clipped and stored */ removeUV(); /* save results */ if(save_model) { dappend_bin(fnameVNS1,sV,NMOVIES); dappend_bin(fnameWNS1,sW,NMOVIES); } return 1; }
int score_train(int loop) { if(fpV && fpW) { int nV=fread(sV,sizeof(double),NMOVIES,fpV); int nW=fread(sW,sizeof(double),NMOVIES,fpW); if(!nV && !nW) { fclose(fpV); fclose(fpW); fpV=NULL; fpW=NULL; } else if(nV!=NMOVIES) error("Failed to read %s %d",fnameVNS1,nV); else if(nW!=NMOVIES) error("Failed to read %s %d",fnameWNS1,nW); else { removeUV(); return 1; } } /* Initial estimation for current feature */ { int m; for(m=0;m<NMOVIES;m++) { sV[m]=0.1; sW[m]=0.1; } } /* Optimize current feature */ { int epoch; double rmse, last_rmse; for(last_rmse=1.e20,epoch=0; epoch<MAX_EPOCHS; epoch++) { clock_t t0=clock(); computeU(); rmse=0.; int u; int ntrain=0; double vslope[NMOVIES]; ZERO(vslope); double wslope[NMOVIES]; ZERO(wslope); //int uucount=0; for(u=0;u<NUSERS;u++) { int base0=useridx[u][0]; float *e=&err[base0]; unsigned int *ent=&userent[base0]; int d0=UNTRAIN(u); int j; double s=0.; double sUu=sU[u]; double uslope=0; for(j=0;j<d0;j++) { int m=(*ent++)&USER_MOVIEMASK; double sVm=sV[m]; double t = (*e++) - sUu*sVm - 0.07; // New estimation error rmse+=t*t; vslope[m]+=t*sUu; uslope+=t*sVm; //if ( (uucount++ % 1000000) == 0 ) { //printf("%d v bef:%f\tdsyg:%f\tu bef:%f t:%f vslope:%f\n", uucount, //sUu, //sUu, //sVm, t, t*(sUu)); //} } ntrain+=d0; uslope*=unorm[u]; ent=&userent[base0]; d0=UNTOTAL(u); for(j=0;j<d0;j++) wslope[(*ent++)&USER_MOVIEMASK]+=uslope; } rmse=sqrt(rmse/ntrain); /* early stopping */ if(rmse>last_rmse) break; last_rmse=rmse; int m; for(m=0;m<NMOVIES;m++) { sV[m] += LRATE*vslope[m] - LRATE_LAMBDA*sV[m]; sW[m] += LRATE*wslope[m] - LRATE_LAMBDA*sW[m]; } lg("%d %f %f\t\r",epoch,rmse,(clock()-t0)/(double)CLOCKS_PER_SEC); } } /* Perform a final iteration in which the errors are clipped and stored */ removeUV(); /* save results */ if(save_model) { dappend_bin(fnameVNS1,sV,NMOVIES); dappend_bin(fnameWNS1,sW,NMOVIES); } return 1; }