00001
00007 #include <fvar.hpp>
00008 #ifdef __TURBOC__
00009 #pragma hdrstop
00010 #include <iomanip.h>
00011 #endif
00012
00013 #ifdef __ZTC__
00014 #include <iomanip.hpp>
00015 #endif
00016
00017 #define TINY 1.0e-20;
00018 void dfinvpret(void);
00019
00020
00021 void df_xdet(void);
00022
00033 dvariable det(const dvar_matrix& aa)
00034 {
00035 int i,j,k;
00036 int n=aa.colsize();
00037 int lb=aa.colmin();
00038 int ub=aa.colmax();
00039 ivector indx(lb,ub);
00040 if (lb!=aa.rowmin()||ub!=aa.colmax())
00041 {
00042 cerr << "Error matrix not square in det()"<<endl;
00043 ad_exit(1);
00044 }
00045 int One=1;
00046 indx.fill_seqadd(lb,One);
00047 double d;
00048 double big,dum,sum,temp;
00049 dvar_matrix_position dmp(aa,1);
00050 dmatrix bb=value(aa);
00051 dvector vv(lb,ub);
00052 dvector part_prod(lb,ub);
00053
00054 d=1.0;
00055 for (i=lb;i<=ub;i++)
00056 {
00057 big=0.0;
00058 for (j=lb;j<=ub;j++)
00059 {
00060 temp=fabs(bb.elem(i,j));
00061 if (temp > big)
00062 {
00063 big=temp;
00064 }
00065 }
00066 if (big == 0.0)
00067 {
00068 cerr << "Error in matrix inverse -- matrix singular in inv(dmatrix)\n";
00069 }
00070 vv[i]=1.0/big;
00071 }
00072
00073 for (j=lb;j<=ub;j++)
00074 {
00075 for (i=lb;i<j;i++)
00076 {
00077 sum=bb.elem(i,j);
00078 for (k=lb;k<i;k++)
00079 {
00080 sum = sum - bb.elem(i,k)*bb.elem(k,j);
00081 }
00082
00083 bb(i,j)=sum;
00084 }
00085 int imax = j;
00086 big=0.0;
00087 for (i=j;i<=ub;i++)
00088 {
00089 sum=bb.elem(i,j);
00090 for (k=lb;k<j;k++)
00091 {
00092 sum = sum - bb(i,k)*bb(k,j);
00093 }
00094 bb(i,j)=sum;
00095 dum=vv.elem(i)*fabs(sum);
00096 if ( dum >= big)
00097 {
00098 big=dum;
00099 imax=i;
00100 }
00101 }
00102 if (j != imax)
00103 {
00104 for (k=lb;k<=ub;k++)
00105 {
00106 dum=bb.elem(imax,k);
00107 bb.elem(imax,k)=bb.elem(j,k);
00108 bb.elem(j,k)=dum;
00109 }
00110 d = -1.*d;
00111 vv.elem(imax)=vv.elem(j);
00112
00113
00114 {
00115 int itemp=indx.elem(imax);
00116 indx.elem(imax)=indx.elem(j);
00117 indx.elem(j)=itemp;
00118 }
00119
00120 }
00121
00122 if (bb.elem(j,j) == 0.0)
00123 {
00124 bb(j,j)=TINY;
00125 }
00126
00127 if (j != n)
00128 {
00129 dum=1.0/bb(j,j);
00130 for (i=j+1;i<=ub;i++)
00131 {
00132 bb.elem(i,j) *= dum;
00133 }
00134 }
00135 }
00136
00137
00138
00139
00140
00141 part_prod(lb) = d*bb(lb,lb);
00142
00143 for (j=lb+1;j<=ub;j++)
00144 {
00145 part_prod(j)=part_prod(j-1)*bb(j,j);
00146 }
00147 double det=part_prod(ub);
00148 dvariable rdet=nograd_assign(det);
00149 save_identifier_string("PLACE7");
00150 part_prod.save_dvector_value();
00151 part_prod.save_dvector_position();
00152 indx.save_ivector_value();
00153 indx.save_ivector_position();
00154 save_identifier_string("PLACE3");
00155 aa.save_dvar_matrix_position();
00156 save_identifier_string("PLACE2b");
00157 rdet.save_prevariable_position();
00158 save_identifier_string("PLACE2a");
00159 bb.save_dmatrix_value();
00160 save_identifier_string("PLACE2");
00161 bb.save_dmatrix_position();
00162 save_identifier_string("PLACE1");
00163 save_double_value(d);
00164 save_identifier_string("PLACE0");
00165 gradient_structure::GRAD_STACK1->
00166 set_gradient_stack(df_xdet);
00167 return rdet;
00168 }
00169
00171 void df_xdet(void)
00172 {
00173 verify_identifier_string("PLACE0");
00174 double d=restore_double_value();
00175 verify_identifier_string("PLACE1");
00176 dmatrix_position bpos=restore_dmatrix_position();
00177 verify_identifier_string("PLACE2");
00178 dmatrix b=restore_dmatrix_value(bpos);
00179 verify_identifier_string("PLACE2a");
00180
00181 double dfdet=restore_prevariable_derivative();
00182 verify_identifier_string("PLACE2b");
00183 dvar_matrix_position a_pos=restore_dvar_matrix_position();
00184 verify_identifier_string("PLACE3");
00185 ivector_position indx_pos=restore_ivector_position();
00186 ivector indx=restore_ivector_value(indx_pos);
00187 dvector_position part_prod_pos=restore_dvector_position();
00188 dvector part_prod=restore_dvector_value(part_prod_pos);
00189 verify_identifier_string("PLACE7");
00190 int lb=b.colmin();
00191 int ub=b.colmax();
00192 dmatrix dfb(lb,ub,lb,ub);
00193
00194 dvector dfpart_prod(lb,ub);
00195
00196 #ifndef SAFE_INITIALIZE
00197 dfb.initialize();
00198 dfpart_prod.initialize();
00199 #endif
00200
00201
00202 dfpart_prod(ub)=dfdet;
00203 int j;
00204 for (j=ub;j>=lb+1;j--)
00205 {
00206
00207 dfpart_prod(j-1)+=dfpart_prod(j)*b(j,j);
00208 dfb(j,j)+=dfpart_prod(j)*part_prod(j-1);
00209 dfpart_prod(j)=0.;
00210 }
00211
00212 dfb(lb,lb)+=dfpart_prod(lb)*d;
00213 dfpart_prod(lb)=0.;
00214
00215 double dfsum=0.;
00216 for (j=ub;j>=lb;j--)
00217 {
00218 for (int i=ub;i>=lb;i--)
00219 {
00220 if (i<=j)
00221 {
00222
00223 dfsum+=dfb(i,j);
00224 dfb(i,j)=0.;
00225 }
00226 else
00227 {
00228
00229 dfsum+=dfb(i,j)/b(j,j);
00230 dfb(j,j)-=dfb(i,j)*b(i,j)/b(j,j);
00231 dfb(i,j)=0.;
00232 }
00233
00234 for (int k=min(i-1,j-1);k>=lb;k--)
00235 {
00236
00237 dfb(i,k)-=dfsum*b(k,j);
00238 dfb(k,j)-=dfsum*b(i,k);
00239 }
00240
00241 save_dmatrix_derivatives(a_pos,dfsum,indx(i),j);
00242 dfsum=0.;
00243 }
00244 }
00245 }
00246
00247 #undef TINY