/* $Id: sgmetric.c 851 2002-02-09 05:39:17Z wdelano $ */ /* The source code contained in this file is */ /* Copyright (C) 1994-2000 by Ralf W. Grosse-Kunstleve. */ /* Please see the LICENSE file for more information. */ #ifdef _PYMOL_WIN32 #include"os_predef.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #undef SG_GLOBAL #include "sglite.h" /* BEGIN: same code as in unitcell.c */ static void MxTranspose(const double *M, int nr, int nc, double *Mt) { int ir, ic; range1(ir, nr) range1(ic, nc) Mt[ic * nr + ir] = M[ir * nc + ic]; } static void MxMultiply(const double *A, const double *B, int ma, int na, int nb, double *AB) { /* AB[ma, nb] = A[ma, na] * B[na, nb] */ int i, j, k; range1(i, ma) { range1(k, nb) { *AB = 0.; range1(j, na) *AB += A[i * na + j] * B[j * nb + k]; AB++; } } } static void getRtGR(const double G[9], const double R[9], double RtGR[9]) { double Rt[9], GR[9]; MxTranspose(R, 3, 3, Rt); MxMultiply(G, R, 3, 3, 3, GR); MxMultiply(Rt, GR, 3, 3, 3, RtGR); } /* END: same code as in unitcell.c */ int CheckMetricalMatrix(const T_SgOps *SgOps, const double *G, double tolerance) { /* for all R in the representative set of SgOps, assert Transpose[R].G.R == G */ int iSMx, i; double R[9], RtGR[9], delta; if (tolerance < 0.) tolerance = 1.e-4; range2(iSMx, 1, SgOps->nSMx) { rangei(9) R[i] = (double) SgOps->SMx[iSMx].s.R[i]; getRtGR(G, R, RtGR); rangei(9) { delta = RtGR[i] - G[i]; if (delta < 0.) delta *= -1.; if (delta > tolerance) { SetSgError( "Error: metrical matrix is incompatible with symmetry operations"); return -1; } } } return 0; }