void *error_grad_routine(void *args) { FiltWorker *fw = (FiltWorker*)args; fw->dedw = createZeroMatrix(fw->w->nrow, fw->w->ncol); for(size_t i=fw->first; i<fw->last; i++) { double gr_val = -2*(fw->target->array[i] - conv(i, fw->y, fw->w)); for(size_t wi=0; wi < fw->dedw->nrow; wi++) { int yi=i; size_t wj=0; for(; (wj < fw->dedw->ncol) && (yi>=0); wj++, yi--) { incMatrixElement(fw->dedw, wi, wj, gr_val * getMatrixElement(fw->y, wi, yi)); } } } return(NULL); }
Matrix* calcErrorGrad(Matrix *y, Matrix *w, doubleVector *target, int jobs) { assert(y->ncol == target->size); pthread_t *threads = (pthread_t *) malloc( jobs * sizeof( pthread_t ) ); FiltWorker *workers = (FiltWorker*) malloc( jobs * sizeof(FiltWorker) ); for(size_t wi=0; wi < jobs; wi++) { int points_per_thread = (y->ncol + jobs - 1) / jobs; workers[wi].first = min( wi * points_per_thread, y->ncol ); workers[wi].last = min( (wi+1) * points_per_thread, y->ncol ); workers[wi].y = y; workers[wi].w = w; workers[wi].target = target; } for( int i = 0; i < jobs; i++ ) { P( pthread_create( &threads[i], NULL, error_grad_routine, &workers[i]) ); } for( int i = 0; i < jobs; i++ ) { P( pthread_join( threads[i], NULL) ); } Matrix *dedw = createZeroMatrix(w->nrow, w->ncol); for( size_t wi=0; wi< jobs; wi++) { for(size_t i=0; i<dedw->nrow; i++) { for(size_t j=0; j<dedw->ncol; j++) { incMatrixElement(dedw, i, j, getMatrixElement(workers[wi].dedw, i, j)); } } } for(size_t i=0; i<dedw->nrow; i++) { for(size_t j=0; j<dedw->ncol; j++) { double dedw_acc = getMatrixElement(dedw, i, j); setMatrixElement(dedw, i, j, dedw_acc/target->size); } } free(threads); free(workers); return dedw; }
Matrix *runLbfgsOptim(Matrix *y, doubleVector *target, int L, int jobs, double epsilon) { int M = y->nrow; Matrix *w = createZeroMatrix(M, L); lbfgsfloatval_t fx; lbfgsfloatval_t *x = lbfgs_malloc(w->nrow*w->ncol); lbfgs_parameter_t param; if (x == NULL) { printf("ERROR: Failed to allocate a memory block for variables.\n"); exit(1); } /* Initialize the variables. */ for (size_t i = 0; i < w->nrow; i++) { for (size_t j = 0; j < w->ncol;j++) { x[j*w->nrow + i] = getMatrixElement(w, i, j); } } lbfgs_parameter_init(¶m); param.epsilon = epsilon; param.m = 20; LbfgsInput inp; inp.target = target; inp.y = y; inp.jobs = jobs; inp.L = w->ncol; int ret = lbfgs(w->nrow*w->ncol, x, &fx, evaluate, progress, (void*)&inp, ¶m); printf("L-BFGS optimization terminated with status code = %d\n", ret); printf(" fx = %f\n", fx); Matrix *w_opt = formMatrixFromFloatVal(x, w->nrow, w->ncol); lbfgs_free(x); return(w_opt); }
Matrix callFunc(const char *funcName, ASTNode *argListNode){ /* sort out args */ ASTNode *argNode[10]; Matrix result; Number calcresult; MatList *p; if (strcmp(funcName, "eye")==0) { /* generate eye matrix */ argNode[0] = getNthArgFromArgList(argListNode,1); result = createEyeMatrix((int)readOneElementOfMatrix(argNode[0]->mat,1,1)); } else if(strcmp(funcName, "rand")==0){/*generate rand matrix*/ argNode[0] = getNthArgFromArgList(argListNode,1); argNode[1] = getNthArgFromArgList(argListNode,2); result = createRandMatrix((int)readOneElementOfMatrix(argNode[0]->mat,1,1),readOneElementOfMatrix(argNode[1]->mat,1,1)); } else if(strcmp(funcName, "zeros")==0){/*generate rand matrix*/ argNode[0] = getNthArgFromArgList(argListNode,1); argNode[1] = getNthArgFromArgList(argListNode,2); result = createZeroMatrix((int)readOneElementOfMatrix(argNode[0]->mat,1,1),readOneElementOfMatrix(argNode[1]->mat,1,1)); } else if(strcmp(funcName, "max")==0){/*calculate maximum of matrix*/ argNode[0] = getNthArgFromArgList(argListNode,1); calcresult = maxMatrix(argNode[0]->mat); result = createEyeMatrix(1); changeOneElementOfMatrix(result, 1, 1, calcresult); } else if(strcmp(funcName, "min")==0){/*calculate minimum of matrix*/ argNode[0] = getNthArgFromArgList(argListNode,1); calcresult = minMatrix(argNode[0]->mat); result = createEyeMatrix(1); changeOneElementOfMatrix(result, 1, 1, calcresult); } else if(strcmp(funcName, "sum")==0){/*calculate sum of matrix*/ argNode[0] = getNthArgFromArgList(argListNode,1); calcresult = sumMatrix(argNode[0]->mat); result = createEyeMatrix(1); changeOneElementOfMatrix(result, 1, 1, calcresult); } else if(strcmp(funcName, "round")==0){/*calculate round of matrix*/ argNode[0] = getNthArgFromArgList(argListNode,1); result = roundMatrix(argNode[0]->mat); } else if(strcmp(funcName, "upper")==0){/*calculate upper of matrix*/ argNode[0] = getNthArgFromArgList(argListNode,1); result = upperMatrix(argNode[0]->mat); } else if(strcmp(funcName, "lower")==0){/*calculate upper of matrix*/ argNode[0] = getNthArgFromArgList(argListNode,1); result = lowerMatrix(argNode[0]->mat); } else if(strcmp(funcName, "det")==0){/*calculate DeterminantCalc*/ argNode[0] = getNthArgFromArgList(argListNode,1); calcresult = DeterminantCalc(argNode[0]->mat.row, argNode[0]->mat); result = createEyeMatrix(1); changeOneElementOfMatrix(result, 1, 1, calcresult); } else if(strcmp(funcName, "turn")==0){/*calculate turn*/ argNode[0] = getNthArgFromArgList(argListNode,1); result = turnMatrix(argNode[0]->mat); } else if(strcmp(funcName, "power")==0){/*calculate power*/ argNode[0] = getNthArgFromArgList(argListNode,1); argNode[1] = getNthArgFromArgList(argListNode,2); result = powerMatrix(argNode[0]->mat,(int)readOneElementOfMatrix(argNode[1]->mat,1,1)); } else if(strcmp(funcName, "dot")==0){/*calculate dot*/ argNode[0] = getNthArgFromArgList(argListNode,1); argNode[1] = getNthArgFromArgList(argListNode,2); result = dotMatrix(argNode[0]->mat,argNode[1]->mat); } else if(strcmp(funcName, "norm")==0){/*calculate norm*/ argNode[0] = getNthArgFromArgList(argListNode,1); result = normMatrix(argNode[0]->mat); } else if(strcmp(funcName, "angle")==0){/*calculate norm*/ argNode[0] = getNthArgFromArgList(argListNode,1); argNode[1] = getNthArgFromArgList(argListNode,2); result = angleMatrix(argNode[0]->mat,argNode[1]->mat); } else{ if (get_submatrix == 1){ p = checkMatName(funcName); argNode[0] = getNthArgFromArgList(argListNode,1); argNode[1] = getNthArgFromArgList(argListNode,2); result = createSubMatrix(p->mat,argNode[0]->mat,argNode[1]->mat); get_submatrix = 0; } else{ p = checkMatName(funcName); argNode[0] = getNthArgFromArgList(argListNode,1); argNode[1] = getNthArgFromArgList(argListNode,2); calcresult = readOneElementOfMatrix(p->mat,(int)readOneElementOfMatrix(argNode[0]->mat,1,1),readOneElementOfMatrix(argNode[1]->mat,1,1)); result = createEyeMatrix(1); changeOneElementOfMatrix(result, 1, 1, calcresult); } } return result; }