• C++ Programming for Financial Engineering
    Highly recommended by thousands of MFE students. Covers essential C++ topics with applications to financial engineering. Learn more Join!
    Python for Finance with Intro to Data Science
    Gain practical understanding of Python to read, understand, and write professional Python code for your first day on the job. Learn more Join!
    An Intuition-Based Options Primer for FE
    Ideal for entry level positions interviews and graduate studies, specializing in options trading arbitrage and options valuation models. Learn more Join!

Blog: Articles on C++11 and Computational Finance (by Daniel J. Duffy)

Code:
// TestSTLVariant101.cpp
//
// Show the essentials of the Variant Library in Boost.
// Supported in C++17, std::variant and std::visit()
//
// Show a variety of methods for type-safe visitation of type-safe unions.
//
// Q. can you get std::variant working with boost::static_visitor<>?
//
// BIG DEAL is: adding functionality NON-INTRUSIVELY to a class by Visior pattern.
//
// (C) Datasim Education BV 2009-2019
//

#include <iostream>
#include <boost/variant.hpp>
#include <variant>

// Basic shapes
struct Point
{
    double x;
    double y;

    void displayPoint()
    {
        std::cout << "Point: " << x << ", " << y << '\n';
    }
};

struct Circle
{
    Point centre;
    double radius;

    void displayCircle()
    {
        std::cout << "Circle, radius " << radius  << '\n';
        std::cout << "Centre point "; centre.displayPoint();
    }

};

struct LineSegment
{
    Point p1;
    Point p2;

    void displayLineSegment()
    {
        std::cout << "Line, endpoints "<< '\n';
        p1.displayPoint();
        p2.displayPoint();
    }
};

using VariantBoost = boost::variant<Point, LineSegment, Circle>;
using VariantSTL = std::variant<Point, LineSegment, Circle>;

// Different ways to add functionality/visit shapes

// A. In combination with Boost visitor pattern
class Print_Visitor : public boost::static_visitor<void>
{
public:
    void operator () (Point& s) { s.displayPoint(); }
    void operator () (LineSegment& s) { s.displayLineSegment(); }
    void operator () (Circle& s) { s.displayCircle(); }
};

class Translate_Visitor : public boost::static_visitor<void>
{ // Move the shapes

private:
    double off;

public:
    Translate_Visitor(double offset) : off(offset) {}
    void operator () (Point& s) { s.x += off; s.y += off;}
    void operator () (LineSegment& s) {(*this)(s.p1); (*this)(s.p2);}
    void operator () (Circle& s) { (*this)(s.centre); }
};

// B. Lambda function to test each type
auto lambdaVisit = [](auto&& arg)
{
    using T = std::decay_t < decltype(arg)>;

    // Hard-coded switch
    if constexpr (std::is_same_v<T, Point>)
        arg.displayPoint();

    if constexpr (std::is_same_v<T, LineSegment>)
        arg.displayLineSegment();

    if constexpr (std::is_same_v<T, Circle>)
        arg.displayCircle();
};

void MyVisit(VariantSTL& var)
{
    std::visit(lambdaVisit, var);
}



void MyVisit2(VariantSTL& v)
{
    switch (v.index()) {
    case 0:
        std::get<0>(v).displayPoint();
        break;
    case 1:
        std::get<1>(v).displayLineSegment();
        break;
    case 2:
        std::get<2>(v).displayCircle();
        break;
    default:
        std::cout << "ugh\n";
    }
}

void MyVisit3(VariantSTL& v)
{

    switch (v.index()) {
    case 0:
        std::get<Point>(v).displayPoint();
        break;
    case 1:
        std::get<LineSegment>(v).displayLineSegment();
        break;
    case 2:
        std::get<Circle>(v).displayCircle();
        break;
    default:
        std::cout << "ugh\n";
    }
}
int main()
{
    // Create some shapes
    Point p1{ 1,1 };
    Point p2{ 2,1 };
    LineSegment myL{ p1, p2 };
    double radius = 2.0;
    Circle c{ p1, radius };

    // Checking the data
    std::cout << "\n*** Sanity checks \n";
    p1.displayPoint(); p2.displayPoint();
    myL.displayLineSegment(); c.displayCircle();

    {

        // Boost Visitor
        std::cout << "\n*** C++11 visit using Boost visitor \n";
        VariantBoost var(p1);
        Print_Visitor vis;

        // Give some values; visit each component
        var = p1;
        boost::apply_visitor(vis, var);

        var = myL;
        boost::apply_visitor(vis, var);

        var = c;
        boost::apply_visitor(vis, var);
    }

    // C++11 solution
    {
        std::cout << "\n*** C++11 visit\n";
        VariantSTL var(p1);
        MyVisit(var);

        var = c;
        MyVisit(var);

        var = myL;
        MyVisit(var);

    }
  
    // C. Based on the variant's index
    {
        std::cout << "\n*** C++11 visit using indices \n";
        VariantSTL var(p1);
        MyVisit2(var);

        var = c;
        MyVisit2(var);

        var = myL;
        MyVisit2(var);

    }
    // D. Based on the variant's type
    {
        std::cout << "\n*** C++11 visit using type as index \n";
        VariantSTL var(p1);
        MyVisit3(var);

        var = c;
        MyVisit3(var);

        var = myL;
        MyVisit3(var);

    }

    // E. Translate Visitor
    {
        std::cout << "\n*** Translate visitor \n";
      
        Point p{ 0.0, 0.0 };
        Point p2 {1.0, 1.0 };
        LineSegment myL{ p, p2 };
        Circle c{ p, 10.0 };

        // Boost Visitor
        std::cout << "\n*** C++11 visit using Boost visitor \n";
        VariantBoost var(p);

        double offset = 2.0;
        Translate_Visitor vis(offset);
        Print_Visitor visP;

        // Give some values; visit each component
        var = p;
        boost::apply_visitor(vis, var);
        boost::apply_visitor(visP, var);

        var = myL;
        boost::apply_visitor(vis, var);
        boost::apply_visitor(visP, var);

        var = c;
        boost::apply_visitor(vis, var);
        boost::apply_visitor(visP, var);

    /*    p.displayPoint();
        myL.displayLineSegment();
        c.displayCircle();*/


    }

     return 0;
}
C++17 (and Boost) type-safe variant and its visitors. Use /std:c++latest
 

Attachments

Some weekend thoughts ...
I didn't always work on high-level languages like C++. Once upon a time I was a summer intern with GE in Ireland testing diodes and triodes (big ones!) using Basic on a noisy teletype machine connected to the computer in Scotland by a very long cable.

Advantage of paper tape: no chance of hacking, easy to make backup
Disadvantage code difficult to maintain (need a pair of scissors .. cut and paste). And earplugs. These days people never had it so good :unsure: 😂

29781
29782
 
Last edited:
C++ 2020 Concepts, finally

Concepts are an extension to the templates feature provided by the C++ programming language.[...] concepts are named Boolean predicates on template parameters, evaluated at compile time. A concept may be associated with a template (class template, function template, or member function of a class template), in which case it serves as a constraint: it limits the set of arguments that are accepted as template parameters.

C++20 Concepts Are Here in Visual Studio 2019 version 16.3 – C++ Team Blog

 
Boost C++ Histogram library.



This library provides a histogram for multi-dimensional data. In the multi-dimensional case, the input consist of tuples of values which belong together and describing different aspects of the same entity. For example, when you make a digital image with a camera, photons hit a pixel detector. The photon is the entity and it has two coordinates values where it hit the detector. The camera only counts how often a photon hit each cell, so it is a real-life example of making a two-dimensional histogram. A two-dimensional histogram collects more information than two separate one-dimensional histograms, one for each coordinate. For example, if the two-dimensional image looks like a checker board, with high and low densities are alternating along each coordinate, then the one-dimensional histograms along each coordinate would look flat. There would be no hint that there is a complex structure in two dimensions.
 
They don't write well-researched books like this any more.

R.G. Dromey How to Solve it by Computer Prentice-Hall 1982

It discusses how to write well-structured modular programs and deep discussions of algorithms and data structures and code in Pascal.
For example, this is a good front-end to C++ STL algorithms and data structures.

Most books (e.g. in Python) are

30% screen sheets
40% tables of output
20% text
10% maths (if you are lucky)

Very little background (e.g. maths, fianance) and certainly no help in developing your own algorithms.

Just using libraries and packages alone means you will always us libraries and packages at the cost of real software design skill IMHO.

BTW I have stopped buying books on Python, for the above reasons.

Caveat: "each to his own"
 
Last edited:
They don't write well-researched books like this any more.

R.G. Dromey How to Solve it by Computer Prentice-Hall 1982

It discusses how to write well-structured modular programs and deep discussions of algorithms and data structures and code in Pascal.
For example, this is a good front-end to C++ STL algorithms and data structures.

Most books (e.g. in Python) are

30% screen sheets
40% tables of output
20% text
10% maths (if you are lucky)

Very little background (e.g. maths, fianance) and certainly no help in developing your own algorithms.

Just using libraries and packages alone means you will always us libraries and packages at the cost of real software design skill IMHO.

BTW I have stopped buying books on Python, for the above reasons.

Caveat: "each to his own"

Speaking of which, I've been reading your latest book, and am really enjoying it. Well done. Can't imagine how much time/effort you put into it. Can't thank you enough.
 
Speaking of which, I've been reading your latest book, and am really enjoying it. Well done. Can't imagine how much time/effort you put into it. Can't thank you enough.
Thank you. A lot of tine (BTW I have lost count) and effort by myself and better half (tex, etc.)
BTW did you request the code? info@datasim.nl
 
Alright then, I downloaded the revamped Imperial Covid C code, built the project and got it running in console mode (it uses GDI which I haven't used since 1992 ... it is deprecated big time and is impossible to find GDI drivers),

I will write up a precise and detailed report in the coming days (BTW I have written code on projects large and small since 1972).

It is going to be a very rough ride; fasten seatbelts. BTW the Microsoft/Github code is still C running under Visual Studio.

Even this new ported code is not fit for purpose
Even this new ported code is not fit for purpose


Watch this space.

Reminds me of the quote from Local Hero

“My parents were Hungarian immigrants. They took the name MacIntyre 'cause they thought it sounded more American!”
 
I have just coined a new term: (Programming) Language Silo

In many cases, developers and quants' monolog interiors seem to be driven by their fascination/obsession with a single programming language (Sapir-Whorf again). This is caused by idiosyncratic views 1) efficiency, 2) elegance, 3) personal preferences, 4) not business-driven.

C++ is being 'attacked' by proprietary, non-mainstream 'quiche' languages (Rust and GO spring to mind).
At this moment in time I think C, C++ and Python are good ones.

I never get asked "How do I design maintainable and flexible software systems on time and within budget? It says buckets about the educational systems. Looks bad.

Silo
 
“The management question, therefore, is not whether to build a pilot system and throw it away. You will do that. The only question is whether to plan in advance to build a throwaway, or to promise to deliver the throwaway to customers.”

Frederick P. Brooks Jr., The Mythical Man-Month: Essays on Software Engineering
 
Back
Top