1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
2 * $Id: gmx_matrix.c,v 1.4 2008/12/02 18:27:57 spoel Exp $
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2008, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * Groningen Machine for Chemical Simulation
44 #include "gmx_fatal.h"
45 #include "gmx_matrix.h"
46 #include "gmx_lapack.h"
48 double **alloc_matrix(int n
,int m
)
53 /* There's always time for more pointer arithmetic! */
54 /* This is necessary in order to be able to work with LAPACK */
62 void free_matrix(double **a
,int n
)
71 void matrix_multiply(FILE *fp
,int n
,int m
,double **x
,double **y
,double **z
)
77 fprintf(fp
,"Multiplying %d x %d matrix with a %d x %d matrix\n",
83 fprintf(fp
," %7g",x
[i
][j
]);
93 z
[i
][j
] += x
[k
][i
]*y
[j
][k
];
98 static void dump_matrix(FILE *fp
,const char *title
,int n
,double **a
)
103 fprintf(fp
,"%s\n",title
);
109 fprintf(fp
," %8.2f",a
[i
][j
]);
113 fprintf(fp
,"Prod a[i][i] = %g\n",d
);
116 int matrix_invert(FILE *fp
,int n
,double **a
)
118 int i
,j
,m
,lda
,*ipiv
,lwork
,info
;
119 double **test
=NULL
,**id
,*work
;
124 fprintf(fp
,"Inverting %d square matrix\n",n
);
125 test
= alloc_matrix(n
,n
);
130 test
[i
][j
] = a
[i
][j
];
133 dump_matrix(fp
,"before inversion",n
,a
);
141 F77_FUNC(dgetrf
,DGETRF
)(&n
,&m
,a
[0],&lda
,ipiv
,&info
);
144 dump_matrix(fp
,"after dgetrf",n
,a
);
148 F77_FUNC(dgetri
,DGETRI
)(&n
,a
[0],&lda
,ipiv
,work
,&lwork
,&info
);
151 dump_matrix(fp
,"after dgetri",n
,a
);
159 id
= alloc_matrix(n
,n
);
160 matrix_multiply(fp
,n
,n
,test
,a
,id
);
161 dump_matrix(fp
,"And here is the product of A and Ainv",n
,id
);
172 double multi_regression(FILE *fp
,int nrow
,double *y
,int ncol
,
173 double **xx
,double *a0
)
176 double ax
,chi2
,**a
,**at
,**ata
,*atx
;
178 a
= alloc_matrix(nrow
,ncol
);
179 at
= alloc_matrix(ncol
,nrow
);
180 ata
= alloc_matrix(ncol
,ncol
);
181 for(i
=0; (i
<nrow
); i
++)
182 for(j
=0; (j
<ncol
); j
++)
183 at
[j
][i
] = a
[i
][j
] = xx
[j
][i
];
184 matrix_multiply(fp
,nrow
,ncol
,a
,at
,ata
);
185 if ((row
= matrix_invert(fp
,ncol
,ata
)) != 0) {
186 gmx_fatal(FARGS
,"Matrix inversion failed. Incorrect row = %d.\nThis probably indicates that you do not have sufficient data points, or that some parameters are linearly dependent.",
191 for(i
=0; (i
<ncol
); i
++)
194 for(j
=0; (j
<nrow
); j
++)
195 atx
[i
] += at
[i
][j
]*y
[j
];
197 for(i
=0; (i
<ncol
); i
++)
200 for(j
=0; (j
<ncol
); j
++)
201 a0
[i
] += ata
[i
][j
]*atx
[j
];
204 for(j
=0; (j
<nrow
); j
++)
207 for(i
=0; (i
<ncol
); i
++)
209 chi2
+= sqr(y
[j
]-ax
);
214 free_matrix(at
,ncol
);
215 free_matrix(ata
,ncol
);