You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1072 lines
49 KiB

/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
/*
requires *vals and *vars to be initialized
external calls: OS_milliseconds(), get_jfp_features(), get_yval(), set_ocas_model(), update_ocas_preds(), ocasCL_glue()
*/
//#include <dispatch/dispatch.h>
typedef float svmtype;
// fadedreamz@gmail.com - added for successful compilation, however, for MSVC probably require a particular OpenCL SDK
// to work with it (e,g nvidia or amd SDK)
typedef struct fake_opencl_double { //use a struct for double2 typedefinition on all OS - ca333@protonmail.ch
double x;
double y;
}double2;
#define MAX_VECTORS (1440 * 365 * 5)
#define MAIN_MAXCORES 16
#define c_to_refc(c) (c)
#define refc_to_c(refc) (refc)
#define CONDITION(feature) (feature)
#define FEATURE_THRESHOLD 10.
#define HWMPERC_THRESHOLD 101
#define HWMPERC_THRESHOLD0 HWMPERC_THRESHOLD
#ifdef INSIDE_OPENCL
#pragma OPENCL EXTENSION cl_khr_fp64: enable
#define local_barrier() barrier(CLK_LOCAL_MEM_FENCE)
#define global_barrier() barrier(CLK_GLOBAL_MEM_FENCE)
#else
//double get_features(register struct ocas_ptrs *PTRS,register int c,register int weekind,register int numfeatures,register double *features,register double *model,register double *addptr,register struct baserel_info *BR,register double wt);
svmtype *get_jfp_features(register int selector,register int numfeatures,register int c,register int weekind);
#endif
#define OCAS_INFINITY (-log(0.0))
#define OCAS_NEGINFINITY (log(0.0))
#define OCAS_DECAY .1
#define OCAS_BIAS 1.
#define OCAS_INDEX(ROW,COL,NUM_ROWS) ((COL)*(NUM_ROWS)+(ROW))
#define QPSOLVER_MAXITER 1000000
#define QPSOLVER_MINITER (QPSOLVER_MAXITER * .1)
//#define NUM_CUDA_GROUPS 14
//#define NUM_BUNDLE_ANSWERS 64
//#define NUM_TOPCOEFFIS 558
//#define SMALLVAL .00000000000001
//#define NUM_PRIMARY_FEATURES 4096
#ifdef __APPLE__
#define MAX_OCAS_LHS 512
#else
#define MAX_OCAS_LHS 2000
#endif
#define MAX_OCAS_FEATURES (1024 * 1024)
struct ptrhdr { long allocsize; void *ptr; int devid; char str[64]; };
struct ocas_lhsbuffers
{
double H[MAX_OCAS_LHS * MAX_OCAS_LHS];
double alpha[MAX_OCAS_LHS],b[MAX_OCAS_LHS],diag_H[MAX_OCAS_LHS],A0[MAX_OCAS_LHS],d[MAX_OCAS_LHS];
double full_A[];
};
struct ocas_CLtmpspace
{
double2 hpfb[MAX_VECTORS];
int poslist[MAX_VECTORS],neglist[MAX_VECTORS];
};
struct ocas_CLbuffers
{
double output_pred[MAX_VECTORS],old_output[MAX_VECTORS];
double W[MAX_OCAS_FEATURES+4],oldW[MAX_OCAS_FEATURES+4],new_a[MAX_OCAS_FEATURES+4];
};
struct ocas_vars
{
struct ptrhdr pH[256];
double Q_P[TRADEBOTS_NUMANSWERS],Q_D[TRADEBOTS_NUMANSWERS];
double netcuts[TRADEBOTS_NUMANSWERS],perc[TRADEBOTS_NUMANSWERS],hwmperc[TRADEBOTS_NUMANSWERS],lastmetrics[TRADEBOTS_NUMANSWERS][2];
double learningrates[TRADEBOTS_NUMANSWERS][2],maxiters[TRADEBOTS_NUMANSWERS],dot_prod_WoldW[TRADEBOTS_NUMANSWERS],cutsum[TRADEBOTS_NUMANSWERS];
double sq_norm_oldW[TRADEBOTS_NUMANSWERS],oldW0[TRADEBOTS_NUMANSWERS],W0[TRADEBOTS_NUMANSWERS],sq_norm_W[TRADEBOTS_NUMANSWERS];
double predabs[TRADEBOTS_NUMANSWERS],predsum[TRADEBOTS_NUMANSWERS],dist[TRADEBOTS_NUMANSWERS];
double xi[TRADEBOTS_NUMANSWERS],pratio[TRADEBOTS_NUMANSWERS],errperc[TRADEBOTS_NUMANSWERS],hwmdist[TRADEBOTS_NUMANSWERS];
double answerabsaves[TRADEBOTS_NUMANSWERS],answeraves[TRADEBOTS_NUMANSWERS];
int answercounts,firstweekinds[TRADEBOTS_NUMANSWERS];
int posA[TRADEBOTS_NUMANSWERS],negA[TRADEBOTS_NUMANSWERS];
int numIt[TRADEBOTS_NUMANSWERS],numlhs[TRADEBOTS_NUMANSWERS],nNZAlpha[TRADEBOTS_NUMANSWERS],trn_err[TRADEBOTS_NUMANSWERS];
int qp_exitflag[TRADEBOTS_NUMANSWERS],exitflag[TRADEBOTS_NUMANSWERS],len[TRADEBOTS_NUMANSWERS];
int have_pendingmodel[TRADEBOTS_NUMANSWERS],cutlen[TRADEBOTS_NUMANSWERS],good[TRADEBOTS_NUMANSWERS],bad[TRADEBOTS_NUMANSWERS];
int nohwm[TRADEBOTS_NUMANSWERS],numposcuts[TRADEBOTS_NUMANSWERS],numnegcuts[TRADEBOTS_NUMANSWERS];
struct ocas_CLbuffers *CLspaces[TRADEBOTS_NUMANSWERS];
struct ocas_lhsbuffers *lhs[TRADEBOTS_NUMANSWERS];
int *weekinds[TRADEBOTS_NUMANSWERS];
float *answers,**features;
//unsigned long CLallocsize,tmpallocsize,tmpCLallocsize;
double C,TolRel,TolAbs,MaxTime,QPBound,QPSolverTolAbs,QPSolverTolRel;
double output_time,sort_time,add_time,w_time,qp_solver_time,ocas_time; // total time spent in svm_ocas_solver
int selector,numthreads,starti,modelind,c,refc,maxlen,numfeatures,firstweekind,startweekind,endweekind,numptrs,maxlhs;
};
/////////////////////////// Most of runtime is in the add/dot functions
#ifdef INSIDE_OPENCL
typedef double svmtype;
// numCLthreads: NUM_CUDA_CORES, numgroups: (numdocs + NUM_CUDA_CORES-1)/NUM_CUDA_CORES
__kernel void dot_featuresCL(__local void *lp,__global double *preds,int numfeatures,__global double *W,double W0,__global svmtype *matrix,int numdocs)
{
register int i,j,docid;
register double sum;
register __global svmtype *features;
if ( (docid = (int)get_global_id(0)) < numdocs )
{
sum = 0.;
features = &matrix[docid * numfeatures];
for (i=0; i<numfeatures; i++)
{
j = ((i + docid) % numfeatures); // interleave global memory accesses statistically without any system overhead
sum += W[j] * CONDITION(features[j]);
}
preds[docid] = sum + W0;
}
}
// numCLthreads: NUM_CUDA_CORES, numgroups: (numfeatures + NUM_CUDA_CORES-1)/NUM_CUDA_CORES
__kernel void add_featuresCL(__local void *lp,__global double *new_a,int numfeatures,__global unsigned int *new_cutCL,int cutlen,__global svmtype *matrix,int numdocs)
{
register int i,j,docid,dir,globalid = (int)get_global_id(0);
register double sum;
register __global svmtype *features;
if ( (j = globalid) < numfeatures )
{
sum = 0.;
for (i=0; i<cutlen; i++)
{
docid = new_cutCL[(i + globalid) % cutlen];
dir = (docid & 1);
docid >>= 1;
if ( docid < numdocs )
{
features = &matrix[docid * numfeatures];
if ( dir == 0 )
sum += CONDITION(features[j]);
else sum -= CONDITION(features[j]);
}
}
new_a[j] = sum;
}
}
#else
void ocas_purge(struct ocas_vars *vars)
{
int32_t i;
free(vars->answers);
for (i=0; i<vars->maxlen; i++)
if ( vars->features[i] != 0 )
free(vars->features[i]);
free(vars->features);
for (i=0; i<TRADEBOTS_NUMANSWERS; i++)
{
if ( vars->CLspaces[i] != 0 )
myaligned_free(vars->CLspaces[i],sizeof(*vars->CLspaces[i]));
if ( vars->lhs[i] != 0 )
myaligned_free(vars->lhs[i],sizeof(*vars->lhs[i]) + vars->numfeatures*vars->maxlhs*sizeof(double));
if ( vars->weekinds[i] != 0 )
free(vars->weekinds[i]);
}
free(vars);
}
/*static inline double dot_expanded_features(register double *W,register int c,register int selector,register int numfeatures)
{
fatal("dot_expanded_features not implemented");
return(0);
}
static inline void add_expanded_features(register double *W,register double y,register int c,register int selector,register int numfeatures)
{
fatal("add_expanded_features not implemented");
}*/
static inline double calc_ocas_output(register struct ocas_vars *vars,register int selector,register int c,register int weekind,register int answerind,register double *W,register double W0,register int numfeatures)
{
register svmtype *features;
register double feature,y,sum = 0.;
register int coeffi;
if ( (y= vars->answers[(weekind-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]) != 0.f )
{
if ( (features= vars->features[weekind-vars->starti]) != 0 )//get_jfp_features(vars->selector,numfeatures,c,weekind)) != 0 )
{
#ifdef OCAS_USE_TOPCOEFFIS
for (int i=0; i<NUM_TOPCOEFFIS; i++)
{
coeffi = _Topcoeffis[answerind][i];
#else
for (coeffi=0; coeffi<numfeatures; coeffi++)
{
#endif
feature = features[coeffi];
if ( isnan(feature) == 0 && fabs(feature) < FEATURE_THRESHOLD )
sum += CONDITION(feature) * W[coeffi];
}
}
//else sum = dot_expanded_features(W,c,vars->selector,numfeatures);
sum = y * (W0 + sum);
}
// printf("%f ",sum);
return(sum);
}
static inline void add_ocas_output(register double y,register struct ocas_vars *vars,register int selector,register int c,register int weekind,register int answerind,register double *W,register double *new_a,register int numfeatures)
{
register int coeffi;
register svmtype *features,feature;
if ( y != 0 )
{
if ( (features= vars->features[weekind-vars->starti]) != 0 )//get_jfp_features(vars->selector,numfeatures,c,weekind)) != 0 )
{
//features = get_jfp_features(vars->selector,numfeatures,c,weekind);
#ifdef OCAS_USE_TOPCOEFFIS
int32_t i;
for (i=0; i<NUM_TOPCOEFFIS; i++)
{
coeffi = _Topcoeffis[answerind][i];
#else
for (coeffi=0; coeffi<numfeatures; coeffi++)
{
#endif
feature = features[coeffi];
if ( isnan(feature) == 0 && fabs(feature) < FEATURE_THRESHOLD )
new_a[coeffi] += y * CONDITION(feature);
}
}
//else add_expanded_features(new_a,y,c,vars->selector,numfeatures);
}
}
static inline void STocas_calc_outputs(register struct ocas_vars *vars,register int c,register int answerind,register double *output,register double *old_output,register double *W,register double W0,register int numfeatures,register int *weekinds,register int numdocs)
{
register int i,j;
//vars->good[answerind] = vars->bad[answerind] = 0;
//printf("start STocas_calc_outputs.(%p %s.A%d %p) %p %p %p\n",vars,CONTRACTS[c],answerind,weekinds,output,old_output,W);
for (i=0; i<numdocs; i++)
{
//old_output[i] = output[i];
output[i] = calc_ocas_output(vars,vars->selector,c,weekinds[i],answerind,W,W0,numfeatures);
if ( 1 && isnan(output[i]) != 0 )
{
svmtype *features = vars->features[weekinds[i]-vars->starti];//get_jfp_features(vars->selector,numfeatures,c,weekinds[i]);
if ( features != 0 )
{
for (j=0; j<numfeatures; j++)
if ( isnan(features[j]) != 0 )
printf("%d ",j);
printf("nans | i.%d w%d output %19.16f\n",i,weekinds[i],output[i]);
}
}
else if ( output[i] != 0. )
{
if ( 0 && vars->answers[(i-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]*output[i] <= 0 )
{
if ( vars->answers[(i-vars->starti)*TRADEBOTS_NUMANSWERS + answerind] != 0.f )
printf("(%f %f) ",vars->answers[(i-vars->starti)*TRADEBOTS_NUMANSWERS + answerind],output[i]);
}
//printf("[%f %f] ",vars->answers[(i-vars->starti)*TRADEBOTS_NUMANSWERS + answerind],output[i]);
}
}
//printf("finish STocas_calc_outputs\n");
}
static inline void STocas_add_newcuts(register struct ocas_vars *vars,register int answerind,register int numfeatures,register int *weekinds,register int *new_cut,register int numcuts,register double *W,register double *new_a)
{
register int weekind,dir,i,c = vars->c;
memset(new_a,0,sizeof(*new_a) * numfeatures);
//printf("STocas_add_newcuts numcuts.%d numfeatures.%d\n",numcuts,numfeatures);
for (i=0; i<numcuts; i++)
{
weekind = new_cut[i];
dir = (weekind & 1);
weekind >>= 1;
add_ocas_output(dir==0?1:-1,vars,vars->selector,c,weekind,answerind,W,new_a,numfeatures);
}
}
//////////////////////////// end of add/dot functions
static inline double _dbufave(register double *buf,register int len)
{
register int i,n;
register double sum;
sum = 0.;
n = 0;
for (i=0; i<len; i++)
{
if ( fabs(buf[i]) > 0.0000000001 )
{
n++;
sum += buf[i];
}
}
if ( n != 0 )
sum /= n;
if ( fabs(sum) <= 0.0000000001 )
sum = 0.;
return(sum);
}
static inline void add_newcut_entry(register struct ocas_vars *vars,register int answerind,register int *new_cut,register int i,register int weekind,register double y)
{
weekind <<= 1;
if ( y > 0 ) vars->numposcuts[answerind]++;
else if ( y < 0 ) vars->numnegcuts[answerind]++, weekind |= 1;
new_cut[vars->cutlen[answerind]++] = weekind;
}
static inline double validate_ocas_model(register struct ocas_vars *vars,register int answerind,register double *output_pred,register double *old_output,register int *weekinds,register int numdocs,register double *W,register double W0,register int numfeatures,register int paranoid)
{
register svmtype *features;
register double y,pred,perc,answer=0.,feature;
register int i,j,pos,neg,good,bad,oldcuts,training_errors,weekind,nonz=0,posA,negA;
for (i=pos=neg=good=bad=oldcuts=training_errors=posA=negA=0; i<numdocs; i++)
{
weekind = (weekinds == 0) ? i : weekinds[i];
if ( (y= vars->answers[(weekind-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]) != 0. )
{
if ( y > 0 ) posA++;
else if ( y < 0 ) negA++;
if ( paranoid != 0 )
{
pred = 0.;
if ( (features= vars->features[weekind-vars->starti]) != 0 )//get_jfp_features(vars->selector,numfeatures,vars->c,weekind)) != 0 )
{
for (j=nonz=0; j<numfeatures; j++)
{
if ( (feature= features[j]) != 0 )
{
if ( isnan(feature) == 0 && fabs(feature) < FEATURE_THRESHOLD )
{
nonz++;
pred += W[j] * CONDITION(feature);
}
}
}
if ( fabs(pred) > SMALLVAL )
pred += W0;
}
else pred = 0;//dot_expanded_features(W,c,selector,numfeatures);
if ( output_pred[i] != 0 && fabs(pred - output_pred[i]) > .000001 )
// if ( (rand() % 10000) == 0 )
printf("i.%d A %9.6f pred %9.6f != output_pred %9.6f [%14.10f]\n",i,answer,pred,output_pred[i],pred-output_pred[i]);
}
else pred = output_pred[i], nonz = numfeatures;
if ( nonz != 0 )
{
if ( pred > 0 ) pos++;
else if ( pred < 0 ) neg++;
if ( pred*y > 0 ) good++;
else if ( pred*y < 0 ) bad++;
}
if ( old_output[i] <= 1. )
{
oldcuts++;
if ( old_output[i] <= 0. )
training_errors++;
}
}
}
nonz = 0;
for (i=0; i<numfeatures; i++)
if ( W[i] != 0. )
nonz++;
perc = (100.*(double)good) / MAX(1,(good+bad));
printf(">>>>>> %d.A%02d.(+%-6d -%-6d oc.%-6d | good.%-6d bad.%-6d >>>>> %6.2f%% <<<<<).%-6d | W0 %9.6f W[%d] %9.6f | A +%-6d -%-6d | paranoid.%d numdocs.%d\n",c_to_refc(vars->c),answerind,pos,neg,oldcuts,good,bad,perc,training_errors,W0,nonz,_dbufave(W,numfeatures),posA,negA,paranoid,numdocs);
return(perc);
}
static int _increasing_double(const void *a,const void *b)
{
#define double_a (*(double *)a)
#define double_b (*(double *)b)
if ( double_b > double_a )
return(-1);
else if ( double_b < double_a )
return(1);
return(0);
#undef double_a
#undef double_b
}
static inline void calc_ocas_strategy(register struct ocas_vars *vars,register int answerind,register double C,register int numfeatures,register int len,register int *weekinds,register int *new_cut,register double *W,register double *oldW,register double *output,register double *old_output,register double2 *hpfb)
{
double answermag;
register int i,j,num_hp,good,bad,zero;
register double Bval,Cval,newoutput,W0,oldW0,sq_norm_W,A0val,B0,dist,GradVal,t,t1,t2,t_new,val,GradVal_new,y,starttime,*preds = output;
num_hp = 0;
W0 = vars->W0[answerind]; oldW0 = vars->oldW0[answerind];
A0val = vars->sq_norm_W[answerind] - (2. * vars->dot_prod_WoldW[answerind]) + vars->sq_norm_oldW[answerind];
B0 = (vars->dot_prod_WoldW[answerind] - vars->sq_norm_oldW[answerind]);
GradVal = B0;
for (i=0; i<len; i++)
{
if ( (y= vars->answers[(weekinds[i]-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]) != 0.f )
{
svmtype *features = vars->features[weekinds[i]-vars->starti];//get_jfp_features(vars->selector,numfeatures,vars->c,weekinds[i]);
//printf("i.%d weekind.%d starti.%d y %f %p\n",i,weekinds[i],vars->starti,y,features);
if ( 0 && features != 0 )
{
double oldsum=oldW0,sum=W0;
for (j=0; j<numfeatures; j++)
{
oldsum += oldW[j] * CONDITION(features[j]);
//sum += W[j] * CONDITION(features[j]);
}
//old_output[i] = oldsum*y;
if ( 0 && fabs(sum*y - output[i]) > .000001 )
{
printf("A%d numIt.%d docid.%-6d sum %11.7f * y%2.0f %11.7f != %11.7f output [%11.7f] W0 %11.7f oldW0 %11.7f\n",answerind,vars->numIt[answerind],i,sum,y,sum*y,output[i],output[i]-sum*y,W0,oldW0);
//output[i] = sum*y;
}
if ( fabs(oldsum*y - old_output[i]) > .000001 )
{
if ( old_output[i] != 0 && oldW0 != 0 && (rand() % 1000) == 0 )
printf("A%d numIt.%d docid.%-6d oldsum %11.7f * y%2.0f %11.7f != %11.7f oldoutput [%11.7f] W0 %11.7f oldW0 %11.7f\n",answerind,vars->numIt[answerind],i,oldsum,y,oldsum*y,old_output[i],old_output[i]-oldsum*y,W0,oldW0);
old_output[i] = oldsum*y;
}
}
Cval = C * (1. - old_output[i]);
Bval = C * (old_output[i] - output[i]);
if ( Bval != 0 )
val = -(Cval / Bval);
else val = OCAS_NEG_INF;
if ( val > 0 )
{
hpfb[num_hp].y = Bval;
hpfb[num_hp].x = val;
num_hp++;
}
if ( (Bval < 0 && val > 0) || (Bval > 0 && val <= 0) )
GradVal += Bval;
}
}
//printf("num_hp.%d\n",num_hp);
t = 0;
if ( GradVal < 0 )
{
starttime = OS_milliseconds();
qsort(hpfb,num_hp,sizeof(double2),_increasing_double);
//ocas_sort(hpfb,num_hp);
i = 0;
while ( GradVal < 0 && i < num_hp )
{
t_new = hpfb[i].x;
GradVal_new = GradVal + fabs(hpfb[i].y) + A0val*(t_new - t);
if ( GradVal_new >= 0 )
t = t + GradVal * (t - t_new) / (GradVal_new - GradVal);
else t = t_new, i++;
GradVal = GradVal_new;
}
vars->sort_time += OS_milliseconds() - starttime;
}
t = MAX(t,0.); // just sanity check; t < 0 should not occur
t1 = t; // new (best so far) W
t2 = t + OCAS_DECAY*(1. - t); // new cutting plane
W0 = oldW0 * (1. - t) + (t * W0);
sq_norm_W = W0 * W0;
for (j=0; j<numfeatures; j++)
{
W[j] = (oldW[j] * (1. - t)) + (t * W[j]);
sq_norm_W += W[j] * W[j];
}
vars->W0[answerind] = W0; vars->sq_norm_W[answerind] = sq_norm_W;
vars->trn_err[answerind] = 0; dist = 0.;
for (i=good=bad=zero=0; i<len; i++) // select a new cut
{
if ( (y= vars->answers[(weekinds[i]-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]) != 0.f )
{
answermag = fabs(y); // 1.;
if ( (old_output[i] * (1. - t2) + t2*output[i]) <= answermag ) //1.
add_newcut_entry(vars,answerind,new_cut,i,weekinds[i],y);
newoutput = (old_output[i] * (1. - t1)) + (t1 * output[i]);
if ( 0 ) // won't match unless old_output corresponds with features*oldW
{
double sum=W0;
svmtype *features = vars->features[weekinds[i]-vars->starti];//get_jfp_features(vars->selector,numfeatures,vars->c,weekinds[i]);
if ( features != 0 )
{
for (j=0; j<numfeatures; j++)
sum += W[j] * CONDITION(features[j]);
if ( fabs(sum*y - newoutput) > .0000001 )
printf("numIt.%d docid.%-6d w%-6d sum %11.7f * y%2.0f %11.7f != %11.7f newoutput [%11.7f] W0 %11.7f oldW0 %11.7f\n",vars->numIt[answerind],i,weekinds[i],sum,y,sum*y,newoutput,newoutput-sum*y,W0,oldW0);
newoutput = sum*y;
}
}
if ( newoutput <= answermag )
{
vars->xi[answerind] += (answermag - newoutput);
if ( newoutput <= 0. )
vars->trn_err[answerind]++;
}
preds[i] = y * newoutput;
dist += fabs(preds[i] - y);
old_output[i] = newoutput;
if ( newoutput > 0. ) good++;
else if ( newoutput < 0. )
{
bad++;
//printf("(%f %f) ",y,newoutput);
}
} else zero++;//,printf("i.%d -> w%d | zeroes.%d good.%d bad.%d of len.%d\n",i,weekinds[i],zero,good,bad,len);
}
//printf("finished strategy\n");
vars->good[answerind] = good; vars->bad[answerind] = bad; vars->dist[answerind] = dist / MAX(1,good+bad);
vars->perc[answerind] = (100. * (double)vars->good[answerind]) / MAX(1,good+bad);
if ( vars->perc[answerind] > vars->hwmperc[answerind] || (vars->perc[answerind] == vars->hwmperc[answerind] && (vars->hwmdist[answerind] == 0 || vars->dist[answerind] < vars->hwmdist[answerind])) )
{
double set_ocas_model(int refc,int answerind,double *W,double W0,int numfeatures,int firstweekind,int len,int bad,double dist,double predabs,int posA,int negA,double answerabs,double aveanswer);
vars->W0[answerind] = set_ocas_model(vars->refc,answerind,vars->CLspaces[answerind]->W,vars->W0[answerind],vars->numfeatures,vars->firstweekind,vars->len[answerind],vars->trn_err[answerind],vars->dist[answerind],vars->predabs[answerind],vars->posA[answerind],vars->negA[answerind],vars->answerabsaves[answerind],0.);
vars->nohwm[answerind] = 0;
vars->hwmperc[answerind] = vars->perc[answerind]; vars->hwmdist[answerind] = vars->dist[answerind];
}
else vars->nohwm[answerind]++;
//printf("good.%d bad.%d zero.%d errors.%d | selector.%d\n",good,bad,zero,vars->trn_err[answerind],vars->selector);
}
static inline double ocas_splx_solver(register int *nonzalphap,register int maxlhs,register double *d,register double *activeH,register double *diag_H,register double *f,register double C,register double *alpha,register int n,register int MaxIter,register double TolAbs,register double TolRel,register double QP_TH)
{
register double *col_u=0,*col_v=0;
register double QP,QD,lastQD,tmp,diff,distA,distB,etaA,etaB,improv,tmp_num,delta,x_neq0,xval,dval,diagval=0.,tmp_den,tau=0.;
register int u=0,v=0,i,j,iter,nonzalpha=0,unlikely = 0;
QP = distA = distB = OCAS_PLUS_INF; lastQD = QD = OCAS_NEG_INF;
x_neq0 = C;
etaA = etaB = 0.;
for (i=0; i<n; i++)
{
x_neq0 -= alpha[i];
d[i] += f[i];
if ( alpha[i] > 0. )
{
col_u = &activeH[maxlhs * i];
for (j=0; j<n; j++)
d[j] += col_u[j] * alpha[i];
}
}
for (iter=0; iter<MaxIter; iter++)
{
// Compute primal and dual objectives
for (tmp=OCAS_PLUS_INF,i=nonzalpha=0,QP=QD=delta=0; i<n; i++)
{
if ( alpha[i] != 0. )
{
nonzalpha++;
QP += alpha[i] * (f[i] + d[i]);
QD += alpha[i] * (f[i] - d[i]);
delta += alpha[i] * d[i];
}
if ( d[i] < tmp )
tmp = d[i], u = i;
}
QP *= .5; QD = QD*.5 + C * MIN(tmp,0.);
if ( 0 && lastQD != 0. && lastQD != QD )
{
diff = (QD - lastQD);
etaA = (distA != 0.) ? fabs(distA/diff) : 0.;
etaB = (distB != 0.) ? fabs(distB/diff) : 0.;
if ( etaA > 10*(MaxIter-iter) && etaB > 10*(MaxIter-iter) )
unlikely++;
else unlikely = 0;
} else unlikely = 0;
diff = (QP - QD);
if ( 0 && (diff <= fabs(QP)*TolRel || diff <= TolAbs || QP <= QP_TH || unlikely > 100) )
{
if ( 0 )
{
if ( diff <= fabs(QP)*TolRel )
printf("caseA %f | ",diff - fabs(QP)*TolRel);
else if ( diff <= TolAbs )
printf("caseB %f | ",diff - TolAbs);
else if ( etaA > 2*(MaxIter-iter) && etaB > 2*(MaxIter-iter) )
printf("caseC etas %f %f | ",etaA,etaB);
printf("%d: QP %f QD %f diff %f n.%d d0 %9.6f dA %9.6f %9.6f dB %9.6f %9.6f\n",iter,QP,QD,QP-QD,n,d[0],distA,etaA,distB,etaB);
}
break;
}
distA = (diff - fabs(QP)*TolRel);
distB = (diff - TolAbs);
lastQD = QD;
if ( d[u] > 0 )
u = -1;
else delta -= C * d[u];
// if satisfied then k-th block of variables needs update
if ( delta > TolAbs && delta > (TolRel * fabs(QP)) )
{
// for fixed u select v = argmax_{i in I_k} Improvement(i)
improv = OCAS_NEG_INF;
for (i=0; i<=n; i++)
{
if ( i == u || (xval = ((i<n) ? alpha[i] : x_neq0)) <= 0. )
continue;
if ( u != -1 )
{
col_u = &activeH[maxlhs * u];
if ( i < n )
dval = (d[u] - d[u]), diagval = (diag_H[u] - 2.*col_u[i] + diagval);
else diagval = diag_H[u], dval = -d[u];
}
else if ( i < n )
dval = d[i], diagval = diag_H[i];
else continue;
if ( (tmp_den= xval * xval * diagval) > 0 )
{
tmp_num = xval * dval;
if ( tmp_num < tmp_den )
tmp = tmp_num*tmp_num / tmp_den;
else tmp = tmp_num - .5 * tmp_den;
if ( 0 && i < n ) // jimbo tweak
{
tmp = alpha[i] * MIN(1.,tmp_num/tmp_den);
alpha[i] -= tmp;
if ( u == -1 )
x_neq0 += tmp;
else alpha[u] += tmp;
}
if ( tmp > improv )
{
improv = tmp;
tau = MIN(1.,tmp_num/tmp_den);
v = i;
}
}
}
// update d = H*x + f
if ( v < n )
{
tau *= alpha[v];
alpha[v] -= tau;
if ( u != -1 )
{
alpha[u] += tau;
col_v = &activeH[maxlhs * v];
for (i=0; i<n; i++)
d[i] += tau * (col_u[i] - col_v[i]);
}
else
{
x_neq0 += tau;
col_v = &activeH[maxlhs * v];
for (i=0; i<n; i++)
d[i] -= tau * col_v[i];
}
}
else
{
tau *= x_neq0;
alpha[u] += tau;
x_neq0 -= tau;
for (i=0; i<n; i++)
d[i] += tau * col_u[i];
}
QP -= improv; // update objective value
}
}
*nonzalphap = nonzalpha;
return(-QP);
}
static inline void update_ocas_model(register double *W,register double *oldW,register struct ocas_vars *vars,register int numfeatures,register int answerind,register struct ocas_lhsbuffers *lhs,register int numlhs)
{
register int i,j;
register double alpha,sq_norm_W,dot_prod_WoldW,W0,oldW0;
vars->sq_norm_oldW[answerind] = vars->sq_norm_W[answerind];
oldW0 = vars->oldW0[answerind] = vars->W0[answerind];
W0 = 0.;
for (i=0; i<numlhs; i++)
{
if ( (alpha= lhs->alpha[i]) > 0 )
{
//printf("%9.6f ",alpha);
for (j=0; j<numfeatures; j++)
W[j] += alpha * lhs->full_A[OCAS_INDEX(j,i,numfeatures)];
W0 += lhs->A0[i] * alpha;
}
}
vars->W0[answerind] = W0;
sq_norm_W = W0 * W0;
dot_prod_WoldW = W0 * oldW0;
for (j=0; j<numfeatures; j++)
{
//if ( W[j] != 0 )
// printf("W.%f ",W[j]);
sq_norm_W += W[j] * W[j];
dot_prod_WoldW += W[j] * oldW[j];
}
//printf("alphas %9.6f | W0 %f sw_norm_W %f | A%02d\n",_dbufave(lhs->alpha,numlhs),W0,sq_norm_W,answerind);
vars->dot_prod_WoldW[answerind] = dot_prod_WoldW;
vars->sq_norm_W[answerind] = sq_norm_W;
}
static inline void ocas_update_Lspace(register struct ocas_vars *vars,register int answerind,register double netcuts,register double cut_length,register int numfeatures,register double C,register double QPSolverTolAbs,register double QPSolverTolRel)
{
register struct ocas_CLbuffers *ptr = vars->CLspaces[answerind];
register struct ocas_lhsbuffers *lhs = vars->lhs[answerind];
register double *new_col_H;
register double sq_norm_a,maxiters,metric,tmp;
register int i,j,iters,numlhs,maxlhs = vars->maxlhs;
numlhs = vars->numlhs[answerind];
new_col_H = &lhs->H[OCAS_INDEX(0,numlhs,maxlhs)];
lhs->A0[numlhs] = netcuts;
lhs->b[numlhs] = -cut_length;
sq_norm_a = lhs->A0[numlhs] * lhs->A0[numlhs];
for (j=0; j<numfeatures; j++)
{
lhs->full_A[OCAS_INDEX(j,numlhs,numfeatures)] = ptr->new_a[j];
if ( fabs(ptr->new_a[j]) > 1000 )
{
//printf("(%d %9.6f %f) ",j,ptr->new_a[j],sq_norm_a);
ptr->new_a[j] = 0.;
}
else
sq_norm_a += ptr->new_a[j] * ptr->new_a[j];
ptr->oldW[j] = ptr->W[j]; ptr->W[j] = 0.;
}
new_col_H[numlhs] = sq_norm_a;
//printf("QPsolver.A%02d: ABS %f Rel %.11f numlhs.%d cutlen.%f netcuts.%f sq_norm_a %f netcuts.%f\n",answerind,QPSolverTolAbs,QPSolverTolRel,vars->numlhs[answerind],cut_length,lhs->A0[numlhs],sq_norm_a,netcuts);
for (i=0; i<numlhs; i++)
{
tmp = lhs->A0[numlhs] * lhs->A0[i];
for (j=0; j<numfeatures; j++)
tmp += ptr->new_a[j] * lhs->full_A[OCAS_INDEX(j,i,numfeatures)];
new_col_H[i] = tmp;
}
lhs->d[numlhs] = lhs->alpha[numlhs] = 0.;
lhs->diag_H[numlhs] = lhs->H[OCAS_INDEX(numlhs,numlhs,maxlhs)];
for (i=0; i <numlhs; i++)
lhs->H[OCAS_INDEX(numlhs,i,maxlhs)] = lhs->H[OCAS_INDEX(i,numlhs,maxlhs)];
numlhs = ++vars->numlhs[answerind];
iters = vars->numIt[answerind];
if ( vars->nohwm[answerind] > 3 )
vars->maxiters[answerind] *= 1 + sqrt(vars->nohwm[answerind])/100;
else if ( vars->nohwm[answerind] == 0 )
vars->maxiters[answerind] *= .5;
if ( vars->maxiters[answerind] > QPSOLVER_MAXITER )
vars->maxiters[answerind] = QPSOLVER_MAXITER;
if ( vars->maxiters[answerind] < QPSOLVER_MINITER )
vars->maxiters[answerind] = QPSOLVER_MINITER;
maxiters = MAX(QPSOLVER_MINITER,vars->maxiters[answerind]);
vars->Q_D[answerind] = ocas_splx_solver(&vars->nNZAlpha[answerind],maxlhs,lhs->d,lhs->H,lhs->diag_H,lhs->b,C,lhs->alpha,vars->numlhs[answerind],MIN(maxiters,QPSOLVER_MAXITER),QPSolverTolAbs,QPSolverTolRel,OCAS_NEG_INF);
metric = ((double)vars->len[answerind] / MAX(1,vars->trn_err[answerind])) / 1.;
vars->lastmetrics[answerind][iters & 1] = metric;
update_ocas_model(ptr->W,ptr->oldW,vars,numfeatures,answerind,lhs,numlhs);
}
static inline void start_ocas_iter(register struct ocas_vars *vars,register int c,register int answerind)
{
if ( vars->pratio[answerind] == 0. )
vars->pratio[answerind] = vars->answerabsaves[answerind];
vars->good[answerind] = -1;
vars->bad[answerind] = vars->trn_err[answerind] = vars->cutlen[answerind] = vars->numposcuts[answerind] = vars->numnegcuts[answerind] = 0;
vars->xi[answerind] = vars->predsum[answerind] = vars->dist[answerind] = vars->cutsum[answerind] = vars->netcuts[answerind] = 0.;
}
static void ocas_print(struct ocas_vars *vars,int answerind,int ishwm,double C)
{
int i;
double dispvals[4];
//printf("ocas_print.A%d\n",answerind);
//printf("%s.A%02d %4d %8.2f | QP %9.3f QD %9.3f [%9.4f %7.3f] SV.%d %4d | M%9.6f (%9.6f max %8.1f %9.6f) %s.A%02d %9.6f%%\n",
dispvals[0] = vars->Q_P[answerind]/1000000000.; dispvals[1] = (C * vars->Q_D[answerind])/1000000000.;
dispvals[2] = (vars->Q_P[answerind]-C * vars->Q_D[answerind]) / 1000000000;
dispvals[3] = (vars->Q_P[answerind]-C * vars->Q_D[answerind]) / MAX(1,fabs(vars->Q_P[answerind]));
printf("%3d %d.A%02d +%d -%d",vars->nohwm[answerind],vars->refc,answerind,vars->good[answerind],vars->bad[answerind]);
printf(" %4d %8.2f |QP %9.3f QD %10.2f [%11.2f %9.1f] SV.%3d %3d |M%9.3f errs.%-6d %-8.0f %5.2f%% errs %6.5f A%9.6f W0%9.6f D%11.9f\n",//[%7.4f%%]\n",
vars->numIt[answerind],vars->ocas_time/1000,dispvals[0],dispvals[1],dispvals[2],dispvals[3],
vars->nNZAlpha[answerind], vars->numlhs[answerind],
// PTRS->lastmetrics[answerind],PTRS->learningrates[answerind][0],PTRS->maxiters[answerind],PTRS->learningrates[answerind][1],
vars->lastmetrics[answerind][0],vars->trn_err[answerind],vars->maxiters[answerind],vars->perc[answerind],
vars->errperc[answerind]/100,_dbufave(vars->CLspaces[answerind]->new_a,vars->numfeatures),vars->W0[answerind],
vars->dist[answerind]/vars->answerabsaves[answerind]);//_dbufave(vars->hwmperc,81));//,vars->errperc+vars->perc);
for (i=0; i<4; i++)
if ( isnan(dispvals[i]) != 0 )
break;
if ( vars->lastmetrics[answerind][0] > 10 )
usleep(vars->lastmetrics[answerind][0] * vars->lastmetrics[answerind][0]);
/*if ( 0 && i < 4 )//|| (vars->answerind >= 32 && fabs(vars->W0) > .9) )
{
int save_model(int refc,int answerind,double *W,int numfeatures,double W0,double perc,int posA,int negA);
memset(&vars->CLspaces[answerind],0,sizeof(vars->CLspaces[answerind]));
vars->W0[answerind] = vars->oldW0[answerind] = 0.;
vars->numIt[answerind] = 0;
vars->perc[answerind] = vars->hwmperc[answerind] = 0.;
printf("reset model %s.A%02d\n",CONTRACTS[vars->selector!=3?vars->refc:NUM_COMBINED],answerind);
save_model(vars->refc,answerind,vars->CLspaces[answerind]->W,vars->numfeatures,vars->W0[answerind],vars->perc[answerind]);
}*/
}
static inline void finish_ocasiter(register int answerind,register struct ocas_vars *vars,register double C)
{
register double den;
vars->have_pendingmodel[answerind] = 0;
if ( vars->good[answerind] == 0 && vars->bad[answerind] == 0 )
{
vars->bad[answerind] = vars->trn_err[answerind];
vars->good[answerind] = (vars->len[answerind] - vars->trn_err[answerind]);
}
den = MAX(1.,vars->good[answerind]+vars->bad[answerind]);
if ( (vars->predabs[answerind] = (vars->predsum[answerind] / den)) != 0. )
vars->pratio[answerind] = (vars->answerabsaves[answerind] / vars->predabs[answerind]);
else vars->pratio[answerind] = 0.;
vars->dist[answerind] = sqrt(vars->dist[answerind] / den);
//printf("W0 %9.6f pred sum %f %f | pratio %f distsum %f (%f vs hwm %f)\n",vars->W0[answerind],vars->predsum[answerind],vars->predabs[answerind],vars->pratio[answerind],vars->dist[answerind],vars->perc[answerind],vars->hwmperc[answerind]);
vars->errperc[answerind] = (100 * (double)vars->trn_err[answerind])/(double)MAX(1,vars->len[answerind]);
vars->Q_P[answerind] = 0.5*vars->sq_norm_W[answerind] + (C * vars->xi[answerind]);
vars->ocas_time = (vars->output_time + vars->w_time + vars->add_time + vars->sort_time + vars->qp_solver_time);
ocas_print(vars,answerind,0,C);
}
static inline int ocas_iter(struct ocas_vars *vars,int max_nohwm)
{
int Method = 1;
int min_nohwm = 1;
int skipflags[84];
static int new_cut[MAX_VECTORS];
static double2 hpfb[MAX_VECTORS];
int inactives[81];
register struct ocas_CLbuffers *ptr;
register double netcuts,startmilli,y,psum,pcount,nosum;
register int i,numfeatures,cutlen,lastanswerind,lwm=(1<<20),numactive,numthreads,answerind,*weekinds;
numactive = 0;
if ( (numfeatures= vars->numfeatures) > MAX_OCAS_FEATURES )
{
printf("numfeatures > MAX_OCAS_FEATURES\n");
exit(-1);
}
psum = pcount = nosum = 0;
{
//printf("c.%d mask %lx %p\n",c,contractmask,PTRS->ocas[c]);
memset(inactives,0,sizeof(inactives));
lastanswerind = TRADEBOTS_NUMANSWERS;
numfeatures = vars->numfeatures;
answerind = 0;
//printf("numIt.%d ocas iter.%s A.mask%lx len.%d CLspace.%p lhs.%p | vars.%p\n",vars->numIt[answerind],CONTRACTS[c_to_refc(c)],answerindmask,vars->len[answerind],vars->CLspaces[answerind],vars->lhs[answerind],vars);
memset(skipflags,0,sizeof(skipflags));
for (answerind=0; answerind<lastanswerind; answerind++)
{
//printf("answerind.%d of %d %ld, active CLspace.%p weekinds.%p | nohwm.%d max.%d\n",answerind,lastanswerind,answerindmask,vars->CLspaces[answerind],vars->weekinds[answerind],vars->nohwm[answerind],max_nohwm);
if ( vars->hwmperc[answerind] != 0 )
{
nosum += vars->nohwm[answerind];
pcount++, psum += vars->hwmperc[answerind];
}
//printf("answerind.%d\n",answerind);
if ( vars->len[answerind] == 0 || vars->CLspaces[answerind] == 0 || (vars->nohwm[answerind] > min_nohwm && vars->hwmperc[answerind] > ((answerind==0) ? HWMPERC_THRESHOLD0 : HWMPERC_THRESHOLD)) )
{
inactives[answerind] = 1;
continue;
}
if ( vars->nohwm[answerind] < max_nohwm )
{
numactive++;
if ( vars->numIt[answerind]++ == 0 )
{
for (i=0; i<numfeatures; i++)
if ( vars->CLspaces[answerind]->W[i] != 0 )
break;
if ( i == numfeatures )
skipflags[answerind] = 1;
}
ptr = vars->CLspaces[answerind];
weekinds = vars->weekinds[answerind];
//printf("start iter %p %p\n",ptr,weekinds);
start_ocas_iter(vars,vars->c,answerind);
numthreads = vars->numthreads;
if ( skipflags[answerind] != 0 )
{
for (i=0; i<vars->len[answerind]; i++)
{
if ( (y= vars->answers[(weekinds[i]-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]) != 0.f )
{
ptr->output_pred[i] = 0;
add_newcut_entry(vars,answerind,new_cut,i,weekinds[i],y);
}
}
fprintf(stderr,"skip %d.A%02d cuts +%d -%d, ",c_to_refc(vars->c),answerind,vars->numposcuts[answerind],vars->numnegcuts[answerind]);
}
else
{
startmilli = OS_milliseconds();
//printf("%s ocas_calc_outputs.A%d len.%d | numthreads.%d\n",CONTRACTS[c_to_refc(c)],answerind,vars->len[answerind],numthreads);
STocas_calc_outputs(vars,vars->c,answerind,ptr->output_pred,ptr->old_output,ptr->W,vars->W0[answerind],numfeatures,weekinds,vars->len[answerind]);
//ocas_calc_outputs(PTRS,numthreads,vars,c,answerind,ptr->output_pred,ptr->old_output,ptr->W,vars->W0[answerind],numfeatures,weekinds,vars->len[answerind]);
vars->output_time += (OS_milliseconds() - startmilli);
if ( Method != 0 )
{
startmilli = OS_milliseconds();
//printf("%d calc_ocas_strategy.A%d len.%d | numthreads.%d\n",c_to_refc(vars->c),answerind,vars->len[answerind],numthreads);
calc_ocas_strategy(vars,answerind,vars->C,numfeatures,vars->maxlen,weekinds,new_cut,ptr->W,ptr->oldW,ptr->output_pred,ptr->old_output,hpfb);
vars->w_time += (OS_milliseconds() - startmilli);
}
finish_ocasiter(answerind,vars,vars->C);
}
//printf("%s calc ocas_add_newcuts.A%d poscuts.%d negcuts.%d | numthreads.%d\n",CONTRACTS[c_to_refc(c)],answerind,vars->numposcuts[answerind],vars->numnegcuts[answerind],vars->numthreads);
startmilli = OS_milliseconds();
//if ( vars->nohwm[answerind] > 13 )
// numthreads = vars->numthreads;///MAIN_MAXCORES;
memset(ptr->new_a,0,sizeof(ptr->new_a));
//ocas_add_newcuts(PTRS,numthreads,vars,answerind,numfeatures,weekinds,new_cut,vars->numposcuts[answerind]+vars->numnegcuts[answerind],ptr->W,ptr->new_a);
STocas_add_newcuts(vars,answerind,numfeatures,weekinds,new_cut,vars->numposcuts[answerind]+vars->numnegcuts[answerind],ptr->W,ptr->new_a);
vars->add_time += (OS_milliseconds() - startmilli);
//printf("done %d calc ocas_add_newcuts.A%d poscuts.%d negcuts.%d | good.%d bad.%d\n",c_to_refc(vars->c),answerind,vars->numposcuts[answerind],vars->numnegcuts[answerind],vars->good[answerind],vars->bad[answerind]);
} else inactives[answerind] = 1;//, printf("maxnohwm.%d\n",max_nohwm);
}
startmilli = OS_milliseconds();
for (answerind=0; answerind<lastanswerind; answerind++)
{
if ( inactives[answerind] != 0 )
continue;
netcuts = (vars->numposcuts[answerind] - vars->numnegcuts[answerind]);
cutlen = (vars->numposcuts[answerind] + vars->numnegcuts[answerind]);
if ( vars->nohwm[answerind] < lwm )
lwm = vars->nohwm[answerind];
ocas_update_Lspace(vars,answerind,netcuts,cutlen,numfeatures,vars->C,0.,vars->QPSolverTolRel);
}
vars->qp_solver_time += (OS_milliseconds() - startmilli);
}
if ( pcount != 0 )
printf("numactive.%d %.0f | ave perf %f%% | ave nohwm %.1f\n",numactive,pcount,psum/pcount,nosum/pcount);
return(numactive);
}
static inline int init_ocas_vars(int numthreads,int selector,long answerindmask,struct ocas_vars *vars,int c,double C,int numfeatures,int maxlhs,int maxlen,int len,double *answerabsave,int *posA,int *negA)
{
int answerind,lastanswerind,retval = 0;
lastanswerind = TRADEBOTS_NUMANSWERS;
vars->maxlen = maxlen;
vars->numthreads = numthreads;
vars->selector = selector;
//printf("init_ocas_vars lastanswerind.%d\n",lastanswerind);
for (answerind=0; answerind<lastanswerind; answerind++)
{
//printf("A%d.len_%d ",answerind,vars->len[answerind]);
if ( vars->len[answerind] > 0 )//&& (answerindmask == -1L || ((1L<<answerind) & answerindmask) != 0) )
{
vars->refc = c_to_refc(c); vars->c = c; vars->C = C;
vars->numfeatures = numfeatures; vars->maxlhs = maxlhs;
if ( vars->CLspaces[answerind] == 0 )
vars->CLspaces[answerind] = myaligned_alloc(sizeof(*vars->CLspaces[answerind]));
vars->answerabsaves[answerind] = answerabsave[answerind];
vars->posA[answerind] = posA[answerind]; vars->negA[answerind] = negA[answerind];
if ( vars->lhs[answerind] == 0 )
vars->lhs[answerind] = myaligned_alloc(sizeof(*vars->lhs[answerind]) + numfeatures*maxlhs*sizeof(double));
vars->maxiters[answerind] = QPSOLVER_MINITER; vars->trn_err[answerind] = vars->len[answerind]; vars->Q_P[answerind] = 0.5*vars->sq_norm_W[answerind] + C*vars->len[answerind];
vars->perc[answerind] = vars->hwmperc[answerind] = vars->dist[answerind] = vars->hwmdist[answerind] = 0.; vars->numIt[answerind] = 0;
//printf("init.A%d %d | %p %p weekinds.%p\n",answerind,vars->len[answerind],vars->CLspaces[answerind],vars->lhs[answerind],vars->weekinds[answerind]);
}
}
//printf("mask.%lx init_ocas_vars selector.%d weekinds[0].%p\n",answerindmask,selector,vars->weekinds[0]);
return(retval);
}
void ocas_init(struct ocas_vars *vars,int32_t c,int32_t numfeatures,int32_t starti,int32_t endi)
{
struct ocas_CLbuffers *ptr; struct ocas_lhsbuffers *lhs;
int32_t nonz,weekind,answerind; double answer,y;
if ( numfeatures < 0 )
return;
vars->maxlhs = MAX_OCAS_LHS;
vars->numfeatures = numfeatures;
vars->maxlen = (endi - starti + 1);
vars->C = 1.;
vars->c = c;
vars->TolRel = 0.01;
vars->TolAbs = 0.0;
vars->QPSolverTolRel = vars->TolRel*0.5;
vars->QPSolverTolAbs = vars->TolAbs*0.5;
vars->MaxTime = OCAS_INFINITY;
vars->QPBound = 0.0;
memset(vars->posA,0,sizeof(vars->posA));
memset(vars->negA,0,sizeof(vars->negA));
memset(vars->answeraves,0,sizeof(vars->answeraves));
memset(vars->answerabsaves,0,sizeof(vars->answerabsaves));
memset(vars->firstweekinds,0,sizeof(vars->firstweekinds));
vars->starti = starti;
vars->answers = calloc(TRADEBOTS_NUMANSWERS,sizeof(vars->answers)*vars->maxlen);
vars->features = calloc(vars->maxlen,sizeof(*vars->features));
for (answerind=0; answerind<TRADEBOTS_NUMANSWERS; answerind++)
vars->weekinds[answerind] = calloc(vars->maxlen,sizeof(*vars->weekinds[answerind]));
for (weekind=starti; weekind<=endi; weekind++)
{
if ( (vars->features[weekind - starti]= get_features(numfeatures,c,weekind)) == 0 )
continue;
for (answerind=0; answerind<TRADEBOTS_NUMANSWERS; answerind++)
{
if ( (vars->posA[answerind]+vars->negA[answerind]) >= vars->maxlen )
continue;
if ( (y= get_yval(&answer,0,weekind,c,answerind)) != 0.f )
{
vars->answers[(weekind-starti)*TRADEBOTS_NUMANSWERS + answerind] = y;
vars->weekinds[answerind][vars->len[answerind]++] = weekind;
if ( vars->posA[answerind]+vars->negA[answerind] == 0 )
vars->firstweekinds[answerind] = weekind;
vars->answeraves[answerind] += answer;
if ( answer > 0 )
{
vars->posA[answerind]++;
vars->answerabsaves[answerind] += answer;
}
else if ( answer < 0 )
{
vars->negA[answerind]++;
vars->answerabsaves[answerind] -= answer;
}
}
}
}
for (answerind=0; answerind<TRADEBOTS_NUMANSWERS; answerind++)
if ( (nonz= (vars->posA[answerind]+vars->negA[answerind])) != 0 )
{
vars->answerabsaves[answerind] /= nonz;
vars->answeraves[answerind] /= nonz;
printf("A%02d.(%9.6f %d %d) ",answerind,vars->answerabsaves[answerind],vars->posA[answerind],vars->negA[answerind]);
}
init_ocas_vars(1,0,-1,vars,c,vars->C,numfeatures,MAX_OCAS_LHS,vars->maxlen,vars->maxlen,vars->answerabsaves,vars->posA,vars->negA);
for (answerind=0; answerind<TRADEBOTS_NUMANSWERS; answerind++)
{
//if ( answerindmask != -1 && ((1L<<answerind) & answerindmask) == 0 )
// continue;
//printf("finish A%d len.%d\n",answerind,vars->len[answerind]);
lhs = vars->lhs[answerind];
ptr = vars->CLspaces[answerind];
//printf("%d.A%d call init ocas vars weekinds[0] %p numfeatures.%d (%p %p)\n",c_to_refc(vars->c),answerind,vars->weekinds[0],numfeatures,lhs,ptr);
if ( lhs == 0 || ptr == 0 )
continue;
vars->numlhs[answerind] = 0;//init_full_A(lhs->full_A,vars->numfeatures,c,answerind,models);
memset(ptr->W,0,sizeof(*ptr->W) * numfeatures);
memset(ptr->oldW,0,sizeof(*ptr->oldW) * numfeatures);
vars->W0[answerind] = vars->oldW0[answerind] = 0;
#ifndef DISABLE_EXISTINGMODEL
double init_model(double *percp,double *W,double *oldW,int c,int answerind,int numfeatures);
vars->W0[answerind] = init_model(&vars->hwmperc[answerind],ptr->W,ptr->oldW,c,answerind,vars->numfeatures);
if ( _dbufave(ptr->W,numfeatures) != 0 )
validate_ocas_model(vars,answerind,ptr->output_pred,ptr->old_output,vars->weekinds[answerind],vars->len[answerind],ptr->W,vars->W0[answerind],numfeatures,1);
#endif
//printf("%s.A%d call init ocas vars weekinds[0] %p\n",CONTRACTS[c_to_refc(c)],answerind,vars->weekinds[0]);
}
vars->output_time = vars->sort_time = vars->w_time = vars->qp_solver_time = vars->ocas_time = vars->add_time = 0;
vars->startweekind = starti; vars->endweekind = endi;
}
int32_t ocas_gen(int32_t c,int32_t numfeatures,int32_t starti,int32_t endi)
{
int32_t i; struct ocas_vars *vars = calloc(1,sizeof(*vars));
ocas_init(vars,c,numfeatures,starti,endi);
for (i=0; i<10; i++)
ocas_iter(vars,3);
ocas_purge(vars);
return(0);
}
#endif