Commit 1bd83a2faa33a928bfd7256ac631780edc4cc27a
1 parent
40f980b8
minor code improvements
Showing
1 changed file
with
66 additions
and
56 deletions
src/obs/GObservation.cpp
| ... | ... | @@ -424,11 +424,19 @@ void GObservation::free_members(void) |
| 424 | 424 | * @param[in] model Model. |
| 425 | 425 | * @param[in] event Event. |
| 426 | 426 | * @param[in] ipar Parameter index for which gradient should be returned. |
| 427 | + * | |
| 428 | + * @todo We simply remove any parameter boundaries here for the computation | |
| 429 | + * to avoid any out of boundary errors. We may have models, however, | |
| 430 | + * for which out of bound parameters lead to illegal computations, such | |
| 431 | + * as division by zero or taking the square root of negative values. | |
| 432 | + * I cannot see any elegant method to catch this at this level. | |
| 433 | + * Eventually, the higher level method should avoid going in a | |
| 434 | + * parameter domain that is not defined. | |
| 427 | 435 | ***************************************************************************/ |
| 428 | 436 | double GObservation::model_grad(const GModel& model, const GEvent& event, |
| 429 | 437 | int ipar) const |
| 430 | 438 | { |
| 431 | - // Initialise gradient | |
| 439 | + // Initialise gradient | |
| 432 | 440 | double grad = 0.0; |
| 433 | 441 | |
| 434 | 442 | // Compute gradient only if parameter is free |
| ... | ... | @@ -441,6 +449,15 @@ double GObservation::model_grad(const GModel& model, const GEvent& event, |
| 441 | 449 | // ... otherwise compute it numerically |
| 442 | 450 | else { |
| 443 | 451 | |
| 452 | + // Get non-const model pointer (circumvent const correctness) | |
| 453 | + GModel* ptr = (GModel*)&model; | |
| 454 | + | |
| 455 | + // Save current model parameter | |
| 456 | + GModelPar current = (*ptr)[ipar]; | |
| 457 | + | |
| 458 | + // Remove any boundaries to avoid limitations | |
| 459 | + (*ptr)[ipar].remove_range(); | |
| 460 | + | |
| 444 | 461 | // Setup derivative function |
| 445 | 462 | GObservation::model_func function(this, model, event, ipar); |
| 446 | 463 | |
| ... | ... | @@ -452,8 +469,11 @@ double GObservation::model_grad(const GModel& model, const GEvent& event, |
| 452 | 469 | //derivative.silent(true); |
| 453 | 470 | grad = derivative.value(x, dx); |
| 454 | 471 | |
| 472 | + // Restore current model parameter | |
| 473 | + (*ptr)[ipar] = current; | |
| 474 | + | |
| 455 | 475 | } // endelse: computed gradient numerically |
| 456 | - | |
| 476 | + | |
| 457 | 477 | } // endif: model parameter was free |
| 458 | 478 | |
| 459 | 479 | // Return gradient |
| ... | ... | @@ -465,33 +485,18 @@ double GObservation::model_grad(const GModel& model, const GEvent& event, |
| 465 | 485 | * @brief Model function evaluation for gradient computation |
| 466 | 486 | * |
| 467 | 487 | * @param[in] x Function value. |
| 468 | - * | |
| 469 | - * @todo We simply remove any parameter boundaries here for the computation | |
| 470 | - * to avoid any out of boundary errors. We may have models, however, | |
| 471 | - * for which out of bound parameters lead to illegal computations, such | |
| 472 | - * as division by zero or taking the square root of negative values. | |
| 473 | - * I cannot see any elegant method to catch this at this level. | |
| 474 | - * Eventually, the higher level method should avoid going in a | |
| 475 | - * parameter domain that is not defined. | |
| 476 | 488 | ***************************************************************************/ |
| 477 | 489 | double GObservation::model_func::eval(double x) |
| 478 | 490 | { |
| 479 | - // Circumvent const correctness | |
| 491 | + // Get non-const model pointer (circumvent const correctness) | |
| 480 | 492 | GModel* model = (GModel*)m_model; |
| 481 | - | |
| 482 | - // Save current model parameter | |
| 483 | - GModelPar current = (*model)[m_ipar]; | |
| 484 | 493 | |
| 485 | - // Set requested model value. Remove any boundaries to avoid limitations. | |
| 494 | + // Set value | |
| 486 | 495 | (*model)[m_ipar].value(x); |
| 487 | - (*model)[m_ipar].remove_range(); | |
| 488 | 496 | |
| 489 | 497 | // Compute model value |
| 490 | 498 | double value = model->eval(*m_event, *m_parent); |
| 491 | 499 | |
| 492 | - // Restore current model parameter | |
| 493 | - (*model)[m_ipar] = current; | |
| 494 | - | |
| 495 | 500 | // Return value |
| 496 | 501 | return value; |
| 497 | 502 | } |
| ... | ... | @@ -528,6 +533,14 @@ double GObservation::model_func::eval(double x) |
| 528 | 533 | * \f$E\f$ is the true photon energy, |
| 529 | 534 | * \f$t\f$ is the true photon arrival time, and |
| 530 | 535 | * \f$d\f$ is the instrument pointing. |
| 536 | + * | |
| 537 | + * @todo We simply remove any parameter boundaries here for the computation | |
| 538 | + * to avoid any out of boundary errors. We may have models, however, | |
| 539 | + * for which out of bound parameters lead to illegal computations, such | |
| 540 | + * as division by zero or taking the square root of negative values. | |
| 541 | + * I cannot see any elegant method to catch this at this level. | |
| 542 | + * Eventually, the higher level method should avoid going in a | |
| 543 | + * parameter domain that is not defined. | |
| 531 | 544 | ***************************************************************************/ |
| 532 | 545 | double GObservation::npred_grad(const GModel& model, int ipar) const |
| 533 | 546 | { |
| ... | ... | @@ -537,13 +550,25 @@ double GObservation::npred_grad(const GModel& model, int ipar) const |
| 537 | 550 | // Compute gradient only if parameter is free |
| 538 | 551 | if (model[ipar].isfree()) { |
| 539 | 552 | |
| 553 | + // Get non-const model pointer (circumvent const correctness) | |
| 554 | + GModel* ptr = (GModel*)&model; | |
| 555 | + | |
| 556 | + // Save current model parameter | |
| 557 | + GModelPar current = (*ptr)[ipar]; | |
| 558 | + | |
| 559 | + // Remove any boundaries to avoid limitations | |
| 560 | + (*ptr)[ipar].remove_range(); | |
| 561 | + | |
| 540 | 562 | // Setup derivative function |
| 541 | 563 | GObservation::npred_func function(this, model, ipar); |
| 542 | 564 | GDerivative derivative(&function); |
| 543 | 565 | |
| 544 | 566 | // Get derivative |
| 545 | 567 | result = derivative.value(model[ipar].value()); |
| 546 | - | |
| 568 | + | |
| 569 | + // Restore current model parameter | |
| 570 | + (*ptr)[ipar] = current; | |
| 571 | + | |
| 547 | 572 | } // endif: model parameter was free |
| 548 | 573 | |
| 549 | 574 | // Return result |
| ... | ... | @@ -552,6 +577,27 @@ double GObservation::npred_grad(const GModel& model, int ipar) const |
| 552 | 577 | |
| 553 | 578 | |
| 554 | 579 | /***********************************************************************//** |
| 580 | + * @brief Npred function evaluation for gradient computation | |
| 581 | + * | |
| 582 | + * @param[in] x Function value. | |
| 583 | + ***************************************************************************/ | |
| 584 | +double GObservation::npred_func::eval(double x) | |
| 585 | +{ | |
| 586 | + // Get non-const model pointer (circumvent const correctness) | |
| 587 | + GModel* model = (GModel*)m_model; | |
| 588 | + | |
| 589 | + // Set value | |
| 590 | + (*model)[m_ipar].value(x); | |
| 591 | + | |
| 592 | + // Compute Npred value | |
| 593 | + double npred = m_parent->npred_temp(*model); | |
| 594 | + | |
| 595 | + // Return value | |
| 596 | + return npred; | |
| 597 | +} | |
| 598 | + | |
| 599 | + | |
| 600 | +/***********************************************************************//** | |
| 555 | 601 | * @brief Temporally integrates spatially and spectrally integrated Npred |
| 556 | 602 | * kernel |
| 557 | 603 | * |
| ... | ... | @@ -725,42 +771,6 @@ double GObservation::npred_kern_spec::eval(double x) |
| 725 | 771 | } |
| 726 | 772 | |
| 727 | 773 | |
| 728 | -/***********************************************************************//** | |
| 729 | - * @brief Npred function evaluation for gradient computation | |
| 730 | - * | |
| 731 | - * @param[in] x Function value. | |
| 732 | - * | |
| 733 | - * @todo We simply remove any parameter boundaries here for the computation | |
| 734 | - * to avoid any out of boundary errors. We may have models, however, | |
| 735 | - * for which out of bound parameters lead to illegal computations, such | |
| 736 | - * a division by zero or taking the square root of negative values. | |
| 737 | - * I cannot see any elegant method to catch this at this level. | |
| 738 | - * Eventually, the higher level method should avoid going in a | |
| 739 | - * parameter domain that is not defined. | |
| 740 | - ***************************************************************************/ | |
| 741 | -double GObservation::npred_func::eval(double x) | |
| 742 | -{ | |
| 743 | - // Circumvent const correctness | |
| 744 | - GModel* model = (GModel*)m_model; | |
| 745 | - | |
| 746 | - // Save current model parameter | |
| 747 | - GModelPar current = (*model)[m_ipar]; | |
| 748 | - | |
| 749 | - // Set requested model value. Remove any boundaries to avoid limitations. | |
| 750 | - (*model)[m_ipar].value(x); | |
| 751 | - (*model)[m_ipar].remove_range(); | |
| 752 | - | |
| 753 | - // Compute Npred value | |
| 754 | - double npred = m_parent->npred_temp(*model); | |
| 755 | - | |
| 756 | - // Restore current model parameter | |
| 757 | - (*model)[m_ipar] = current; | |
| 758 | - | |
| 759 | - // Return value | |
| 760 | - return npred; | |
| 761 | -} | |
| 762 | - | |
| 763 | - | |
| 764 | 774 | /*========================================================================== |
| 765 | 775 | = = |
| 766 | 776 | = Friends = | ... | ... |