//----------------------------------------------------------------------------- //! //----------------------------------------------------------------------------- void tStartLineTacticalWidget::UpdateMap() { tDigitalData hdg( DATA_TYPE_HEADING ); float heading; bool hdgValid = hdg.DampedValidValue( heading ); m_pMapWidget->SetHeading( RadiansToDegreesf( heading ), hdgValid ); tDigitalData startLinePortData( DATA_TYPE_START_LINE_PORT_POSITION ); tRCoord portPos; bool portEndValid = startLinePortData.ValidValue( portPos ); tDigitalData startLineStbdData( DATA_TYPE_START_LINE_STBD_POSITION ); tRCoord stbdPos; bool stbdEndValid = startLineStbdData.ValidValue( stbdPos ); tDigitalData bowPosData( DATA_TYPE_BOW_POSITION ); tRCoord bowPos; bool bowPosValid = bowPosData.ValidValue( bowPos ); if( portEndValid && stbdEndValid && bowPosValid ) { m_pMapWidget->SetPortEndValid( true ); m_pMapWidget->SetStbdEndValid( true ); float lineLengthNM = static_cast<float>( tGisCalc::SphericalDistance( stbdPos, portPos, tGisCalc::GREAT_CIRCLE ) ); float lineBearingR = static_cast<float>( tGisCalc::SphericalBearing( stbdPos, portPos, tGisCalc::GREAT_CIRCLE ) ); m_pMapWidget->SetBearingStbdEndToPortEnd( RadiansToDegreesf( lineBearingR ) ); m_pMapWidget->SetDistanceStbdEndToPortEnd( lineLengthNM ); m_pMapWidget->SetLineLength( lineLengthNM ); float distanceBoatFromStbdEndNM = static_cast<float>( tGisCalc::SphericalDistance( stbdPos, bowPos, tGisCalc::GREAT_CIRCLE ) ); float bearingBoatFromStbdEndR = static_cast<float>( tGisCalc::SphericalBearing( stbdPos, bowPos, tGisCalc::GREAT_CIRCLE ) ); m_pMapWidget->SetBearingStbdEndToBow( RadiansToDegreesf( bearingBoatFromStbdEndR ) ); m_pMapWidget->SetDistanceStbdEndToBow( distanceBoatFromStbdEndNM ); tDigitalData startLineBias( DATA_TYPE_START_LINE_BIAS ); float biasR = 0.0F; if( startLineBias.ValidValue( biasR ) ) { m_pMapWidget->SetLineBias( RadiansToDegreesf( biasR ) ); } else { m_pMapWidget->SetLineBiasValid( false ); } } else { m_pMapWidget->SetPortEndValid( false ); m_pMapWidget->SetStbdEndValid( false ); } UpdateLaylineData(); UpdateZeroBurnLine(); m_pMapWidget->update(); }
void ML_multi_QuasiNewton::dfpmin(v_ratep_type& p, const double gtol, int& iter, double& fret, ptr_eval_func func, ptr_eval_gradient_func dfunc // double func(const v_ratep_type& p), // void dfunc(const v_ratep_type& in, // v_ratep_type& out) ) { // from Press et al 2002 const int ITMAX = 200; const double EPS=std::numeric_limits<double>::epsilon(); const double TOLX = 4.0*EPS, STPMX = 100.0; bool check; int i, its, j; double den, fac, fad, fae, fp, stpmax, sum=0.0, sumdg, sumxi, temp, test; int n = p.size(); v_ratep_type dg(n), g(n), hdg(n), pnew(n), xi(n); std::vector<v_ratep_type> hessin; hessin.resize(n); for (int i = 0; i < n; ++i) hessin[i].resize(n); fp = (this->*func)(p); // fp = func(p); (this->*dfunc)(p, g); // dfunc(p, g); for (i = 0; i < n; ++i) { for (j = 0; j < n; ++j) hessin[i][j] = 0.0; hessin[i][i] = 1.0; xi[i] = -g[i]; sum += p[i]*p[i]; } stpmax = STPMX * MAX(std::sqrt(sum), double(n)); for (its = 0; its < ITMAX; ++its) { iter = its; lnsrch(p, fp, g, xi, pnew, fret, stpmax, check, func); fp = fret; for (i = 0; i < n; ++i) { xi[i] = pnew[i] - p[i]; p[i] = pnew[i]; } test = 0.0; for (i = 0; i < n; ++i) { temp = std::abs(xi[i]) / MAX(std::abs(p[i]), 1.0); if (temp > test) test = temp; } if (test < TOLX) return; for (i = 0; i < n; ++i) dg[i] = g[i]; (this->*dfunc)(p, g); // dfunc(p, g); test = 0.0; den = MAX(fret, 1.0); for (i = 0; i < n; ++i) { temp = std::abs(g[i])*MAX(std::abs(p[i]), 1.0)/den; if (temp > test) test = temp; } if (test < gtol) return; for (i = 0; i < n; ++i) dg[i] = g[i] - dg[i]; for (i = 0; i < n; ++i) { hdg[i] = 0.0; for (j = 0; j < n; ++j) hdg[i] += hessin[i][j]*dg[j]; } fac = fae = sumdg = sumxi = 0.0; for (i = 0; i < n; ++i) { fac += dg[i]*xi[i]; fae += dg[i]*hdg[i]; sumdg += SQR(dg[i]); sumxi += SQR(xi[i]); } if (fac > std::sqrt(EPS*sumdg*sumxi)) { fac = 1.0 / fac; fad = 1.0 / fae; for (i = 0; i < n; ++i) dg[i] = fac*xi[i] - fad*hdg[i]; for (i = 0; i < n; ++i) { for (j = i; j < n; ++j) { hessin[i][j] += fac*xi[i]*xi[j] - fad*hdg[i]*hdg[j] + fae*dg[i]*dg[j]; hessin[j][i] = hessin[i][j]; } } } for (i = 0; i < n; ++i) { xi[i] = 0.0; for (j = 0; j < n; ++j) xi[i] -= hessin[i][j]*g[j]; } } std::cerr << "dfpmin(): too many iterations" << std::endl; assert(false); }