예제 #1
0
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);
	}
}
예제 #2
0
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 ;
	}
}
예제 #3
0
파일: gamsel.c 프로젝트: cran/gamsel
/* 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;
}