1 /*
2  * Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT,
3  * Applied Mathematics, Norway.
4  *
5  * Contact information: E-mail: tor.dokken@sintef.no
6  * SINTEF ICT, Department of Applied Mathematics,
7  * P.O. Box 124 Blindern,
8  * 0314 Oslo, Norway.
9  *
10  * This file is part of SISL.
11  *
12  * SISL is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Affero General Public License as
14  * published by the Free Software Foundation, either version 3 of the
15  * License, or (at your option) any later version.
16  *
17  * SISL is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Affero General Public License for more details.
21  *
22  * You should have received a copy of the GNU Affero General Public
23  * License along with SISL. If not, see
24  * <http://www.gnu.org/licenses/>.
25  *
26  * In accordance with Section 7(b) of the GNU Affero General Public
27  * License, a covered work must retain the producer line in every data
28  * file that is created or manipulated using SISL.
29  *
30  * Other Usage
31  * You can be released from the requirements of the license by purchasing
32  * a commercial license. Buying such a license is mandatory as soon as you
33  * develop commercial activities involving the SISL library without
34  * disclosing the source code of your own applications.
35  *
36  * This file may be used in accordance with the terms contained in a
37  * written agreement between you and SINTEF ICT.
38  */
39 
40 #include "sisl-copyright.h"
41 
42 /*
43  *
44  * $Id: s6lufacp.c,v 1.2 2001-03-19 15:59:02 afr Exp $
45  *
46  */
47 
48 
49 #define S6LUFACP
50 
51 #include "sislP.h"
52 
53 #if defined(SISLNEEDPROTOTYPES)
54 void
s6lufacp(double ea[],int nl[],int im,int * jstat)55 s6lufacp(double ea[],int nl[],int im,int *jstat)
56 #else
57 void s6lufacp(ea,nl,im,jstat)
58      double ea[];
59      int    nl[];
60      int    im;
61      int    *jstat;
62 #endif
63 /*
64 ***********************************************************************
65 *
66 ************************************************************************
67 *
68 *   PURPOSE : LU-factorisation of a full matrix. The matrix is stored
69 *             in a one-dimensional array.
70 *
71 *
72 *   INPUT   : im   - The number of equations.
73 *
74 *
75 *
76 *   INPUT/OUTPUT : eb - the array in which the matrix is stored.
77 *                       The elements are stored row-wise.
78 *
79 *
80 *   OUTPUT  : nl    - Array that indicates order of rows after pivoting.
81 *             jstat - Status variable.
82 *                       < 0 : error
83 *                       = 0 : ok
84 *                       > 0 : warning
85 *
86 *
87 *   METHOD  : Gauss-elimination with partial pivoting.
88 *
89 *
90 *   REFERENCES : Cheney & Kincaid : Numerical Mathematics and
91 *                                   Computing.
92 *
93 *-
94 *   CALLS      :
95 *
96 *   WRITTEN BY : Vibeke Skytt, SI, 86-12.
97 *
98 ************************************************************************
99 */
100 {
101   int kpos = 0;   /* Position of error.                               */
102   int ki,kj,kk;   /* Counters.                                        */
103   int kmax = 0;   /* Number of row with maximum greates element.      */
104   int kchange;    /* Help variable to change order of two rows.       */
105   double tmult;   /* Factor with which to multiply a row before it is
106 		     added to another.                                */
107   double t1;      /* Help variabel to find maximum of a number of elements.*/
108   double tmax;    /* Maximum of a number of elements.                 */
109   double tdiv;    /* Dividend in expression.                          */
110   double *smax = SISL_NULL; /* Maximum elements in the rows of ea.         */
111 
112   /* Allocate space for local array.  */
113 
114   if ((smax = new0array(im,double)) == SISL_NULL) goto err101;
115 
116   /* Find largest element in each row.  */
117 
118   for (ki=0; ki<im; ki++)
119     {
120       nl[ki] = ki;
121       for (kj=0; kj<im; kj++)
122 	smax[ki] = MAX(smax[ki],fabs(ea[ki*im+kj]));
123     }
124 
125   for (ki=0; ki<im-1; ki++)
126     {
127 
128       /* Find row with maximum greates element to treat now.  */
129 
130       tmax = DZERO;
131       for (kj=ki; kj<im; kj++)
132 	{
133 	  tdiv = smax[nl[kj]];
134 	  if (DEQUAL(tdiv,DZERO)) goto warn1;
135 	  t1 = fabs(ea[nl[kj]*im+ki]/tdiv);
136 	  if (t1 > tmax)
137 	    {
138 	      tmax = t1;
139 	      kmax = kj;
140 	    }
141 	}
142       kchange  = nl[kmax];
143       nl[kmax] = nl[ki];
144       nl[ki]   = kchange;
145 
146       /* Add a multiplum of current row to all later rows in order to
147 	 get an upper triangular matrix ea.                           */
148 
149       for (kj=ki+1; kj<im; kj++)
150 	{
151 	  tdiv = ea[ki+kchange*im];
152 	  if (DEQUAL(tdiv,DZERO)) goto warn1;
153 	  tmult = ea[ki+nl[kj]*im]/tdiv;
154 	  ea[ki+nl[kj]*im] = tmult;
155 
156 	  for (kk=ki+1; kk<im; kk++)
157 	    ea[kk+nl[kj]*im] -= ea[kk+kchange*im]*tmult;
158 	}
159     }
160 
161   /* LU-factorizing performed.  */
162 
163   *jstat = 0;
164   goto out;
165 
166 /* Singular equation system.  */
167 
168 warn1 : *jstat = 1;
169         goto out;
170 
171 /* Error in space allocation.  */
172 
173 err101: *jstat = -101;
174         s6err("s6lufacp",*jstat,kpos);
175         goto out;
176 
177 out:
178 
179 /* Free space occupied by local array.  */
180 
181 if (smax != SISL_NULL) freearray(smax);
182 
183 return;
184 }
185 
186 
187 
188 
189