void ConjugateGradient( float **A, float *b, float *x, int N, int iterations) { // vectors float r[N]; float w[N]; float z[N]; // scalars float alpha; float beta; float temp[N]; // initialization of residual vector: r matrixVectorProduct( A, x, temp, N); vectorDifference( b, temp, r, N); // w vectorScale( r, -1, w, N); // z matrixVectorProduct( A, w, z, N); // alpha alpha = dotProduct( r, w, N) / dotProduct( w, z, N); // beta beta = 0.; // x vectorScale( w, alpha, temp, N); vectorSum( x, temp, x, N); for( int i=0; i<iterations; i++){ vectorScale( z, alpha, temp, N); vectorDifference( r, temp, r, N); if( sqrt( dotProduct( r, r, N)) < 1e-10) return; // B = (r'*z)/(w'*z); beta = dotProduct( r, z, N) / dotProduct( w, z, N); // w = -r + B*w; vectorScale( w, beta, w, N); vectorDifference( w, r, w, N); // z = A*w; matrixVectorProduct( A, w, z, N); // a = (r'*w)/(w'*z); alpha = dotProduct( r, w, N) / dotProduct( w, z, N); // x = x + a*w; vectorScale( w, alpha, temp, N); vectorSum( x, temp, x, N); } }
void ConjugateGradient3( float **A, float *b, float *x, int N, int iterations) { float r[N]; float r2[N]; float p[N]; float q[N]; //float beta[N]; //float alpha[N]; float beta; float alpha; float temp[N]; // initialization of residual vector: r_0 matrixVectorProduct( A, x, temp, N); vectorDifference( b, temp, r, N); // initialization of p_0 vectorCopy( r, p, N); for( int i=0; i<iterations; i++){ // q_k matrixVectorProduct( A, p, q, N); alpha = dotProduct( r, r, N); if(i>0){ beta = alpha / dotProduct( r2, r2, N); vectorScale( p, beta, p, N); vectorSum( r, p, p, N); } alpha /= dotProduct( p, q, N); // next x vectorScale( p, alpha, temp, N); vectorSum( x, temp, x, N); // old r vectorCopy( r, r2, N); // next r vectorScale( q, -alpha, temp, N); vectorSum( r, temp, r, N); //float *pointer ; } }
/* Computes objective function at given values of the parameters. */ double calculateObjective(int *n, int *p, double *X, double *U, double *y, double *D, int *degrees, int *cum_degrees, int *numcolsU, double *lambdas_alpha, double *lambdas_beta, double *psis, double *alpha0, double *alphas, double *betas, int *family, double *fit, int *active_alpha, int *active_beta) { double obj = 0.0; double lasso_penalty = 0.0; double group_penalty = 0.0; double spline_penalty = 0.0; double group_norm_squared = 0.0; int group_start_index = 0; double *resid = Calloc(*n, double); memset(fit, 0.0, (*n)*sizeof(double)); /** Calculate linear fit: */ for(int j=0; j<*p; j++) { if(active_alpha[j] == 1) { for(int i=0; i<*n; i++) { fit[i] += alphas[j]*X[(*n)*j + i]; } } if(active_beta[j] == 1) { F77_CALL(dgemv)("N", n, degrees+j, &one, U+(*n)*(cum_degrees[j]), n, betas + cum_degrees[j], &inc_one, &one, fit, &inc_one); } // Increment fit by X*alpha // F77_CALL(dgemv)("N", n, p, &one, X, n, alphas, &inc_one, &one, fit, &inc_one); // Increment by U*beta // F77_CALL(dgemv)("N", n, numcolsU, &one, U, n, betas, &inc_one, &one, fit, &inc_one); } // Increment by intercept for(int i=0; i<*n; i++) { fit[i] += alpha0[0]; } /** End linear fit calculation */ if(*family == 0) { // Linear model // Calculate residual vectorDifference(n, y, fit, resid); // Increment objective by RSS obj += F77_CALL(ddot)(n, resid, &inc_one, resid, &inc_one); } else if(*family == 1){ // Logistic model // Add negative log-likelihood to objective for(int i=0; i<*n; i++) { obj += -(y[i]*fit[i] - log(1 + exp(fit[i]))); } } // Calculate lasso penalty for(int i=0; i<*p; i++) { if(active_alpha[i] == 1) { lasso_penalty += lambdas_alpha[i]*fabs(alphas[i]); } } double *Dbeta = Calloc(*numcolsU, double); for(int i=0; i<*numcolsU; i++) { Dbeta[i] = betas[i]*D[i]; } // Calculate group penalty and spline penalty for(int i=0; i<*p; i++) { if(active_beta[i] == 1) { // group penalty group_norm_squared = F77_CALL(ddot)(degrees+i, Dbeta + group_start_index, &inc_one, betas + group_start_index, &inc_one); group_penalty += lambdas_beta[i]*sqrt(group_norm_squared); // spline penalty spline_penalty += psis[i]*(group_norm_squared- Dbeta[group_start_index]*betas[group_start_index]); } group_start_index += degrees[i]; } // Calculate objective if(*family == 0) obj*=0.5; obj += lasso_penalty + group_penalty + 0.5*spline_penalty; // obj = obj/(*n); // Apply 1/n factor Free(resid); Free(Dbeta); return obj; }