1*ede5e988SBarry Smith 2*ede5e988SBarry Smith /* 3*ede5e988SBarry Smith This routine was converted by f2c from Linpack source 4*ede5e988SBarry Smith linpack. this version dated 08/14/78 5*ede5e988SBarry Smith cleve moler, university of new mexico, argonne national lab. 6*ede5e988SBarry Smith */ 7*ede5e988SBarry Smith #include "petsc.h" 8*ede5e988SBarry Smith 9*ede5e988SBarry Smith int Linpack_DGEFA(Scalar *a, int n, int *ipvt) 10*ede5e988SBarry Smith { 11*ede5e988SBarry Smith int i__2, i__3, kp1, nm1, j, k, l,ll; 12*ede5e988SBarry Smith Scalar t,*aa,*ax,*ay; 13*ede5e988SBarry Smith double tmp,max; 14*ede5e988SBarry Smith 15*ede5e988SBarry Smith /* gaussian elimination with partial pivoting */ 16*ede5e988SBarry Smith 17*ede5e988SBarry Smith /* Parameter adjustments */ 18*ede5e988SBarry Smith --ipvt; 19*ede5e988SBarry Smith a -= n + 1; 20*ede5e988SBarry Smith 21*ede5e988SBarry Smith /* Function Body */ 22*ede5e988SBarry Smith nm1 = n - 1; 23*ede5e988SBarry Smith if (nm1 < 1) { 24*ede5e988SBarry Smith goto L70; 25*ede5e988SBarry Smith } 26*ede5e988SBarry Smith for (k = 1; k <= nm1; ++k) { 27*ede5e988SBarry Smith kp1 = k + 1; 28*ede5e988SBarry Smith 29*ede5e988SBarry Smith /* find l = pivot index */ 30*ede5e988SBarry Smith 31*ede5e988SBarry Smith i__2 = n - k + 1; 32*ede5e988SBarry Smith aa = &a[k + k * n]; 33*ede5e988SBarry Smith max = PetscAbsScalar(aa[0]); 34*ede5e988SBarry Smith l = 1; 35*ede5e988SBarry Smith for ( ll=1; ll<i__2; ll++ ) { 36*ede5e988SBarry Smith tmp = PetscAbsScalar(aa[ll]); 37*ede5e988SBarry Smith if (tmp > max) { max = tmp; l = ll+1;} 38*ede5e988SBarry Smith } 39*ede5e988SBarry Smith l += k - 1; 40*ede5e988SBarry Smith ipvt[k] = l; 41*ede5e988SBarry Smith 42*ede5e988SBarry Smith if (a[l + k * n] == 0.) { 43*ede5e988SBarry Smith SETERRQ(k,"Linpack_DGEFA:Zero pivot"); 44*ede5e988SBarry Smith } 45*ede5e988SBarry Smith 46*ede5e988SBarry Smith /* interchange if necessary */ 47*ede5e988SBarry Smith 48*ede5e988SBarry Smith if (l != k) { 49*ede5e988SBarry Smith t = a[l + k * n]; 50*ede5e988SBarry Smith a[l + k * n] = a[k + k * n]; 51*ede5e988SBarry Smith a[k + k * n] = t; 52*ede5e988SBarry Smith } 53*ede5e988SBarry Smith 54*ede5e988SBarry Smith /* compute multipliers */ 55*ede5e988SBarry Smith 56*ede5e988SBarry Smith t = -1. / a[k + k * n]; 57*ede5e988SBarry Smith i__2 = n - k; 58*ede5e988SBarry Smith aa = &a[k + 1 + k * n]; 59*ede5e988SBarry Smith for ( ll=0; ll<i__2; ll++ ) { 60*ede5e988SBarry Smith aa[ll] *= t; 61*ede5e988SBarry Smith } 62*ede5e988SBarry Smith 63*ede5e988SBarry Smith /* row elimination with column indexing */ 64*ede5e988SBarry Smith 65*ede5e988SBarry Smith ax = &a[k+1+k*n]; 66*ede5e988SBarry Smith for (j = kp1; j <= n; ++j) { 67*ede5e988SBarry Smith t = a[l + j * n]; 68*ede5e988SBarry Smith if (l != k) { 69*ede5e988SBarry Smith a[l + j * n] = a[k + j * n]; 70*ede5e988SBarry Smith a[k + j * n] = t; 71*ede5e988SBarry Smith } 72*ede5e988SBarry Smith 73*ede5e988SBarry Smith i__3 = n - k; 74*ede5e988SBarry Smith ay = &a[k+1+j*n]; 75*ede5e988SBarry Smith for ( ll=0; ll<i__3; ll++ ) { 76*ede5e988SBarry Smith ay[ll] += t*ax[ll]; 77*ede5e988SBarry Smith } 78*ede5e988SBarry Smith } 79*ede5e988SBarry Smith } 80*ede5e988SBarry Smith L70: 81*ede5e988SBarry Smith ipvt[n] = n; 82*ede5e988SBarry Smith if (a[n + n * n] == 0.) { 83*ede5e988SBarry Smith SETERRQ(n,"Linpack_DGEFA:Zero pivot,final row"); 84*ede5e988SBarry Smith } 85*ede5e988SBarry Smith return 0; 86*ede5e988SBarry Smith } 87*ede5e988SBarry Smith 88*ede5e988SBarry Smith /* 89*ede5e988SBarry Smith Version for 3 by 3 matrices. 90*ede5e988SBarry Smith 91*ede5e988SBarry Smith THIS CODE HAS NOT BEEN TESTED YET! 92*ede5e988SBarry Smith 93*ede5e988SBarry Smith */ 94*ede5e988SBarry Smith int Linpack_DGEFA_3(Scalar *a, int *ipvt) 95*ede5e988SBarry Smith { 96*ede5e988SBarry Smith int i__2, i__3, kp1, j, k, l,ll; 97*ede5e988SBarry Smith Scalar t,*aa,*ax,*ay; 98*ede5e988SBarry Smith double tmp,max; 99*ede5e988SBarry Smith 100*ede5e988SBarry Smith /* gaussian elimination with partial pivoting */ 101*ede5e988SBarry Smith 102*ede5e988SBarry Smith /* Parameter adjustments */ 103*ede5e988SBarry Smith --ipvt; 104*ede5e988SBarry Smith a -= 4; 105*ede5e988SBarry Smith 106*ede5e988SBarry Smith /* Function Body */ 107*ede5e988SBarry Smith for (k = 1; k <= 2; ++k) { 108*ede5e988SBarry Smith kp1 = k + 1; 109*ede5e988SBarry Smith 110*ede5e988SBarry Smith /* find l = pivot index */ 111*ede5e988SBarry Smith 112*ede5e988SBarry Smith i__2 = 4 - k; 113*ede5e988SBarry Smith aa = &a[4*k]; 114*ede5e988SBarry Smith max = PetscAbsScalar(aa[0]); 115*ede5e988SBarry Smith l = 1; 116*ede5e988SBarry Smith for ( ll=1; ll<i__2; ll++ ) { 117*ede5e988SBarry Smith tmp = PetscAbsScalar(aa[ll]); 118*ede5e988SBarry Smith if (tmp > max) { max = tmp; l = ll+1;} 119*ede5e988SBarry Smith } 120*ede5e988SBarry Smith l += k - 1; 121*ede5e988SBarry Smith ipvt[k] = l; 122*ede5e988SBarry Smith 123*ede5e988SBarry Smith if (a[l + 3*k] == 0.) { 124*ede5e988SBarry Smith SETERRQ(k,"Linpack_DGEFA:Zero pivot"); 125*ede5e988SBarry Smith } 126*ede5e988SBarry Smith 127*ede5e988SBarry Smith /* interchange if necessary */ 128*ede5e988SBarry Smith 129*ede5e988SBarry Smith if (l != k) { 130*ede5e988SBarry Smith t = a[l + 3*k]; 131*ede5e988SBarry Smith a[l + 3*k] = a[4*k]; 132*ede5e988SBarry Smith a[4*k] = t; 133*ede5e988SBarry Smith } 134*ede5e988SBarry Smith 135*ede5e988SBarry Smith /* compute multipliers */ 136*ede5e988SBarry Smith 137*ede5e988SBarry Smith t = -1. / a[4*k]; 138*ede5e988SBarry Smith i__2 = 3 - k; 139*ede5e988SBarry Smith aa = &a[1 + 4*k]; 140*ede5e988SBarry Smith for ( ll=0; ll<i__2; ll++ ) { 141*ede5e988SBarry Smith aa[ll] *= t; 142*ede5e988SBarry Smith } 143*ede5e988SBarry Smith 144*ede5e988SBarry Smith /* row elimination with column indexing */ 145*ede5e988SBarry Smith 146*ede5e988SBarry Smith ax = &a[4*k+1]; 147*ede5e988SBarry Smith for (j = kp1; j <= 3; ++j) { 148*ede5e988SBarry Smith t = a[l + 3*j]; 149*ede5e988SBarry Smith if (l != k) { 150*ede5e988SBarry Smith a[l + 3*j] = a[k + 3*j]; 151*ede5e988SBarry Smith a[k + 3*j] = t; 152*ede5e988SBarry Smith } 153*ede5e988SBarry Smith 154*ede5e988SBarry Smith i__3 = 3 - k; 155*ede5e988SBarry Smith ay = &a[k+1+3*j]; 156*ede5e988SBarry Smith for ( ll=0; ll<i__3; ll++ ) { 157*ede5e988SBarry Smith ay[ll] += t*ax[ll]; 158*ede5e988SBarry Smith } 159*ede5e988SBarry Smith } 160*ede5e988SBarry Smith } 161*ede5e988SBarry Smith ipvt[3] = 3; 162*ede5e988SBarry Smith if (a[12] == 0.) { 163*ede5e988SBarry Smith SETERRQ(3,"Linpack_DGEFA:Zero pivot,final row"); 164*ede5e988SBarry Smith } 165*ede5e988SBarry Smith return 0; 166*ede5e988SBarry Smith } 167*ede5e988SBarry Smith 168*ede5e988SBarry Smith 169*ede5e988SBarry Smith #ifndef lint 170*ede5e988SBarry Smith static char vcid[] = "$Id: dgedi.c,v 1.2 1996/03/04 05:16:18 bsmith Exp bsmith $"; 171*ede5e988SBarry Smith #endif 172*ede5e988SBarry Smith 173*ede5e988SBarry Smith /* 174*ede5e988SBarry Smith This file creating by running f2c 175*ede5e988SBarry Smith linpack. this version dated 08/14/78 176*ede5e988SBarry Smith cleve moler, university of new mexico, argonne national lab. 177*ede5e988SBarry Smith 178*ede5e988SBarry Smith Computes the inverse of a matrix given its factors and pivots 179*ede5e988SBarry Smith calculated by Linpack_DGEFA(). 180*ede5e988SBarry Smith */ 181*ede5e988SBarry Smith 182*ede5e988SBarry Smith #include "petsc.h" 183*ede5e988SBarry Smith 184*ede5e988SBarry Smith int Linpack_DGEDI(Scalar *a,int n,int *ipvt,Scalar *work) 185*ede5e988SBarry Smith { 186*ede5e988SBarry Smith int i__2,kb, kp1, nm1,i, j, k, l, ll; 187*ede5e988SBarry Smith Scalar t, *aa,*ax,*ay,tmp; 188*ede5e988SBarry Smith 189*ede5e988SBarry Smith --work; 190*ede5e988SBarry Smith --ipvt; 191*ede5e988SBarry Smith a -= n + 1; 192*ede5e988SBarry Smith 193*ede5e988SBarry Smith /* compute inverse(u) */ 194*ede5e988SBarry Smith 195*ede5e988SBarry Smith for (k = 1; k <= n; ++k) { 196*ede5e988SBarry Smith a[k + k * n] = 1. / a[k + k * n]; 197*ede5e988SBarry Smith t = -a[k + k * n]; 198*ede5e988SBarry Smith i__2 = k - 1; 199*ede5e988SBarry Smith aa = &a[k * n + 1]; 200*ede5e988SBarry Smith for ( ll=0; ll<i__2; ll++ ) aa[ll] *= t; 201*ede5e988SBarry Smith kp1 = k + 1; 202*ede5e988SBarry Smith if (n < kp1) continue; 203*ede5e988SBarry Smith ax = aa; 204*ede5e988SBarry Smith for (j = kp1; j <= n; ++j) { 205*ede5e988SBarry Smith t = a[k + j * n]; 206*ede5e988SBarry Smith a[k + j * n] = 0.; 207*ede5e988SBarry Smith ay = &a[j * n + 1]; 208*ede5e988SBarry Smith for ( ll=0; ll<k; ll++ ) { 209*ede5e988SBarry Smith ay[ll] += t*ax[ll]; 210*ede5e988SBarry Smith } 211*ede5e988SBarry Smith } 212*ede5e988SBarry Smith } 213*ede5e988SBarry Smith 214*ede5e988SBarry Smith /* form inverse(u)*inverse(l) */ 215*ede5e988SBarry Smith 216*ede5e988SBarry Smith nm1 = n - 1; 217*ede5e988SBarry Smith if (nm1 < 1) { 218*ede5e988SBarry Smith return 0; 219*ede5e988SBarry Smith } 220*ede5e988SBarry Smith for (kb = 1; kb <= nm1; ++kb) { 221*ede5e988SBarry Smith k = n - kb; 222*ede5e988SBarry Smith kp1 = k + 1; 223*ede5e988SBarry Smith aa = a + k * n; 224*ede5e988SBarry Smith for (i = kp1; i <= n; ++i) { 225*ede5e988SBarry Smith work[i] = aa[i]; 226*ede5e988SBarry Smith aa[i] = 0.; 227*ede5e988SBarry Smith } 228*ede5e988SBarry Smith for (j = kp1; j <= n; ++j) { 229*ede5e988SBarry Smith t = work[j]; 230*ede5e988SBarry Smith ax = &a[j * n + 1]; 231*ede5e988SBarry Smith ay = &a[k * n + 1]; 232*ede5e988SBarry Smith for ( ll=0; ll<n; ll++ ) { 233*ede5e988SBarry Smith ay[ll] += t*ax[ll]; 234*ede5e988SBarry Smith } 235*ede5e988SBarry Smith } 236*ede5e988SBarry Smith l = ipvt[k]; 237*ede5e988SBarry Smith if (l != k) { 238*ede5e988SBarry Smith ax = &a[k * n + 1]; 239*ede5e988SBarry Smith ay = &a[l * n + 1]; 240*ede5e988SBarry Smith for ( ll=0; ll<n; ll++ ) { 241*ede5e988SBarry Smith tmp = ax[ll]; 242*ede5e988SBarry Smith ax[ll] = ay[ll]; 243*ede5e988SBarry Smith ay[ll] = tmp; 244*ede5e988SBarry Smith } 245*ede5e988SBarry Smith } 246*ede5e988SBarry Smith } 247*ede5e988SBarry Smith return 0; 248*ede5e988SBarry Smith } 249*ede5e988SBarry Smith 250