Commit de91f8392608eff7e8d4d1da379927f417ed0ee2
1 parent
813252eb
Revert "GModels access operator now returns reference instead of pointer."
This reverts commit 813252eb589e317fd139d0cdde4f20bdd7959ef2.
Showing
12 changed files
with
119 additions
and
89 deletions
NEWS
| ... | ... | @@ -36,9 +36,6 @@ GOptimizer & GOptimizerLM |
| 36 | 36 | The optimization operators have been removed and replaced by the |
| 37 | 37 | optimize method. |
| 38 | 38 | |
| 39 | -GModels | |
| 40 | - The model access operators now return the model by reference | |
| 41 | - instead of returning a pointer. | |
| 42 | 39 | |
| 43 | 40 | 3. Configuration |
| 44 | 41 | ----------------- | ... | ... |
include/GModels.hpp
| ... | ... | @@ -72,10 +72,10 @@ public: |
| 72 | 72 | |
| 73 | 73 | // Operators |
| 74 | 74 | GModels& operator=(const GModels& models); |
| 75 | - GModel& operator[](const int& index); | |
| 76 | - const GModel& operator[](const int& index) const; | |
| 77 | - GModel& operator[](const std::string& name); | |
| 78 | - const GModel& operator[](const std::string& name) const; | |
| 75 | + GModel* operator[](const int& index); | |
| 76 | + const GModel* operator[](const int& index) const; | |
| 77 | + GModel* operator[](const std::string& name); | |
| 78 | + const GModel* operator[](const std::string& name) const; | |
| 79 | 79 | |
| 80 | 80 | // Methods |
| 81 | 81 | void clear(void); | ... | ... |
inst/com/test/test_COM.cpp
| ... | ... | @@ -605,9 +605,9 @@ void TestGCOMOptimize::test_binned_optimizer(void) |
| 605 | 605 | obs.optimize(opt); |
| 606 | 606 | test_try_success(); |
| 607 | 607 | for (int i = 0, j = 0; i < obs.models().size(); ++i) { |
| 608 | - const GModel& model = obs.models()[i]; | |
| 609 | - for (int k = 0; k < model.size(); ++k) { | |
| 610 | - GModelPar par = model[k]; | |
| 608 | + const GModel* model = obs.models()[i]; | |
| 609 | + for (int k = 0; k < model->size(); ++k) { | |
| 610 | + GModelPar par = (*model)[k]; | |
| 611 | 611 | std::string msg = "Verify optimization result for " + par.print(); |
| 612 | 612 | test_value(par.real_value(), fit_results[j++], 5.0e-5, msg); |
| 613 | 613 | test_value(par.real_error(), fit_results[j++], 5.0e-5, msg); | ... | ... |
inst/cta/test/test_CTA.cpp
| ... | ... | @@ -525,9 +525,9 @@ void TestGCTAOptimize::test_unbinned_optimizer(void) |
| 525 | 525 | obs.optimize(opt); |
| 526 | 526 | test_try_success(); |
| 527 | 527 | for (int i = 0, j = 0; i < obs.models().size(); ++i) { |
| 528 | - const GModel& model = obs.models()[i]; | |
| 529 | - for (int k = 0; k < model.size(); ++k) { | |
| 530 | - GModelPar par = model[k]; | |
| 528 | + const GModel* model = obs.models()[i]; | |
| 529 | + for (int k = 0; k < model->size(); ++k) { | |
| 530 | + GModelPar par = (*model)[k]; | |
| 531 | 531 | std::string msg = "Verify optimization result for " + par.print(); |
| 532 | 532 | test_value(par.real_value(), fit_results[j++], 5.0e-5, msg); |
| 533 | 533 | test_value(par.real_error(), fit_results[j++], 5.0e-5, msg); |
| ... | ... | @@ -587,9 +587,9 @@ void TestGCTAOptimize::test_binned_optimizer(void) |
| 587 | 587 | obs.optimize(opt); |
| 588 | 588 | test_try_success(); |
| 589 | 589 | for (int i = 0, j = 0; i < obs.models().size(); ++i) { |
| 590 | - const GModel& model = obs.models()[i]; | |
| 591 | - for (int k = 0; k < model.size(); ++k) { | |
| 592 | - GModelPar par = model[k]; | |
| 590 | + const GModel* model = obs.models()[i]; | |
| 591 | + for (int k = 0; k < model->size(); ++k) { | |
| 592 | + GModelPar par = (*model)[k]; | |
| 593 | 593 | std::string msg = "Verify optimization result for " + par.print(); |
| 594 | 594 | test_value(par.real_value(), fit_results[j++], 5.0e-5, msg); |
| 595 | 595 | test_value(par.real_error(), fit_results[j++], 5.0e-5, msg); | ... | ... |
inst/lat/test/test_LAT.cpp
| ... | ... | @@ -663,9 +663,9 @@ void TestGLATOptimize::test_one_binned_optimizer(const std::string& datadir, |
| 663 | 663 | obs.optimize(opt); |
| 664 | 664 | test_try_success(); |
| 665 | 665 | for (int i = 0, j = 0; i < obs.models().size(); ++i) { |
| 666 | - const GModel& model = obs.models()[i]; | |
| 667 | - for (int k = 0; k < model.size(); ++k) { | |
| 668 | - GModelPar par = model[k]; | |
| 666 | + const GModel* model = obs.models()[i]; | |
| 667 | + for (int k = 0; k < model->size(); ++k) { | |
| 668 | + GModelPar par = (*model)[k]; | |
| 669 | 669 | std::string msg = "Verify optimization result for " + par.print(); |
| 670 | 670 | test_value(par.real_value(), fit_results[j++], 5.0e-5, msg); |
| 671 | 671 | test_value(par.real_error(), fit_results[j++], 5.0e-5, msg); | ... | ... |
inst/mwl/test/test_MWL.cpp
| ... | ... | @@ -221,9 +221,9 @@ void TestGMWL::test_optimizer(void) |
| 221 | 221 | obs.optimize(opt); |
| 222 | 222 | test_try_success(); |
| 223 | 223 | for (int i = 0, j = 0; i < obs.models().size(); ++i) { |
| 224 | - const GModel& model = obs.models()[i]; | |
| 225 | - for (int k = 0; k < model.size(); ++k) { | |
| 226 | - GModelPar par = model[k]; | |
| 224 | + const GModel* model = obs.models()[i]; | |
| 225 | + for (int k = 0; k < model->size(); ++k) { | |
| 226 | + GModelPar par = (*model)[k]; | |
| 227 | 227 | std::string msg = "Verify optimization result for " + par.print(); |
| 228 | 228 | test_value(par.real_value(), fit_results[j++], 1.0e-4, msg); |
| 229 | 229 | test_value(par.real_error(), fit_results[j++], 1.0e-3, msg); | ... | ... |
pyext/GModels.i
| ... | ... | @@ -32,7 +32,7 @@ |
| 32 | 32 | %} |
| 33 | 33 | |
| 34 | 34 | /* __ Typemaps ___________________________________________________________ */ |
| 35 | -%typemap(out) GModel& { | |
| 35 | +%typemap(out) GModel* { | |
| 36 | 36 | if (dynamic_cast<GModelSky*>($1) != NULL) { |
| 37 | 37 | $result = SWIG_NewPointerObj(SWIG_as_voidptr($1), SWIGTYPE_p_GModelSky, 0 | 0 ); |
| 38 | 38 | } |
| ... | ... | @@ -88,7 +88,7 @@ public: |
| 88 | 88 | char *__str__() { |
| 89 | 89 | return tochar(self->print()); |
| 90 | 90 | } |
| 91 | - GModel& __getitem__(const int& index) { | |
| 91 | + GModel* __getitem__(const int& index) { | |
| 92 | 92 | if (index >= 0 && index < self->size()) { |
| 93 | 93 | return (*self)[index]; |
| 94 | 94 | } |
| ... | ... | @@ -97,7 +97,7 @@ public: |
| 97 | 97 | 0, self->size()-1); |
| 98 | 98 | } |
| 99 | 99 | } |
| 100 | - GModel& __getitem__(const std::string& name) { | |
| 100 | + GModel* __getitem__(const std::string& name) { | |
| 101 | 101 | return (*self)[name]; |
| 102 | 102 | } |
| 103 | 103 | void __setitem__(const int& index, const GModel& val) { | ... | ... |
src/model/GModels.cpp
| ... | ... | @@ -162,16 +162,17 @@ GModels& GModels::operator= (const GModels& models) |
| 162 | 162 | |
| 163 | 163 | |
| 164 | 164 | /***********************************************************************//** |
| 165 | - * @brief Return model | |
| 165 | + * @brief Return pointer to model | |
| 166 | 166 | * |
| 167 | 167 | * @param[in] index Model index (0,...,size()-1). |
| 168 | 168 | * |
| 169 | 169 | * @exception GException::out_of_range |
| 170 | 170 | * Model index is out of range. |
| 171 | 171 | * |
| 172 | - * Returns the model with the specified @p index. | |
| 172 | + * Returns a pointer to the model with the specified @p index. | |
| 173 | + * The return value will never be NULL. | |
| 173 | 174 | ***************************************************************************/ |
| 174 | -GModel& GModels::operator[](const int& index) | |
| 175 | +GModel* GModels::operator[](const int& index) | |
| 175 | 176 | { |
| 176 | 177 | // Compile option: raise exception if index is out of range |
| 177 | 178 | #if defined(G_RANGE_CHECK) |
| ... | ... | @@ -181,21 +182,22 @@ GModel& GModels::operator[](const int& index) |
| 181 | 182 | #endif |
| 182 | 183 | |
| 183 | 184 | // Return pointer |
| 184 | - return *(m_models[index]); | |
| 185 | + return m_models[index]; | |
| 185 | 186 | } |
| 186 | 187 | |
| 187 | 188 | |
| 188 | 189 | /***********************************************************************//** |
| 189 | - * @brief Return model (const version) | |
| 190 | + * @brief Return pointer to model (const version) | |
| 190 | 191 | * |
| 191 | 192 | * @param[in] index Model index (0,...,size()-1). |
| 192 | 193 | * |
| 193 | 194 | * @exception GException::out_of_range |
| 194 | 195 | * Model index is out of range. |
| 195 | 196 | * |
| 196 | - * Returns the model with the specified @p index. | |
| 197 | + * Returns a pointer to the model with the specified @p index. | |
| 198 | + * The return value will never be NULL. | |
| 197 | 199 | ***************************************************************************/ |
| 198 | -const GModel& GModels::operator[](const int& index) const | |
| 200 | +const GModel* GModels::operator[](const int& index) const | |
| 199 | 201 | { |
| 200 | 202 | // Compile option: raise exception if index is out of range |
| 201 | 203 | #if defined(G_RANGE_CHECK) |
| ... | ... | @@ -205,21 +207,22 @@ const GModel& GModels::operator[](const int& index) const |
| 205 | 207 | #endif |
| 206 | 208 | |
| 207 | 209 | // Return pointer |
| 208 | - return *(m_models[index]); | |
| 210 | + return m_models[index]; | |
| 209 | 211 | } |
| 210 | 212 | |
| 211 | 213 | |
| 212 | 214 | /***********************************************************************//** |
| 213 | - * @brief Return model | |
| 215 | + * @brief Return pointer to model | |
| 214 | 216 | * |
| 215 | 217 | * @param[in] name Model name. |
| 216 | 218 | * |
| 217 | 219 | * @exception GException::model_not_found |
| 218 | 220 | * Model with specified name not found in container. |
| 219 | 221 | * |
| 220 | - * Returns the model with the specified @p name. | |
| 222 | + * Returns a pointer to the model with the specified @p name. | |
| 223 | + * The return value will never be NULL. | |
| 221 | 224 | ***************************************************************************/ |
| 222 | -GModel& GModels::operator[](const std::string& name) | |
| 225 | +GModel* GModels::operator[](const std::string& name) | |
| 223 | 226 | { |
| 224 | 227 | // Get parameter index |
| 225 | 228 | int index = get_index(name); |
| ... | ... | @@ -230,21 +233,22 @@ GModel& GModels::operator[](const std::string& name) |
| 230 | 233 | } |
| 231 | 234 | |
| 232 | 235 | // Return pointer |
| 233 | - return *(m_models[index]); | |
| 236 | + return m_models[index]; | |
| 234 | 237 | } |
| 235 | 238 | |
| 236 | 239 | |
| 237 | 240 | /***********************************************************************//** |
| 238 | - * @brief Return model (const version) | |
| 241 | + * @brief Return pointer to model (const version) | |
| 239 | 242 | * |
| 240 | 243 | * @param[in] name Model name. |
| 241 | 244 | * |
| 242 | 245 | * @exception GException::model_not_found |
| 243 | 246 | * Model with specified name not found in container. |
| 244 | 247 | * |
| 245 | - * Returns the model with the specified @p name. | |
| 248 | + * Returns a pointer to the model with the specified @p name. | |
| 249 | + * The return value will never be NULL. | |
| 246 | 250 | ***************************************************************************/ |
| 247 | -const GModel& GModels::operator[](const std::string& name) const | |
| 251 | +const GModel* GModels::operator[](const std::string& name) const | |
| 248 | 252 | { |
| 249 | 253 | // Get parameter index |
| 250 | 254 | int index = get_index(name); |
| ... | ... | @@ -255,7 +259,7 @@ const GModel& GModels::operator[](const std::string& name) const |
| 255 | 259 | } |
| 256 | 260 | |
| 257 | 261 | // Return pointer |
| 258 | - return *(m_models[index]); | |
| 262 | + return m_models[index]; | |
| 259 | 263 | } |
| 260 | 264 | |
| 261 | 265 | |
| ... | ... | @@ -308,8 +312,13 @@ GModels* GModels::clone(void) const |
| 308 | 312 | ***************************************************************************/ |
| 309 | 313 | void GModels::append(const GModel& model) |
| 310 | 314 | { |
| 311 | - // Append model to the container | |
| 312 | - m_models.push_back(model.clone()); | |
| 315 | + // Make deep copy of model | |
| 316 | + GModel* model_copy = model.clone(); | |
| 317 | + | |
| 318 | + // If copy is valid, append it to the container | |
| 319 | + if (model_copy != NULL) { | |
| 320 | + m_models.push_back(model_copy); | |
| 321 | + } | |
| 313 | 322 | |
| 314 | 323 | // Set parameter pointers |
| 315 | 324 | set_pointers(); |
| ... | ... | @@ -340,8 +349,13 @@ void GModels::insert(const int& index, const GModel& model) |
| 340 | 349 | } |
| 341 | 350 | #endif |
| 342 | 351 | |
| 343 | - // Insert model into the container | |
| 344 | - m_models.insert(m_models.begin()+index, model.clone()); | |
| 352 | + // Make deep copy of model | |
| 353 | + GModel* model_copy = model.clone(); | |
| 354 | + | |
| 355 | + // If copy is valid, insert it to the container | |
| 356 | + if (model_copy != NULL) { | |
| 357 | + m_models.insert(m_models.begin()+index, model_copy); | |
| 358 | + } | |
| 345 | 359 | |
| 346 | 360 | // Set parameter pointers |
| 347 | 361 | set_pointers(); |
| ... | ... | @@ -373,8 +387,13 @@ void GModels::insert(const std::string& name, const GModel& model) |
| 373 | 387 | throw GException::model_not_found(G_INSERT2, name); |
| 374 | 388 | } |
| 375 | 389 | |
| 376 | - // Insert model into the container | |
| 377 | - m_models.insert(m_models.begin()+index, model.clone()); | |
| 390 | + // Make deep copy of model | |
| 391 | + GModel* model_copy = model.clone(); | |
| 392 | + | |
| 393 | + // If copy is valid, insert it to the container | |
| 394 | + if (model_copy != NULL) { | |
| 395 | + m_models.insert(m_models.begin()+index, model_copy); | |
| 396 | + } | |
| 378 | 397 | |
| 379 | 398 | // Set parameter pointers |
| 380 | 399 | set_pointers(); |
| ... | ... | @@ -460,10 +479,18 @@ void GModels::extend(const GModels& models) |
| 460 | 479 | // Reserve enough space |
| 461 | 480 | reserve(size() + models.size()); |
| 462 | 481 | |
| 463 | - // Loop over all model components and append deep copies to container | |
| 482 | + // Loop over all model components | |
| 464 | 483 | for (int i = 0; i < models.size(); ++i) { |
| 465 | - m_models.push_back(models[i].clone()); | |
| 466 | - } | |
| 484 | + | |
| 485 | + // Make deep copy of model | |
| 486 | + GModel* model_copy = models[i]->clone(); | |
| 487 | + | |
| 488 | + // If copy is valid, append it to the container | |
| 489 | + if (model_copy != NULL) { | |
| 490 | + m_models.push_back(model_copy); | |
| 491 | + } | |
| 492 | + | |
| 493 | + } // endfor: looped over all model components | |
| 467 | 494 | |
| 468 | 495 | // Set parameter pointers |
| 469 | 496 | set_pointers(); | ... | ... |
src/obs/GObservation.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * GObservation.cpp - Abstract observation base class * | |
| 2 | + * GObservation.cpp - Abstract observation base class * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | 4 | * copyright (C) 2008-2013 by Juergen Knoedlseder * |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| ... | ... | @@ -190,7 +190,7 @@ double GObservation::model(const GModels& models, const GEvent& event, |
| 190 | 190 | #endif |
| 191 | 191 | |
| 192 | 192 | // Initialise |
| 193 | - double value = 0.0; // Reset model value | |
| 193 | + double model = 0.0; // Reset model value | |
| 194 | 194 | int igrad = 0; // Reset gradient counter |
| 195 | 195 | |
| 196 | 196 | // If gradient is available then reset gradient vector elements to 0 |
| ... | ... | @@ -201,32 +201,35 @@ double GObservation::model(const GModels& models, const GEvent& event, |
| 201 | 201 | // Loop over models |
| 202 | 202 | for (int i = 0; i < models.size(); ++i) { |
| 203 | 203 | |
| 204 | - // Get model | |
| 205 | - const GModel& model = models[i]; | |
| 204 | + // Get model pointer. Continue only if pointer is valid | |
| 205 | + const GModel* mptr = models[i]; | |
| 206 | + if (mptr != NULL) { | |
| 206 | 207 | |
| 207 | - // Continue only if model applies to specific instrument and | |
| 208 | - // observation identifier | |
| 209 | - if (model.isvalid(instrument(), id())) { | |
| 208 | + // Continue only if model applies to specific instrument and | |
| 209 | + // observation identifier | |
| 210 | + if (mptr->isvalid(instrument(), id())) { | |
| 210 | 211 | |
| 211 | - // Compute value and add to model | |
| 212 | - value += model.eval_gradients(event, *this); | |
| 212 | + // Compute value and add to model | |
| 213 | + model += mptr->eval_gradients(event, *this); | |
| 213 | 214 | |
| 214 | - // Optionally determine model gradients | |
| 215 | - if (gradient != NULL) { | |
| 216 | - for (int k = 0; k < model.size(); ++k) { | |
| 217 | - (*gradient)[igrad+k] = model_grad(model, event, k); | |
| 215 | + // Optionally determine model gradients | |
| 216 | + if (gradient != NULL) { | |
| 217 | + for (int k = 0; k < mptr->size(); ++k) { | |
| 218 | + (*gradient)[igrad+k] = model_grad(*mptr, event, k); | |
| 219 | + } | |
| 218 | 220 | } |
| 219 | - } | |
| 220 | 221 | |
| 221 | - // Increment parameter counter for gradients | |
| 222 | - igrad += model.size(); | |
| 222 | + } // endif: model component was valid for instrument | |
| 223 | + | |
| 224 | + // Increment parameter counter for gradients | |
| 225 | + igrad += mptr->size(); | |
| 223 | 226 | |
| 224 | 227 | } // endif: model was valid |
| 225 | 228 | |
| 226 | 229 | } // endfor: Looped over models |
| 227 | 230 | |
| 228 | - // Return value | |
| 229 | - return value; | |
| 231 | + // Return | |
| 232 | + return model; | |
| 230 | 233 | } |
| 231 | 234 | |
| 232 | 235 | |
| ... | ... | @@ -273,27 +276,30 @@ double GObservation::npred(const GModels& models, GVector* gradient) const |
| 273 | 276 | // Loop over models |
| 274 | 277 | for (int i = 0; i < models.size(); ++i) { |
| 275 | 278 | |
| 276 | - // Get model | |
| 277 | - const GModel& model = models[i]; | |
| 279 | + // Get model pointer. Continue only if pointer is valid | |
| 280 | + const GModel* mptr = models[i]; | |
| 281 | + if (mptr != NULL) { | |
| 278 | 282 | |
| 279 | - // Continue only if model applies to specific instrument and | |
| 280 | - // observation identifier | |
| 281 | - if (model.isvalid(instrument(), id())) { | |
| 283 | + // Continue only if model applies to specific instrument and | |
| 284 | + // observation identifier | |
| 285 | + if (mptr->isvalid(instrument(), id())) { | |
| 282 | 286 | |
| 283 | - // Determine Npred for model | |
| 284 | - npred += npred_temp(model); | |
| 287 | + // Determine Npred for model | |
| 288 | + npred += npred_temp(*mptr); | |
| 285 | 289 | |
| 286 | - // Optionally determine Npred gradients | |
| 287 | - if (gradient != NULL) { | |
| 288 | - for (int k = 0; k < model.size(); ++k) { | |
| 289 | - (*gradient)[igrad+k] = npred_grad(model, k); | |
| 290 | + // Optionally determine Npred gradients | |
| 291 | + if (gradient != NULL) { | |
| 292 | + for (int k = 0; k < mptr->size(); ++k) { | |
| 293 | + (*gradient)[igrad+k] = npred_grad(*mptr, k); | |
| 294 | + } | |
| 290 | 295 | } |
| 291 | - } | |
| 292 | 296 | |
| 293 | - } // endif: model component was valid for instrument | |
| 297 | + } // endif: model component was valid for instrument | |
| 294 | 298 | |
| 295 | - // Increment parameter counter for gradient | |
| 296 | - igrad += model.size(); | |
| 299 | + // Increment parameter counter for gradient | |
| 300 | + igrad += mptr->size(); | |
| 301 | + | |
| 302 | + } // endif: model was valid | |
| 297 | 303 | |
| 298 | 304 | } // endfor: Looped over models |
| 299 | 305 | ... | ... |
test/test_GModel.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * test_GModel.cpp - test GModel class * | |
| 2 | + * test_GModel.cpp - test GModel class * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | 4 | * copyright (C) 2009-2013 by Juergen Knoedlseder * |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| ... | ... | @@ -193,9 +193,9 @@ void TestGModel::test_model(void) |
| 193 | 193 | models2.append(crab); |
| 194 | 194 | models2.save("test_instrument.xml"); |
| 195 | 195 | models2.load("test_instrument.xml"); |
| 196 | - test_value(models2[0].scale("LAT").real_value(), 1.0); | |
| 197 | - test_value(models2[0].scale("CTA").real_value(), 0.5); | |
| 198 | - test_value(models2[0].scale("COM").real_value(), 1.0); | |
| 196 | + test_value(models2[0]->scale("LAT").real_value(), 1.0); | |
| 197 | + test_value(models2[0]->scale("CTA").real_value(), 0.5); | |
| 198 | + test_value(models2[0]->scale("COM").real_value(), 1.0); | |
| 199 | 199 | |
| 200 | 200 | // Exit test |
| 201 | 201 | return; | ... | ... |
test/test_GObservation.cpp
| ... | ... | @@ -621,7 +621,7 @@ void TestOpenMP::test_observations_optimizer(const int& mode) |
| 621 | 621 | obs.optimize(opt); |
| 622 | 622 | |
| 623 | 623 | // Get the result |
| 624 | - GModelPar result = (obs.models()[0])[0]; | |
| 624 | + GModelPar result = (*(obs.models()[0]))[0]; | |
| 625 | 625 | |
| 626 | 626 | // Check if converged |
| 627 | 627 | test_assert(opt.status()==0, "Check if converged", | ... | ... |
test/test_GOptimizer.cpp
| ... | ... | @@ -122,7 +122,7 @@ void TestGOptimizer::test_optimizer(const int& mode) |
| 122 | 122 | obs.optimize(opt); |
| 123 | 123 | |
| 124 | 124 | // Get the result |
| 125 | - GModelPar result = (obs.models()[0])[0]; | |
| 125 | + GModelPar result = (*(obs.models()[0]))[0]; | |
| 126 | 126 | |
| 127 | 127 | // Check if converged |
| 128 | 128 | test_assert(opt.status()==0, "Check if converged", | ... | ... |