ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dmat3.cpp
Go to the documentation of this file.
1 
7 #include "fvar.hpp"
8 #include <math.h>
9 #ifndef OPT_LIB
10  #include <cassert>
11  #include <climits>
12 #endif
13 
14 #ifdef ISZERO
15  #undef ISZERO
16 #endif
17 #define ISZERO(d) ((d)==0.0)
18 
24 #define TINY 1.0e-20;
25 
26 void lubksb(dmatrix a, const ivector& indx,dvector b);
27 void ludcmp(const dmatrix& a, const ivector& indx, const double& d);
28 
37 dmatrix inv(const dmatrix& m1)
38 {
39  int min = m1.rowmin();
40  int max = m1.rowmax();
41 
42 #ifndef OPT_LIB
43  if (min != m1.colmin() || max != m1.colmax())
44  {
45  cerr << " Error in dmatrix inv(const dmatrix&) -- matrix not square \n";
46  }
47 #endif
48 
49  dmatrix a(min, max, min, max);
50 
51  dvector* pai = &a(min);
52  const dvector* pm1i = &m1(min);
53  for (int i = min; i <= max; ++i)
54  {
55  double* pm1ij = pm1i->get_v() + min;
56  double* paij = pai->get_v() + min;
57  for (int j = min; j <= max; ++j)
58  {
59  *paij = *pm1ij;
60 
61  ++pm1ij;
62  ++paij;
63  }
64  ++pm1i;
65  ++pai;
66  }
67  ivector indx(min, max);
68  //int indx[30];
69 
70  double d;
71  ludcmp(a,indx,d);
72 
73  dmatrix y(min, max, min, max);
74  dvector col(min, max);
75 
76  double* pcolj = col.get_v() + min;
77  for (int j = min; j <= max; ++j)
78  {
79  double* pcoli = col.get_v() + min;
80  for (int i= min; i <= max; ++i)
81  {
82  *pcoli = 0.0;
83 
84  ++pcoli;
85  }
86  *pcolj = 1.0;
87 
88  lubksb(a,indx,col);
89 
90  dvector* pyi = &y(min);
91  pcoli = col.get_v() + min;
92  for (int i= min; i <= max; ++i)
93  {
94  *(pyi->get_v() + j)= *pcoli;
95 
96  ++pyi;
97  ++pcoli;
98  }
99 
100  ++pcolj;
101  }
102  return y;
103 }
104 
114 dmatrix inv(const dmatrix& m1,const double& _ln_det, const int& _sgn)
115 {
116  int min = m1.rowmin();
117  int max = m1.rowmax();
118 
119 #ifndef OPT_LIB
120  if (min != m1.colmin() || max != m1.colmax())
121  {
122  cerr << " Error in dmatrix inv(const dmatrix&) -- matrix not square \n";
123  }
124 #endif
125 
126  dmatrix a(min, max, min, max);
127 
128  dvector* pai = &a(min);
129  const dvector* pm1i = &m1(min);
130  for (int i = min; i <= max; ++i)
131  {
132  double* pm1ij = pm1i->get_v() + min;
133  double* paij = pai->get_v() + min;
134  for (int j = min; j <= max; ++j)
135  {
136  *paij = *pm1ij;
137 
138  ++pm1ij;
139  ++paij;
140  }
141  ++pm1i;
142  ++pai;
143  }
144  ivector indx(min, max);
145  //int indx[30];
146 
147  double d = 0.0;
148  ludcmp(a,indx,d);
149 
150  int& sgn=(int&)(_sgn);
151  if (d>.1)
152  {
153  sgn=1;
154  }
155  else if (d<-0.1)
156  {
157  sgn=-1;
158  }
159  else
160  {
161  sgn=0;
162  }
163  double& ln_det=(double&)(_ln_det);
164  ln_det=0.0;
165  for (int j = min; j <= max; ++j)
166  {
167  double ajj = a(j, j);
168  if (ajj > 0)
169  {
170  ln_det += log(ajj);
171  }
172  else if (ajj < 0)
173  {
174  sgn = -sgn;
175  ln_det += log(-ajj);
176  }
177  else
178  {
179  sgn = 0;
180  }
181  }
182 
183  dmatrix y(min, max, min, max);
184  dvector col(min, max);
185 
186  double* pcolj = col.get_v() + min;
187  for (int j = min; j <= max; ++j)
188  {
189  double* pcoli = col.get_v() + min;
190  for (int i= min; i <= max; ++i)
191  {
192  *pcoli = 0.0;
193 
194  ++pcoli;
195  }
196  *pcolj = 1.0;
197 
198  lubksb(a,indx,col);
199 
200  dvector* pyi = &y(min);
201  pcoli = col.get_v() + min;
202  for (int i = min; i <= max; ++i)
203  {
204  *(pyi->get_v() + j)= *pcoli;
205 
206  ++pcoli;
207  ++pyi;
208  }
209  }
210  return y;
211 }
212 
221 void ludcmp(const dmatrix& _a, const ivector& _indx, const double& _d)
222 {
223  int i=0;
224  int j=0;
225  int k=0;
226  double& d=(double&)_d;
227  dmatrix& a=(dmatrix&)_a;
228  ivector& indx=(ivector&)_indx;
229 
230 #if !defined(OPT_LIB) && (__cplusplus >= 201103L)
231  int n = [](unsigned int colsize) -> int
232  {
233  assert(colsize <= INT_MAX);
234  return static_cast<int>(colsize);
235  } (a.colsize());
236 #else
237  int n = static_cast<int>(a.colsize());
238 #endif
239  int lb=a.colmin();
240  int ub=a.colmax();
241 
242  dvector vv(lb,ub);
243 
244  d=1.0;
245 
246  dvector* pai = &a(lb);
247  double* pvvi = vv.get_v() + lb;
248  for (i=lb;i<=ub;++i)
249  {
250  double big=0.0;
251 
252  double* paij = pai->get_v() + lb;
253  for (j=lb;j<=ub;++j)
254  {
255  double temp=fabs(*paij);
256  if (temp > big)
257  {
258  big=temp;
259  }
260 
261  ++paij;
262  }
263  if (big == 0.0)
264  {
265  std::ostream& output_stream = get_output_stream();
266  output_stream << "Error: division by zero in ludcmp\n";
267  }
268  *pvvi = 1.0 / big;
269 
270  ++pai;
271  ++pvvi;
272  }
273 
274 
275 
276  for (j=lb;j<=ub;j++)
277  {
278  for (i=lb;i<j;i++)
279  {
280  double sum=a[i][j];
281  for (k=lb;k<i;k++)
282  {
283  sum = sum - a[i][k]*a[k][j];
284  }
285  a[i][j]=sum;
286  }
287  int imax=j;
288  double big=0.0;
289  for (i=j;i<=ub;i++)
290  {
291  double sum=a[i][j];
292  for (k=lb;k<j;k++)
293  {
294  sum = sum - a[i][k]*a[k][j];
295  }
296  a[i][j]=sum;
297  double dum=vv[i]*fabs(sum);
298  if ( dum >= big)
299  {
300  big=dum;
301  imax=i;
302  }
303  }
304  if (j != imax)
305  {
306  for (k=lb;k<=ub;k++)
307  {
308  double dum=a[imax][k];
309  a[imax][k]=a[j][k];
310  a[j][k]=dum;
311  }
312  d = -d;
313  vv[imax]=vv[j];
314  }
315  indx[j]=imax;
316 
317  if (a[j][j] == 0.0)
318  {
319  a[j][j]=TINY;
320  }
321 
322  if (j != n)
323  {
324  double dum=1.0/(a[j][j]);
325  for (i=j+1;i<=ub;i++)
326  {
327  a[i][j] = a[i][j] * dum;
328  }
329  }
330  }
331 }
332 #undef TINY
333 
334 #define TINY 1.0e-50;
335 
344 void ludcmp_det(const dmatrix& _a, const ivector& _indx, const double& _d)
345 {
346  int i,j,k;
347  double& d=(double&)_d;
348  dmatrix& a=(dmatrix&)_a;
349  ivector& indx=(ivector&)_indx;
350 
351 #if !defined(OPT_LIB) && (__cplusplus >= 201103L)
352  int n = [](unsigned int colsize) -> int
353  {
354  assert(colsize <= INT_MAX);
355  return static_cast<int>(colsize);
356  } (a.colsize());
357 #else
358  int n = static_cast<int>(a.colsize());
359 #endif
360  int lb=a.colmin();
361  int ub=a.colmax();
362 
363  dvector vv(lb,ub);
364 
365  d=1.0;
366 
367  for (i=lb;i<=ub;i++)
368  {
369  double big=0.0;
370  for (j=lb;j<=ub;j++)
371  {
372  double temp=fabs(a[i][j]);
373  if (temp > big)
374  {
375  big=temp;
376  }
377  }
378  if (big == 0.0)
379  {
380  d=0.;
381  }
382  vv[i]=1.0/big;
383  }
384 
385 
386 
387  for (j=lb;j<=ub;j++)
388  {
389  for (i=lb;i<j;i++)
390  {
391  double sum=a[i][j];
392  for (k=lb;k<i;k++)
393  {
394  sum = sum - a[i][k]*a[k][j];
395  }
396  a[i][j]=sum;
397  }
398  int imax = j;
399  double big=0.0;
400  for (i=j;i<=ub;i++)
401  {
402  double sum=a[i][j];
403  for (k=lb;k<j;k++)
404  {
405  sum = sum - a[i][k]*a[k][j];
406  }
407  a[i][j]=sum;
408  double dum=vv[i]*fabs(sum);
409  if ( dum >= big)
410  {
411  big=dum;
412  imax=i;
413  }
414  }
415  if (j != imax)
416  {
417  for (k=lb;k<=ub;k++)
418  {
419  double dum=a[imax][k];
420  a[imax][k]=a[j][k];
421  a[j][k]=dum;
422  }
423  d = -d;
424  vv[imax]=vv[j];
425  }
426  indx[j]=imax;
427 
428  if (a[j][j] == 0.0)
429  {
430  a[j][j]=TINY;
431  }
432 
433  if (j != n)
434  {
435  double dum=1.0/(a[j][j]);
436  for (i=j+1;i<=ub;i++)
437  {
438  a[i][j] = a[i][j] * dum;
439  }
440  }
441  }
442 }
443 
444 
455 void lubksb(dmatrix a, const ivector& indx, dvector b)
456 {
457  int i,ii=0,ip,j,iiflag=0;
458  int lb=a.colmin();
459  int ub=a.colmax();
460  for (i=lb;i<=ub;i++)
461  {
462  ip=indx[i];
463  double sum=b[ip];
464  b[ip]=b[i];
465  if (iiflag)
466  {
467  for (j=ii;j<=i-1;j++)
468  {
469  sum -= a[i][j]*b[j];
470  }
471  }
472  else if (!ISZERO(sum))
473  {
474  ii=i;
475  iiflag=1;
476  }
477  b[i]=sum;
478  }
479 
480  for (i=ub;i>=lb;i--)
481  {
482  double sum=b[i];
483  for (j=i+1;j<=ub;j++)
484  { // !!! remove to show bug
485  sum -= a[i][j]*b[j];
486  } // !!! remove to show bug
487  b[i]=sum/a[i][i];
488  }
489 }
490 
499 double det(const dmatrix& m1)
500 {
501  double d = 0.0;
502  dmatrix a(m1.rowmin(),m1.rowmax(),m1.rowmin(),m1.rowmax());
503 
504  if (m1.rowmin()!=m1.colmin()||m1.rowmax()!=m1.colmax())
505  {
506  cerr << "Matrix not square in routine det()" << endl;
507  ad_exit(1);
508  }
509 
510  for (int i=m1.rowmin(); i<=m1.rowmax(); i++)
511  {
512  for (int j=m1.rowmin(); j<=m1.rowmax(); j++)
513  {
514  a[i][j]=m1[i][j];
515  }
516  }
517 
518  ivector indx(m1.rowmin(),m1.rowmax());
519  ludcmp_det(a,indx,d);
520  for (int j=m1.rowmin();j<=m1.rowmax();j++)
521  {
522  d*=a[j][j];
523  }
524 
525  return(d);
526 }
527 
536 double ln_det(const dmatrix& m1, int& sgn)
537 {
538  int min = m1.rowmin();
539  int max = m1.rowmax();
540 
541 #ifndef OPT_LIB
542  if (min != m1.colmin() || max != m1.colmax())
543  {
544  cerr << "Matrix not square in routine det()" << endl;
545  ad_exit(1);
546  }
547 #endif
548 
549  dmatrix a(min, max, min, max);
550 
551  dvector* pai = &a(min);
552  const dvector* pm1i = &m1(min);
553  for (int i = min; i <= max; ++i)
554  {
555  double* pm1ij = pm1i->get_v() + min;
556  double* paij = pai->get_v() + min;
557  for (int j = min; j <= max; ++j)
558  {
559  *paij = *pm1ij;
560 
561  ++pm1ij;
562  ++paij;
563  }
564  ++pm1i;
565  ++pai;
566  }
567 
568  ivector indx(min, max);
569 
570  double d = 0.0;
571  ludcmp_det(a,indx,d);
572  double ln_det=0.0;
573 
574  if (d>.1)
575  {
576  sgn=1;
577  }
578  else if (d<-0.1)
579  {
580  sgn=-1;
581  }
582  else
583  {
584  sgn=0;
585  }
586  for (int j = min; j <= max; ++j)
587  {
588  double ajj = a(j, j);
589  if (ajj > 0)
590  {
591  ln_det += log(ajj);
592  }
593  else if (ajj < 0)
594  {
595  sgn=-sgn;
596  ln_det += log(-ajj);
597  }
598  else
599  {
600  sgn = 0;
601  }
602  }
603  return ln_det;
604 }
605 
613 void ludcmp_index(const dmatrix& _a, const ivector& _indx, const double& _d)
614 {
615  int i=0;
616  int j=0;
617  int k=0;
618  double& d=(double&)_d;
619  dmatrix& a=(dmatrix&)_a;
620  ivector& indx=(ivector&)_indx;
621 #if !defined(OPT_LIB) && (__cplusplus >= 201103L)
622  int n = [](unsigned int colsize) -> int
623  {
624  assert(colsize <= INT_MAX);
625  return static_cast<int>(colsize);
626  } (a.colsize());
627 #else
628  int n = static_cast<int>(a.colsize());
629 #endif
630  int lb=a.colmin();
631  int ub=a.colmax();
632  indx.fill_seqadd(lb,1);
633 
634  dvector vv(lb,ub);
635 
636  d=1.0;
637 
638  for (i=lb;i<=ub;i++)
639  {
640  double big=0.0;
641  for (j=lb;j<=ub;j++)
642  {
643  double temp=fabs(a[i][j]);
644  if (temp > big)
645  {
646  big=temp;
647  }
648  }
649  if (big == 0.0)
650  {
651  cerr << "Error in matrix inverse -- matrix singular in inv(dmatrix)\n";
652  }
653  vv[i]=1.0/big;
654  }
655 
656 
657 
658  for (j=lb;j<=ub;j++)
659  {
660  for (i=lb;i<j;i++)
661  {
662  double sum=a[i][j];
663  for (k=lb;k<i;k++)
664  {
665  sum = sum - a[i][k]*a[k][j];
666  }
667  a[i][j]=sum;
668  }
669  int imax=j;
670  double big=0.0;
671  for (i=j;i<=ub;i++)
672  {
673  double sum=a[i][j];
674  for (k=lb;k<j;k++)
675  {
676  sum = sum - a[i][k]*a[k][j];
677  }
678  a[i][j]=sum;
679  double dum=vv[i]*fabs(sum);
680  if ( dum >= big)
681  {
682  big=dum;
683  imax=i;
684  }
685  }
686  if (j != imax)
687  {
688  for (k=lb;k<=ub;k++)
689  {
690  double dum=a[imax][k];
691  a[imax][k]=a[j][k];
692  a[j][k]=dum;
693  }
694  d = -d;
695  vv[imax]=vv[j];
696  int itemp=indx.elem(imax);
697  indx.elem(imax)=indx.elem(j);
698  indx.elem(j)=itemp;
699  }
700 
701  if (a[j][j] == 0.0)
702  {
703  a[j][j]=TINY;
704  }
705 
706  if (j != n)
707  {
708  double dum=1.0/(a[j][j]);
709  for (i=j+1;i<=ub;i++)
710  {
711  a[i][j] = a[i][j] * dum;
712  }
713  }
714  }
715 }
716 #undef TINY
int & elem(int i)
Definition: ivector.h:90
#define ISZERO(d)
Definition: dmat3.cpp:17
void ludcmp_index(const dmatrix &_a, const ivector &_indx, const double &_d)
LU decomposition.
Definition: dmat3.cpp:613
void ludcmp(const dmatrix &a, const ivector &indx, const double &d)
Lu decomposition of a constant matrix.
Definition: dmat3.cpp:221
Vector of double precision numbers.
Definition: dvector.h:50
void lubksb(dmatrix a, const ivector &indx, dvector b)
LU decomposition back susbstitution alogrithm for constant object.
Definition: dmat3.cpp:455
double sum(const d3_array &darray)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr.cpp:21
exitptr ad_exit
Definition: gradstrc.cpp:53
df1_two_variable fabs(const df1_two_variable &x)
Definition: df12fun.cpp:891
void fill_seqadd(int, int)
Fills ivector elements with values starting from base and incremented by offset.
Definition: cranfill.cpp:73
#define TINY
A small number.
Definition: dmat3.cpp:334
unsigned int colsize() const
Definition: fvar.hpp:2948
ivector sgn(const dvector &v)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: dvect24.cpp:11
double det(const dmatrix &m1)
Compute determinant of a constant matrix.
Definition: dmat3.cpp:499
prnstream & endl(prnstream &)
Array of integers(int) with indexes from index_min to indexmax.
Definition: ivector.h:50
int rowmax() const
Definition: fvar.hpp:2929
#define min(a, b)
Definition: cbivnorm.cpp:188
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
int colmin(void) const
Definition: fvar.hpp:2939
Description not yet available.
Definition: fvar.hpp:2819
double ln_det(const dmatrix &m1, int &sgn)
Compute log determinant of a constant matrix.
Definition: dmat3.cpp:536
std::ostream & get_output_stream()
Definition: adglobl.cpp:45
void ludcmp_det(const dmatrix &_a, const ivector &_indx, const double &_d)
LU decomposition.
Definition: dmat3.cpp:344
#define max(a, b)
Definition: cbivnorm.cpp:189
double *& get_v(void)
Definition: dvector.h:148
int rowmin() const
Definition: fvar.hpp:2925
df1_one_variable inv(const df1_one_variable &x)
Definition: df11fun.cpp:384
d3_array log(const d3_array &arr3)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: d3arr2a.cpp:13
int colmax(void) const
Definition: fvar.hpp:2943