Menu

#182 internal compiler error: Segmentation fault building QuantLib on OpenSUSE 42.1

None
closed
nobody
None
5
2017-01-30
2016-06-05
No

After a successful build of boost 1_61_0, I could not build QuantLib version 1.8. The build fails while attempting to compile cdo.cpp in the /experimental folder:

libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c cdo.cpp -fPIC -DPIC -o .libs/cdo.o
cdo.cpp: In member function 'virtual void QuantLib::CDO::performCalculations() const':
cdo.cpp:123:10: internal compiler error: Segmentation fault
void CDO::performCalculations() const {

Here are the details:
make error:

Making all in config
make[1]: Entering directory '/usr/local/quantlib/QuantLib-1.8/config'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/config'
Making all in ql
make[1]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql'
make all-recursive
make[2]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql'
Making all in cashflows
make[3]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/cashflows'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/cashflows'
Making all in currencies
make[3]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/currencies'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/currencies'
Making all in experimental
make[3]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental'
Making all in amortizingbonds
make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/amortizingbonds'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/amortizingbonds'
Making all in barrieroption
make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/barrieroption'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/barrieroption'
Making all in callablebonds
make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/callablebonds'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/callablebonds'
Making all in catbonds
make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/catbonds'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/catbonds'
Making all in commodities
make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/commodities'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/commodities'
Making all in convertiblebonds
make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/convertiblebonds'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/convertiblebonds'
Making all in coupons
make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/coupons'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/coupons'
Making all in credit
make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit'
/bin/sh ../../../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c -o cdo.lo cdo.cpp
libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c cdo.cpp -fPIC -DPIC -o .libs/cdo.o
Makefile:517: recipe for target 'cdo.lo' failed
make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit'
Makefile:508: recipe for target 'all-recursive' failed
make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental'
Makefile:661: recipe for target 'all-recursive' failed
make[2]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql'
Makefile:494: recipe for target 'all' failed
make[1]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql'
Makefile:593: recipe for target 'all-recursive' failed
make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit'
/bin/sh ../../../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c -o cdo.lo cdo.cpp
libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c cdo.cpp -fPIC -DPIC -o .libs/cdo.o
cdo.cpp: In member function 'virtual void QuantLib::CDO::performCalculations() const':
cdo.cpp:123:10: internal compiler error: Segmentation fault
void CDO::performCalculations() const {
^
Please submit a full bug report,
with preprocessed source if appropriate.
See http://bugs.opensuse.org/ for instructions.
Makefile:517: recipe for target 'cdo.lo' failed
make[4]: *** [cdo.lo] Error 1
make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit'
Makefile:508: recipe for target 'all-recursive' failed
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental'
Makefile:661: recipe for target 'all-recursive' failed
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql'
Makefile:494: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql'
Makefile:593: recipe for target 'all-recursive' failed
make: *** [all-recursive] Error 1

gcc version:

linux-k07u:/usr/local/quantlib/QuantLib-1.8 # gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/4.8/lto-wrapper
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.8 --enable-ssp --disable-libssp --disable-plugin --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --enable-linker-build-id --enable-linux-futex --program-suffix=-4.8 --without-system-libunwind --with-arch-32=i586 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux
Thread model: posix
gcc version 4.8.5 (SUSE Linux)

OS:
linux-k07u:/usr/local/quantlib/QuantLib-1.8 # cat /etc/os-release
NAME="openSUSE Leap"
VERSION="42.1"
VERSION_ID="42.1"
PRETTY_NAME="openSUSE Leap 42.1 (x86_64)"
ID=opensuse
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:opensuse:42.1"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://opensuse.org/"
ID_LIKE="suse"

boost version:

// Boost version.hpp configuration header file ------------------------------//

// (C) Copyright John maddock 1999. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

// See http://www.boost.org/libs/config for documentation

ifndef BOOST_VERSION_HPP

define BOOST_VERSION_HPP

//
// Caution: this is the only Boost header that is guaranteed
// to change with every Boost release. Including this header
// will cause a recompile every time a new Boost version is
// used.
//
// BOOST_VERSION % 100 is the patch level
// BOOST_VERSION / 100 % 1000 is the minor version
// BOOST_VERSION / 100000 is the major version

define BOOST_VERSION 106100

//
// BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION
// but as a string in the form "x_y[_z]" where x is the major version
// number, y is the minor version number, and z is the patch level if not 0.
// This is used by <config auto_link.hpp=""> to select which library version to link to.</config>

define BOOST_LIB_VERSION "1_61"

endif

Affected File(s):
cdo.cpp
/ -- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -- /

/*
Copyright (C) 2008 Roland Lichters

This file is part of QuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://quantlib.org/

QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license. You should have received a
copy of the license along with this program; if not, please email
quantlib-dev@lists.sf.net. The license is also available online at
http://quantlib.org/license.shtml.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
*/

include <ql experimental="" credit="" cdo.hpp=""></ql>

include <ql event.hpp=""></ql>

using namespace std;

namespace QuantLib {

CDO::CDO (Real attachment,
          Real detachment,
          const vector<Real>& nominals,
          const vector<Handle<DefaultProbabilityTermStructure> >& basket,
          const Handle<OneFactorCopula>& copula,
          bool protectionSeller,
          const Schedule& premiumSchedule,
          Rate premiumRate,
          const DayCounter& dayCounter,
          Rate recoveryRate,
          Rate upfrontPremiumRate,
          const Handle<YieldTermStructure>& yieldTS,
          Size nBuckets,
          const Period& integrationStep)
: attachment_(attachment), detachment_(detachment),
  nominals_(nominals), basket_(basket),
  copula_(copula),
  protectionSeller_(protectionSeller),
  premiumSchedule_(premiumSchedule),
  premiumRate_(premiumRate),
  dayCounter_(dayCounter),
  recoveryRate_(recoveryRate),
  upfrontPremiumRate_(upfrontPremiumRate),
  yieldTS_(yieldTS),
  nBuckets_(nBuckets),
  integrationStep_(integrationStep) {

    QL_REQUIRE (!basket.empty(), "basket is empty");
    QL_REQUIRE (attachment_ >= 0 && attachment_ < detachment_
                && detachment_ <= 1,
                "illegal attachment/detachment point");

    registerWith (yieldTS_);
    registerWith (copula_);
    for (Size i = 0; i < basket_.size(); i++)
        registerWith (basket_[i]);

    QL_REQUIRE (nominals_.size() <= basket_.size(),
                "nominal vector size too large");

    if (nominals_.size() < basket_.size()) {
        Size n = basket_.size() - nominals_.size();
        Real back = nominals_.back();
        for (Size i = 0; i < n; i++)
            nominals_.push_back(back);
    }

    QL_REQUIRE (nominals_.size() == basket_.size(),
                "nominal size " << nominals_.size()
                << " != basket size " << basket_.size());

    nominal_ = 0;
    for (Size i = 0; i < nominals_.size(); i++) {
        lgds_.push_back (nominals_[i] * (1.0 - recoveryRate_));
        nominal_ += nominals_[i];
        lgd_ += lgds_[i];
    }
    xMax_ = detachment_ * nominal_;
    xMin_ = attachment_ * nominal_;
}


bool CDO::isExpired () const {
    return detail::simple_event(premiumSchedule_.dates().back())
           .hasOccurred(yieldTS_->referenceDate());
}


void CDO::setupExpired() const {
    Instrument::setupExpired();
}


Real CDO::expectedTrancheLoss (Date d) const {
    if (d <= basket_.front()->referenceDate())
        return 0;

    vector<Real> defProb (basket_.size());
    for (Size j = 0; j < basket_.size(); j++)
        defProb[j] = basket_[j]->defaultProbability (d);

    LossDistBucketing op (nBuckets_, xMax_);
    Distribution dist = copula_->integral (op, lgds_, defProb);

    return dist.trancheExpectedValue (xMin_, xMax_);

    // The following causes two errors in test against literature values.
    // FIXME: Investigate accuracy.
    // return dist.cumulativeExcessProbability (xMin_, xMax_);

    //   TranchePayoff func (xMin_, xMax_);
    //   return (dist.expectedValue (func)
    //    + (xMax_ - xMin_) * (1.0 - dist.cumulatedProbability (xMax_)));
}


void CDO::performCalculations() const {

    QL_REQUIRE(!yieldTS_.empty(), "no yield term structure set");

    errorEstimate_ = Null<Real>();

    NPV_ = 0.0;
    premiumValue_ = 0;
    protectionValue_ = 0;
    error_ = 0;

    /* Expectations e1 and e2 are portfolio loss given default,
       i.e.  with recovery already "bult in". Multiplication by
       (1-r) is therefore not necessary, neither in premium nor
       protection value calculation.
    */

    Real e1 = 0;
    Date today = yieldTS_->referenceDate();
    if (premiumSchedule_[0] > today)
        e1 = expectedTrancheLoss (premiumSchedule_[0]);

    for (Size i = 1; i < premiumSchedule_.size(); i++) {
        Date d2 = premiumSchedule_[i];
        if (d2 < today)
            continue;

        Date d1 = premiumSchedule_[i-1];

        Date d, d0 = d1;
        do {
            d = NullCalendar().advance (d0 > today ? d0 : today,
                                        integrationStep_);
            if (d > d2)
                d = d2;

            Real e2 = expectedTrancheLoss (d);

            premiumValue_ += (xMax_ - xMin_ - e2)
                * premiumRate_ * dayCounter_.yearFraction (d0, d)
                * yieldTS_->discount (d);

            if (e2 < e1) {
                error_ ++;
            }

            protectionValue_ -= (e2 - e1) * yieldTS_->discount (d);

            d0 = d;
            e1 = e2;
        }
        while (d < d2);
    }

    if (premiumSchedule_[0] >= today)
        upfrontPremiumValue_ = (xMax_ - xMin_) * upfrontPremiumRate_ *
            yieldTS_->discount(premiumSchedule_[0]);
    else
        upfrontPremiumValue_ = 0.0;

    if (!protectionSeller_) {
        premiumValue_ *= -1;
        upfrontPremiumValue_ *= -1;
        protectionValue_ *= -1;
    }

    NPV_ = premiumValue_ + protectionValue_ + upfrontPremiumValue_;
}


Rate CDO::premiumValue () const {
    calculate();
    return premiumValue_;
}

Rate CDO::protectionValue () const {
    calculate();
    return protectionValue_;
}

Size CDO::error () const {
    calculate();
    return error_;
}

Rate CDO::fairPremium () const {
    calculate();
    return - premiumRate_ * protectionValue_ / premiumValue_;
}

}

cdo.hpp:
/ -- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -- /

/*
Copyright (C) 2008 Roland Lichters

This file is part of QuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://quantlib.org/

QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license. You should have received a
copy of the license along with this program; if not, please email
quantlib-dev@lists.sf.net. The license is also available online at
http://quantlib.org/license.shtml.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
*/

/! \file cdo.hpp
\brief collateralized debt obligation
/

ifndef quantlib_cdo_hpp

define quantlib_cdo_hpp

include <ql instrument.hpp=""></ql>

include <ql termstructures="" yieldtermstructure.hpp=""></ql>

include <ql termstructures="" defaulttermstructure.hpp=""></ql>

include <ql experimental="" credit="" lossdistribution.hpp=""></ql>

include <ql experimental="" credit="" onefactorcopula.hpp=""></ql>

include <ql time="" schedule.hpp=""></ql>

namespace QuantLib {

//! collateralized debt obligation
/*! The instrument prices a mezzanine CDO tranche with loss given
    default between attachment point \f$ D_1\f$ and detachment
    point \f$ D_2 > D_1 \f$.

    For purchased protection, the instrument value is given by the
    difference of the protection value \f$ V_1 \f$ and premium
    value \f$ V_2 \f$,

    \f[ V = V_1 - V_2. \f]

    The protection leg is priced as follows:

    - Build the probability distribution for volume of defaults
      \f$ L \f$ (before recovery) or Loss Given Default \f$ LGD =
      (1-r)\,L \f$ at times/dates \f$ t_i, i=1, ..., N\f$ (premium
      schedule times with intermediate steps)
    - Determine the expected value
      \f$ E_i = E_{t_i}\,\left[Pay(LGD)\right] \f$
      of the protection payoff \f$ Pay(LGD) \f$ at each time
      \f$ t_i\f$ where
     \f[
     Pay(L) = min (D_1, LGD) - min (D_2, LGD) = \left\{
     \begin{array}{lcl}
     \displaystyle 0 &;& LGD < D_1 \\
     \displaystyle LGD - D_1 &;& D_1 \leq LGD \leq D_2 \\
     \displaystyle D_2 - D_1 &;& LGD > D_2
     \end{array}
     \right.
     \f]
    - The protection value is then calculated as
      \f[ V_1 \:=\: \sum_{i=1}^N (E_i - E_{i-1}) \cdot  d_i \f]
      where \f$ d_i\f$ is the discount factor at time/date \f$ t_i \f$

    The premium is paid on the protected notional amount,
    initially \f$ D_2 - D_1. \f$ This notional amount is reduced
    by the expected protection payments \f$ E_i \f$ at times
    \f$ t_i, \f$ so that the premium value is calculated as

    \f[
    V_2 = m \, \cdot \sum_{i=1}^N \,(D_2 - D_1 - E_i)
               \cdot \Delta_{i-1,i}\,d_i
    \f]

    where \f$ m \f$ is the premium rate, \f$ \Delta_{i-1, i}\f$ is
    the day count fraction between date/time \f$ t_{i-1}\f$ and
    \f$ t_i.\f$

    The construction of the portfolio loss distribution \f$ E_i
    \f$ is based on the probability bucketing algorithm described
    in

    <strong>
    John Hull and Alan White, "Valuation of a CDO and nth to default CDS
    without Monte Carlo simulation", Journal of Derivatives 12, 2, 2004
    </strong>

    The pricing algorithm allows for varying notional amounts and
    default termstructures of the underlyings.

    \todo Investigate and fix cases \f$ E_{i+1} < E_i. \f$
*/
class CDO : public Instrument {
  public:
    /*! \param attachment  fraction of the LGD where protection starts
        \param detachment  fraction of the LGD where protection ends
        \param nominals    vector of basket nominal amounts
        \param basket      default basket represented by a vector of
                           default term structures that allow
                           computing single name default
                           probabilities depending on time
        \param copula      one-factor copula
        \param protectionSeller   sold protection if set to true, purchased
                                  otherwise
        \param premiumSchedule    schedule for premium payments
        \param premiumRate        annual premium rate, e.g. 0.05 for 5% p.a.
        \param dayCounter         day count convention for the premium rate
        \param recoveryRate       recovery rate as a fraction
        \param upfrontPremiumRate premium as a tranche notional fraction
        \param yieldTS            yield term structure handle
        \param nBuckets           number of distribution buckets
        \param integrationStep    time step for integrating over one
                                  premium period; if larger than premium
                                  period length, a single step is taken
    */
    CDO (Real attachment,
         Real detachment,
         const std::vector<Real>& nominals,
         const std::vector<Handle<DefaultProbabilityTermStructure> >& basket,
         const Handle<OneFactorCopula>& copula,
         bool protectionSeller,
         const Schedule& premiumSchedule,
         Rate premiumRate,
         const DayCounter& dayCounter,
         Rate recoveryRate,
         Rate upfrontPremiumRate,
         const Handle<YieldTermStructure>& yieldTS,
         Size nBuckets,
         const Period& integrationStep = Period(10, Years));

    Real nominal() { return nominal_; }
    Real lgd() { return lgd_; }
    Real attachment () { return attachment_; }
    Real detachment () { return detachment_; }
    std::vector<Real> nominals() { return nominals_; }
    Size size() { return basket_.size(); }

    bool isExpired () const;
    Rate fairPremium() const;
    Rate premiumValue () const;
    Rate protectionValue () const;
    Size error () const;

  private:
    void setupExpired() const;
    void performCalculations() const;
    Real expectedTrancheLoss (Date d) const;

    Real attachment_;
    Real detachment_;
    std::vector<Real> nominals_;
    std::vector<Handle<DefaultProbabilityTermStructure> > basket_;
    Handle<OneFactorCopula> copula_;
    bool protectionSeller_;

    Schedule premiumSchedule_;
    Rate premiumRate_;
    DayCounter dayCounter_;
    Rate recoveryRate_;
    Rate upfrontPremiumRate_;
    Handle<YieldTermStructure> yieldTS_;
    Size nBuckets_; // number of buckets up to detachment point
    Period integrationStep_;

    std::vector<Real> lgds_;

    Real nominal_;  // total basket volume (sum of nominals_)
    Real lgd_;      // maximum loss given default (sum of lgds_)
    Real xMax_;     // tranche detachment point (tranche_ * nominal_)
    Real xMin_;     // tranche attachment point (tranche_ * nominal_)

    mutable Size error_;

    mutable Real premiumValue_;
    mutable Real protectionValue_;
    mutable Real upfrontPremiumValue_;
};

}

endif

Related

Bugs: #182

Discussion

  • Luigi Ballabio

    Luigi Ballabio - 2016-06-10

    I don't have access to an OpenSUSE system, so I haven't been able to reproduce this. I was able to compile the file successfully with gcc 4.8.4 and Boost 1.61 on an Ubuntu system, but that doesn't help much. May you try, for instance, using a lower optimization level for the affected file?

     
    • William Dickinson

      Cool! Thanks for looking at this. I will do as you suggest and post back. Cheers!

      Bill

      Sent from my iPhone

      On Jun 10, 2016, at 8:48 AM, Luigi Ballabio lballabio@users.sf.net wrote:

      I don't have access to an OpenSUSE system, so I haven't been able to reproduce this. I was able to compile the file successfully with gcc 4.8.4 and Boost 1.61 on an Ubuntu system, but that doesn't help much. May you try, for instance, using a lower optimization level for the affected file?

      [bugs:#182] internal compiler error: Segmentation fault building QuantLib on OpenSUSE 42.1

      Status: open
      Group:
      Created: Sun Jun 05, 2016 02:39 AM UTC by William Dickinson
      Last Updated: Sun Jun 05, 2016 02:39 AM UTC
      Owner: nobody

      After a successful build of boost 1_61_0, I could not build QuantLib version 1.8. The build fails while attempting to compile cdo.cpp in the /experimental folder:

      libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c cdo.cpp -fPIC -DPIC -o .libs/cdo.o
      cdo.cpp: In member function 'virtual void QuantLib::CDO::performCalculations() const':
      cdo.cpp:123:10: internal compiler error: Segmentation fault
      void CDO::performCalculations() const {

      Here are the details:
      make error:

      Making all in config
      make[1]: Entering directory '/usr/local/quantlib/QuantLib-1.8/config'
      make[1]: Nothing to be done for 'all'.
      make[1]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/config'
      Making all in ql
      make[1]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql'
      make all-recursive
      make[2]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql'
      Making all in cashflows
      make[3]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/cashflows'
      make[3]: Nothing to be done for 'all'.
      make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/cashflows'
      Making all in currencies
      make[3]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/currencies'
      make[3]: Nothing to be done for 'all'.
      make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/currencies'
      Making all in experimental
      make[3]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental'
      Making all in amortizingbonds
      make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/amortizingbonds'
      make[4]: Nothing to be done for 'all'.
      make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/amortizingbonds'
      Making all in barrieroption
      make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/barrieroption'
      make[4]: Nothing to be done for 'all'.
      make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/barrieroption'
      Making all in callablebonds
      make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/callablebonds'
      make[4]: Nothing to be done for 'all'.
      make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/callablebonds'
      Making all in catbonds
      make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/catbonds'
      make[4]: Nothing to be done for 'all'.
      make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/catbonds'
      Making all in commodities
      make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/commodities'
      make[4]: Nothing to be done for 'all'.
      make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/commodities'
      Making all in convertiblebonds
      make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/convertiblebonds'
      make[4]: Nothing to be done for 'all'.
      make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/convertiblebonds'
      Making all in coupons
      make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/coupons'
      make[4]: Nothing to be done for 'all'.
      make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/coupons'
      Making all in credit
      make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit'
      /bin/sh ../../../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c -o cdo.lo cdo.cpp
      libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c cdo.cpp -fPIC -DPIC -o .libs/cdo.o
      Makefile:517: recipe for target 'cdo.lo' failed
      make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit'
      Makefile:508: recipe for target 'all-recursive' failed
      make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental'
      Makefile:661: recipe for target 'all-recursive' failed
      make[2]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql'
      Makefile:494: recipe for target 'all' failed
      make[1]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql'
      Makefile:593: recipe for target 'all-recursive' failed
      make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit'
      /bin/sh ../../../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c -o cdo.lo cdo.cpp
      libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c cdo.cpp -fPIC -DPIC -o .libs/cdo.o
      cdo.cpp: In member function 'virtual void QuantLib::CDO::performCalculations() const':
      cdo.cpp:123:10: internal compiler error: Segmentation fault
      void CDO::performCalculations() const {
      ^
      Please submit a full bug report,
      with preprocessed source if appropriate.
      See http://bugs.opensuse.org/ for instructions.
      Makefile:517: recipe for target 'cdo.lo' failed
      make[4]: [cdo.lo] Error 1
      make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit'
      Makefile:508: recipe for target 'all-recursive' failed
      make[3]: [all-recursive] Error 1
      make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental'
      Makefile:661: recipe for target 'all-recursive' failed
      make[2]: [all-recursive] Error 1
      make[2]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql'
      Makefile:494: recipe for target 'all' failed
      make[1]: [all] Error 2
      make[1]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql'
      Makefile:593: recipe for target 'all-recursive' failed
      make: *** [all-recursive] Error 1

      gcc version:

      linux-k07u:/usr/local/quantlib/QuantLib-1.8 # gcc -v
      Using built-in specs.
      COLLECT_GCC=gcc
      COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/4.8/lto-wrapper
      Target: x86_64-suse-linux
      Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.8 --enable-ssp --disable-libssp --disable-plugin --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --enable-linker-build-id --enable-linux-futex --program-suffix=-4.8 --without-system-libunwind --with-arch-32=i586 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux
      Thread model: posix
      gcc version 4.8.5 (SUSE Linux)

      OS:
      linux-k07u:/usr/local/quantlib/QuantLib-1.8 # cat /etc/os-release
      NAME="openSUSE Leap"
      VERSION="42.1"
      VERSION_ID="42.1"
      PRETTY_NAME="openSUSE Leap 42.1 (x86_64)"
      ID=opensuse
      ANSI_COLOR="0;32"
      CPE_NAME="cpe:/o:opensuse:opensuse:42.1"
      BUG_REPORT_URL="https://bugs.opensuse.org"
      HOME_URL="https://opensuse.org/"
      ID_LIKE="suse"

      boost version:

      // Boost version.hpp configuration header file ------------------------------//

      // (C) Copyright John maddock 1999. Distributed under the Boost
      // Software License, Version 1.0. (See accompanying file
      // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

      // See http://www.boost.org/libs/config for documentation

      ifndef BOOST_VERSION_HPP

      define BOOST_VERSION_HPP

      //
      // Caution: this is the only Boost header that is guaranteed
      // to change with every Boost release. Including this header
      // will cause a recompile every time a new Boost version is
      // used.
      //
      // BOOST_VERSION % 100 is the patch level
      // BOOST_VERSION / 100 % 1000 is the minor version
      // BOOST_VERSION / 100000 is the major version

      define BOOST_VERSION 106100

      //
      // BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION
      // but as a string in the form "x_y[_z]" where x is the major version
      // number, y is the minor version number, and z is the patch level if not 0.
      // This is used by <config auto_link.hpp=""> to select which library version to link to.</config>

      define BOOST_LIB_VERSION "1_61"

      endif

      Affected File(s):
      cdo.cpp
      / -- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -- /

      /*
      Copyright (C) 2008 Roland Lichters

      This file is part of QuantLib, a free-software/open-source library
      for financial quantitative analysts and developers - http://quantlib.org/

      QuantLib is free software: you can redistribute it and/or modify it
      under the terms of the QuantLib license. You should have received a
      copy of the license along with this program; if not, please email
      quantlib-dev@lists.sf.net. The license is also available online at
      http://quantlib.org/license.shtml.

      This program is distributed in the hope that it will be useful, but WITHOUT
      ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      FOR A PARTICULAR PURPOSE. See the license for more details.
      */

      include <ql experimental="" credit="" cdo.hpp=""></ql>

      include <ql event.hpp=""></ql>

      using namespace std;

      namespace QuantLib {

      CDO::CDO (Real attachment,
      Real detachment,
      const vector<real>& nominals,</real>
      const vector<handle\<defaultprobabilitytermstructure> >& basket,</handle\<defaultprobabilitytermstructure>
      const Handle<onefactorcopula>& copula,</onefactorcopula>
      bool protectionSeller,
      const Schedule& premiumSchedule,
      Rate premiumRate,
      const DayCounter& dayCounter,
      Rate recoveryRate,
      Rate upfrontPremiumRate,
      const Handle<yieldtermstructure>& yieldTS,</yieldtermstructure>
      Size nBuckets,
      const Period& integrationStep)

      attachment_(attachment), detachment_(detachment),
      nominals_(nominals), basket_(basket),
      copula_(copula),
      protectionSeller_(protectionSeller),
      premiumSchedule_(premiumSchedule),
      premiumRate_(premiumRate),
      dayCounter_(dayCounter),
      recoveryRate_(recoveryRate),
      upfrontPremiumRate_(upfrontPremiumRate),
      yieldTS_(yieldTS),
      nBuckets_(nBuckets),
      integrationStep_(integrationStep) {

      QL_REQUIRE (!basket.empty(), "basket is empty");
      QL_REQUIRE (attachment_ >= 0 && attachment_ < detachment_
      && detachment_ <= 1,
      "illegal attachment/detachment point");

      registerWith (yieldTS_);
      registerWith (copula_);
      for (Size i = 0; i < basket_.size(); i++)
      registerWith (basket_[i]);

      QL_REQUIRE (nominals_.size() <= basket_.size(),
      "nominal vector size too large");

      if (nominals_.size() < basket_.size()) {
      Size n = basket_.size() - nominals_.size();
      Real back = nominals_.back();
      for (Size i = 0; i < n; i++)
      nominals_.push_back(back);
      }

      QL_REQUIRE (nominals_.size() == basket_.size(),
      "nominal size " << nominals_.size()
      << " != basket size " << basket_.size());

      nominal_ = 0;
      for (Size i = 0; i < nominals_.size(); i++) {
      lgds_.push_back (nominals_[i] * (1.0 - recoveryRate_));
      nominal_ += nominals_[i];
      lgd_ += lgds_[i];
      }
      xMax_ = detachment_ * nominal_;
      xMin_ = attachment_ * nominal_;
      }

      bool CDO::isExpired () const {
      return detail::simple_event(premiumSchedule_.dates().back())
      .hasOccurred(yieldTS_->referenceDate());
      }

      void CDO::setupExpired() const {
      Instrument::setupExpired();
      }

      Real CDO::expectedTrancheLoss (Date d) const {
      if (d <= basket_.front()->referenceDate())
      return 0;

      vector<Real> defProb (basket_.size());
      for (Size j = 0; j < basket_.size(); j++)
          defProb[j] = basket_[j]->defaultProbability (d);
      
      LossDistBucketing op (nBuckets_, xMax_);
      Distribution dist = copula_->integral (op, lgds_, defProb);
      
      return dist.trancheExpectedValue (xMin_, xMax_);
      
      // The following causes two errors in test against literature values.
      // FIXME: Investigate accuracy.
      // return dist.cumulativeExcessProbability (xMin_, xMax_);
      
      //   TranchePayoff func (xMin_, xMax_);
      //   return (dist.expectedValue (func)
      //    + (xMax_ - xMin_) * (1.0 - dist.cumulatedProbability (xMax_)));
      

      }

      void CDO::performCalculations() const {

      QL_REQUIRE(!yieldTS_.empty(), "no yield term structure set");
      
      errorEstimate_ = Null<Real>();
      
      NPV_ = 0.0;
      premiumValue_ = 0;
      protectionValue_ = 0;
      error_ = 0;
      
      /* Expectations e1 and e2 are portfolio loss given default,
         i.e.  with recovery already "bult in". Multiplication by
         (1-r) is therefore not necessary, neither in premium nor
         protection value calculation.
      */
      
      Real e1 = 0;
      Date today = yieldTS_->referenceDate();
      if (premiumSchedule_[0] > today)
          e1 = expectedTrancheLoss (premiumSchedule_[0]);
      
      for (Size i = 1; i < premiumSchedule_.size(); i++) {
          Date d2 = premiumSchedule_[i];
          if (d2 < today)
              continue;
      
          Date d1 = premiumSchedule_[i-1];
      
          Date d, d0 = d1;
          do {
              d = NullCalendar().advance (d0 > today ? d0 : today,
                                          integrationStep_);
              if (d > d2)
                  d = d2;
      
              Real e2 = expectedTrancheLoss (d);
      
              premiumValue_ += (xMax_ - xMin_ - e2)
                  * premiumRate_ * dayCounter_.yearFraction (d0, d)
                  * yieldTS_->discount (d);
      
              if (e2 < e1) {
                  error_ ++;
              }
      
              protectionValue_ -= (e2 - e1) * yieldTS_->discount (d);
      
              d0 = d;
              e1 = e2;
          }
          while (d < d2);
      }
      
      if (premiumSchedule_[0] >= today)
          upfrontPremiumValue_ = (xMax_ - xMin_) * upfrontPremiumRate_ *
              yieldTS_->discount(premiumSchedule_[0]);
      else
          upfrontPremiumValue_ = 0.0;
      
      if (!protectionSeller_) {
          premiumValue_ *= -1;
          upfrontPremiumValue_ *= -1;
          protectionValue_ *= -1;
      }
      
      NPV_ = premiumValue_ + protectionValue_ + upfrontPremiumValue_;
      

      }

      Rate CDO::premiumValue () const {
      calculate();
      return premiumValue_;
      }

      Rate CDO::protectionValue () const {
      calculate();
      return protectionValue_;
      }

      Size CDO::error () const {
      calculate();
      return error_;
      }

      Rate CDO::fairPremium () const {
      calculate();
      return - premiumRate_ * protectionValue_ / premiumValue_;
      }
      }

      cdo.hpp:
      / -- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -- /

      /*
      Copyright (C) 2008 Roland Lichters

      This file is part of QuantLib, a free-software/open-source library
      for financial quantitative analysts and developers - http://quantlib.org/

      QuantLib is free software: you can redistribute it and/or modify it
      under the terms of the QuantLib license. You should have received a
      copy of the license along with this program; if not, please email
      quantlib-dev@lists.sf.net. The license is also available online at
      http://quantlib.org/license.shtml.

      This program is distributed in the hope that it will be useful, but WITHOUT
      ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      FOR A PARTICULAR PURPOSE. See the license for more details.
      */

      /! \file cdo.hpp
      \brief collateralized debt obligation/

      ifndef quantlib_cdo_hpp

      define quantlib_cdo_hpp

      include <ql instrument.hpp=""></ql>

      include <ql termstructures="" yieldtermstructure.hpp=""></ql>

      include <ql termstructures="" defaulttermstructure.hpp=""></ql>

      include <ql experimental="" credit="" lossdistribution.hpp=""></ql>

      include <ql experimental="" credit="" onefactorcopula.hpp=""></ql>

      include <ql time="" schedule.hpp=""></ql>

      namespace QuantLib {

      //! collateralized debt obligation
      /*! The instrument prices a mezzanine CDO tranche with loss given
      default between attachment point \f$ D_1\f$ and detachment
      point \f$ D_2 > D_1 \f$.

      For purchased protection, the instrument value is given by the
      difference of the protection value \f$ V_1 \f$ and premium
      value \f$ V_2 \f$,
      
      \f[ V = V_1 - V_2. \f]
      
      The protection leg is priced as follows:
      
      - Build the probability distribution for volume of defaults
        \f$ L \f$ (before recovery) or Loss Given Default \f$ LGD =
        (1-r)\,L \f$ at times/dates \f$ t_i, i=1, ..., N\f$ (premium
        schedule times with intermediate steps)
      - Determine the expected value
        \f$ E_i = E_{t_i}\,\left[Pay(LGD)\right] \f$
        of the protection payoff \f$ Pay(LGD) \f$ at each time
        \f$ t_i\f$ where
       \f[
       Pay(L) = min (D_1, LGD) - min (D_2, LGD) = \left\{
       \begin{array}{lcl}
       \displaystyle 0 &;& LGD < D_1 \\
       \displaystyle LGD - D_1 &;& D_1 \leq LGD \leq D_2 \\
       \displaystyle D_2 - D_1 &;& LGD > D_2
       \end{array}
       \right.
       \f]
      - The protection value is then calculated as
        \f[ V_1 \:=\: \sum_{i=1}^N (E_i - E_{i-1}) \cdot  d_i \f]
        where \f$ d_i\f$ is the discount factor at time/date \f$ t_i \f$
      
      The premium is paid on the protected notional amount,
      initially \f$ D_2 - D_1. \f$ This notional amount is reduced
      by the expected protection payments \f$ E_i \f$ at times
      \f$ t_i, \f$ so that the premium value is calculated as
      
      \f[
      V_2 = m \, \cdot \sum_{i=1}^N \,(D_2 - D_1 - E_i)
                 \cdot \Delta_{i-1,i}\,d_i
      \f]
      
      where \f$ m \f$ is the premium rate, \f$ \Delta_{i-1, i}\f$ is
      the day count fraction between date/time \f$ t_{i-1}\f$ and
      \f$ t_i.\f$
      
      The construction of the portfolio loss distribution \f$ E_i
      \f$ is based on the probability bucketing algorithm described
      in
      
      <strong>
      John Hull and Alan White, "Valuation of a CDO and nth to default CDS
      without Monte Carlo simulation", Journal of Derivatives 12, 2, 2004
      </strong>
      
      The pricing algorithm allows for varying notional amounts and
      default termstructures of the underlyings.
      
      \todo Investigate and fix cases \f$ E_{i+1} < E_i. \f$
      

      /
      class CDO : public Instrument {
      public:
      /
      ! \param attachment fraction of the LGD where protection starts
      \param detachment fraction of the LGD where protection ends
      \param nominals vector of basket nominal amounts
      \param basket default basket represented by a vector of
      default term structures that allow
      computing single name default
      probabilities depending on time
      \param copula one-factor copula
      \param protectionSeller sold protection if set to true, purchased
      otherwise
      \param premiumSchedule schedule for premium payments
      \param premiumRate annual premium rate, e.g. 0.05 for 5% p.a.
      \param dayCounter day count convention for the premium rate
      \param recoveryRate recovery rate as a fraction
      \param upfrontPremiumRate premium as a tranche notional fraction
      \param yieldTS yield term structure handle
      \param nBuckets number of distribution buckets
      \param integrationStep time step for integrating over one
      premium period; if larger than premium
      period length, a single step is taken
      */
      CDO (Real attachment,
      Real detachment,
      const std::vector<real>& nominals,
      const std::vector<handle\<defaultprobabilitytermstructure> >& basket,
      const Handle<onefactorcopula>& copula,
      bool protectionSeller,
      const Schedule& premiumSchedule,
      Rate premiumRate,
      const DayCounter& dayCounter,
      Rate recoveryRate,
      Rate upfrontPremiumRate,
      const Handle<yieldtermstructure>& yieldTS,
      Size nBuckets,
      const Period& integrationStep = Period(10, Years));</yieldtermstructure></onefactorcopula></handle\<defaultprobabilitytermstructure></real>

      Real nominal() { return nominal_; }
      Real lgd() { return lgd_; }
      Real attachment () { return attachment_; }
      Real detachment () { return detachment_; }
      std::vector<Real> nominals() { return nominals_; }
      Size size() { return basket_.size(); }
      
      bool isExpired () const;
      Rate fairPremium() const;
      Rate premiumValue () const;
      Rate protectionValue () const;
      Size error () const;
      

      private:
      void setupExpired() const;
      void performCalculations() const;
      Real expectedTrancheLoss (Date d) const;

      Real attachment_;
      Real detachment_;
      std::vector<Real> nominals_;
      std::vector<Handle<DefaultProbabilityTermStructure> > basket_;
      Handle<OneFactorCopula> copula_;
      bool protectionSeller_;
      
      Schedule premiumSchedule_;
      Rate premiumRate_;
      DayCounter dayCounter_;
      Rate recoveryRate_;
      Rate upfrontPremiumRate_;
      Handle<YieldTermStructure> yieldTS_;
      Size nBuckets_; // number of buckets up to detachment point
      Period integrationStep_;
      
      std::vector<Real> lgds_;
      
      Real nominal_;  // total basket volume (sum of nominals_)
      Real lgd_;      // maximum loss given default (sum of lgds_)
      Real xMax_;     // tranche detachment point (tranche_ * nominal_)
      Real xMin_;     // tranche attachment point (tranche_ * nominal_)
      
      mutable Size error_;
      
      mutable Real premiumValue_;
      mutable Real protectionValue_;
      mutable Real upfrontPremiumValue_;
      

      };
      }

      endif

      Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/quantlib/bugs/182/

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

       

      Related

      Bugs: #182

  • Luigi Ballabio

    Luigi Ballabio - 2017-01-30
    • status: open --> closed
    • Group: -->
     

Log in to post a comment.