Skip to content

Commit

Permalink
add python complex interface
Browse files Browse the repository at this point in the history
  • Loading branch information
j8xixo12 committed Jan 5, 2025
1 parent fa52b10 commit b6042a6
Show file tree
Hide file tree
Showing 14 changed files with 496 additions and 36 deletions.
3 changes: 2 additions & 1 deletion cpp/modmesh/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ add_subdirectory(pilot)
add_subdirectory(inout)
add_subdirectory(serialization)
add_subdirectory(transform)
add_subdirectory(math)

if(USE_PYTEST_HELPER_BINDING)
add_subdirectory(testhelper)
Expand All @@ -50,7 +51,6 @@ endif() # USE_PYTEST_HELPER_BINDING
set(MODMESH_ROOT_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/modmesh.hpp
${CMAKE_CURRENT_SOURCE_DIR}/base.hpp
${CMAKE_CURRENT_SOURCE_DIR}/math.hpp
${CMAKE_CURRENT_SOURCE_DIR}/grid.hpp
CACHE FILEPATH "" FORCE)

Expand Down Expand Up @@ -95,6 +95,7 @@ set(MODMESH_TERMINAL_FILES
${MODMESH_TESTHELPER_FILES}
${MODMESH_SERIALIZATION_FILES}
${MODMESH_TRANSFORM_FILES}
${MODMESH_MATH_FILES}
CACHE FILEPATH "" FORCE)

set(MODMESH_GRAPHIC_FILES
Expand Down
23 changes: 23 additions & 0 deletions cpp/modmesh/math/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.16)

set(MODMESH_MATH_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/math.hpp
${CMAKE_CURRENT_SOURCE_DIR}/Complex.hpp
CACHE FILEPATH "" FORCE)

set(MODMESH_MATH_PYMODHEADERS
${CMAKE_CURRENT_SOURCE_DIR}/pymod/math_pymod.hpp
CACHE FILEPATH "" FORCE)

set(MODMESH_MATH_PYMODSOURCES
${CMAKE_CURRENT_SOURCE_DIR}/pymod/math_pymod.cpp
${CMAKE_CURRENT_SOURCE_DIR}/pymod/wrap_Complex.cpp
CACHE FILEPATH "" FORCE)

set(MODMESH_MATH_FILES
${MODMESH_MATH_HEADERS}
${MODMESH_MATH_PYMODHEADERS}
${MODMESH_MATH_PYMODSOURCES}
CACHE FILEPATH "" FORCE)

# vim: set ff=unix fenc=utf8 nobomb et sw=4 ts=4 sts=4:
56 changes: 26 additions & 30 deletions cpp/modmesh/math.hpp → cpp/modmesh/math/Complex.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
#pragma once

/*
* Copyright (c) 2019, Yung-Yu Chen <[email protected]>
* BSD 3-Clause License, see COPYING
* Copyright (c) 2025, Chun-Hsu Lai <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include <type_traits>
Expand All @@ -13,22 +34,6 @@ namespace modmesh

namespace detail
{

template <typename T>
inline constexpr T pow(T /*base*/, std::integral_constant<size_t, 0> /*unused*/) { return 1; }

template <typename T>
inline constexpr T pow(T base, std::integral_constant<size_t, 1> /*unused*/) { return base; }

template <typename T, size_t N>
inline constexpr T pow(T base, std::integral_constant<size_t, N> /*unused*/)
{
return pow(base, std::integral_constant<size_t, N - 1>()) * base;
}

template <typename T>
constexpr T pi_v = std::enable_if_t<std::is_floating_point_v<T>, T>(3.141592653589793238462643383279502884L);

template <typename T, typename = std::enable_if_t<std::is_arithmetic<T>::value>>
struct ComplexImpl
{
Expand Down Expand Up @@ -99,19 +104,10 @@ struct ComplexImpl
T real() const { return real_v; }
T imag() const { return imag_v; }
T norm() const { return real_v * real_v + imag_v * imag_v; }
}; /* end class ComplexImpl */
}; /* end struct ComplexImpl */

} /* end namespace detail */

template <size_t N, typename T>
inline constexpr T pow(T base)
{
return detail::pow(base, std::integral_constant<size_t, N>());
}

template <typename T>
constexpr T pi = detail::pi_v<T>;

template <typename T>
using Complex = detail::ComplexImpl<T>;

Expand Down
47 changes: 47 additions & 0 deletions cpp/modmesh/math/math.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once

/*
* Copyright (c) 2019, Yung-Yu Chen <[email protected]>
* BSD 3-Clause License, see COPYING
*/

#include <modmesh/math/Complex.hpp>

#include <type_traits>
#include <cmath>

namespace modmesh
{

namespace detail
{

template <typename T>
inline constexpr T pow(T /*base*/, std::integral_constant<size_t, 0> /*unused*/) { return 1; }

template <typename T>
inline constexpr T pow(T base, std::integral_constant<size_t, 1> /*unused*/) { return base; }

template <typename T, size_t N>
inline constexpr T pow(T base, std::integral_constant<size_t, N> /*unused*/)
{
return pow(base, std::integral_constant<size_t, N - 1>()) * base;
}

template <typename T>
constexpr T pi_v = std::enable_if_t<std::is_floating_point_v<T>, T>(3.141592653589793238462643383279502884L);

} /* end namespace detail */

template <size_t N, typename T>
inline constexpr T pow(T base)
{
return detail::pow(base, std::integral_constant<size_t, N>());
}

template <typename T>
constexpr T pi = detail::pi_v<T>;

} /* end namespace modmesh */

// vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4:
60 changes: 60 additions & 0 deletions cpp/modmesh/math/pymod/math_pymod.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2025, Chun-Hsu Lai <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include <modmesh/math/pymod/math_pymod.hpp>

namespace modmesh
{

namespace python
{

struct math_pymod_tag;

template <>
OneTimeInitializer<math_pymod_tag> & OneTimeInitializer<math_pymod_tag>::me()
{
static OneTimeInitializer<math_pymod_tag> instance;
return instance;
}

void initialize_math(pybind11::module & mod)
{
auto initialize_impl = [](pybind11::module & mod)
{
wrap_Complex(mod);
};

OneTimeInitializer<math_pymod_tag>::me()(mod, initialize_impl);
}

} /* end namespace python */

} /* end namespace modmesh */

// vim: set ff=unix fenc=utf8 nobomb et sw=4 ts=4 sts=4:
46 changes: 46 additions & 0 deletions cpp/modmesh/math/pymod/math_pymod.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2025, Chun-Hsu Lai <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include <pybind11/pybind11.h>

#include <modmesh/python/common.hpp>

namespace modmesh
{

namespace python
{

void initialize_math(pybind11::module & mod);
void wrap_Complex(pybind11::module & mod);

} /* end namespace python */

} /* end namespace modmesh */

// vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4:
97 changes: 97 additions & 0 deletions cpp/modmesh/math/pymod/wrap_Complex.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2025, Chun-Hsu Lai <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include <modmesh/math/pymod/math_pymod.hpp>

#include <modmesh/modmesh.hpp>

#include <pybind11/operators.h>

namespace modmesh
{

namespace python
{
template <typename T>
class MODMESH_PYTHON_WRAPPER_VISIBILITY WrapComplex
: public WrapBase<WrapComplex<T>, modmesh::Complex<T>, std::shared_ptr<modmesh::Complex<T>>>
{
using base_type = WrapBase<WrapComplex<T>, modmesh::Complex<T>, std::shared_ptr<modmesh::Complex<T>>>;
using wrapped_type = typename base_type::wrapped_type;
using value_type = T;

friend base_type;

WrapComplex(pybind11::module & mod, char const * pyname, char const * pydoc)
: WrapBase<WrapComplex<value_type>, modmesh::Complex<value_type>, std::shared_ptr<modmesh::Complex<value_type>>>(mod, pyname, pydoc)
{
namespace py = pybind11; // NOLINT(misc-unused-alias-decls)

(*this)
.def(
py::init(
[](const value_type & real_v, const value_type & imag_v)
{ return std::make_shared<wrapped_type>(real_v, imag_v); }),
py::arg("real_v"),
py::arg("imag_v"))
.def(
py::init(
[]()
{ return std::make_shared<wrapped_type>(); }))
.def(
py::init(
[](const wrapped_type & other)
{ return std::make_shared<wrapped_type>(other); }),
py::arg("other"))
.def(py::self + py::self) // NOLINT(misc-redundant-expression)
.def(py::self - py::self) // NOLINT(misc-redundant-expression)
.def(py::self * py::self) // NOLINT(misc-redundant-expression)
.def(py::self / value_type()) // NOLINT(misc-redundant-expression)
.def(py::self += py::self) // NOLINT(misc-redundant-expression)
.def(py::self -= py::self) // NOLINT(misc-redundant-expression)
.def_property_readonly("real", &wrapped_type::real)
.def_property_readonly("imag", &wrapped_type::imag)
.def("norm", &wrapped_type::norm)
.def("__complex__",
[](wrapped_type const & self)
{ return std::complex<T>(self.real(), self.imag()); });
}

}; /* end class WrapComplex */

void wrap_Complex(pybind11::module & mod)
{
WrapComplex<float>::commit(mod, "ComplexFloat32", "ComplexFloat32");
WrapComplex<double>::commit(mod, "ComplexFloat64", "ComplexFloat64");
}

} /* end namespace python */

} /* end namespace modmesh */

// vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4:
2 changes: 1 addition & 1 deletion cpp/modmesh/modmesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
*/

#include <modmesh/base.hpp>
#include <modmesh/math.hpp>
#include <modmesh/math/math.hpp>
#include <modmesh/buffer/buffer.hpp>
#include <modmesh/grid.hpp>
#include <modmesh/mesh/mesh.hpp>
Expand Down
2 changes: 1 addition & 1 deletion cpp/modmesh/onedim/Euler1DCore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

#include <modmesh/onedim/core.hpp>
#include <modmesh/base.hpp>
#include <modmesh/math.hpp>
#include <modmesh/math/math.hpp>
#include <modmesh/buffer/buffer.hpp>
#include <modmesh/toggle/profile.hpp>
#include <memory>
Expand Down
Loading

0 comments on commit b6042a6

Please sign in to comment.