/* build orthonormal basis matrix
Q = Y;
for j=1:k
    vj = Q(:,j);
    for i=1:(j-1)
        vi = Q(:,i);
        vj = vj - project_vec(vj,vi);
    end
    vj = vj/norm(vj);
    Q(:,j) = vj;
end
*/
void build_orthonormal_basis_from_mat(mat *A, mat *Q){
    int m,n,i,j,ind,num_ortos=2;
    double vec_norm;
    vec *vi,*vj,*p;
    m = A->nrows;
    n = A->ncols;
    vi = vector_new(m);
    vj = vector_new(m);
    p = vector_new(m);
    matrix_copy(Q, A);

    for(ind=0; ind<num_ortos; ind++){
        for(j=0; j<n; j++){
            matrix_get_col(Q, j, vj);
            for(i=0; i<j; i++){
                matrix_get_col(Q, i, vi);
                project_vector(vj, vi, p);
                vector_sub(vj, p);
            }
            vec_norm = vector_get2norm(vj);
            vector_scale(vj, 1.0/vec_norm);
            matrix_set_col(Q, j, vj);
        }
    }
    vector_delete(vi);
    vector_delete(vj);
    vector_delete(p);
}
Beispiel #2
0
static void ProjectAmplitude ( 
    BeadParams *p, 
    const float *observed, 
    const float *const *model_trace, 
    const float *em_vector, 
    int npts, 
    float negative_amplitude_limit ,
    float positive_amplitude_limit,
    int flow_block_size
  )
{
  static int numWarnings = 0;
  for ( int fnum=0; fnum<flow_block_size; fnum++ )
  {
    float tmp_mult= project_vector ( & ( observed[npts*fnum] ),model_trace[fnum],em_vector,npts );
    p->Ampl[fnum] *=tmp_mult;
    // Some limited warnings
    if ( p->Ampl[fnum]!=p->Ampl[fnum] && numWarnings++ < 10 )
    {
      printf ( "BSA: tmp_mult:\t%f\n",tmp_mult );
      printf ( "BSA: em\t" );
      for ( int ix=0; ix<npts; ix++ )
        printf ( "%f\t",em_vector[ix] );
      printf ( "\n" );
      printf ( "BSA: obser\t" );
      for ( int ix=0; ix<npts; ix++ )
        printf ( "%f\t",observed[npts*fnum+ix] );
      printf ( "\n" );
      printf ( "BSA: model\t" );
      for ( int ix=0; ix<npts; ix++ )
        printf ( "%f\t",model_trace[fnum][ix] );
      printf ( "\n" );

    }
    // Not sure why 1.0f but this is how I found it...
    if ( p->Ampl[fnum]!=p->Ampl[fnum] )
    {
      p->Ampl[fnum]=1.0f;
    }
    // bounds check
    if ( p->Ampl[fnum]<negative_amplitude_limit )
      p->Ampl[fnum] = negative_amplitude_limit; // Projection onto zero returns potentially large number, but we may want negative values here
    if ( p->Ampl[fnum]>positive_amplitude_limit )
      p->Ampl[fnum]=positive_amplitude_limit; // we limit this everywhere else, so keep from explosion
  }
}
/* build orthonormal basis matrix
Q = Y;
for j=1:k
    vj = Q(:,j);
    for i=1:(j-1)
        vi = Q(:,i);
        vj = vj - project_vec(vj,vi);
    end
    vj = vj/norm(vj);
    Q(:,j) = vj;
end
*/
void build_orthonormal_basis_from_mat(gsl_matrix *A, gsl_matrix *Q){
    int m,n,i,j,ind,num_ortos=2;
    double vec_norm;
    gsl_vector *vi,*vj,*p;
    m = A->size1;
    n = A->size2;
    vi = gsl_vector_calloc(m);
    vj = gsl_vector_calloc(m);
    p = gsl_vector_calloc(m);
    gsl_matrix_memcpy(Q, A);
    for(ind=0; ind<num_ortos; ind++){
        for(j=0; j<n; j++){
            gsl_matrix_get_col(vj, Q, j);
            for(i=0; i<j; i++){
                gsl_matrix_get_col(vi, Q, i);
                project_vector(vj, vi, p);
                gsl_vector_sub(vj, p);
            }
            vec_norm = gsl_blas_dnrm2(vj);
            gsl_vector_scale(vj, 1.0/vec_norm);
            gsl_matrix_set_col (Q, j, vj);
        }
    }
}
void estimate_rank_and_buildQ(mat *M, double frac_of_max_rank, double TOL, mat **Q, int *good_rank){
    int m,n,i,j,ind,maxdim;
    double vec_norm;
    mat *RN,*Y,*Qbig,*Qsmall;
    vec *vi,*vj,*p,*p1;
    m = M->nrows;
    n = M->ncols;
    maxdim = round(min(m,n)*frac_of_max_rank);

    vi = vector_new(m);
    vj = vector_new(m);
    p = vector_new(m);
    p1 = vector_new(m);

    // build random matrix
    printf("form RN..\n");
    RN = matrix_new(n, maxdim);
    initialize_random_matrix(RN);

    // multiply to get matrix of random samples Y
    printf("form Y: %d x %d..\n",m,maxdim);
    Y = matrix_new(m, maxdim);
    matrix_matrix_mult(M, RN, Y);

    // estimate rank k and build Q from Y
    printf("form Qbig..\n");
    Qbig = matrix_new(m, maxdim);

    matrix_copy(Qbig, Y);

    printf("estimate rank with TOL = %f..\n", TOL);
    *good_rank = maxdim;
    int forbreak = 0;
    for(j=0; !forbreak && j<maxdim; j++){
        matrix_get_col(Qbig, j, vj);
        for(i=0; i<j; i++){
            matrix_get_col(Qbig, i, vi);
            project_vector(vj, vi, p);
            vector_sub(vj, p);
            if(vector_get2norm(p) < TOL && vector_get2norm(p1) < TOL){
                *good_rank = j;
                forbreak = 1;
                break;
            }
            vector_copy(p1,p);
        }
        vec_norm = vector_get2norm(vj);
        vector_scale(vj, 1.0/vec_norm);
        matrix_set_col(Qbig, j, vj);
    }

    printf("estimated rank = %d\n", *good_rank);
    Qsmall = matrix_new(m, *good_rank);
    *Q = matrix_new(m, *good_rank);
    matrix_copy_first_columns(Qsmall, Qbig);
    QR_factorization_getQ(Qsmall, *Q);

    matrix_delete(RN);
    matrix_delete(Y);
    matrix_delete(Qsmall);
    matrix_delete(Qbig);
}
void estimate_rank_and_buildQ(gsl_matrix *M, double frac_of_max_rank, double TOL, gsl_matrix **Q, int *good_rank){
    int m,n,i,j,ind,maxdim;
    double vec_norm;
    gsl_matrix *RN,*Y,*Qbig,*Qsmall;
    gsl_vector *vi,*vj,*p,*p1;
    m = M->size1;
    n = M->size2;
    maxdim = round(min(m,n)*frac_of_max_rank);

    vi = gsl_vector_calloc(m);
    vj = gsl_vector_calloc(m);
    p = gsl_vector_calloc(m);
    p1 = gsl_vector_calloc(m);

    // build random matrix
    printf("form RN..\n");
    RN = gsl_matrix_calloc(n, maxdim);
    initialize_random_matrix(RN);

    // multiply to get matrix of random samples Y
    printf("form Y: %d x %d..\n",m,maxdim);
    Y = gsl_matrix_calloc(m, maxdim);
    matrix_matrix_mult(M, RN, Y);

    // estimate rank k and build Q from Y
    printf("form Qbig..\n");
    Qbig = gsl_matrix_calloc(m, maxdim);

    gsl_matrix_memcpy(Qbig, Y);

    printf("estimate rank with TOL = %f..\n", TOL);
    *good_rank = maxdim;
    int forbreak = 0;
    for(j=0; !forbreak && j<maxdim; j++){
        gsl_matrix_get_col(vj, Qbig, j);
        for(i=0; i<j; i++){
            gsl_matrix_get_col(vi, Qbig, i);
            project_vector(vj, vi, p);
            gsl_vector_sub(vj, p);
            if(gsl_blas_dnrm2(p) < TOL && gsl_blas_dnrm2(p1) < TOL){
                *good_rank = j;
                forbreak = 1;
                break;
            }
            gsl_vector_memcpy(p1,p);
        }
        vec_norm = gsl_blas_dnrm2(vj);
        gsl_vector_scale(vj, 1.0/vec_norm);
        gsl_matrix_set_col(Qbig, j, vj);
    }

    printf("estimated rank = %d\n", *good_rank);
    Qsmall = gsl_matrix_calloc(m, *good_rank);
    *Q = gsl_matrix_calloc(m, *good_rank);
    matrix_copy_first_columns(Qsmall, Qbig);
    QR_factorization_getQ(Qsmall, *Q);

    gsl_matrix_free(RN);
    gsl_matrix_free(Y);
    gsl_matrix_free(Qbig);
    gsl_matrix_free(Qsmall);
    gsl_vector_free(p);
    gsl_vector_free(p1);
    gsl_vector_free(vi);
    gsl_vector_free(vj);
}