Ejemplo n.º 1
0
int LinearFitting::computeFitting(double *fitting, double *model, int nModel,
                                  int index1, int index2, double &xAtMin)
//The model is represented by an array of real numbers that are the 
//exponentials. For example, if model={0, 0.5, 1.0, 2.0}, then, 
//nModel would be 4; and y=c_0*x^0 + c_1*x^0.5 + c_2*x + c_3*x^2.0 . 
//index1 and index2 are the starting index and endind index of the 
//fitting range.
{
  if( index1>index2 || index1<0 || index2>(nDim-1) ) 
    return 1;

  int M=index2-index1+1;
  int N=nModel;
  int i, j;
  double lastMin, xx, val;
  double inc=1.0/(nDim-1);

  double *a=(double *)malloc(N*M*sizeof(double));
  double *aa=(double *)malloc(N*nDim*sizeof(double));
  for( i=0; i<N; i++){
    for(j=0; j<M; j++){
      *(a+i*M+j)=pow( (index1+j)*inc, model[i] );
    }
  }

  for( i=0; i<N; i++)
    for(j=0; j<nDim; j++){
      *(aa+i*nDim+j)=pow( j*inc, model[i] );
    }


  double *b=(double *)malloc(M*sizeof(double));
  for(i=0;i<M;i++) {
    b[i]=raw[i+index1]; 
  }
  for(i=0;i<nDim;i++)
    fitting[i]=0.0;

  int NRHS=1;
  int LWORK=5*M*N;
  double *work=(double*)malloc(LWORK*sizeof(double));
  /*  = 0:  successful exit
  *   < 0:  if INFO = -i, the i-th argument had an illegal value.
  *   > 0:  the algorithm for computing the SVD failed to converge;
  *   if INFO = i, i off-diagonal elements of an intermediate
  *   bidiagonal form did not converge to zero.
  */
  int INFO=1000;
  double *sv=(double*)malloc(N*sizeof(double)); // store singular values
  //negative: so machine precision is used as minimun singular value;
  double RCOND=-5.0; 
  int RANK=-3;

  //Solve the minimum norm problem || b- A^T * X ||, 
  //M is the number of rows of A^T, the solution is stored in b.  
  dgelss(&M, &N, &NRHS, a, &M, b, &M, sv, &RCOND, &RANK, work, &LWORK, 
          &INFO);
  for(i=0;i<nDim;i++)
    for(j=0;j<N;j++)
      fitting[i]+=b[j]*(*(aa+j*nDim+i));

  printf("Linear fitting parameters for range %d to %d are:\n", index1, index2);
  for(i=0;i<N;i++)
    printf("x[%d]=%f\t", i, b[i]);
  printf("RANK=%d INFO=%d \n", RANK, INFO);

  // Find the first minimum after the starting point
  xAtMin = index1 * inc;
  lastMin = fitting[index1];
  for (i = 0; i < (index2 + 1 - index1) * 10000; i++) {
    xx = (index1 + (i + 1) / 10000.) * inc;
    val = 0.;
    for(j=0;j<N;j++)
      val += b[j] * pow(xx, model[j]);
    if (val > lastMin)
      break;
    xAtMin = xx;
    lastMin = val;
  }

  free(a);
  free(aa);
  free(b);
  free(work);
  free(sv);
  return INFO; 
}
Ejemplo n.º 2
0
END_TEST

START_TEST( using_MKL_SVD )
{
  PetscErrorCode ierr;

  int Np = 7;  
  int m = Np, n = 3;
  int lda = m;
  double *a;
  PetscMalloc(m*n*sizeof(double), &a);
  double aa[21] = {1., -2.50725, 6.28632, 1., -1.7072, 2.91453, 1., -0.726423, 0.527691, 1., \
0.452286, 0.204562, 1., 1.81034, 3.27735, 1., 2.53149, 6.40844, 1., 3.76245, \
14.1561};
  double at[21] = {1, 1, 1, 1, 1, 1, 1, -2.50725, -1.7072, -0.726423, 0.452286, 1.81034, \
      2.53149, 3.76245, 3.14316, 1.45727, 0.263846, 0.102281, 1.63868, 3.20422, \
      7.07805};
  double y[7]={1, 2, 5, 9, 7, 6, 5};
  for( int i = 0; i < m*n; i++ )
    a[i] = at[i];
  
  int ldb = Np;
  int nrhs = 1;
  double *b;
  PetscMalloc(Np*nrhs*sizeof(double), &b);
  PetscMemzero(b,Np*nrhs*sizeof(double));
//  double bb[9] = {one,  zero, zero,
//                  zero, one,  zero,
//                  zero, zero, one};
//  for( int i = 0; i < nrhs*m; i++)
//    b[i] = bb[i];

/* NEED B matrix to be Np identity!!! */
  for( int i = 0; i < Np*nrhs; i++)
    b[i] = y[i];
//    b[i+i*Np] = one;
    
  double rcond = -1;
  
  int lwork = 1000;
  double *work;
  PetscMalloc(lwork*sizeof(double), &work);
//  PetscMemzero(work, lwork*sizeof(double));
  
  int rank;
  double *s;
  PetscMalloc( m*sizeof(double), &s);
  int info;
  
  dgelss(
    &m /* num rows in A */,   //3 
    &n /* num cols in A */,   //7
    &nrhs /* num cols in B */,//3
    a /* matrix A for SVD */, 
    &lda /* first dim of A = max( 1, m )*/,  //3 
    b /* matrix B of RHS (become solution matrix x) */, 
    &ldb /* first dim of B = max( 1, m, n ) */, //7
    s /* matrix of s.v */, 
    &rcond /* relative condition s.v. treated as zero */, //-1 
    &rank /*  */, 
    work /*  */, 
    &lwork /* size of work */, 
    &info /*  */
  );
  
  printf("rank: %d\n", rank);
  printf("work[0]: %f\n", work[0] );
  printf("info: %d\n", info);
  
  for( int i = 0; i < n+0*Np*nrhs; i++)
    printf("b %d: %f\n", i, b[i]);
  printf("\n");
  for( int i = 0; i < 3; i++)
    printf("s %d: %f\n", i, s[i]);
  printf("\n");
  for( int i = 0; i < m*n; i++)
    printf("a %d: %f\n", i, a[i]);
  printf("\n");
}