From c7f9f572a626895fc128ff06587ed45728108e41 Mon Sep 17 00:00:00 2001 From: Maksym Zhelyeznyakov Date: Sat, 16 Aug 2025 16:16:11 +0200 Subject: [PATCH] added licence files and removed py files --- example/autodiff_reverse_black_scholes.cpp | 4 + ...reverse_mode_linear_regression_example.cpp | 4 + test/generate_cpp_derivative_expr.py | 92 ------------- test/generate_cpp_derivative_expr.py~ | 57 -------- test/generate_cpp_derivative_expr2.py | 94 ------------- ...enerate_cpp_derivative_expr_gamma_ratio.py | 128 ------------------ ...t_reverse_mode_autodiff_basic_math_ops.cpp | 14 +- ...rse_mode_autodiff_comparison_operators.cpp | 4 + ...est_reverse_mode_autodiff_constructors.cpp | 5 + ..._reverse_mode_autodiff_error_functions.cpp | 4 + ...se_mode_autodiff_flat_linear_allocator.cpp | 4 + ...test_reverse_mode_autodiff_stl_support.cpp | 4 + 12 files changed, 33 insertions(+), 381 deletions(-) delete mode 100644 test/generate_cpp_derivative_expr.py delete mode 100644 test/generate_cpp_derivative_expr.py~ delete mode 100644 test/generate_cpp_derivative_expr2.py delete mode 100644 test/generate_cpp_derivative_expr_gamma_ratio.py diff --git a/example/autodiff_reverse_black_scholes.cpp b/example/autodiff_reverse_black_scholes.cpp index e02069a47..c52fec317 100644 --- a/example/autodiff_reverse_black_scholes.cpp +++ b/example/autodiff_reverse_black_scholes.cpp @@ -1,3 +1,7 @@ +// Copyright Maksym Zhelyenzyakov 2025-2026. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) #include using namespace boost::math::differentiation::reverse_mode; diff --git a/example/reverse_mode_linear_regression_example.cpp b/example/reverse_mode_linear_regression_example.cpp index e6ba5039c..cb69daee8 100644 --- a/example/reverse_mode_linear_regression_example.cpp +++ b/example/reverse_mode_linear_regression_example.cpp @@ -1,3 +1,7 @@ +// Copyright Maksym Zhelyenzyakov 2025-2026. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) #include #include #include diff --git a/test/generate_cpp_derivative_expr.py b/test/generate_cpp_derivative_expr.py deleted file mode 100644 index 4a9226e52..000000000 --- a/test/generate_cpp_derivative_expr.py +++ /dev/null @@ -1,92 +0,0 @@ -from sympy import symbols, simplify, ccode -from sympy.tensor.array import derive_by_array -import sys - -def generate_cpp_tensor(expr, vars, order): - derivatives = expr - for _ in range(order): - derivatives = derive_by_array(derivatives, vars) - - # Flatten tensor for variable assignment - def flatten(tensor): - if not hasattr(tensor, '__iter__') or isinstance(tensor, (str, bytes)): - return [tensor] - if hasattr(tensor, 'tolist'): - tensor = tensor.tolist() - flat_list = [] - for e in tensor: - flat_list.extend(flatten(e)) - return flat_list - - flat_derivs = flatten(derivatives) - - # Generate multi-indices for all tensor elements - def generate_indices(d, order): - if order == 0: - return [[]] - else: - smaller = generate_indices(d, order - 1) - return [s + [i] for s in smaller for i in range(d)] - - all_indices = generate_indices(len(vars), order) - - # Generate variable names like f_x, f_xy, f_xyz, etc. - var_names = [] - for idx in all_indices: - suffix = ''.join(str(vars[i]) for i in idx) - var_names.append(f"f_{suffix}") - - # Assign each derivative to a separate variable - code_lines = [] - for var_name, expr in zip(var_names, flat_derivs): - simplified = simplify(expr) - c_expr = ccode(simplified) - code_lines.append(f" T {var_name} = static_cast({c_expr});") - - # Now build nested vector initialization recursively matching the shape of derivatives - def build_nested_vector(tensor, level=0, index_start=0): - if level == order: - # At the scalar level, return the variable name at flat index - return var_names[index_start], 1 - else: - # tensor is iterable, build vector of sub-elements - if hasattr(tensor, 'tolist'): - tensor = tensor.tolist() - elems = [] - count = 0 - for t in tensor: - s, c = build_nested_vector(t, level+1, index_start + count) - elems.append(s) - count += c - return '{ ' + ', '.join(elems) + ' }', count - - nested_vector_str, _ = build_nested_vector(derivatives) - - # Compose return type string depending on order - def vector_type(level): - if level == 0: - return "T" - else: - return f"std::vector<{vector_type(level-1)}>" - - return_type = vector_type(order) - - # Compose final C++ function body with separate variable assignments and nested return vector - body = '\n'.join(code_lines) + f'\n return {nested_vector_str};' - - return return_type, body - -if __name__ == "__main__": - x, y, z = symbols('x y z') - vars = [x, y] - f = x*x*x*x*y*y*y*y - order = int(sys.argv[1]) if len(sys.argv) > 1 else 2 - - print(f"// Order-{order} derivative of f(x, y) = {f}") - - ret_type, func_body = generate_cpp_tensor(f, vars, order) - - print(f"template") - print(f"{ret_type} gf_a(T x, T y) {{") - print(func_body) - print("}") diff --git a/test/generate_cpp_derivative_expr.py~ b/test/generate_cpp_derivative_expr.py~ deleted file mode 100644 index bc330750b..000000000 --- a/test/generate_cpp_derivative_expr.py~ +++ /dev/null @@ -1,57 +0,0 @@ -from sympy import quo -from sympy import symbols, simplify, ccode -from sympy.tensor.array import derive_by_array -import sys - -def generate_cpp_tensor(expr, vars, order): - derivatives = expr - for _ in range(order): - derivatives = derive_by_array(derivatives, vars) - - def flatten(tensor): - if not hasattr(tensor, '__iter__') or isinstance(tensor, (str, bytes)): - return [tensor] - if hasattr(tensor, 'tolist'): - tensor = tensor.tolist() - flat_list = [] - for e in tensor: - flat_list.extend(flatten(e)) - return flat_list - - flat_derivs = flatten(derivatives) - - def index_to_suffix(idx): - return ''.join([str(vars[i]) for i in idx]) - - def generate_indices(d, order): - if order == 0: - return [[]] - else: - smaller = generate_indices(d, order - 1) - return [s + [i] for s in smaller for i in range(d)] - - all_indices = generate_indices(len(vars), order) - - var_names = [] - for idx in all_indices: - suffix = ''.join(str(vars[i]) for i in idx) - var_names.append(f"f_{suffix}") - code_lines = [] - for var_name, expr in zip(var_names, flat_derivs): - simplified = simplify(expr) - c_expr = ccode(simplified) - code_lines.append(f" T {var_name} = static_cast({c_expr});") - return_line = " return { " + ', '.join(var_names) + " };" - return '\n'.join(code_lines) + '\n' + return_line - -if __name__ == "__main__": - x, y, z = symbols('x y z') - vars = [x, y] - f = x/(y+x)*y/(x-y) - order = int(sys.argv[1]) if len(sys.argv) > 1 else 2 - - print(f"// Order-{order} derivative of f(x, y, z) = {f}") - print("template") - print("std::vector gf_a(T x, T y) {") - print(generate_cpp_tensor(f, vars, order)) - print("}") diff --git a/test/generate_cpp_derivative_expr2.py b/test/generate_cpp_derivative_expr2.py deleted file mode 100644 index 7d1fe03f5..000000000 --- a/test/generate_cpp_derivative_expr2.py +++ /dev/null @@ -1,94 +0,0 @@ -from sympy import symbols, simplify, ccode -from sympy.tensor.array import derive_by_array -import sys -import math -import sympy -def generate_cpp_tensor(expr, vars, order): - derivatives = expr - for _ in range(order): - derivatives = derive_by_array(derivatives, vars) - - # Flatten tensor for variable assignment - def flatten(tensor): - if not hasattr(tensor, '__iter__') or isinstance(tensor, (str, bytes)): - return [tensor] - if hasattr(tensor, 'tolist'): - tensor = tensor.tolist() - flat_list = [] - for e in tensor: - flat_list.extend(flatten(e)) - return flat_list - - flat_derivs = flatten(derivatives) - - # Generate multi-indices for all tensor elements - def generate_indices(d, order): - if order == 0: - return [[]] - else: - smaller = generate_indices(d, order - 1) - return [s + [i] for s in smaller for i in range(d)] - - all_indices = generate_indices(len(vars), order) - - # Generate variable names like f_x, f_xy, f_xyz, etc. - var_names = [] - for idx in all_indices: - suffix = ''.join(str(vars[i]) for i in idx) - var_names.append(f"f_{suffix}") - - # Assign each derivative to a separate variable - code_lines = [] - for var_name, expr in zip(var_names, flat_derivs): - simplified = simplify(expr) - c_expr = ccode(simplified) - code_lines.append(f" T {var_name} = static_cast({c_expr});") - - # Now build nested vector initialization recursively matching the shape of derivatives - def build_nested_vector(tensor, level=0, index_start=0): - if level == order: - # At the scalar level, return the variable name at flat index - return var_names[index_start], 1 - else: - # tensor is iterable, build vector of sub-elements - if hasattr(tensor, 'tolist'): - tensor = tensor.tolist() - elems = [] - count = 0 - for t in tensor: - s, c = build_nested_vector(t, level+1, index_start + count) - elems.append(s) - count += c - return '{ ' + ', '.join(elems) + ' }', count - - nested_vector_str, _ = build_nested_vector(derivatives) - - # Compose return type string depending on order - def vector_type(level): - if level == 0: - return "T" - else: - return f"std::vector<{vector_type(level-1)}>" - - return_type = vector_type(order) - - # Compose final C++ function body with separate variable assignments and nested return vector - body = '\n'.join(code_lines) + f'\n return {nested_vector_str};' - - return return_type, body - -if __name__ == "__main__": - x, y, z = symbols('x y z') - vars = [x, y] - #f = sympy.log(1+sympy.sqrt(x**2))*sympy.exp(y) + sympy.Pow(x+y,2.5) - sympy.sqrt(1+x*y) - f = x/(y+x)*y/(x-y) - order = int(sys.argv[1]) if len(sys.argv) > 1 else 2 - - print(f"// Order-{order} derivative of f(x, y) = {f}") - - ret_type, func_body = generate_cpp_tensor(f, vars, order) - - print(f"template") - print(f"{ret_type} gf_a(T x, T y) {{") - print(func_body) - print("}") diff --git a/test/generate_cpp_derivative_expr_gamma_ratio.py b/test/generate_cpp_derivative_expr_gamma_ratio.py deleted file mode 100644 index 01f167199..000000000 --- a/test/generate_cpp_derivative_expr_gamma_ratio.py +++ /dev/null @@ -1,128 +0,0 @@ -from sympy import symbols, simplify, ccode, Function -from sympy.tensor.array import derive_by_array -from sympy.printing.cxx import CXX11CodePrinter -import sys -import math -import sympy - -# Define a custom C++ code printer to handle special functions -class MyCCodePrinter(CXX11CodePrinter): - """ - Custom printer that handles specific SymPy functions and maps them - to C++ equivalents. - """ - def _print_GammaFunction(self, expr): - """ - Custom handler for sympy.gamma. Maps it to std::tgamma from . - """ - arg_code = self._print(expr.args[0]) - # Use std::tgamma from the library, which requires C++11 or later. - return f"std::tgamma({arg_code})" - -def my_ccode(expr, **settings): - """ - A wrapper function to use our custom C++ code printer. - """ - return MyCCodePrinter(settings).doprint(expr) - -def generate_cpp_tensor(expr, vars, order): - """ - Generates C++ code for a tensor of derivatives of a given function. - - Args: - expr (sympy.Expr): The function to differentiate. - vars (list of sympy.Symbol): The variables to differentiate with respect to. - order (int): The order of the derivatives. - - Returns: - tuple: A tuple containing the C++ return type and the function body. - """ - derivatives = expr - for _ in range(order): - derivatives = derive_by_array(derivatives, vars) - - # Flatten tensor for variable assignment - def flatten(tensor): - if not hasattr(tensor, '__iter__') or isinstance(tensor, (str, bytes)): - return [tensor] - if hasattr(tensor, 'tolist'): - tensor = tensor.tolist() - flat_list = [] - for e in tensor: - flat_list.extend(flatten(e)) - return flat_list - - flat_derivs = flatten(derivatives) - - # Generate multi-indices for all tensor elements - def generate_indices(d, order): - if order == 0: - return [[]] - else: - smaller = generate_indices(d, order - 1) - return [s + [i] for s in smaller for i in range(d)] - - all_indices = generate_indices(len(vars), order) - - # Generate variable names like f_x, f_xy, f_xyz, etc. - var_names = [] - for idx in all_indices: - suffix = ''.join(str(vars[i]) for i in idx) - var_names.append(f"f_{suffix}") - - # Assign each derivative to a separate variable - code_lines = [] - for var_name, expr in zip(var_names, flat_derivs): - simplified = simplify(expr) - # Use our custom code generator here - c_expr = my_ccode(simplified) - code_lines.append(f" T {var_name} = static_cast({c_expr});") - - # Now build nested vector initialization recursively matching the shape of derivatives - def build_nested_vector(tensor, level=0, index_start=0): - if level == order: - # At the scalar level, return the variable name at flat index - return var_names[index_start], 1 - else: - # tensor is iterable, build vector of sub-elements - if hasattr(tensor, 'tolist'): - tensor = tensor.tolist() - elems = [] - count = 0 - for t in tensor: - s, c = build_nested_vector(t, level+1, index_start + count) - elems.append(s) - count += c - return '{ ' + ', '.join(elems) + ' }', count - - nested_vector_str, _ = build_nested_vector(derivatives) - - # Compose return type string depending on order - def vector_type(level): - if level == 0: - return "T" - else: - return f"std::vector<{vector_type(level-1)}>" - - return_type = vector_type(order) - - # Compose final C++ function body with separate variable assignments and nested return vector - body = '\n'.join(code_lines) + f'\n return {nested_vector_str};' - - return return_type, body - -if __name__ == "__main__": - x, y = symbols('x y') - vars = [x, y] - # Here is the function using sympy.gamma - f = sympy.gamma(2 * x) / sympy.gamma(y * x) - order = int(sys.argv[1]) if len(sys.argv) > 1 else 2 - - print(f"// Order-{order} derivative of f(x, y) = {f}") - - ret_type, func_body = generate_cpp_tensor(f, vars, order) - - print(f"template") - print(f"{ret_type} gf_a(T x, T y) {{") - print(func_body) - print("}") diff --git a/test/test_reverse_mode_autodiff_basic_math_ops.cpp b/test/test_reverse_mode_autodiff_basic_math_ops.cpp index 90bcf082f..c2cc70003 100644 --- a/test/test_reverse_mode_autodiff_basic_math_ops.cpp +++ b/test/test_reverse_mode_autodiff_basic_math_ops.cpp @@ -1,13 +1,7 @@ -/*#include -using namespace boost::math::differentiation::reverse_mode; -int main() -{ - rvar x = 1.5; - auto z = x*x*x*x*x; - rvarzz(z); - zz.backward(); - std::cout< diff --git a/test/test_reverse_mode_autodiff_comparison_operators.cpp b/test/test_reverse_mode_autodiff_comparison_operators.cpp index 85b869003..1b32b5d63 100644 --- a/test/test_reverse_mode_autodiff_comparison_operators.cpp +++ b/test/test_reverse_mode_autodiff_comparison_operators.cpp @@ -1,3 +1,7 @@ +// Copyright Maksym Zhelyenzyakov 2025-2026. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) #include "test_autodiff_reverse.hpp" BOOST_AUTO_TEST_SUITE(test_comparison_operators) using namespace rdiff; diff --git a/test/test_reverse_mode_autodiff_constructors.cpp b/test/test_reverse_mode_autodiff_constructors.cpp index e5e2a73b7..d62b12a4f 100644 --- a/test/test_reverse_mode_autodiff_constructors.cpp +++ b/test/test_reverse_mode_autodiff_constructors.cpp @@ -1,3 +1,8 @@ +// Copyright Maksym Zhelyenzyakov 2025-2026. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + #include "test_autodiff_reverse.hpp" BOOST_AUTO_TEST_SUITE(explicit_rvar_constructors) diff --git a/test/test_reverse_mode_autodiff_error_functions.cpp b/test/test_reverse_mode_autodiff_error_functions.cpp index fa086a887..d96aaba79 100644 --- a/test/test_reverse_mode_autodiff_error_functions.cpp +++ b/test/test_reverse_mode_autodiff_error_functions.cpp @@ -1,3 +1,7 @@ +// Copyright Maksym Zhelyenzyakov 2025-2026. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) #include "test_autodiff_reverse.hpp" #include #include diff --git a/test/test_reverse_mode_autodiff_flat_linear_allocator.cpp b/test/test_reverse_mode_autodiff_flat_linear_allocator.cpp index 7d6695ec4..a2c2cfec8 100644 --- a/test/test_reverse_mode_autodiff_flat_linear_allocator.cpp +++ b/test/test_reverse_mode_autodiff_flat_linear_allocator.cpp @@ -1,3 +1,7 @@ +// Copyright Maksym Zhelyenzyakov 2025-2026. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) #include "test_autodiff_reverse.hpp" #include BOOST_AUTO_TEST_SUITE(test_flat_linear_allocator) diff --git a/test/test_reverse_mode_autodiff_stl_support.cpp b/test/test_reverse_mode_autodiff_stl_support.cpp index 85d5c30c3..ee27617c0 100644 --- a/test/test_reverse_mode_autodiff_stl_support.cpp +++ b/test/test_reverse_mode_autodiff_stl_support.cpp @@ -1,3 +1,7 @@ +// Copyright Maksym Zhelyenzyakov 2025-2026. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) #include "test_autodiff_reverse.hpp" #include #include