unsigned int difSums(int n){ return sumSquared(n) - sumSquares(n); }
void bracket( struct LMStruct *LM ) { int iflag = 1,i; double eps, delta, delta_max; int changed, c = 1; fcn(LM->m, LM->n, LM->x, LM->fvec, &iflag); if( iflag < 0 ) return; // and do a print iflag = 0; fcn(LM->m, LM->n, LM->x, LM->fvec, &iflag); if( iflag < 0 ) return; iflag = 1; eps = sumSquared( LM->fvec, LM->m ); // Choose delta_max to be between 1 and 2 degrees if( LM->epsfcn <= 0.0 ) return; // This is an error for( delta_max = LM->epsfcn; delta_max < 1.0; delta_max *= 2.0){} for( delta = delta_max; delta >= LM->epsfcn; delta /= 2.0 ) { c = 1; // PrintError("delta = %lf", delta); while( c ) { c = 0; for( i = 0; i < LM->n; i++ ) { changed = 0; LM->x[i] += delta; fcn(LM->m, LM->n, LM->x, LM->fvec, &iflag); if( iflag < 0 ) return; if( delta == delta_max ) // search everywhere { while( sumSquared( LM->fvec, LM->m ) < eps ) { changed = 1; eps = sumSquared( LM->fvec, LM->m ); LM->x[i] += delta; fcn(LM->m, LM->n, LM->x, LM->fvec, &iflag);if( iflag < 0 ) return; } LM->x[i] -= delta; } else // do just this one step { if( sumSquared( LM->fvec, LM->m ) < eps ) { eps = sumSquared( LM->fvec, LM->m ); changed = 1; } else LM->x[i] -= delta; } if( !changed ) // Try other direction { LM->x[i] -= delta; fcn(LM->m, LM->n, LM->x, LM->fvec, &iflag);if( iflag < 0 ) return; if( delta == delta_max ) // search everywhere { while( sumSquared( LM->fvec, LM->m ) < eps ) { changed = 1; eps = sumSquared( LM->fvec, LM->m ); LM->x[i] -= delta; fcn(LM->m, LM->n, LM->x, LM->fvec, &iflag);if( iflag < 0 ) return; } LM->x[i] += delta; } else // do just this one step { if( sumSquared( LM->fvec, LM->m ) < eps ) { eps = sumSquared( LM->fvec, LM->m ); changed = 1; } else LM->x[i] += delta; } } if( changed ) c = 1; if (c) { // an improvement, let's see it (and give the user a chance to bail out) iflag = 0; fcn(LM->m, LM->n, LM->x, LM->fvec, &iflag); if( iflag < 0 ) return; iflag = 1; } } } // PrintError("%lf %ld %lf", delta, c, eps); iflag = 0; LM->fvec[0] = sqrt(eps/LM->m); fcn(LM->m, LM->n, LM->x, LM->fvec, &iflag); if( iflag < 0 ) return; iflag = 1; } }
void LteFadingTestCase::DoRun (void) { // LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL); // LogComponentEnable ("LteEnbRrc", logLevel); // LogComponentEnable ("LteUeRrc", logLevel); // LogComponentEnable ("LteEnbMac", logLevel); // LogComponentEnable ("LteUeMac", logLevel); // LogComponentEnable ("LteRlc", logLevel); // LogComponentEnable ("RrPacketScheduler", logLevel); // // LogComponentEnable ("LtePhy", logLevel); // LogComponentEnable ("LteEnbPhy", logLevel); // LogComponentEnable ("LteUePhy", logLevel); // // LogComponentEnable ("LteSpectrumPhy", logLevel); // LogComponentEnable ("LteInterference", logLevel); // LogComponentEnable ("LteSinrChunkProcessor", logLevel); // // LogComponentEnable ("LtePropagationLossModel", logLevel); // LogComponentEnable ("LossModel", logLevel); // LogComponentEnable ("ShadowingLossModel", logLevel); // LogComponentEnable ("PenetrationLossModel", logLevel); // LogComponentEnable ("MultipathLossModel", logLevel); // LogComponentEnable ("PathLossModel", logLevel); // // LogComponentEnable ("LteNetDevice", logLevel); // LogComponentEnable ("LteUeNetDevice", logLevel); // LogComponentEnable ("LteEnbNetDevice", logLevel); LogComponentEnable ("TraceFadingLossModel", LOG_LEVEL_ALL); // LogComponentEnable ("TraceFadingLossModel", LOG_LEVEL_ALL); // LogComponentEnable ("BuildingsPropagationLossModel", LOG_LEVEL_ALL); NS_LOG_INFO ("Testing " << GetName()); m_fadingModule = CreateObject<TraceFadingLossModel> (); m_fadingModule->SetAttribute("TraceFilename", StringValue("../../../src/lte/model/fading-traces/fading_trace_EPA_3kmph.fad")); //m_fadingModule->SetAttribute("WindowSize", TimeValue(Seconds (0.003))); m_fadingModule->CreateFadingChannelRealization (m_node1, m_node2); // Ptr<SpectrumModel> sm; // // Bands bands; // BandInfo bi; // // bi.fl = 2.400e9; // bi.fc = 2.410e9; // bi.fh = 2.420e9; // bands.push_back (bi); // // bi.fl = 2.420e9; // bi.fc = 2.431e9; // bi.fh = 2.442e9; // bands.push_back (bi); // // sm = Create<SpectrumModel> (bands); // // /** // * TX signal #1: Power Spectral Density (W/Hz) of the signal = [0 0] dBm and BW = [20 22] MHz // */ // Ptr<SpectrumValue> inPsd1 = Create<SpectrumValue> (sm); // (*inPsd1)[0] = 1.; // (*inPsd1)[1] = 1.; // Ptr<SpectrumValue> outPsd1 = Create<SpectrumValue> (sm); // outPsd1 = m_fadingModule->CalcRxPowerSpectralDensity (inPsd1, m_node1, m_node2); // // NS_LOG_INFO ("A ver " << (*outPsd1)[0] << " " << (*outPsd1)[1]); double samplingInterval = 0.001; double time = 0.0; while (time<0.010) { Time t = Seconds (time); Simulator::Schedule(t, &LteFadingTestCase::GetFadingSample, this); time += samplingInterval; } Simulator::Stop (Seconds (10.1)); Simulator::Run (); Simulator::Destroy (); // double loss = m_downlinkPropagationLossModel->GetLoss (m_node1, m_node2); time = 0.0; int rbNum = 2; std::vector<double> sum (rbNum); std::vector<double> sumSquared (rbNum); for (int i = 0; i < rbNum; i++) { sum.at (i) = 0.; sumSquared.at (i) = 0.; } for (uint i = 0; i < m_fadingSamples.size (); i++) { NS_LOG_INFO ("Sample time " << time << " : " << m_fadingSamples.at(i)[0] << " " << m_fadingSamples.at(i)[1]); time += samplingInterval; for (int j = 0; j < rbNum; j++) { sum.at (j) += m_fadingSamples.at(i)[j]; sumSquared.at (j) += (m_fadingSamples.at(i)[j]*m_fadingSamples.at(i)[j]); } } // NS_LOG_INFO ("Calculated loss: " << loss); NS_LOG_INFO ("Theoretical loss: " << m_lossRef); for (int i = 0; i < rbNum; i++) { double mean = sum.at (i)/m_fadingSamples.size (); double sigma = sqrt(sumSquared.at (i)/m_fadingSamples.size () - (mean*mean)); NS_LOG_INFO (" Mean " << mean << " sigma " << sigma); } // NS_TEST_ASSERT_MSG_EQ_TOL(loss, m_lossRef, 0.1, "Wrong loss !"); }
void RunLMOptimizer( OptInfo *o) { struct LMStruct LM; int iflag; char *warning; char *infmsg[] = { "improper input parameters", "the relative error in the sum of squares is at most tol", "the relative error between x and the solution is at most tol", "conditions for info = 1 and info = 2 both hold", "fvec is orthogonal to the columns of the jacobian to machine precision", "number of calls to fcn has reached or exceeded 200*(n+1)", "tol is too small. no further reduction in the sum of squares is possible", "tol too small. no further improvement in approximate solution x possible", "Interrupted" }; int istrat; // strategy int totalfev; // total function evaluations int numconstraints; // number of constraints imposed by control points int i; int lmInfo; AlignInfo *g; // obtained from adjust.c // PrintError("RunLMOptimizer"); // The method used here is a hybrid of two optimization strategies. // In the first strategy, fcnPano is configured to return one function per // control point, that function being total distance without regard for // direction. In the second strategy, fcnPano is configured to return two // functions per control point, those functions being distance in two // directions, typically longitude and latitude. The second strategy // converges much faster, but may be less stable with poor initial estimates. // So, we use the first method as long as it makes significant progress // (currently 5% reduction in error per iteration), and then switch to // the second method to rapidly polish the estimate. Final result // returned to the user is that of the second method. // // Older versions of Panorama Tools used just the first strategy, // with error tolerances set to make it run to full convergence, // which often took hundreds or thousands of iterations. The hybrid // approach typically converges much faster (a few tens of iterations) // and appears to be equally robust in testing to date. Full convergence // (to am lmdif ftol of 1.0e-14) is not always achieved faster than the old // version. However the convergence rate (error reduction per wall-clock // second) has been significantly better in all cases tested, and the final // accuracy has been equal or improved. // // So, in the interest of behavior that is friendlier to the user, I have // set an ftol convergence criterion that is looser than before, 1.0e-6 // instead of 1.0e-14. By this point, it is very unlikely that // significant reductions can be achieved by more iterating, since // even 10,000 more iterations would be predicted to make at most 1% // improvement in the total error. // // I have also made the diagnosis of too few control points more precise // and more obvious to the user. The old version complained if the // number of control points was less than the number of parameters, // although in fact each normal control point contributes two independent // constraints (x and y) so the actual critical number is // 2*controlpoints >= parameters. As a result, the old version often // complained even when things were fine, and never complained more loudly // even when things were awful. This version does not complain // at all unless there are not enough actual constraints, and then it puts // out an error dialog that must be dismissed by the user. // // Rik Littlefield ([email protected]), May 2004. LM.n = o->numVars; g = GetGlobalPtr(); numconstraints = 0; for(i=0; i < g->numPts; i++) { if (g->cpt[i].type == 0) numconstraints += 2; else numconstraints += 1; } warning = ""; if( numconstraints < LM.n ) { char msgx[200]; warning = "Warning: Number of Data Points is smaller than Number of Variables to fit.\n"; sprintf (msgx,"You have too few control points (%d) or too many parameters (%d). Strange values may result!",o->numData,LM.n); PrintError(msgx); } totalfev = 0; for (istrat=1; istrat <= 2; istrat++) { setFcnPanoNperCP(istrat); LM.m = o->numData*FUNCS_PER_CP; if( LM.m < LM.n ) LM.m = LM.n; // in strategy #1, fcnpano will pad fvec if needed fcn = o->fcn; if( AllocateLMStruct( &LM ) != 0 ) { PrintError( "Not enough Memory" ); return; } // Initialize optimization params if( o->SetVarsToX( LM.x ) != 0) { PrintError("Internal Error"); return; } iflag = -100; // reset counter and initialize dialog fcn(LM.m, LM.n, LM.x, LM.fvec, &iflag); if (istrat == 2) setFcnPanoDoNotInitAvgFov(); // infoDlg ( _initProgress, "Optimizing Variables" ); /* Call lmdif. */ LM.ldfjac = LM.m; LM.mode = 1; LM.nprint = 1; // 10 LM.info = 0; LM.factor = 100.0; LM.ftol = 1.0e-6; // used to be DBL_EPSILON; //1.0e-14; if (istrat == 1) { LM.ftol = 0.05; // for distance-only strategy, bail out when convergence slows } lmdif( LM.m, LM.n, LM.x, LM.fvec, LM.ftol, LM.xtol, LM.gtol, LM.maxfev, LM.epsfcn, LM.diag, LM.mode, LM.factor, LM.nprint, &LM.info, &LM.nfev, LM.fjac, LM.ldfjac, LM.ipvt, LM.qtf, LM.wa1, LM.wa2, LM.wa3, LM.wa4); lmInfo = LM.info; // At end, one final evaluation to get errors that do not have fov stabilization applied, // for reporting purposes. if (istrat == 2) { forceFcnPanoReinitAvgFov(); iflag = 1; fcn(LM.m, LM.n, LM.x, LM.fvec, &iflag); } o->SetXToVars( LM.x ); iflag = -99; // reset counter and dispose dialog fcn(LM.m, LM.n, LM.x, LM.fvec, &iflag); // infoDlg ( _disposeProgress, "" ); // Display solver info if(LM.info >= 8) LM.info = 4; if(LM.info < 0) LM.info = 8; totalfev += LM.nfev; sprintf( (char*) o->message, "# %s%d function evaluations\n# %s\n# final rms error %g units\n", warning, totalfev, infmsg[LM.info], sqrt(sumSquared(LM.fvec,LM.m)/LM.m) * sqrt((double)FUNCS_PER_CP)); FreeLMStruct( &LM ); if (lmInfo < 0) break; // to honor user cancel in strategy 1 } setFcnPanoNperCP(1); // Force back to startegy 1 for backwards compatability }