Skip to content
Snippets Groups Projects
Commit a0020497 authored by Jonathan Lambrechts's avatar Jonathan Lambrechts
Browse files

HighOrderMeshOptimizer : optimize barrier max (2 passes for now)

parent b8b36a96
Branches
Tags
No related merge requests found
...@@ -14,6 +14,31 @@ ...@@ -14,6 +14,31 @@
#include "linalg.h" #include "linalg.h"
#include "optimization.h" #include "optimization.h"
static inline double compute_f(double v, double barrier)
{
if ((v > barrier && barrier < 1) || (v < barrier && barrier > 1)) {
const double l = log((v - barrier) / (1 - barrier));
const double m = (v - 1);
return l * l + m * m;
}
else return 1.e300;
// if (v < 1.) return pow(1.-v,powM);
// if (v < 1.) return exp((long double)pow(1.-v,3));
// else return pow(v-1.,powP);
}
static inline double compute_f1(double v, double barrier)
{
if ((v > barrier && barrier < 1) || (v < barrier && barrier > 1)) {
return 2 * (v - 1) + 2 * log((v - barrier) / (1 - barrier)) / (v - barrier);
}
else return barrier < 1 ? -1.e300 : 1e300;
// if (v < 1.) return -powM*pow(1.-v,powM-1.);
// if (v < 1.) return -3.*pow(1.-v,2)*exp((long double)pow(1.-v,3));
// else return powP*pow(v-1.,powP-1.);
}
// Constructor // Constructor
...@@ -38,8 +63,12 @@ bool OptHOM::addJacObjGrad(double &Obj, alglib::real_1d_array &gradObj) ...@@ -38,8 +63,12 @@ bool OptHOM::addJacObjGrad(double &Obj, alglib::real_1d_array &gradObj)
mesh.scaledJacAndGradients (iEl,sJ,gSJ); mesh.scaledJacAndGradients (iEl,sJ,gSJ);
for (int l = 0; l < mesh.nBezEl(iEl); l++) { for (int l = 0; l < mesh.nBezEl(iEl); l++) {
Obj += compute_f(sJ[l]); double f1 = compute_f1(sJ[l], jacBar);
const double f1 = compute_f1(sJ[l]); Obj += compute_f(sJ[l], jacBar);
if (_optimizeBarrierMax) {
Obj += compute_f(sJ[l], barrier_min);
f1 += compute_f1(sJ[l], barrier_min);
}
for (int iPC = 0; iPC < mesh.nPCEl(iEl); iPC++) for (int iPC = 0; iPC < mesh.nPCEl(iEl); iPC++)
gradObj[mesh.indPCEl(iEl,iPC)] += f1*gSJ[mesh.indGSJ(iEl,l,iPC)]; gradObj[mesh.indPCEl(iEl,iPC)] += f1*gSJ[mesh.indGSJ(iEl,l,iPC)];
minJac = std::min(minJac, sJ[l]); minJac = std::min(minJac, sJ[l]);
...@@ -63,8 +92,8 @@ bool OptHOM::addMetricMinObjGrad(double &Obj, alglib::real_1d_array &gradObj) ...@@ -63,8 +92,8 @@ bool OptHOM::addMetricMinObjGrad(double &Obj, alglib::real_1d_array &gradObj)
mesh.metricMinAndGradients (iEl,sJ,gSJ); mesh.metricMinAndGradients (iEl,sJ,gSJ);
for (int l = 0; l < mesh.nBezEl(iEl); l++) { for (int l = 0; l < mesh.nBezEl(iEl); l++) {
Obj += compute_f(sJ[l]); Obj += compute_f(sJ[l], jacBar);
const double f1 = compute_f1(sJ[l]); const double f1 = compute_f1(sJ[l], jacBar);
for (int iPC = 0; iPC < mesh.nPCEl(iEl); iPC++) for (int iPC = 0; iPC < mesh.nPCEl(iEl); iPC++)
gradObj[mesh.indPCEl(iEl,iPC)] += f1*gSJ[mesh.indGSJ(iEl,l,iPC)]; gradObj[mesh.indPCEl(iEl,iPC)] += f1*gSJ[mesh.indGSJ(iEl,l,iPC)];
minJac = std::min(minJac, sJ[l]); minJac = std::min(minJac, sJ[l]);
...@@ -115,9 +144,7 @@ void OptHOM::evalObjGrad(const alglib::real_1d_array &x, double &Obj, alglib::re ...@@ -115,9 +144,7 @@ void OptHOM::evalObjGrad(const alglib::real_1d_array &x, double &Obj, alglib::re
addDistObjGrad(lambda, lambda2, Obj, gradObj); addDistObjGrad(lambda, lambda2, Obj, gradObj);
if(_optimizeMetricMin) if(_optimizeMetricMin)
addMetricMinObjGrad(Obj, gradObj); addMetricMinObjGrad(Obj, gradObj);
if ((minJac > barrier_min) && (maxJac < barrier_max || !_optimizeBarrierMax)) {
if ((minJac > barrier_min) && (maxJac < barrier_max)) {
printf("INFO: reached %s (%g %g) requirements, setting null gradient\n", _optimizeMetricMin ? "svd" : "jacobian", minJac, maxJac); printf("INFO: reached %s (%g %g) requirements, setting null gradient\n", _optimizeMetricMin ? "svd" : "jacobian", minJac, maxJac);
Obj = 0.; Obj = 0.;
for (int i = 0; i < gradObj.length(); i++) gradObj[i] = 0.; for (int i = 0; i < gradObj.length(); i++) gradObj[i] = 0.;
...@@ -296,6 +323,7 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double ...@@ -296,6 +323,7 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double
jacBar = jacBarStart; jacBar = jacBarStart;
setBarrierTerm(jacBarStart); setBarrierTerm(jacBarStart);
_optimizeBarrierMax = false;
// Calculate initial objective function value and gradient // Calculate initial objective function value and gradient
initObj = 0.; initObj = 0.;
alglib::real_1d_array gradObj; alglib::real_1d_array gradObj;
...@@ -309,7 +337,7 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double ...@@ -309,7 +337,7 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double
<< " and max. barrier = " << barrier_max << std::endl; << " and max. barrier = " << barrier_max << std::endl;
int ITER = 0; int ITER = 0;
while (minJac < barrier_min || maxJac > barrier_max ) { while (minJac < barrier_min) {
OptimPass(x, gradObj, itMax); OptimPass(x, gradObj, itMax);
recalcJacDist(); recalcJacDist();
jacBar = (minJac > 0.) ? 0.9*minJac : 1.1*minJac; jacBar = (minJac > 0.) ? 0.9*minJac : 1.1*minJac;
...@@ -317,6 +345,19 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double ...@@ -317,6 +345,19 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double
if (ITER ++ > 50) break; if (ITER ++ > 50) break;
} }
if (!_optimizeMetricMin) {
_optimizeBarrierMax = true;
jacBar = 1.1 * maxJac;
setBarrierTerm(jacBar);
while (maxJac > barrier_max ) {
OptimPass(x, gradObj, itMax);
recalcJacDist();
jacBar = 1.1 * maxJac;
setBarrierTerm(jacBar);
if (ITER ++ > 50) break;
}
}
// for (int i = 0; i<3; i++) { // for (int i = 0; i<3; i++) {
// lambda *= 100; // lambda *= 100;
// OptimPass(x, gradObj, itMax); // OptimPass(x, gradObj, itMax);
......
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
class Mesh; class Mesh;
class OptHOM class OptHOM
{ {
public: public:
Mesh mesh; Mesh mesh;
...@@ -43,46 +43,18 @@ private: ...@@ -43,46 +43,18 @@ private:
double initObj, initMaxDist, initAvgDist; // Values for reporting double initObj, initMaxDist, initAvgDist; // Values for reporting
double minJac, maxJac, maxDist, avgDist; // Values for reporting double minJac, maxJac, maxDist, avgDist; // Values for reporting
bool _optimizeBarrierMax; // false : only moving barrier min; true : fixed barrier min + moving barrier max
inline void setBarrierTerm(double jacBarrier) {jacBar = jacBarrier;} inline void setBarrierTerm(double jacBarrier) {jacBar = jacBarrier;}
inline double compute_f(double v);
inline double compute_f1(double v);
bool addJacObjGrad(double &Obj, alglib::real_1d_array &gradObj); bool addJacObjGrad(double &Obj, alglib::real_1d_array &gradObj);
bool addMetricMinObjGrad(double &Obj, alglib::real_1d_array &gradObj); bool addMetricMinObjGrad(double &Obj, alglib::real_1d_array &gradObj);
bool addDistObjGrad(double Fact, double Fact2, double &Obj, alglib::real_1d_array &gradObj); bool addDistObjGrad(double Fact, double Fact2, double &Obj, alglib::real_1d_array &gradObj);
void calcScale(alglib::real_1d_array &scale); void calcScale(alglib::real_1d_array &scale);
void OptimPass(alglib::real_1d_array &x, const alglib::real_1d_array &initGradObj, int itMax); void OptimPass(alglib::real_1d_array &x, const alglib::real_1d_array &initGradObj, int itMax);
}; };
inline double OptHOM::compute_f(double v)
{
if (v > jacBar) {
const double l = log((v - jacBar) / (1 -jacBar));
const double m = (v - 1);
return l * l + m * m;
}
else return 1.e300;
// if (v < 1.) return pow(1.-v,powM);
// if (v < 1.) return exp((long double)pow(1.-v,3));
// else return pow(v-1.,powP);
}
inline double OptHOM::compute_f1(double v)
{
if (v > jacBar) {
return 2 * (v - 1) + 2 * log((v - jacBar) / (1 - jacBar)) / (v - jacBar);
}
else return -1.e300;
// if (v < 1.) return -powM*pow(1.-v,powM-1.);
// if (v < 1.) return -3.*pow(1.-v,2)*exp((long double)pow(1.-v,3));
// else return powP*pow(v-1.,powP-1.);
}
void OptHOM::getJacDist(double &minJ, double &maxJ, double &maxD, double &avgD) void OptHOM::getJacDist(double &minJ, double &maxJ, double &maxD, double &avgD)
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment