1 // MeshOptimizer - Copyright (C) 2013-2019 UCLouvain-ULiege
2 //
3 // Permission is hereby granted, free of charge, to any person
4 // obtaining a copy of this software and associated documentation
5 // files (the "Software"), to deal in the Software without
6 // restriction, including without limitation the rights to use, copy,
7 // modify, merge, publish, distribute, and/or sell copies of the
8 // Software, and to permit persons to whom the Software is furnished
9 // to do so, provided that the above copyright notice(s) and this
10 // permission notice appear in all copies of the Software and that
11 // both the above copyright notice(s) and this permission notice
12 // appear in supporting documentation.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE
18 // COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR
19 // ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
20 // DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21 // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
22 // ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23 // OF THIS SOFTWARE.
24 
25 #ifndef OBJ_CONTRIB_FUNC_H
26 #define OBJ_CONTRIB_FUNC_H
27 
28 #include <string>
29 
30 class ObjContribFuncSimple {
31 protected:
getNamePrefix()32   std::string getNamePrefix() { return ""; }
initialize(double vMin,double vMax)33   void initialize(double vMin, double vMax) {}
updateParameters(double vMin,double vMax)34   void updateParameters(double vMin, double vMax) {}
targetReached(double vMin,double vMax)35   bool targetReached(double vMin, double vMax) { return true; }
stagnated(double vMin,double vMax)36   bool stagnated(double vMin, double vMax) { return false; }
compute(double v)37   double compute(double v) { return v; }
computeDiff(double v)38   double computeDiff(double v) { return 1.; }
39 };
40 
41 class ObjContribFuncSimpleTargetMax : public ObjContribFuncSimple {
42 public:
43   ObjContribFuncSimpleTargetMax();
44   void setTarget(double target);
45 
46 protected:
47   static const double
48     STAGTHRESHOLD; // Threshold to consider that measures stagnates
49   double _target, _init;
50   void updateParameters(double vMin, double vMax);
targetReached(double vMin,double vMax)51   bool targetReached(double vMin, double vMax) { return (vMax <= _target); }
52   bool stagnated(double vMin, double vMax);
53 };
54 
55 class ObjContribFuncBarrier {
56 public:
57   ObjContribFuncBarrier();
58   void setTarget(double target, double opt = 1., double defaultMargin = 0.);
59 
60 protected:
61   static const double
62     MARGINCOEFF; // Margin coefficient w.r.t. min. & max. to set barrier
63   static const double
64     STAGTHRESHOLD; // Threshold to consider that measures stagnates
65   double _opt; // Optimal value of measure in barrier function
66   double _defaultMargin; // Default margin value to set barrier w.r.t. of
67                          // min./max. of measure
68   double _barrier,
69     _target; // Current barrier and target of min./max. of measure
70   double _init; // Initial value of min./max. of measure
71   static double logBarrier(double v, double barrier, double opt);
72   static double diffLogBarrier(double v, double barrier, double opt);
73 };
74 
75 class ObjContribFuncBarrierMovMin : public ObjContribFuncBarrier {
76 protected:
getNamePrefix()77   std::string getNamePrefix() { return "BarrierMovMin"; }
initialize(double vMin,double vMax)78   void initialize(double vMin, double vMax) {}
79   void updateParameters(double vMin, double vMax);
targetReached(double vMin,double vMax)80   bool targetReached(double vMin, double vMax) { return (vMin >= _target); }
81   bool stagnated(double vMin, double vMax);
82   double compute(double v);
83   double computeDiff(double v);
84 };
85 
86 class ObjContribFuncBarrierMovMax : public ObjContribFuncBarrier {
87 protected:
getNamePrefix()88   std::string getNamePrefix() { return "BarrierMovMax"; }
initialize(double vMin,double vMax)89   void initialize(double vMin, double vMax) {}
90   void updateParameters(double vMin, double vMax);
targetReached(double vMin,double vMax)91   bool targetReached(double vMin, double vMax) { return (vMax <= _target); }
92   bool stagnated(double vMin, double vMax);
93   double compute(double v);
94   double computeDiff(double v);
95 };
96 
97 class ObjContribFuncBarrierFixMin : public ObjContribFuncBarrier {
98 protected:
getNamePrefix()99   std::string getNamePrefix() { return "BarrierFixMin"; }
100   void initialize(double vMin, double vMax);
updateParameters(double vMin,double vMax)101   void updateParameters(double vMin, double vMax) {}
targetReached(double vMin,double vMax)102   bool targetReached(double vMin, double vMax) { return (vMin >= _barrier); }
stagnated(double vMin,double vMax)103   bool stagnated(double vMin, double vMax) { return false; }
104   inline double compute(double v);
105   inline double computeDiff(double v);
106 };
107 
108 class ObjContribFuncBarrierFixMinMovMax : public ObjContribFuncBarrierMovMax {
109 protected:
getNamePrefix()110   std::string getNamePrefix() { return "BarrierFixMinMovMax"; }
111   void initialize(double vMin, double vMax);
112   inline double compute(double v);
113   inline double computeDiff(double v);
114 
115 protected:
116   double _fixedMinBarrier;
117 };
118 
logBarrier(double v,double barrier,double opt)119 inline double ObjContribFuncBarrier::logBarrier(double v, double barrier,
120                                                 double opt)
121 {
122   const double l = log((v - barrier) / (opt - barrier));
123   const double m = (v - opt);
124   return l * l + m * m;
125 }
126 
diffLogBarrier(double v,double barrier,double opt)127 inline double ObjContribFuncBarrier::diffLogBarrier(double v, double barrier,
128                                                     double opt)
129 {
130   return 2. *
131          ((v - opt) + log((v - barrier) / (opt - barrier)) / (v - barrier));
132 }
133 
compute(double v)134 inline double ObjContribFuncBarrierMovMin::compute(double v)
135 {
136   if(v > _barrier)
137     return logBarrier(v, _barrier, _opt);
138   else
139     return 1e300;
140 }
141 
computeDiff(double v)142 inline double ObjContribFuncBarrierMovMin::computeDiff(double v)
143 {
144   if(v > _barrier)
145     return diffLogBarrier(v, _barrier, _opt);
146   else
147     return -1e300;
148 }
149 
compute(double v)150 inline double ObjContribFuncBarrierMovMax::compute(double v)
151 {
152   if(v < _barrier)
153     return logBarrier(v, _barrier, _opt);
154   else
155     return 1e300;
156 }
157 
computeDiff(double v)158 inline double ObjContribFuncBarrierMovMax::computeDiff(double v)
159 {
160   if(v < _barrier)
161     return diffLogBarrier(v, _barrier, _opt);
162   else
163     return 1e300;
164 }
165 
compute(double v)166 inline double ObjContribFuncBarrierFixMin::compute(double v)
167 {
168   if(v > _barrier)
169     return logBarrier(v, _barrier, _opt);
170   else
171     return 1e300;
172 }
173 
computeDiff(double v)174 inline double ObjContribFuncBarrierFixMin::computeDiff(double v)
175 {
176   if(v > _barrier)
177     return diffLogBarrier(v, _barrier, _opt);
178   else
179     return -1e300;
180 }
181 
compute(double v)182 inline double ObjContribFuncBarrierFixMinMovMax::compute(double v)
183 {
184   double obj;
185   if(v < _barrier)
186     obj = logBarrier(v, _barrier, _opt);
187   else
188     return 1e300;
189   if(v > _fixedMinBarrier) {
190     obj += logBarrier(v, _fixedMinBarrier, _opt);
191     return obj;
192   }
193   else
194     return 1e300;
195 }
196 
computeDiff(double v)197 inline double ObjContribFuncBarrierFixMinMovMax::computeDiff(double v)
198 {
199   double dobj;
200   if(v < _barrier)
201     dobj = diffLogBarrier(v, _barrier, _opt);
202   else
203     return 1e300;
204   if(v > _fixedMinBarrier) {
205     dobj += diffLogBarrier(v, _fixedMinBarrier, _opt);
206     return dobj;
207   }
208   else
209     return -1e300;
210 }
211 
212 #endif
213