Revised wording in pdb2gmx.c, hopefully clearer now.
[gromacs/rigid-bodies.git] / src / gmxlib / nrjac.c
blobfcd1729edb9ee5d52462b011cf00dfb0912fb253
1 /*
2 *
3 * This source code is part of
4 *
5 * G R O M A C S
6 *
7 * GROningen MAchine for Chemical Simulations
8 *
9 * VERSION 3.2.0
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
32 * And Hey:
33 * GROningen Mixture of Alchemy and Childrens' Stories
35 /* This file is completely threadsafe - keep it that way! */
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <math.h>
43 #include "gstat.h"
44 #include "smalloc.h"
45 #include "gmx_fatal.h"
46 #include "nrjac.h"
49 #define ROTATE(a,i,j,k,l) g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);\
50 a[k][l]=h+s*(g-h*tau);
52 void jacobi(double **a,int n,double d[],double **v,int *nrot)
54 int j,i;
55 int iq,ip;
56 double tresh,theta,tau,t,sm,s,h,g,c,*b,*z;
58 snew(b,n);
59 snew(z,n);
60 for (ip=0; ip<n; ip++) {
61 for (iq=0; iq<n; iq++) v[ip][iq]=0.0;
62 v[ip][ip]=1.0;
64 for (ip=0; ip<n;ip++) {
65 b[ip]=d[ip]=a[ip][ip];
66 z[ip]=0.0;
68 *nrot=0;
69 for (i=1; i<=50; i++) {
70 sm=0.0;
71 for (ip=0; ip<n-1; ip++) {
72 for (iq=ip+1; iq<n; iq++)
73 sm += fabs(a[ip][iq]);
75 if (sm == 0.0) {
76 sfree(z);
77 sfree(b);
78 return;
80 if (i < 4)
81 tresh=0.2*sm/(n*n);
82 else
83 tresh=0.0;
84 for (ip=0; ip<n-1; ip++) {
85 for (iq=ip+1; iq<n; iq++) {
86 g=100.0*fabs(a[ip][iq]);
87 if (i > 4 && fabs(d[ip])+g == fabs(d[ip])
88 && fabs(d[iq])+g == fabs(d[iq]))
89 a[ip][iq]=0.0;
90 else if (fabs(a[ip][iq]) > tresh) {
91 h=d[iq]-d[ip];
92 if (fabs(h)+g == fabs(h))
93 t=(a[ip][iq])/h;
94 else {
95 theta=0.5*h/(a[ip][iq]);
96 t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
97 if (theta < 0.0) t = -t;
99 c=1.0/sqrt(1+t*t);
100 s=t*c;
101 tau=s/(1.0+c);
102 h=t*a[ip][iq];
103 z[ip] -= h;
104 z[iq] += h;
105 d[ip] -= h;
106 d[iq] += h;
107 a[ip][iq]=0.0;
108 for (j=0; j<ip; j++) {
109 ROTATE(a,j,ip,j,iq)
111 for (j=ip+1; j<iq; j++) {
112 ROTATE(a,ip,j,j,iq)
114 for (j=iq+1; j<n; j++) {
115 ROTATE(a,ip,j,iq,j)
117 for (j=0; j<n; j++) {
118 ROTATE(v,j,ip,j,iq)
120 ++(*nrot);
124 for (ip=0; ip<n; ip++) {
125 b[ip] += z[ip];
126 d[ip] = b[ip];
127 z[ip] = 0.0;
130 gmx_fatal(FARGS,"Error: Too many iterations in routine JACOBI\n");
133 int m_inv_gen(real **m,int n,real **minv)
135 double **md,**v,*eig,tol,s;
136 int nzero,i,j,k,nrot;
138 snew(md,n);
139 for(i=0; i<n; i++)
140 snew(md[i],n);
141 snew(v,n);
142 for(i=0; i<n; i++)
143 snew(v[i],n);
144 snew(eig,n);
145 for(i=0; i<n; i++)
146 for(j=0; j<n; j++)
147 md[i][j] = m[i][j];
149 tol = 0;
150 for(i=0; i<n; i++)
151 tol += fabs(md[i][i]);
152 tol = 1e-6*tol/n;
154 jacobi(md,n,eig,v,&nrot);
156 nzero = 0;
157 for(i=0; i<n; i++)
158 if (fabs(eig[i]) < tol) {
159 eig[i] = 0;
160 nzero++;
161 } else
162 eig[i] = 1.0/eig[i];
164 for(i=0; i<n; i++)
165 for(j=0; j<n; j++) {
166 s = 0;
167 for(k=0; k<n; k++)
168 s += eig[k]*v[i][k]*v[j][k];
169 minv[i][j] = s;
172 sfree(eig);
173 for(i=0; i<n; i++)
174 sfree(v[i]);
175 sfree(v);
176 for(i=0; i<n; i++)
177 sfree(md[i]);
178 sfree(md);
180 return nzero;