示例#1
0
int mappedCoords2rotation (double **x, double **y, int no_vectors,
			   double q[4], double **R, double T[3], double *rmsd) {

    double x_mp[3], y_mp[3];
    int  ctr;
     int  i, j;
 
    double ATA     [4][4] = {{0.0}};
    double prev_ATA[4][4] = {{0.0}};
    double ATA_sum [4][4] = {{0.0}};
    double a[3] = {0.0}, b[3] = {0.0};

    
    int add_matrices  (double matrix1[4][4],double matrix2[4][4],
		       double result[4][4]);
    int construct_ATA (double ATA[4][4], double a[3], double  b[3]);

    /* note how we pass the matrix: pointer to the first element in the block */
    void dsyev_ (char * jobz, char *uplo,  int *n,
		  double *A, int * lda, double * w, double * work, int * lwork, int *info);

    if (!no_vectors) {
	*rmsd = -1;
	return 1;
    }

    memset ( &(q[0]), 0, 4*sizeof(double) );
    /* turn the matching atoms into vectors x and y - use only c-alphas*/
     
    /* check: */
    if (0) {
	printf (" Number of vectors read in: %d. \n", no_vectors);
	for ( ctr =0; ctr < no_vectors; ctr++ ) {
	    printf ("\t x%1d   %10.4lf  %10.4lf  %10.4lf   ",
		    ctr, x[0][ctr], x[1][ctr], x[2][ctr]);
	    printf ("\t y%1d   %10.4lf  %10.4lf  %10.4lf \n",
		    ctr, y[0][ctr], y[1][ctr], y[2][ctr]);
	}
	exit (1);
    }

    /* find the meanpoints: */
    for ( i =0; i < 3; i++ ) {
	x_mp[i] = 0.0;
	y_mp[i] = 0.0;
    }
    for ( ctr =0; ctr < no_vectors; ctr++ ) {
	for ( i =0; i < 3; i++ ) {
	    x_mp[i] += x[i][ctr];
	    y_mp[i] += y[i][ctr];
	}
    }
    for ( i =0; i < 3; i++ ) {
	x_mp[i] /= no_vectors;
	y_mp[i] /= no_vectors;
    }
    /* subtract them from x, y */
    for ( ctr =0; ctr < no_vectors; ctr++ ) {
	for ( i =0; i < 3; i++ ) {
	    x[i][ctr] -= x_mp[i];
	    y[i][ctr] -= y_mp[i];
	}
    }
    /* B = ATA_sum matrix to diagonalize in order to get the quaternion */
    for ( ctr =0; ctr < no_vectors; ctr++ ) {
   	for (i=0; i<3; i++ ) {
	    a[i] = y[i][ctr] + x[i][ctr];
	    b[i] = y[i][ctr] - x[i][ctr];
	}
 	construct_ATA (ATA, a, b);
	add_matrices (prev_ATA, ATA, ATA_sum);
	memcpy (prev_ATA[0], ATA_sum[0], 4*4*sizeof(double));
    }
    for (i=0; i<4; i++ ) {
	for (j=0; j<4; j++ ) {
	    ATA_sum[i][j] /= no_vectors;
	}
    }
    /* diagonalize ATA_sum - the eigenvector corresponsing to the
       smallest lambda is the quaternion we are looking for; the
       eigenvalue is the rmsd*/
    /* use the nomenclature from dsyev*/
    char jobz= 'V'; /*Compute eigenvalues and eigenvectors.*/
    char uplo= 'U'; /* Upper triangle of A (the matrix we are diagonalizing) is stored; */
    int  n = 4;     /* order and the leading dimension of A */
    int  lda = 4;
    double ** A;
    int  info;
    int  lwork = 200;
    double w [4];
    double work[200];
    
    if ( !( A=dmatrix(4,4) ) ) exit (1);
    memcpy (A[0], ATA_sum[0], 4*4*sizeof(double));


   /* note how we pass the matrix: */
    dsyev_ ( &jobz, &uplo,  &n, A[0], &lda, w, work, &lwork, &info);
    if (  ! info) {
	*rmsd = sqrt (w[0]);
	for (i=0; i<4; i++ ) q[i] = A[0][i];
	if (0) {
	    /* w contains the eigenvalues */
	    printf ("\n");
	    for (i=0; i<4; i++ ) printf ("%8.3lf ", w[i]);
	    printf ("\nrmsd: %8.3lf \n", *rmsd);
	    printf ("quat:\n");
	    for (i=0; i<4; i++ ) printf ("%8.3lf ", q[i]);
	    printf ("\n");
	    /* printf (" opt lwork: %d\n", (int) work[0]); */
	}
    } else {
	fprintf (stderr, "Error in dsyev().\n");
	exit (1);
    }
    
    /* construct the rotation matrix R */
    quat_to_R (q,R);
    /* T = y_mp - R x_mp */
    for (i=0; i<3; i++ ) {
	T[i] = y_mp[i];
	for (j=0; j<3; j++ ) {
	    T[i] -= R[i][j]*x_mp[j];
	}
    }
   
    
    free_dmatrix(A);

 
    return 0;
}
示例#2
0
double moment ( int moment_n, double x[][3], double y[][3], double delta) {

    int n_steps     = 100;
    int phi_n_steps = 100;
    int i, j, n;
    int k, t, p;
    double value = 0.0;
    double delta_sq = delta*delta;
    double kappa, theta, phi;
    double kappa_step, theta_step, phi_step;
    double cosk, sink, costh, sinth;
    double surface_element, phi_contributn;
    
    double ATA     [4][4] = {{0.0}};
    double prev_ATA[4][4] = {{0.0}};
    double ATA_sum [4][4] = {{0.0}};
    double a[3] = {0.0}, b[3] = {0.0};
    double q[4] = {0.0};
    /**************/
    int construct_ATA (double ATA[4][4], double a[3],double b[3]);
    int add_matrices  (double matrix1[4][4],double matrix2[4][4],double result[4][4]);
    double braket     (double ATA[4][4], double q[4]);
    
    /* sum of A^TA matrices */
    for (n=0; n<moment_n; n++ ) {
	
	for (i=0; i<3; i++ ) {
	    a[i] = y[n][i] + x[n][i];
	    b[i] = y[n][i] - x[n][i];
	}
	construct_ATA (ATA, a, b);
	add_matrices (prev_ATA, ATA, ATA_sum);
	memcpy (prev_ATA[0], ATA_sum[0], 4*4*sizeof(double));
    }

    if (0) { /*check */

	q[0] = 1;
	for (i=0; i<4; i++ ) {
	    for (j=0; j<4; j++ ) {
		printf ("%8.3lf ", ATA_sum[i][j]);
	    }
	    printf ("\n");
	}
	printf ("\n");
	double aux, sum_sq = 0.0;;
	for (i=0; i<4; i++ ) {
	    aux = x[1][i]-y[1][i];
	    sum_sq +=  aux*aux;
	}
	printf ( " 00: %8.4le   %8.4le  %8.4le \n",
		 ATA_sum[0][0], braket(ATA_sum, q), sum_sq);
	exit(1);
    }

    
    value = 0.0;
    kappa_step = M_PI/n_steps;
    theta_step = M_PI/n_steps;
    phi_step   = 2*M_PI/phi_n_steps;
    
    /* for angles kappa, theta phi */
    for (k=1; k<=n_steps; k++) {
	kappa = ( (double)k-0.5)*kappa_step;
	cosk = cos(kappa);
	sink = sin(kappa);
	
	q[0] = cosk;
	
	for (t=1; t<=n_steps; t++) {
	    theta = ( (double)t-0.5)*theta_step;
	    sinth = sin (theta);
	    costh = cos (theta);

	    q[3] = sink*costh;
	    surface_element = sink*sink*sinth;
	    phi_contributn  = 0;
	    
	    for (p=1; p<=phi_n_steps; p++) {
		phi  = ((double)p-0.5)*phi_step;

		q[1] = sink*sinth*cos(phi); 
		q[2] = sink*sinth*sin(phi); 

		phi_contributn += exp(-braket(ATA_sum, q)/delta_sq);
		//value += sink*sink*sinth;
		//printf ( "%3d  %3d  %3d  %8.4le  %8.2le   --  %8.4le \n", k, t, p,
		//braket(ATA, q), exp(-braket(ATA, q)/delta_sq), phi_contributn);
	    }

	    value += phi_contributn*surface_element;
	}
    }
    
    value *= kappa_step*theta_step*phi_step; /*integration steps*/

    value /= 2*M_PI*M_PI; /* the function should return the average*/
    
    return value;
    
}
int opt_quat ( double ** x, int NX, int *set_of_directions_x,
	       double ** y, int NY, int *set_of_directions_y,
	       int set_size, double * q, double * rmsd) {

    
    double * x_sub[set_size], * y_sub[set_size];
    int  ctr;
    int  i, j;
 
    double ATA     [4][4] = {{0.0}};
    double prev_ATA[4][4] = {{0.0}};
    double ATA_sum [4][4] = {{0.0}};
    double a[3] = {0.0}, b[3] = {0.0};
    
    int add_matrices  (double matrix1[4][4],double matrix2[4][4],
		       double result[4][4]);
    int construct_ATA (double ATA[4][4], double a[3], double  b[3]);

    /* note how we pass the matrix: pointer to the first element in the block */
    void dsyev_ (char * jobz, char *uplo,  int *n,
		  double *A, int * lda, double * w, double * work, int * lwork, int *info);

    if (!set_size) {
	*rmsd = -1;
	return 1;
    }

    memset ( &(q[0]), 0, 4*sizeof(double) );

    
    /* find the subset */
    ctr = 0;
    for ( ctr =0; ctr < set_size; ctr++ ) {
	x_sub[ctr] =  x[set_of_directions_x[ctr]];
	y_sub[ctr] =  y[set_of_directions_y[ctr]];
    }

    /* check: */
    if (0) {
	printf (" Number of vectors to match: %d. \n", set_size);
	for ( ctr =0; ctr < set_size; ctr++ ) {
	    printf ("\t x%1d   %10.4lf  %10.4lf  %10.4lf   ",
		    ctr, x_sub[ctr][0], x_sub[ctr][1], x_sub[ctr][2]);
	    printf ("\t y%1d   %10.4lf  %10.4lf  %10.4lf \n",
		    ctr, y_sub[ctr][0], y_sub[ctr][1], y_sub[ctr][2]);
	}
	exit (1);
    }

     
    /* B = ATA_sum matrix to diagonalize in order to get the quaternion */
    for ( ctr =0; ctr < set_size; ctr++ ) {
   	for (i=0; i<3; i++ ) {
	    a[i] = y_sub[ctr][i] + x_sub[ctr][i];
	    b[i] = y_sub[ctr][i] - x_sub[ctr][i];
	}
 	construct_ATA (ATA, a, b);
	add_matrices (prev_ATA, ATA, ATA_sum);
	memcpy (prev_ATA[0], ATA_sum[0], 4*4*sizeof(double));
    }
    for (i=0; i<4; i++ ) {
	for (j=0; j<4; j++ ) {
	    ATA_sum[i][j] /= set_size;
	}
    }
    /* diagonalize ATA_sum - the eigenvector corresponsing to the
       smallest lambda is the quaternion we are looking for; the
       eigenvalue is the rmsd*/
    /* use the nomenclature from dsyev*/
    char jobz= 'V'; /*Compute eigenvalues and eigenvectors.*/
    char uplo= 'U'; /* Upper triangle of A (the matrix we are diagonalizing) is stored; */
    int  n = 4;     /* order and the leading dimension of A */
    int  lda = 4;
    double ** A;
    int  info;
    int  lwork = 200;
    double w [4];
    double work[200];
    
    if ( !( A=dmatrix(4,4) ) ) exit (1);
    memcpy (A[0], ATA_sum[0], 4*4*sizeof(double));


   /* note how we pass the matrix: */
    dsyev_ ( &jobz, &uplo,  &n, A[0], &lda, w, work, &lwork, &info);
    if (  ! info) {
	*rmsd = sqrt (w[0]);
	for (i=0; i<4; i++ ) q[i] = A[0][i];
	if (0) {
	    /* w contains the eigenvalues */
	    printf ("\n");
	    for (i=0; i<4; i++ ) printf ("%8.3lf ", w[i]);
	    printf ("\nrmsd: %8.3lf \n", *rmsd);
	    printf ("quat:\n");
	    for (i=0; i<4; i++ ) printf ("%8.3lf ", q[i]);
	    printf ("\n");
	    /* printf (" opt lwork: %d\n", (int) work[0]); */
	}
    } else {
	fprintf (stderr, "Error in dsyev().\n");
	exit (1);
    }
    
   
    
    free_dmatrix(A);

    return 0;
    
}