00001
00007 #include <fvar.hpp>
00008
00009 #ifdef __TURBOC__
00010 #pragma hdrstop
00011 #include <iostream.h>
00012 #endif
00013
00014 #if defined (__WAT32__)
00015 #include <iostream.h>
00016 #include <strstrea.h>
00017 #endif
00018
00019 #ifdef __ZTC__
00020 #include <iostream.hpp>
00021 #endif
00022
00023 #define TINY 1.0e-20;
00024 void dmdv_solve(void);
00025
00026
00028 dvector csolve(const dmatrix& aa,const dvector& z)
00029 {
00030 double ln_unsigned_det;
00031 double sign;
00032 dvector sol=solve(aa,z,ln_unsigned_det,sign);
00033 return sol;
00034 }
00035
00042 dvector solve(const dmatrix& aa,const dvector& z)
00043 {
00044 double ln_unsigned_det;
00045 double sign;
00046 dvector sol=solve(aa,z,ln_unsigned_det,sign);
00047 return sol;
00048 }
00049
00062 dvector solve(const dmatrix& aa,const dvector& z,
00063 const double& _ln_unsigned_det,double& sign)
00064 {
00065 double& ln_unsigned_det=(double&) (_ln_unsigned_det);
00066 int n=aa.colsize();
00067 int lb=aa.colmin();
00068 int ub=aa.colmax();
00069 if (lb!=aa.rowmin()||ub!=aa.rowmax())
00070 {
00071 cerr << "Error matrix not square in solve()"<<endl;
00072 ad_exit(1);
00073 }
00074 dmatrix bb(lb,ub,lb,ub);
00075 bb=aa;
00076 ivector indx(lb,ub);
00077 int One=1;
00078 indx.fill_seqadd(lb,One);
00079 double d;
00080 double big,dum,sum,temp;
00081 dvector vv(lb,ub);
00082
00083 d=1.0;
00084 for (int i=lb;i<=ub;i++)
00085 {
00086 big=0.0;
00087 for (int j=lb;j<=ub;j++)
00088 {
00089 temp=fabs(bb(i,j));
00090 if (temp > big)
00091 {
00092 big=temp;
00093 }
00094 }
00095 if (big == 0.0)
00096 {
00097 cerr << "Error in matrix inverse -- matrix singular in inv(dmatrix)\n";
00098 }
00099 vv[i]=1.0/big;
00100 }
00101
00102 for (int j=lb;j<=ub;j++)
00103 {
00104 for (int i=lb;i<j;i++)
00105 {
00106 sum=bb(i,j);
00107 for (int k=lb;k<i;k++)
00108 {
00109 sum -= bb(i,k)*bb(k,j);
00110 }
00111
00112 bb(i,j)=sum;
00113 }
00114 int imax = j;
00115 big=0.0;
00116 for (int i=j;i<=ub;i++)
00117 {
00118 sum=bb(i,j);
00119 for (int k=lb;k<j;k++)
00120 {
00121 sum -= bb(i,k)*bb(k,j);
00122 }
00123 bb(i,j)=sum;
00124 dum=vv[i]*fabs(sum);
00125 if ( dum >= big)
00126 {
00127 big=dum;
00128 imax=i;
00129 }
00130 }
00131 if (j != imax)
00132 {
00133 for (int k=lb;k<=ub;k++)
00134 {
00135 dum=bb(imax,k);
00136 bb(imax,k)=bb(j,k);
00137 bb(j,k)=dum;
00138 }
00139 d = -1.*d;
00140 vv[imax]=vv[j];
00141
00142
00143 {
00144 int itemp=indx(imax);
00145 indx(imax)=indx(j);
00146 indx(j)=itemp;
00147 }
00148
00149 }
00150
00151 if (bb(j,j) == 0.0)
00152 {
00153 bb(j,j)=TINY;
00154 }
00155
00156 if (j != n)
00157 {
00158 dum=1.0/bb(j,j);
00159 for (int i=j+1;i<=ub;i++)
00160 {
00161 bb(i,j) = bb(i,j) * dum;
00162 }
00163 }
00164 }
00165
00166
00167 sign=d;
00168 dvector part_prod(lb,ub);
00169 part_prod(lb)=log(fabs(bb(lb,lb)));
00170 if (bb(lb,lb)<0) sign=-sign;
00171 for (int j=lb+1;j<=ub;j++)
00172 {
00173 if (bb(j,j)<0) sign=-sign;
00174 part_prod(j)=part_prod(j-1)+log(fabs(bb(j,j)));
00175 }
00176 ln_unsigned_det=part_prod(ub);
00177
00178 dvector x(lb,ub);
00179 dvector y(lb,ub);
00180
00181
00182 dmatrix& b=bb;
00183 ivector indxinv(lb,ub);
00184 for (int i=lb;i<=ub;i++)
00185 {
00186 indxinv(indx(i))=i;
00187 }
00188
00189 for (int i=lb;i<=ub;i++)
00190 {
00191 y(indxinv(i))=z(i);
00192 }
00193
00194 for (int i=lb;i<=ub;i++)
00195 {
00196 sum=y(i);
00197 for (int j=lb;j<=i-1;j++)
00198 {
00199 sum-=b(i,j)*y(j);
00200 }
00201 y(i)=sum;
00202 }
00203 for (int i=ub;i>=lb;i--)
00204 {
00205 sum=y(i);
00206 for (int j=i+1;j<=ub;j++)
00207 {
00208 sum-=b(i,j)*x(j);
00209 }
00210 x(i)=sum/b(i,i);
00211 }
00212
00213 return x;
00214 }
00215 #undef TINY