File Coverage

palsrc/palDmat.c
Criterion Covered Total %
statement 45 48 93.7
branch 36 40 90.0
condition n/a
subroutine n/a
pod n/a
total 81 88 92.0


line stmt bran cond sub pod time code
1             /*
2             *+
3             * Name:
4             * palDmat
5              
6             * Purpose:
7             * Matrix inversion & solution of simultaneous equations
8              
9             * Language:
10             * Starlink ANSI C
11              
12             * Type of Module:
13             * Library routine
14              
15             * Invocation:
16             * void palDmat( int n, double *a, double *y, double *d, int *jf,
17             * int *iw );
18              
19             * Arguments:
20             * n = int (Given)
21             * Number of simultaneous equations and number of unknowns.
22             * a = double[] (Given & Returned)
23             * A non-singular NxN matrix (implemented as a contiguous block
24             * of memory). After calling this routine "a" contains the
25             * inverse of the matrix.
26             * y = double[] (Given & Returned)
27             * On input the vector of N knowns. On exit this vector contains the
28             * N solutions.
29             * d = double * (Returned)
30             * The determinant.
31             * jf = int * (Returned)
32             * The singularity flag. If the matrix is non-singular, jf=0
33             * is returned. If the matrix is singular, jf=-1 & d=0.0 are
34             * returned. In the latter case, the contents of array "a" on
35             * return are undefined.
36             * iw = int[] (Given)
37             * Integer workspace of size N.
38              
39             * Description:
40             * Matrix inversion & solution of simultaneous equations
41             * For the set of n simultaneous equations in n unknowns:
42             * A.Y = X
43             * this routine calculates the inverse of A, the determinant
44             * of matrix A and the vector of N unknowns.
45              
46             * Authors:
47             * PTW: Pat Wallace (STFC)
48             * TIMJ: Tim Jenness (JAC, Hawaii)
49             * {enter_new_authors_here}
50              
51             * History:
52             * 2012-02-11 (TIMJ):
53             * Combination of a port of the Fortran and a comparison
54             * with the obfuscated GPL C routine.
55             * Adapted with permission from the Fortran SLALIB library.
56             * {enter_further_changes_here}
57              
58             * Notes:
59             * - Implemented using Gaussian elimination with partial pivoting.
60             * - Optimized for speed rather than accuracy with errors 1 to 4
61             * times those of routines optimized for accuracy.
62              
63             * Copyright:
64             * Copyright (C) 2001 Rutherford Appleton Laboratory.
65             * Copyright (C) 2012 Science and Technology Facilities Council.
66             * All Rights Reserved.
67              
68             * Licence:
69             * This program is free software: you can redistribute it and/or
70             * modify it under the terms of the GNU Lesser General Public
71             * License as published by the Free Software Foundation, either
72             * version 3 of the License, or (at your option) any later
73             * version.
74             *
75             * This program is distributed in the hope that it will be useful,
76             * but WITHOUT ANY WARRANTY; without even the implied warranty of
77             * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
78             * GNU Lesser General Public License for more details.
79             *
80             * You should have received a copy of the GNU Lesser General
81             * License along with this program. If not, see
82             * .
83              
84             * Bugs:
85             * {note_any_bugs_here}
86             *-
87             */
88              
89             #include "pal.h"
90              
91 3           void palDmat ( int n, double *a, double *y, double *d, int *jf, int *iw ) {
92              
93             const double SFA = 1e-20;
94              
95             int k;
96             double*aoff;
97              
98 3           *jf=0;
99 3           *d=1.0;
100 14 100         for(k=0,aoff=a; k
101             int imx;
102             double * aoff2 = aoff;
103 11           double amx=fabs(aoff[k]);
104             imx=k;
105 11 50         if(k!=n){
106             int i;
107             double *apos2;
108 26 100         for(i=k+1,apos2=aoff+n;i
109 15           double t=fabs(apos2[k]);
110 15 100         if(t>amx){
111             amx=t;
112             imx=i;
113             aoff2=apos2;
114             }
115             }
116             }
117 11 50         if(amx
118 0           *jf=-1;
119             } else {
120 11 100         if(imx!=k){
121             double t;
122             int j;
123 28 100         for(j=0;j
124 22           t=aoff[j];
125 22           aoff[j]=aoff2[j];
126 22           aoff2[j]=t;
127             }
128 6           t=y[k];
129 6           y[k]=y[imx];
130 6           y[imx]=t;*d=-*d;
131             }
132 11           iw[k]=imx;
133 11           *d*=aoff[k];
134 11 50         if(fabs(*d)
135 0           *jf=-1;
136             } else {
137             double yk;
138             double * apos2;
139             int i, j;
140 11           aoff[k]=1.0/aoff[k];
141 52 100         for(j=0;j
142 41 100         if(j!=k){
143 30           aoff[j]*=aoff[k];
144             }
145             }
146 11           yk=y[k]*aoff[k];
147 11           y[k]=yk;
148 52 100         for(i=0,apos2=a;i
149 41 100         if(i!=k){
150 144 100         for(j=0;j
151 114 100         if(j!=k){
152 84           apos2[j]-=apos2[k]*aoff[j];
153             }
154             }
155 30           y[i]-=apos2[k]*yk;
156             }
157             }
158 52 100         for(i=0,apos2=a;i
159 41 100         if(i!=k){
160 30           apos2[k]*=-aoff[k];
161             }
162             }
163             }
164             }
165             }
166 3 50         if(*jf!=0){
167 0           *d=0.0;
168             } else {
169 14 100         for(k=n;k-->0;){
170 11           int ki=iw[k];
171 11 100         if(k!=ki){
172             int i;
173             double *apos = a;
174 33 100         for(i=0;i
175 22           double t=apos[k];
176 22           apos[k]=apos[ki];
177 22           apos[ki]=t;
178             }
179             }
180             }
181             }
182 3           }