• 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!

SHOW ME THE CODE !

why not build your own Euler fdm 101 from 1st principles w/o all that boiler plate code i.e. virtual.
C++:
 /* Let's try to solve the first order ODE given by
    *  x' = (1-2t)x
    */
 
Thank you for the invitation to join you on this quest for learning and growth. Learning new skills, mastering programming languages, and delving into finance-related models like the Black-Scholes option pricing model is indeed a rewarding journey.

While I'm here to assist and guide you through your learning experiences, I'm not able to directly code, download, or store files. However, I'd be more than happy to help you understand the concepts, provide guidance, and answer any questions you might have regarding programming, finance, or related topics.

If you have specific questions about the Black-Scholes option pricing model, C#, or any other related topic, feel free to ask. I'm here to help you along your learning journey and provide insights to the best of my ability!
 
oops.cpp:
#include <iostream>
#include <thread>

using namespace std;
void oops()
{
    int some_local_state {1};
   
    std::thread my_thread([&some_local_state]()
    {
        for(int i{};i<100;++i){
            cout << "my_thread: "<<some_local_state << "\n";
        }
    });
    my_thread.detach();
    cout << "\nExiting oops..." << "\n";
}

int main()
{
    oops();
    return 0;
}

Learning: It's a well-known red-flag to access memory occupied by automatic stack-allocated local variables after a function exits. This could also happen when you have multiple threads. The new thread associated with the std::thread object my_thread, will continue to access some_local_state, even after oops() exits.
 
Scary code.
Why not use TLS?

BTW lambdas are not robust (e.g. capture by reference).

 
Last edited:
or even

C++:
int x = 4;
int z = [&r = x, y = x+1] {
            r += 2;         // set x to 6; "R is for Renamed Ref"
            return y+2;     // return 7 to initialize z
        }(); // invoke lambda
 
Hi guys,

I am writing a matrix class - and wanted to get some feedback. My idea is that one should be capable of creating both fixed-size(compile-time) and dynamic matrices. So, containerType template parameter would be either std::array<T,N> or std::vector<N>.

I should provide proper iterators to traverse through my matrix and also need to overload the assignment operator.

Matrix.h:
#pragma once

#include <array>
#include <vector>

template <typename T, int r, int c, typename cType=std::array<T,r*c>>
class Matrix;

using Matrix1d = Matrix<double, 1, 1>;
using Matrix2d = Matrix<double, 2, 2>;
using Matrix3d = Matrix<double, 3, 3>;
using Matrix4d = Matrix<double, 4, 4>;

using Matrix1i = Matrix<int, 1, 1>;
using Matrix2i = Matrix<int, 2, 2>;
using Matrix3i = Matrix<int, 3, 3>;
using Matrix4i = Matrix<int, 4, 4>;

using Matrix1f = Matrix<float, 1, 1>;
using Matrix2f = Matrix<float, 2, 2>;
using Matrix3f = Matrix<float, 3, 3>;
using Matrix4f = Matrix<float, 4, 4>;

using Vector1d = Matrix<double, 1, 1>;
using Vector2d = Matrix<double, 1, 2>;
using Vector3d = Matrix<double, 1, 3>;
using Vector4d = Matrix<double, 1, 4>;

using Vector1i = Matrix<int, 1, 1>;
using Vector2i = Matrix<int, 2, 2>;
using Vector3i = Matrix<int, 3, 3>;
using Vector4i = Matrix<int, 4, 4>;

using Vector1f = Matrix<float, 1, 1>;
using Vector2f = Matrix<float, 2, 2>;
using Vector3f = Matrix<float, 3, 3>;
using Vector4f = Matrix<float, 4, 4>;

using MatrixXi = Matrix<int, 0, 0, std::vector<int>>;
using MatrixXd = Matrix<double, 0, 0, std::vector<double>>;
using MatrixXf = Matrix<float, 0, 0, std::vector<float>>;

template <typename scalarType, int rowsAtCompileTime = 0, int colsAtCompileTime = 0, typename containerType = std::array<scalarType,(rowsAtCompileTime * colsAtCompileTime)>>
class Matrix
{
private:
    containerType A;
    int _rows;
    int _cols;
public:
    Matrix() = default;
    Matrix(const Matrix& m);

    int rows() const;
    int cols() const;
    int size() const;
 
    //Overloaded operators
    scalarType operator()(const int i, const int j) const;
    scalarType& operator()(const int i, const int j);
    Matrix operator+(const Matrix& m) const;
    Matrix operator-(const Matrix& m) const;
    Matrix operator*(const Matrix& m) const;
};

Matrix.cpp:
#pragma once

#include "Matrix.h"
#include <stdexcept>

template<typename scalarType, int rowsAtCompileTime, int colsAtCompileTime, typename containerType>
Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType>::Matrix(const Matrix& m):A{m.A}, _rows{m.rows()}, _cols{m.cols()}, _size{m.size()}
{
}

template<typename scalarType, int rowsAtCompileTime, int colsAtCompileTime, typename containerType>
int Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType>::rows() const
{
    return _rows;
}

template<typename scalarType, int rowsAtCompileTime, int colsAtCompileTime, typename containerType>
int Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType>::cols() const
{
    return _cols;
}

template<typename scalarType, int rowsAtCompileTime, int colsAtCompileTime, typename containerType>
int Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType>::size() const
{
    return A.size();
}

/// <summary>
/// Coefficient accessors.
/// The primary coefficient accessor is the overloaded parenthesis operators. The data of the matrix
/// is stored in an underlying sequential container such as std::array or std::vector. The element
/// A(i,j) is at an offset of (i*_cols)+j in memory.
/// </summary>
/// <typeparam name="scalarType"></typeparam>
/// <typeparam name="containerType"></typeparam>
/// <param name="i">The row index</param>
/// <param name="j">The col index</param>
/// <returns>The element at position (i,j)</returns>
template<typename scalarType, int rowsAtCompileTime, int colsAtCompileTime, typename containerType>
scalarType Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType>::operator()(const int i, const int j) const
{
    containerType::const_iterator it{ A.begin() };
    it = it + (i * _cols) + j;
    if (it < A.end())
        return *it;
    else
        throw std::out_of_range("\nError accessing an element beyond matrix bounds");
}

/// <summary>
/// Matrix addition.
/// Overload of the binary operator +. The left hand side and the right hand side matrix must have
/// the same number of rows and columns.
/// </summary>
/// <typeparam name="scalarType"></typeparam>
/// <typeparam name="containerType"></typeparam>
/// <param name="i"></param>
/// <param name="j"></param>
/// <returns></returns>
template<typename scalarType, int rowsAtCompileTime, int colsAtCompileTime, typename containerType>
scalarType& Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType>::operator()(const int i, const int j)
{
    containerType::iterator it{ A.begin() };
    it = it + (i * _cols) + j;
    if (it < A.end())
        return *it;
    else
        throw std::out_of_range("\nError accessing an element beyond matrix bounds");
}

template<typename scalarType, int rowsAtCompileTime, int colsAtCompileTime, typename containerType>
Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType> Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType>::operator+(const Matrix& m) const
{
    Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType> result{};

    if (this->rows() == m.rows() && this->cols() == m.cols())
    {
        containerType::const_iterator it1{ A.begin() };
        containerType::const_iterator it2{ m.A.begin() };
        containerType::iterator resultIter{ result.A.begin() };
        while (it1 < A.end() && it2 < m.A.end())
        {
            *resultIter = *it1 + *it2;
            ++it1; ++it2; ++resultIter;
        }
    }
    else
    {
        throw std::logic_error("Matrices have different dimensions; therefore cannot be added!");
    }

 
    return result;
}

template<typename scalarType, int rowsAtCompileTime, int colsAtCompileTime, typename containerType>
Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType> Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType>::operator-(const Matrix& B) const
{
    Matrix<scalarType, rowsAtCompileTime, colsAtCompileTime, containerType> result{};

    if (this->rows() == m.rows() && this->cols() == m.cols())
    {
        containerType::const_iterator it1{ A.begin() };
        containerType::const_iterator it2{ m.A.begin() };
        containerType::iterator resultIter{ result.A.begin() };
        while (it1 < A.end() && it2 < m.A.end())
        {
            *resultIter = *it1 - *it2;
            ++it1; ++it2; ++resultIter;
        }
    }
    else
    {
        throw std::logic_error("Matrices have different dimensions; therefore cannot be added!");
    }
    return result;
}

template<typename scalarType, int m, int n, int p, typename containerType>
Matrix<scalarType, m, p, containerType> operator*(const Matrix<scalarType, m, n, containerType>& A, const Matrix<scalarType, n, p, containerType>& B)
{
    Matrix<scalarType, m, p, containerType> result;

    for (int i{}; i < m; ++i)
    {
        for (int k{}; k < p; ++k)
        {
            scalarType sum{};
            for (int j{}; j < n; ++j)
            {
                sum += A(i, j) * B(j, k);
            }
            result(i, k) = sum;
        }
    }
}

You might find Eigen interesting
 
Back
Top