Skip to content

Commit

Permalink
Merge pull request #182 from SimonRohou/codac2_dev
Browse files Browse the repository at this point in the history
CMake + SIVIA
  • Loading branch information
SimonRohou authored Jan 17, 2025
2 parents 6315e68 + 1ebc5ff commit 2c20d6e
Show file tree
Hide file tree
Showing 25 changed files with 156 additions and 22 deletions.
33 changes: 27 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,39 @@

if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
message(STATUS "Configuring ${PROJECT_NAME} in DEBUG mode as none was specified.")
if(MSVC)
add_compile_options(/MD) # Temporary fix to avoid debug vs release inconsistencies...
else()
add_compile_options(-O3)
endif()
endif()

if(FAST_RELEASE)
add_compile_definitions(FAST_RELEASE)
endif()

if(NOT WIN32)
string(ASCII 27 Esc)
set(COLOR_RED "${Esc}[31m")
set(COLOR_BLUE "${Esc}[36m")
set(COLOR_RESET "${Esc}[m")
else()
set(COLOR_RED "")
set(COLOR_BLUE "")
set(COLOR_RESET "")
endif()

message(STATUS "${COLOR_BLUE}Configuring ${PROJECT_NAME} in ${CMAKE_BUILD_TYPE} mode.${COLOR_RESET}")

if(FAST_RELEASE)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "${COLOR_RED}Option FAST_RELEASE cannot be used in Debug mode.${COLOR_RESET}")
else()
message(STATUS "${COLOR_BLUE}Option FAST_RELEASE enabled.${COLOR_RESET}")
endif()
else()
message(STATUS "Note: in Release build mode, the option FAST_RELEASE=ON would allow faster computations if enabled.")
endif()

if(MSVC)
add_compile_options(/W4)
Expand Down Expand Up @@ -115,11 +141,6 @@
# Compile sources
################################################################################

if(FAST_RELEASE)
add_compile_definitions(FAST_RELEASE)
message(STATUS "You are running Codac in fast release mode. (option -DCMAKE_BUILD_TYPE=Release is required)")
endif()

add_subdirectory(src) # C++ sources
add_subdirectory(doc) # documentation (Doxygen + Sphinx manual)

Expand Down
102 changes: 101 additions & 1 deletion doc/manual/development/info_dev.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _sec-dev-info:

Information for developers
==========================

Expand All @@ -21,4 +23,102 @@ To build this manual using Sphinx, follow these steps:
The generated website will be locally available in ``./build/doc/manual``.

To contribute and extend this manual, please consult the Sphinx documentation:
https://www.sphinx-doc.org
https://www.sphinx-doc.org

.. _sec-dev-info-binding:

Building a local Python binding for Codac
-----------------------------------------

You can compile Codac's Python binding binaries locally on your machine to take advantage of the library's latest features.
If you simply want to use the latest Codac release in Python, you can download the binaries directly from `PyPi <https://pypi.org/project/codac/>`_ or :ref:`follow the standard installation procedure <sec-install-py>`.

1. **Ensure the following prerequisites are met**:

- the prerequisites for the :ref:`C++ installation of Codac <sec-install-cpp-prerequisites>`.
- a recent `Doxygen <https://www.doxygen.nl>`_ version. On Linux systems, Debian packages are available:

.. code-block:: bash
sudo apt-get install -y doxygen
- a supported version of Python (>=3.6).

2. **Configure IBEX prior to compiling Codac**:

We recall that IBEX sources can be obtained with:

.. code-block:: bash
git clone -b master https://github.com/lebarsfa/ibex-lib.git $HOME/ibex-lib
You will need to compile both IBEX and Codac using the ``-fPIC`` options. This can be done with the following CMake configuration:

.. code-block:: bash
cd $HOME/ibex-lib/build
cmake -DCMAKE_CXX_FLAGS="-fPIC" -DCMAKE_C_FLAGS="-fPIC" -DCMAKE_INSTALL_PREFIX=$HOME/ibex-lib/build_install -DCMAKE_BUILD_TYPE=Release ..
make
make install
3. **Compile Codac with Python binding**:

We recall that Codac sources can be obtained with:

.. code-block:: bash
git clone https://github.com/codac-team/codac $HOME/codac
In addition to the ``-fPIC`` options, you will have to configure ``WITH_PYTHON=ON``. Note that the ``git submodule`` commands will automatically get the `pybind11 <https://pybind11.readthedocs.io>`_ files required for the binding.

.. code-block:: bash
cd $HOME/codac/build
# Get automatically pybind11 and eigen submodules:
git submodule init ; git submodule update
# Configure CMake
cmake -DCMAKE_CXX_FLAGS="-fPIC" -DCMAKE_C_FLAGS="-fPIC" -DWITH_PYTHON=ON -DCMAKE_INSTALL_PREFIX=$HOME/codac/build_install -DCMAKE_PREFIX_PATH=$HOME/ibex-lib/build_install -DCMAKE_BUILD_TYPE=Release ..
make
4. **Configure your Python environment**:

Finally, you need to configure your system so that Python can find access to your Codac binding binaries:

.. code-block:: bash
cd $HOME/codac/build/python/python_package
python setup.py develop --user
5. **Verify the installation** (optional):

To ensure that the installation has worked properly, the unit tests of the library can be run:

.. code-block:: bash
python -m unittest discover codac.tests
6. **Try an example** (optional):

You may want to try Codac in Python by running one of the proposed examples. After the installation, you can run the following commands:

.. code-block:: bash
cd $HOME/codac/examples/03_sivia
python main.py
Note that before executing the example, you will have to launch the VIBes viewer.
You should obtain a graphical output corresponding to a set inversion.


.. admonition:: About the use of Doxygen

Doxygen software extracts C++ documentation from header files into XML format. We then convert this data into docstring format before embedding it into the binding binaries. In this way, the writing of the documentation is centralized in a single location in the C++ header files.


.. admonition:: For admins

The command for uploading the generated wheels on PyPi is:

.. code-block:: bash
python -m twine upload --repository pypi *
11 changes: 6 additions & 5 deletions doc/manual/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ Welcome to the Codac website.
:caption: User manual
:maxdepth: 2

installation/index.rst
intervals/index.rst
ellipsoids/index.rst
visualization/index.rst
extensions/index.rst
manual/installation/index.rst
manual/intervals/index.rst
manual/visualization/index.rst
manual/extensions/index.rst

.. manual/ellipsoids/index.rst
.. linear/index.rst
.. functions/index.rst
Expand Down
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ If you prefer to use the latest development version, you can install Codac by co
Steps
~~~~~

.. _sec-install-cpp-prerequisites:

1. **Ensure the following prerequisites are met**:

- A C++ compiler supporting C++20 or later (*e.g.*, GCC 11.0+, Clang 13.0+).
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ Depending on your configuration, you may encounter difficulties when installing
Depending on the way Python was installed, the path to specify after ``--target`` may differ, *e.g.* if Python was installed from https://www.python.org/ftp/python/3.10.4/python-3.10.4-macos11.pkg, it may be ``/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages``. Otherwise, run ``python3 -m site`` to check the ``site-packages`` full path in ``sys.path`` list. Also, the value ``10_9`` may need to be changed to ``10_14`` (or possibly another value) for some Python versions.


Finally, note that unsupported configurations can still probably follow the instructions from :ref:`Installing local Python binding <sec-manual-dev>`, for building the Codac Python binding locally on your machine.
Finally, note that unsupported configurations can still probably follow the instructions from :ref:`sec-dev-info-binding`, for building the Codac Python binding locally on your machine.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion examples/03_sivia/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ int main()
{
VectorVar x(2);
AnalyticFunction f { {x}, sqr(x[0])*sin(sqr(x[0])+sqr(x[1]))-sqr(x[1]) };
auto p = sivia({{-5,5},{-4,4}}, f, {0,oo}, 1e-2);
auto p = sivia({{-5,5},{-4,4}}, f, {0,oo}, 1e-2, true);
DefaultView::draw_paving(p);
}
2 changes: 1 addition & 1 deletion examples/03_sivia/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

x = VectorVar(2)
f = AnalyticFunction([x], sqr(x[0])*sin(sqr(x[0])+sqr(x[1]))-sqr(x[1]))
p = sivia([[-5,5],[-4,4]], f, [0,oo], 1e-2)
p = sivia([[-5,5],[-4,4]], f, [0,oo], 1e-2, True)
DefaultView.draw_paving(p)
12 changes: 6 additions & 6 deletions python/src/core/paver/codac2_py_pave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void export_pave(py::module& m)
"x"_a, "s"_a, "eps"_a);

m.def("sivia",
[](const IntervalVector& x, const py::object& f, const py::object& y, double eps)
[](const IntervalVector& x, const py::object& f, const py::object& y, double eps, bool verbose)
{
if(!is_instance<AnalyticFunction<ScalarType>>(f)
&& !is_instance<AnalyticFunction<VectorType>>(f)
Expand All @@ -40,14 +40,14 @@ void export_pave(py::module& m)
}

if(is_instance<AnalyticFunction<ScalarType>>(f))
return sivia(x, cast<AnalyticFunction<ScalarType>>(f), y.cast<Interval>(), eps);
return sivia(x, cast<AnalyticFunction<ScalarType>>(f), y.cast<Interval>(), eps, verbose);

else if(is_instance<AnalyticFunction<VectorType>>(f))
return sivia(x, cast<AnalyticFunction<VectorType>>(f), y.cast<IntervalVector>(), eps);
return sivia(x, cast<AnalyticFunction<VectorType>>(f), y.cast<IntervalVector>(), eps, verbose);

else
return sivia(x, cast<AnalyticFunction<MatrixType>>(f), y.cast<IntervalMatrix>(), eps);
return sivia(x, cast<AnalyticFunction<MatrixType>>(f), y.cast<IntervalMatrix>(), eps, verbose);
},
PAVINGINOUT_SIVIA_CONST_INTERVALVECTOR_REF_CONST_ANALYTICFUNCTION_Y_REF_CONST_TYPENAME_Y_DOMAIN_REF_DOUBLE,
"x"_a, "f"_a, "y"_a, "eps"_a);
PAVINGINOUT_SIVIA_CONST_INTERVALVECTOR_REF_CONST_ANALYTICFUNCTION_Y_REF_CONST_TYPENAME_Y_DOMAIN_REF_DOUBLE_BOOL,
"x"_a, "f"_a, "y"_a, "eps"_a, "verbose"_a=false);
}
12 changes: 11 additions & 1 deletion src/core/paver/codac2_pave.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ namespace codac2
PavingInOut pave(const IntervalVector& x, const SepBase& s, double eps);

template<typename Y>
PavingInOut sivia(const IntervalVector& x, const AnalyticFunction<Y>& f, const typename Y::Domain& y, double eps)
PavingInOut sivia(const IntervalVector& x, const AnalyticFunction<Y>& f, const typename Y::Domain& y, double eps, bool verbose = false)
{
clock_t t_start = clock();
Index n_inner = 0, n_boundary = 0;

PavingInOut p(x);
std::list<std::shared_ptr<PavingInOut_Node>> l { p.tree() };

Expand All @@ -38,7 +41,10 @@ namespace codac2
auto eval = f.eval(n->unknown());

if(eval.is_subset(y))
{
std::get<1>(n->boxes()).set_empty();
n_inner++;
}

else if(!eval.intersects(y))
std::get<0>(n->boxes()).set_empty();
Expand All @@ -48,9 +54,13 @@ namespace codac2
n->bisect();
l.push_back(n->left());
l.push_back(n->right());
n_boundary++;
}
}

if(verbose)
printf("Computation time: %.4fs, %ld inner boxes, %ld boundary boxes\n",
(double)(clock()-t_start)/CLOCKS_PER_SEC, n_inner, n_boundary);
return p;
}
}

0 comments on commit 2c20d6e

Please sign in to comment.