Don't use POSIX fnmatch() for pattern matching.
[gromacs/qmmm-gamess-us.git] / src / gmxlib / nrjac.c
bloba0d1fc4ca14d2efc9ff988c222e1cda16d3e5828
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"
47 #define ROTATE(a,i,j,k,l) g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);\
48 a[k][l]=h+s*(g-h*tau);
50 void jacobi(double **a,int n,double d[],double **v,int *nrot)
52 int j,i;
53 int iq,ip;
54 double tresh,theta,tau,t,sm,s,h,g,c,*b,*z;
56 snew(b,n);
57 snew(z,n);
58 for (ip=0; ip<n; ip++) {
59 for (iq=0; iq<n; iq++) v[ip][iq]=0.0;
60 v[ip][ip]=1.0;
62 for (ip=0; ip<n;ip++) {
63 b[ip]=d[ip]=a[ip][ip];
64 z[ip]=0.0;
66 *nrot=0;
67 for (i=1; i<=50; i++) {
68 sm=0.0;
69 for (ip=0; ip<n-1; ip++) {
70 for (iq=ip+1; iq<n; iq++)
71 sm += fabs(a[ip][iq]);
73 if (sm == 0.0) {
74 sfree(z);
75 sfree(b);
76 return;
78 if (i < 4)
79 tresh=0.2*sm/(n*n);
80 else
81 tresh=0.0;
82 for (ip=0; ip<n-1; ip++) {
83 for (iq=ip+1; iq<n; iq++) {
84 g=100.0*fabs(a[ip][iq]);
85 if (i > 4 && fabs(d[ip])+g == fabs(d[ip])
86 && fabs(d[iq])+g == fabs(d[iq]))
87 a[ip][iq]=0.0;
88 else if (fabs(a[ip][iq]) > tresh) {
89 h=d[iq]-d[ip];
90 if (fabs(h)+g == fabs(h))
91 t=(a[ip][iq])/h;
92 else {
93 theta=0.5*h/(a[ip][iq]);
94 t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
95 if (theta < 0.0) t = -t;
97 c=1.0/sqrt(1+t*t);
98 s=t*c;
99 tau=s/(1.0+c);
100 h=t*a[ip][iq];
101 z[ip] -= h;
102 z[iq] += h;
103 d[ip] -= h;
104 d[iq] += h;
105 a[ip][iq]=0.0;
106 for (j=0; j<ip; j++) {
107 ROTATE(a,j,ip,j,iq)
109 for (j=ip+1; j<iq; j++) {
110 ROTATE(a,ip,j,j,iq)
112 for (j=iq+1; j<n; j++) {
113 ROTATE(a,ip,j,iq,j)
115 for (j=0; j<n; j++) {
116 ROTATE(v,j,ip,j,iq)
118 ++(*nrot);
122 for (ip=0; ip<n; ip++) {
123 b[ip] += z[ip];
124 d[ip] = b[ip];
125 z[ip] = 0.0;
128 gmx_fatal(FARGS,"Error: Too many iterations in routine JACOBI\n");
131 int m_inv_gen(real **m,int n,real **minv)
133 double **md,**v,*eig,tol,s;
134 int nzero,i,j,k,nrot;
136 snew(md,n);
137 for(i=0; i<n; i++)
138 snew(md[i],n);
139 snew(v,n);
140 for(i=0; i<n; i++)
141 snew(v[i],n);
142 snew(eig,n);
143 for(i=0; i<n; i++)
144 for(j=0; j<n; j++)
145 md[i][j] = m[i][j];
147 tol = 0;
148 for(i=0; i<n; i++)
149 tol += fabs(md[i][i]);
150 tol = 1e-6*tol/n;
152 jacobi(md,n,eig,v,&nrot);
154 nzero = 0;
155 for(i=0; i<n; i++)
156 if (fabs(eig[i]) < tol) {
157 eig[i] = 0;
158 nzero++;
159 } else
160 eig[i] = 1.0/eig[i];
162 for(i=0; i<n; i++)
163 for(j=0; j<n; j++) {
164 s = 0;
165 for(k=0; k<n; k++)
166 s += eig[k]*v[i][k]*v[j][k];
167 minv[i][j] = s;
170 sfree(eig);
171 for(i=0; i<n; i++)
172 sfree(v[i]);
173 sfree(v);
174 for(i=0; i<n; i++)
175 sfree(md[i]);
176 sfree(md);
178 return nzero;