Skip to content

Commit

Permalink
modified 2D rv slightly for C++ 20
Browse files Browse the repository at this point in the history
  • Loading branch information
theonlynavin committed Apr 4, 2024
1 parent e0b0369 commit e711932
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 11 deletions.
42 changes: 36 additions & 6 deletions src/Core/2D.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
#ifndef DF_2DRV_H
#define DF_2DRV_H

#if (__cplusplus >= 202002L)

#include <iostream>
#include <vector>
#include <cmath>
#include <type_traits>
#include <concepts>
#include "basicfxn.h"

namespace DiceForge
{
/* Helper functions for integration */

// defining a concept which is a predicate to constrain template type T is of arithmetic type
template <typename T>
concept arithmetic_c = std::is_arithmetic_v<std::remove_cvref_t<T>>;
Expand All @@ -23,6 +31,7 @@ namespace DiceForge
else
static_assert(arithmetic_c<FuncType> || requires { f(value); });
}
// helper function for evaluating value
template <typename FuncType1, typename FuncType2, arithmetic_c ValueType>
auto evaluate(std::tuple<FuncType1, FuncType2> funcs, /* bound of integral */
ValueType value)
Expand All @@ -31,17 +40,36 @@ namespace DiceForge
evaluate(std::get<1>(funcs), value) /*upper bound*/};
}

/// @brief An integrator for functions in one variable, to be used as integrate(f, bounds)
/// @param f the function to be integrated f(x)
/// @param bounds integration bounds as a tuple
/// @return The evaluated value of the integral
template <typename FuncType, typename BoundType>
BoundType integrate(FuncType &&f, std::tuple<BoundType, BoundType> bounds)
{
return gaussian_quadrature(f, std::get<0>(bounds), std::get<1>(bounds));
}

// use DiceForge::dx_dy for integration of f(x,y)dxdy and DiceForge::dy_dx for integration of f(x,y)dydx

// Integrate wrt x first, then wrt y in f(x, y)
auto dx_dy = std::integer_sequence<int, 1, 0>{};
// Integrate wrt y first, then wrt x in f(x, y)
auto dy_dx = std::integer_sequence<int, 0, 1>{};

/// @brief An integrator for functions in two variables, to be used as integrate(f, bounds_0, bounds_1, integration sequence)
/// @param f the function to be integrated f(x, y)
/// @param bounds_0 integration bounds of the first variable (x or y depending on integration sequence) as a tuple
/// @param bounds_1 integration bounds of the second variable (x or y depending on integration sequence) as a tuple
/// @param integration_sequence dx_dy or dy_dx (using DiceForge::dx_dy, DiceForge::dy_dx)
/// @return The evaluated value of the integral
template <auto First, auto Second, typename FuncType,
typename Lower_0, typename Upper_0,
typename Lower_1, typename Upper_1>
std::common_type_t<Lower_0, Upper_0>
integral(FuncType &&f,
std::tuple<Lower_0, Upper_0> bound_0,
std::tuple<Lower_1, Upper_1> bound_1, std::integer_sequence<int, First, Second>)
integrate(FuncType &&f,
std::tuple<Lower_0, Upper_0> bounds_0,
std::tuple<Lower_1, Upper_1> bounds_1, std::integer_sequence<int, First, Second> integration_sequence)
{
using bound_t = std::common_type_t<Lower_0, Upper_0>;

Expand All @@ -57,10 +85,12 @@ namespace DiceForge
return std::apply(f, args);
};

return DiceForge::integrals(F1, evaluate(bound_1, v0));
return DiceForge::integrate(F1, evaluate(bounds_1, v0));
};

return DiceForge::integrals(F0, bound_0);
return DiceForge::integrate(F0, bounds_0);
}

}

#endif
#endif
11 changes: 6 additions & 5 deletions testing/test_2D.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#include "../src/Core/2D.h"
#include <iomanip>

template <typename Type>
void test_double_integral_one()
void test_double_integral_1()
{
auto f = [](auto x, auto y)
{
Expand All @@ -13,8 +14,8 @@ void test_double_integral_one()
auto bound_x = std::tuple<Type, Type>{0.0, pi / 2};
auto bound_y = std::tuple<Type, Type>{0.0, pi / 2};

auto int_x_y = DiceForge::integral(f, bound_x, bound_y, DiceForge::dy_dx);
auto int_y_x = DiceForge::integral(f, bound_y, bound_x, DiceForge::dx_dy);
auto int_x_y = DiceForge::integrate(f, bound_x, bound_y, DiceForge::dy_dx);
auto int_y_x = DiceForge::integrate(f, bound_y, bound_x, DiceForge::dx_dy);

std::cout << std::setprecision(17) << "int_x_y = " << int_x_y << std::endl;
std::cout << std::setprecision(17) << "int_y_x = " << int_y_x << std::endl;
Expand All @@ -37,7 +38,7 @@ void test_double_integral_2()

auto bound_x = std::make_tuple(lower, upper);

auto calculated_answer = DiceForge::integral(z, bound_y, bound_x, DiceForge::dx_dy);
auto calculated_answer = DiceForge::integrate(z, bound_y, bound_x, DiceForge::dx_dy);

auto actual_answer = 20803.0 / 1680.0;

Expand All @@ -48,7 +49,7 @@ void test_double_integral_2()
int main()
{
std::cout<<"for test case one :"<<std::endl;
test_double_integral_one<double>();
test_double_integral_1<double>();
std::cout<<"for test case two :"<<std::endl;
test_double_integral_2<double>();
}

0 comments on commit e711932

Please sign in to comment.