Main Page | Directories | File List | File Members

ludcmp.h

Go to the documentation of this file.
00001 /*
00002    This file belongs to Aeneas. Aeneas is a GNU package released under GPL 3.
00003    This code is a simulator for Submicron 3D Semiconductor Devices. 
00004    It implements the Monte Carlo transport in 3D tetrahedra meshes
00005    for the simulation of the semiclassical Boltzmann equation for both electrons.
00006    It also includes all the relevant quantum effects for nanodevices.
00007 
00008    Copyright (C) 2007 Jean Michel Sellier <sellier@dmi.unict.it>
00009  
00010    This program is free software; you can redistribute it and/or modify
00011    it under the terms of the GNU General Public License as published by
00012    the Free Software Foundation; either version 3, or (at your option)
00013    any later version.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License
00021    along with this program. If not, see <http://www.gnu.org/licenses/>.
00022 */
00023 
00024 // Created on : 08 june 2007, Siracusa, Jean Michel Sellier
00025 // Last modified : 16 september 2007, Siracusa, Jean Michel Sellier
00026 
00027 // given a matrix a[1..n][1..n], this routine replaces it by the LU decomposition
00028 // of a rowwise permutation of itself. a and n are input. a is output, arranged
00029 // as a lu decomposition; indx[1..n] is an output vector that records the row
00030 // permutation effected by the partial pivoting; d is the output as +-1 depending
00031 // on whether the number of row interchanges was even or odd, respectively.
00032 // This routine is used in combination with lubksb to solve linear equations
00033 // or invert a matrix.
00034 
00035 {
00036  int i, imax, j, k;
00037  double big, dum, sum, temp;
00038  double *vv;
00039  
00040 // imax=0; // dummy value, just to avoid warnings during the compilation...
00041 
00042  vv = malloc((n+1)*sizeof(double)); // vv[1..n]
00043  if(vv==NULL){
00044    printf("ludcmp error : not enough memory!\n");
00045    exit(0);
00046  }
00047 /*     {int ii,jj;
00048      for(ii=1;ii<=4;ii++){
00049         for(jj=1;jj<=4;jj++) printf("*[%d][%d] = %g   ",ii,jj,a[ii][jj]);
00050         printf("\n");
00051      }}*/
00052 
00053  d=1.0;
00054  for(i=1;i<=n;i++){
00055     big=0.0;
00056     for(j=1;j<=n;j++)
00057       if((temp=fabs(a[i][j]))>big) big=temp;
00058     if(big==0.0){
00059      int ii,jj;
00060      for(ii=1;ii<=4;ii++){
00061         for(jj=1;jj<=4;jj++) printf("a[%d][%d] = %g   ",ii,jj,a[ii][jj]);
00062         printf("\n");
00063      }
00064      printf("ludcmp error : singular matrix!\n");
00065      exit(0);
00066     }
00067 // non zero largest element
00068     vv[i]=1.0/big; // save the scaling    
00069  }
00070  for(j=1;j<=n;j++){
00071     for(i=1;i<j;i++){
00072       sum=a[i][j];
00073       for(k=1;k<i;k++) sum-=a[i][k]*a[k][j];
00074       a[i][j]=sum;
00075     }
00076     big=0.0; // initialise for the search for largest pivot element
00077     for(i=j;i<=n;i++){
00078       sum=a[i][j];
00079       for(k=1;k<j;k++) sum-=a[i][k]*a[k][j];
00080       a[i][j]=sum;
00081       if((dum=vv[i]*fabs(sum))>=big){
00082 // Is the figure of merit for the pivot better than the best so far?
00083         big=dum;
00084         imax=i;
00085       }
00086     }
00087     if(j!=imax){ // do we need to interchage the row?
00088       for(k=1;k<=n;k++){
00089         dum=a[imax][k];
00090         a[imax][k]=a[j][k];
00091         a[j][k]=dum;
00092       }
00093       d=-d; // ...and change the parity of d.
00094       vv[imax]=vv[j];
00095     }
00096     indx[j]=imax;
00097     if(a[j][j]==0.0) a[j][j]=TINY;
00098 // if the pivot element is zero the matrix is singular (at least to the precision
00099 // of the algorithm). For some applications on singular matrices, it is desirable
00100 // to substitute TINY for zero.
00101     if(j!=n){
00102       dum=1.0/(a[j][j]);
00103       for(i=j+1;i<=n;i++) a[i][j]*=dum;
00104     }
00105  }
00106  free(vv);
00107 }
00108 

© sourcejam.com 2005-2008