MC++
ffdep.hpp
1 // Copyright (C) 2009-2013 Benoit Chachuat, Imperial College London.
2 // All Rights Reserved.
3 
76 #ifndef MC__FFDEP_HPP
77 #define MC__FFDEP_HPP
78 
79 #include <iostream>
80 #include <map>
81 
82 namespace mc
83 {
84 
90 class FFDep
92 {
93  // friends of class FFDep for operator and function overloading
94  friend FFDep operator+ ( const FFDep& );
95  friend FFDep operator+ ( const FFDep&, const FFDep& );
96  friend FFDep operator+ ( const double, const FFDep& );
97  friend FFDep operator+ ( const FFDep&, const double );
98  friend FFDep operator- ( const FFDep& );
99  friend FFDep operator- ( const FFDep&, const FFDep& );
100  friend FFDep operator- ( const double, const FFDep& );
101  friend FFDep operator- ( const FFDep&, const double );
102  friend FFDep operator* ( const FFDep&, const FFDep& );
103  friend FFDep operator* ( const FFDep&, const double );
104  friend FFDep operator* ( const double, const FFDep& );
105  friend FFDep operator/ ( const FFDep&, const FFDep& );
106  friend FFDep operator/ ( const FFDep&, const double );
107  friend FFDep operator/ ( const double, const FFDep& );
108  friend std::ostream& operator<< ( std::ostream&, const FFDep& );
109  friend bool operator== ( const FFDep&, const FFDep& );
110  friend bool operator!= ( const FFDep&, const FFDep& );
111  friend bool operator<= ( const FFDep&, const FFDep& );
112  friend bool operator>= ( const FFDep&, const FFDep& );
113  friend bool operator< ( const FFDep&, const FFDep& );
114  friend bool operator> ( const FFDep&, const FFDep& );
115  friend FFDep inv ( const FFDep& );
116  friend FFDep sqr ( const FFDep& );
117  friend FFDep exp ( const FFDep& );
118  friend FFDep log ( const FFDep& );
119  friend FFDep cos ( const FFDep& );
120  friend FFDep sin ( const FFDep& );
121  friend FFDep tan ( const FFDep& );
122  friend FFDep acos ( const FFDep& );
123  friend FFDep asin ( const FFDep& );
124  friend FFDep atan ( const FFDep& );
125  friend FFDep fabs ( const FFDep& );
126  friend FFDep sqrt ( const FFDep& );
127  friend FFDep erf ( const FFDep& );
128  friend FFDep erfc ( const FFDep& );
129  friend FFDep fstep ( const FFDep& );
130  friend FFDep bstep ( const FFDep& );
131  friend FFDep pow ( const FFDep&, const int );
132  friend FFDep pow ( const FFDep&, const double );
133  friend FFDep pow ( const FFDep&, const FFDep& );
134  friend FFDep min ( const FFDep&, const FFDep& );
135  friend FFDep max ( const FFDep&, const FFDep& );
136  friend FFDep min ( const unsigned int, const FFDep* );
137  friend FFDep max ( const unsigned int, const FFDep* );
138  friend FFDep sum ( const unsigned int, const FFDep* );
139  friend FFDep prod ( const unsigned int, const FFDep* );
140 
141 public:
142 
145  {
146  public:
148  enum TYPE{
149  UNDEF=-33
150  };
152  Exceptions( TYPE ierr ) : _ierr( ierr ){}
153 
155  int ierr(){ return _ierr; }
156  private:
157  TYPE _ierr;
159  std::string what(){
160  switch( _ierr ){
161  case UNDEF:
162  return "mc::FFDep\t Feature not yet implemented in MC++";
163  default:
164  return "mc::FFDep\t Undocumented error";
165  }
166  }
167  };
168 
169  typedef std::map<int,bool> t_FFDep;
170  typedef t_FFDep::iterator it_FFDep;
171  typedef t_FFDep::const_iterator cit_FFDep;
172 
173  // other operator overloadings (inlined)
174  FFDep& operator=
175  ( const double c )
176  { _dep.clear(); return *this; }
177  FFDep& operator=
178  ( const FFDep&S )
179  { if( this != &S ) _dep = S._dep; return *this; }
180  FFDep& operator+=
181  ( const double c )
182  { return *this; }
183  FFDep& operator+=
184  ( const FFDep&S )
185  { return combine( S ); }
186  FFDep& operator-=
187  ( const double c )
188  { return *this; }
189  FFDep& operator-=
190  ( const FFDep&S )
191  { return combine( S ); }
192  FFDep& operator*=
193  ( const double c )
194  { return *this; }
195  FFDep& operator*=
196  ( const FFDep&S )
197  { return combine( S, false ); }
198  FFDep& operator/=
199  ( const double c )
200  { return *this; }
201  FFDep& operator/=
202  ( const FFDep&S )
203  { return combine( S, false ); }
204 
208  FFDep
210  ( const double c=0. )
211  {}
213  FFDep
214  ( const FFDep&S ):
215  _dep(S._dep)
216  {}
219  {}
220 
222  FFDep& indep
223  ( const int ind )
224  { _dep.clear(); _dep.insert( std::make_pair(ind,true) ); return *this; }
225 
227  std::pair<bool,bool> dep
228  ( const int ind )
229  { cit_FFDep it = _dep.find(ind);
230  return( it==_dep.end()? std::make_pair(false,true):
231  std::make_pair(true,it->second) ); }
232 
234  const t_FFDep& dep() const
235  { return _dep; }
236  t_FFDep& dep()
237  { return _dep; }
238 
240  FFDep& combine
241  ( const FFDep&S, const bool linear=true );
243  static FFDep combine
244  ( const FFDep&S1, const FFDep&S2, const bool linear=true );
245 
247  FFDep& nonlinear();
249  static FFDep nonlinear
250  ( const FFDep&S );
253 private:
254 
256  t_FFDep _dep;
257 };
258 
260 
261 inline FFDep&
263 {
264  it_FFDep it = _dep.begin();
265  for( ; it != _dep.end(); ++it ) it->second = false;
266  return *this;
267 }
268 
269 inline FFDep
271 ( const FFDep&S )
272 {
273  FFDep S2( S );
274  return S2.nonlinear();
275 }
276 
277 inline FFDep&
279 ( const FFDep&S, const bool linear )
280 {
281  cit_FFDep cit = S._dep.begin();
282  for( ; cit != S._dep.end(); ++cit ){
283  std::pair<it_FFDep,bool> ins = _dep.insert( *cit );
284  if( !ins.second ) ins.first->second = ( ins.first->second && cit->second );
285  }
286  return( linear? *this: nonlinear() );
287 }
288 
289 inline FFDep
291 ( const FFDep&S1, const FFDep&S2, const bool linear )
292 {
293  FFDep S3( S1 );
294  return S3.combine( S2, linear );
295 }
296 
297 inline std::ostream&
298 operator<<
299 ( std::ostream&out, const FFDep&S)
300 {
301  out << "{ ";
302  FFDep::cit_FFDep iS = S._dep.begin();
303  for( ; iS != S._dep.end(); ++iS )
304  out << iS->first << (iS->second?"L":"NL") << " ";
305  out << "}";
306  return out;
307 }
308 
309 inline FFDep
310 operator+
311 ( const FFDep&S )
312 {
313  return S;
314 }
315 
316 inline FFDep
317 operator-
318 ( const FFDep&S )
319 {
320  return S;
321 }
322 
323 inline FFDep
324 operator+
325 ( const double c, const FFDep&S )
326 {
327  return S;
328 }
329 
330 inline FFDep
331 operator+
332 ( const FFDep&S, const double c )
333 {
334  return S;
335 }
336 
337 inline FFDep
338 operator+
339 ( const FFDep&S1, const FFDep&S2 )
340 {
341  return FFDep::combine( S1, S2 );
342 }
343 
344 inline FFDep
345 sum
346 ( const unsigned int n, const FFDep*S )
347 {
348  if( n==2 ) return S[0] + S[1];
349  return S[0] + sum( n-1, S+1 );
350 }
351 
352 inline FFDep
353 operator-
354 ( const double c, const FFDep&S )
355 {
356  return S;
357 }
358 
359 inline FFDep
360 operator-
361 ( const FFDep&S, const double c )
362 {
363  return S;
364 }
365 
366 inline FFDep
367 operator-
368 ( const FFDep&S1, const FFDep&S2 )
369 {
370  return FFDep::combine( S1, S2 );
371 }
372 
373 inline FFDep
374 operator*
375 ( const double c, const FFDep&S )
376 {
377  return S;
378 }
379 
380 inline FFDep
381 operator*
382 ( const FFDep&S, const double c )
383 {
384  return S;
385 }
386 
387 inline FFDep
388 operator*
389 ( const FFDep&S1, const FFDep&S2 )
390 {
391  if( S1._dep.empty() ) return S2;
392  if( S2._dep.empty() ) return S1;
393  return FFDep::combine( S1, S2, false );
394 }
395 
396 inline FFDep
397 prod
398 ( const unsigned int n, const FFDep*S )
399 {
400  if( n==2 ) return S[0] * S[1];
401  return S[0] * prod( n-1, S+1 );
402 }
403 
404 inline FFDep
405 operator/
406 ( const FFDep&S, const double c )
407 {
408  return S;
409 }
410 
411 inline FFDep
412 operator/
413 ( const double c, const FFDep&S )
414 {
415  return S;
416 }
417 
418 inline FFDep
419 operator/
420 ( const FFDep&S1, const FFDep&S2 )
421 {
422  if( S1._dep.empty() ) return inv( S2 );
423  if( S2._dep.empty() ) return S1;
424  return FFDep::combine( S1, S2, false );
425 }
426 
427 inline FFDep
428 inv
429 ( const FFDep &S )
430 {
431  return FFDep::nonlinear( S );
432 }
433 
434 inline FFDep
435 sqr
436 ( const FFDep&S )
437 {
438  return FFDep::nonlinear( S );
439 }
440 
441 inline FFDep
442 exp
443 ( const FFDep &S )
444 {
445  return FFDep::nonlinear( S );
446 }
447 
448 inline FFDep
449 arh
450 ( const FFDep &S, const double a )
451 {
452  return FFDep::nonlinear( S );
453 }
454 
455 inline FFDep
456 log
457 ( const FFDep &S )
458 {
459  return FFDep::nonlinear( S );
460 }
461 
462 inline FFDep
463 xlog
464 ( const FFDep&S )
465 {
466  return FFDep::nonlinear( S );
467 }
468 
469 inline FFDep
470 erf
471 ( const FFDep &S )
472 {
473  return FFDep::nonlinear( S );
474 }
475 
476 inline FFDep
477 erfc
478 ( const FFDep &S )
479 {
480  return FFDep::nonlinear( S );
481 }
482 
483 inline FFDep
484 fstep
485 ( const FFDep &S )
486 {
487  return FFDep::nonlinear( S );
488 }
489 
490 inline FFDep
491 bstep
492 ( const FFDep &S )
493 {
494  return FFDep::nonlinear( S );
495 }
496 
497 inline FFDep
498 sqrt
499 ( const FFDep&S )
500 {
501  return FFDep::nonlinear( S );
502 }
503 
504 inline FFDep
505 fabs
506 ( const FFDep&S )
507 {
508  return FFDep::nonlinear( S );
509 }
510 
511 inline FFDep
512 pow
513 ( const FFDep&S, const int n )
514 {
515  if( n == 0 ){ FFDep S2; return S2; }
516  if( n == 1 ) return S;
517  return FFDep::nonlinear( S );
518 }
519 
520 inline FFDep
521 pow
522 ( const FFDep&S, const double a )
523 {
524  return FFDep::nonlinear( S );
525 }
526 
527 inline FFDep
528 pow
529 ( const FFDep&S1, const FFDep&S2 )
530 {
531  if( S1._dep.empty() ) return FFDep::nonlinear( S2 );
532  if( S2._dep.empty() ) return FFDep::nonlinear( S1 );
533  return FFDep::combine( S1, S2, false );
534 }
535 
536 inline FFDep
537 min
538 ( const FFDep&S1, const FFDep&S2 )
539 {
540  if( S1._dep.empty() ) return S2;
541  if( S2._dep.empty() ) return S1;
542  return FFDep::combine( S1, S2, false );
543 }
544 
545 inline FFDep
546 max
547 ( const FFDep&S1, const FFDep&S2 )
548 {
549  if( S1._dep.empty() ) return S2;
550  if( S2._dep.empty() ) return S1;
551  return FFDep::combine( S1, S2, false );
552 }
553 
554 inline FFDep
555 min
556 ( const unsigned int n, const FFDep*S )
557 {
558  if( n==2 ) return min( S[0], S[1] );
559  return min( S[0], min( n-1, S+1 ) );
560 }
561 
562 inline FFDep
563 max
564 ( const unsigned int n, const FFDep*S )
565 {
566  if( n==2 ) return max( S[0], S[1] );
567  return max( S[0], max( n-1, S+1 ) );
568 }
569 
570 inline FFDep
571 cos
572 ( const FFDep&S )
573 {
574  return FFDep::nonlinear( S );
575 }
576 
577 inline FFDep
578 sin
579 ( const FFDep &S )
580 {
581  return FFDep::nonlinear( S );
582 }
583 
584 inline FFDep
585 tan
586 ( const FFDep&S )
587 {
588  return FFDep::nonlinear( S );
589 }
590 
591 inline FFDep
592 acos
593 ( const FFDep &S )
594 {
595  return FFDep::nonlinear( S );
596 }
597 
598 inline FFDep
599 asin
600 ( const FFDep &S )
601 {
602  return FFDep::nonlinear( S );
603 }
604 
605 inline FFDep
606 atan
607 ( const FFDep &S )
608 {
609  return FFDep::nonlinear( S );
610 }
611 
612 inline bool
613 operator==
614 ( const FFDep&S1, const FFDep&S2 )
615 {
616  return( S1._dep == S2._dep );
617 }
618 
619 inline bool
620 operator!=
621 ( const FFDep&S1, const FFDep&S2 )
622 {
623  return( S1._dep != S2._dep );
624 }
625 
626 inline bool
627 operator<=
628 ( const FFDep&S1, const FFDep&S2 )
629 {
630  return( S1._dep <= S2._dep );
631 }
632 
633 inline bool
634 operator>=
635 ( const FFDep&S1, const FFDep&S2 )
636 {
637  return( S1._dep >= S2._dep );
638 }
639 
640 inline bool
641 operator<
642 ( const FFDep&S1, const FFDep&S2 )
643 {
644  return( S1._dep < S2._dep );
645 }
646 
647 inline bool
648 operator>
649 ( const FFDep&S1, const FFDep&S2 )
650 {
651  return( S1._dep > S2._dep );
652 }
653 
654 } // namespace mc
655 
656 #endif
Exceptions(TYPE ierr)
Constructor for error ierr
Definition: ffdep.hpp:152
FFDep & nonlinear()
Turns current dependent variables into nonlinear.
Definition: ffdep.hpp:262
C++ class for evaluation of the sparsity pattern of a factorable function.
Definition: ffdep.hpp:90
FFDep(const double c=0.)
Default constructor (needed to declare arrays of FFDep class)
Definition: ffdep.hpp:210
const t_FFDep & dep() const
Returns the dependency set.
Definition: ffdep.hpp:234
FFDep & combine(const FFDep &S, const bool linear=true)
Combines with the dependency sets of another variable.
Definition: ffdep.hpp:279
~FFDep()
Destructor.
Definition: ffdep.hpp:218
Exceptions of mc::FFDep.
Definition: ffdep.hpp:144
FFDep & indep(const int ind)
Sets as independent with index ind
Definition: ffdep.hpp:223
TYPE
Enumeration type for FFDep exception handling.
Definition: ffdep.hpp:148
int ierr()
Inline function returning the error flag.
Definition: ffdep.hpp:155
Error due to calling a function/feature not yet implemented in mc::FFDep.
Definition: ffdep.hpp:149