Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
O
outils-dev-log
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
3
Issues
3
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Matthieu Boileau
outils-dev-log
Commits
054051ce
Commit
054051ce
authored
Apr 25, 2019
by
Matthieu Boileau
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update tp6/exercice2
plot moved to external function
parent
1fb66d71
Pipeline
#4003
passed with stages
in 1 minute and 59 seconds
Changes
11
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
128 additions
and
1794 deletions
+128
-1794
tp6/exercice2/Makefile
tp6/exercice2/Makefile
+0
-17
tp6/exercice2/include/graphe.hpp
tp6/exercice2/include/graphe.hpp
+21
-6
tp6/exercice2/include/modele_graphe.hpp
tp6/exercice2/include/modele_graphe.hpp
+8
-2
tp6/exercice2/include/modele_seir.hpp
tp6/exercice2/include/modele_seir.hpp
+2
-2
tp6/exercice2/include/plot.hpp
tp6/exercice2/include/plot.hpp
+9
-0
tp6/exercice2/include/solveur_temps.hpp
tp6/exercice2/include/solveur_temps.hpp
+6
-4
tp6/exercice2/src/ext/matplotlibcpp.h
tp6/exercice2/src/ext/matplotlibcpp.h
+0
-1685
tp6/exercice2/src/main.cpp
tp6/exercice2/src/main.cpp
+16
-23
tp6/exercice2/src/modele.cpp
tp6/exercice2/src/modele.cpp
+1
-1
tp6/exercice2/src/plot.cpp
tp6/exercice2/src/plot.cpp
+59
-0
tp6/exercice2/src/solveur_temps.cpp
tp6/exercice2/src/solveur_temps.cpp
+6
-54
No files found.
tp6/exercice2/Makefile
deleted
100644 → 0
View file @
1fb66d71
CC
=
g++
CC_FLAGS
=
-std
=
c++11
-Wall
EXEC_NAME
=
main
OBJ_FILES
=
main.o modele.o modele_sir.o modele_seir.o solveur_temps.o euler_ex.o rk2.o graphe.o
all
:
$(EXEC_NAME)
clean
:
rm
-f
$(EXEC_NAME)
$(OBJ_FILES)
$(EXEC_NAME)
:
$(OBJ_FILES)
$(CC)
$(CC_FLAGS)
-o
$(EXEC_NAME)
$(OBJ_FILES)
%.o
:
%.cpp %.hpp
$(CC)
$(CC_FLAGS)
-o
$@
-c
$<
main.o
:
main.cpp modele_graphe.hpp
tp6/exercice2/include/graphe.hpp
View file @
054051ce
...
...
@@ -39,15 +39,23 @@ public:
template
<
class
T
>
class
noeud
{
T
val
;
int
number
;
string
name
;
vector
<
voisin
>
voisins
;
public:
noeud
(){
val
=
T
();
number
=
0
;
name
=
""
;
};
noeud
(
string
n
){
val
=
T
();
number
=
0
;
name
=
n
;
};
noeud
(
const
noeud
&
n
){
val
=
n
.
val
;
number
=
n
.
number
;
name
=
n
.
name
;
voisins
=
n
.
voisins
;
};
~
noeud
(){
...
...
@@ -59,7 +67,9 @@ public:
void
ajout_num
(
int
n
){
number
=
n
;
}
void
ajout_nom
(
string
n
){
name
=
n
;
}
vector
<
voisin
>
get_voisins
()
{
return
voisins
;
}
...
...
@@ -68,6 +78,10 @@ public:
return
val
;
}
string
get_nom
()
{
return
name
;
}
int
num
(){
return
number
;
}
...
...
@@ -90,15 +104,16 @@ public:
noeud
&
operator
=
(
const
noeud
&
n
){
if
(
this
!=
&
n
){
voisins
.
clear
();
val
=
n
.
val
;
voisins
=
n
.
voisins
;
number
=
n
.
number
;
val
=
n
.
val
;
voisins
=
n
.
voisins
;
number
=
n
.
number
;
name
=
n
.
name
;
}
return
*
this
;
}
bool
operator
==
(
const
noeud
&
n
){
bool
res
=
false
;
res
=
(
val
==
n
.
val
)
&&
(
n
.
number
==
number
);
res
=
(
val
==
n
.
val
)
&&
(
n
.
number
==
number
)
&&
(
n
.
name
==
name
)
;
return
res
;
}
...
...
@@ -156,7 +171,7 @@ template <class T> ostream & operator<<(ostream & out, noeud<T> & x){
vector
<
voisin
>::
iterator
ii
;
int
nvoisins
=
0
;
out
<<
" noeu
f
numero: "
<<
x
.
number
<<
" de valeur "
<<
x
.
val
<<
endl
;
out
<<
" noeu
d "
<<
x
.
name
<<
"
numero: "
<<
x
.
number
<<
" de valeur "
<<
x
.
val
<<
endl
;
if
(
x
.
voisins
.
size
()
!=
0
){
out
<<
">>>>> liste des voisins:"
<<
endl
;
for
(
ii
=
x
.
voisins
.
begin
();
ii
!=
x
.
voisins
.
end
();
ii
++
){
...
...
tp6/exercice2/include/modele_graphe.hpp
View file @
054051ce
...
...
@@ -12,9 +12,10 @@ class ModeleGraphe : public Modele {
// Graphe sur lequel le modèle d'épidémie sera appliqué
graphe
<
T
>
*
m_graphe
;
public:
ModeleGraphe
();
ModeleGraphe
();
ModeleGraphe
(
graphe
<
T
>
*
g
);
~
ModeleGraphe
();
~
ModeleGraphe
();
graphe
<
T
>
*
get_graphe
();
// Calcule les conditions initiales du modèle en fonction des conditions initiales
// du modèle associé à chaque noeud du graphe.
void
setInitialValue
();
...
...
@@ -43,6 +44,11 @@ template<class T>
ModeleGraphe
<
T
>::~
ModeleGraphe
()
{
}
template
<
class
T
>
graphe
<
T
>
*
ModeleGraphe
<
T
>::
get_graphe
()
{
return
m_graphe
;
}
template
<
class
T
>
void
ModeleGraphe
<
T
>::
setInitialValue
()
{
// création du vecteur contenant les conditions initiale :
...
...
tp6/exercice2/include/modele_seir.hpp
View file @
054051ce
...
...
@@ -7,7 +7,7 @@
class
ModeleSeir
:
public
Modele
{
private:
double
m_beta
;
double
m_gamma
;
double
m_gamma
;
double
m_alpha
;
double
m_nu
;
double
m_mu
;
...
...
@@ -16,7 +16,7 @@ class ModeleSeir : public Modele {
ModeleSeir
();
ModeleSeir
(
double
beta
,
double
gamma
,
double
alpha
,
double
nu
,
double
mu
,
double
g
);
~
ModeleSeir
()
{}
double
g
();
double
g
();
std
::
vector
<
double
>
flux
(
std
::
vector
<
double
>
);
};
...
...
tp6/exercice2/include/plot.hpp
0 → 100644
View file @
054051ce
#ifndef PLOT_HPP
#define PLOT_HPP
#include "solveur_temps.hpp"
#include "matplotlibcpp.h"
void
plotSolutionNoeud
(
const
int
,
const
std
::
string
&
,
SolveurTemps
*
);
#endif
tp6/exercice2/include/solveur_temps.hpp
View file @
054051ce
...
...
@@ -4,7 +4,6 @@
#include <vector>
#include "modele.hpp"
#include "matplotlibcpp.h"
class
SolveurTemps
{
protected:
...
...
@@ -25,10 +24,13 @@ class SolveurTemps {
// Calcule la valeur initiale du vecteur solution
void
setInitialValue
();
// Renvoie le temps correspondant au dernier vecteur de m_variablesTemps
double
getCurrentTime
();
double
getCurrentTime
();
// Renvoie le pas de temps
double
get_dt
();
// Renvoie la dernière solution calculée
std
::
vector
<
double
>
getSolutionCurrentTime
();
void
plotSolution
(
const
int
inoeud
,
const
std
::
string
&
);
std
::
vector
<
double
>
getSolutionCurrentTime
();
// Renvoie les solutions pour chaque pas de temps
std
::
vector
<
std
::
vector
<
double
>
>
getVariablesTime
();
};
#endif
tp6/exercice2/src/ext/matplotlibcpp.h
deleted
100644 → 0
View file @
1fb66d71
#pragma once
#include <vector>
#include <map>
#include <array>
#include <numeric>
#include <algorithm>
#include <stdexcept>
#include <iostream>
#include <cstdint> // <cstdint> requires c++11 support
#include <functional>
#include <Python.h>
#ifndef WITHOUT_NUMPY
# define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
# include <numpy/arrayobject.h>
#endif // WITHOUT_NUMPY
#if PY_MAJOR_VERSION >= 3
# define PyString_FromString PyUnicode_FromString
# define PyInt_FromLong PyLong_FromLong
# define PyString_FromString PyUnicode_FromString
#endif
namespace
matplotlibcpp
{
namespace
detail
{
static
std
::
string
s_backend
;
struct
_interpreter
{
PyObject
*
s_python_function_show
;
PyObject
*
s_python_function_close
;
PyObject
*
s_python_function_draw
;
PyObject
*
s_python_function_pause
;
PyObject
*
s_python_function_save
;
PyObject
*
s_python_function_figure
;
PyObject
*
s_python_function_fignum_exists
;
PyObject
*
s_python_function_plot
;
PyObject
*
s_python_function_quiver
;
PyObject
*
s_python_function_semilogx
;
PyObject
*
s_python_function_semilogy
;
PyObject
*
s_python_function_loglog
;
PyObject
*
s_python_function_fill
;
PyObject
*
s_python_function_fill_between
;
PyObject
*
s_python_function_hist
;
PyObject
*
s_python_function_scatter
;
PyObject
*
s_python_function_subplot
;
PyObject
*
s_python_function_legend
;
PyObject
*
s_python_function_xlim
;
PyObject
*
s_python_function_ion
;
PyObject
*
s_python_function_ginput
;
PyObject
*
s_python_function_ylim
;
PyObject
*
s_python_function_title
;
PyObject
*
s_python_function_axis
;
PyObject
*
s_python_function_xlabel
;
PyObject
*
s_python_function_ylabel
;
PyObject
*
s_python_function_xticks
;
PyObject
*
s_python_function_yticks
;
PyObject
*
s_python_function_grid
;
PyObject
*
s_python_function_clf
;
PyObject
*
s_python_function_errorbar
;
PyObject
*
s_python_function_annotate
;
PyObject
*
s_python_function_tight_layout
;
PyObject
*
s_python_colormap
;
PyObject
*
s_python_empty_tuple
;
PyObject
*
s_python_function_stem
;
PyObject
*
s_python_function_xkcd
;
PyObject
*
s_python_function_text
;
PyObject
*
s_python_function_suptitle
;
PyObject
*
s_python_function_bar
;
PyObject
*
s_python_function_subplots_adjust
;
/* For now, _interpreter is implemented as a singleton since its currently not possible to have
multiple independent embedded python interpreters without patching the python source code
or starting a separate process for each.
http://bytes.com/topic/python/answers/793370-multiple-independent-python-interpreters-c-c-program
*/
static
_interpreter
&
get
()
{
static
_interpreter
ctx
;
return
ctx
;
}
private:
#ifndef WITHOUT_NUMPY
# if PY_MAJOR_VERSION >= 3
void
*
import_numpy
()
{
import_array
();
// initialize C-API
return
NULL
;
}
# else
void
import_numpy
()
{
import_array
();
// initialize C-API
}
# endif
#endif
_interpreter
()
{
// optional but recommended
#if PY_MAJOR_VERSION >= 3
wchar_t
name
[]
=
L"plotting"
;
#else
char
name
[]
=
"plotting"
;
#endif
Py_SetProgramName
(
name
);
Py_Initialize
();
#ifndef WITHOUT_NUMPY
import_numpy
();
// initialize numpy C-API
#endif
PyObject
*
matplotlibname
=
PyString_FromString
(
"matplotlib"
);
PyObject
*
pyplotname
=
PyString_FromString
(
"matplotlib.pyplot"
);
PyObject
*
cmname
=
PyString_FromString
(
"matplotlib.cm"
);
PyObject
*
pylabname
=
PyString_FromString
(
"pylab"
);
if
(
!
pyplotname
||
!
pylabname
||
!
matplotlibname
||
!
cmname
)
{
throw
std
::
runtime_error
(
"couldnt create string"
);
}
PyObject
*
matplotlib
=
PyImport_Import
(
matplotlibname
);
Py_DECREF
(
matplotlibname
);
if
(
!
matplotlib
)
{
PyErr_Print
();
throw
std
::
runtime_error
(
"Error loading module matplotlib!"
);
}
// matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
// or matplotlib.backends is imported for the first time
if
(
!
s_backend
.
empty
())
{
PyObject_CallMethod
(
matplotlib
,
const_cast
<
char
*>
(
"use"
),
const_cast
<
char
*>
(
"s"
),
s_backend
.
c_str
());
}
PyObject
*
pymod
=
PyImport_Import
(
pyplotname
);
Py_DECREF
(
pyplotname
);
if
(
!
pymod
)
{
throw
std
::
runtime_error
(
"Error loading module matplotlib.pyplot!"
);
}
s_python_colormap
=
PyImport_Import
(
cmname
);
Py_DECREF
(
cmname
);
if
(
!
s_python_colormap
)
{
throw
std
::
runtime_error
(
"Error loading module matplotlib.cm!"
);
}
PyObject
*
pylabmod
=
PyImport_Import
(
pylabname
);
Py_DECREF
(
pylabname
);
if
(
!
pylabmod
)
{
throw
std
::
runtime_error
(
"Error loading module pylab!"
);
}
s_python_function_show
=
PyObject_GetAttrString
(
pymod
,
"show"
);
s_python_function_close
=
PyObject_GetAttrString
(
pymod
,
"close"
);
s_python_function_draw
=
PyObject_GetAttrString
(
pymod
,
"draw"
);
s_python_function_pause
=
PyObject_GetAttrString
(
pymod
,
"pause"
);
s_python_function_figure
=
PyObject_GetAttrString
(
pymod
,
"figure"
);
s_python_function_fignum_exists
=
PyObject_GetAttrString
(
pymod
,
"fignum_exists"
);
s_python_function_plot
=
PyObject_GetAttrString
(
pymod
,
"plot"
);
s_python_function_quiver
=
PyObject_GetAttrString
(
pymod
,
"quiver"
);
s_python_function_semilogx
=
PyObject_GetAttrString
(
pymod
,
"semilogx"
);
s_python_function_semilogy
=
PyObject_GetAttrString
(
pymod
,
"semilogy"
);
s_python_function_loglog
=
PyObject_GetAttrString
(
pymod
,
"loglog"
);
s_python_function_fill
=
PyObject_GetAttrString
(
pymod
,
"fill"
);
s_python_function_fill_between
=
PyObject_GetAttrString
(
pymod
,
"fill_between"
);
s_python_function_hist
=
PyObject_GetAttrString
(
pymod
,
"hist"
);
s_python_function_scatter
=
PyObject_GetAttrString
(
pymod
,
"scatter"
);
s_python_function_subplot
=
PyObject_GetAttrString
(
pymod
,
"subplot"
);
s_python_function_legend
=
PyObject_GetAttrString
(
pymod
,
"legend"
);
s_python_function_ylim
=
PyObject_GetAttrString
(
pymod
,
"ylim"
);
s_python_function_title
=
PyObject_GetAttrString
(
pymod
,
"title"
);
s_python_function_axis
=
PyObject_GetAttrString
(
pymod
,
"axis"
);
s_python_function_xlabel
=
PyObject_GetAttrString
(
pymod
,
"xlabel"
);
s_python_function_ylabel
=
PyObject_GetAttrString
(
pymod
,
"ylabel"
);
s_python_function_xticks
=
PyObject_GetAttrString
(
pymod
,
"xticks"
);
s_python_function_yticks
=
PyObject_GetAttrString
(
pymod
,
"yticks"
);
s_python_function_grid
=
PyObject_GetAttrString
(
pymod
,
"grid"
);
s_python_function_xlim
=
PyObject_GetAttrString
(
pymod
,
"xlim"
);
s_python_function_ion
=
PyObject_GetAttrString
(
pymod
,
"ion"
);
s_python_function_ginput
=
PyObject_GetAttrString
(
pymod
,
"ginput"
);
s_python_function_save
=
PyObject_GetAttrString
(
pylabmod
,
"savefig"
);
s_python_function_annotate
=
PyObject_GetAttrString
(
pymod
,
"annotate"
);
s_python_function_clf
=
PyObject_GetAttrString
(
pymod
,
"clf"
);
s_python_function_errorbar
=
PyObject_GetAttrString
(
pymod
,
"errorbar"
);
s_python_function_tight_layout
=
PyObject_GetAttrString
(
pymod
,
"tight_layout"
);
s_python_function_stem
=
PyObject_GetAttrString
(
pymod
,
"stem"
);
s_python_function_xkcd
=
PyObject_GetAttrString
(
pymod
,
"xkcd"
);
s_python_function_text
=
PyObject_GetAttrString
(
pymod
,
"text"
);
s_python_function_suptitle
=
PyObject_GetAttrString
(
pymod
,
"suptitle"
);
s_python_function_bar
=
PyObject_GetAttrString
(
pymod
,
"bar"
);
s_python_function_subplots_adjust
=
PyObject_GetAttrString
(
pymod
,
"subplots_adjust"
);
if
(
!
s_python_function_show
||
!
s_python_function_close
||
!
s_python_function_draw
||
!
s_python_function_pause
||
!
s_python_function_figure
||
!
s_python_function_fignum_exists
||
!
s_python_function_plot
||
!
s_python_function_quiver
||
!
s_python_function_semilogx
||
!
s_python_function_semilogy
||
!
s_python_function_loglog
||
!
s_python_function_fill
||
!
s_python_function_fill_between
||
!
s_python_function_subplot
||
!
s_python_function_legend
||
!
s_python_function_ylim
||
!
s_python_function_title
||
!
s_python_function_axis
||
!
s_python_function_xlabel
||
!
s_python_function_ylabel
||
!
s_python_function_grid
||
!
s_python_function_xlim
||
!
s_python_function_ion
||
!
s_python_function_ginput
||
!
s_python_function_save
||
!
s_python_function_clf
||
!
s_python_function_annotate
||
!
s_python_function_errorbar
||
!
s_python_function_errorbar
||
!
s_python_function_tight_layout
||
!
s_python_function_stem
||
!
s_python_function_xkcd
||
!
s_python_function_text
||
!
s_python_function_suptitle
||
!
s_python_function_bar
||
!
s_python_function_subplots_adjust
)
{
throw
std
::
runtime_error
(
"Couldn't find required function!"
);
}
if
(
!
PyFunction_Check
(
s_python_function_show
)
||
!
PyFunction_Check
(
s_python_function_close
)
||
!
PyFunction_Check
(
s_python_function_draw
)
||
!
PyFunction_Check
(
s_python_function_pause
)
||
!
PyFunction_Check
(
s_python_function_figure
)
||
!
PyFunction_Check
(
s_python_function_fignum_exists
)
||
!
PyFunction_Check
(
s_python_function_plot
)
||
!
PyFunction_Check
(
s_python_function_quiver
)
||
!
PyFunction_Check
(
s_python_function_semilogx
)
||
!
PyFunction_Check
(
s_python_function_semilogy
)
||
!
PyFunction_Check
(
s_python_function_loglog
)
||
!
PyFunction_Check
(
s_python_function_fill
)
||
!
PyFunction_Check
(
s_python_function_fill_between
)
||
!
PyFunction_Check
(
s_python_function_subplot
)
||
!
PyFunction_Check
(
s_python_function_legend
)
||
!
PyFunction_Check
(
s_python_function_annotate
)
||
!
PyFunction_Check
(
s_python_function_ylim
)
||
!
PyFunction_Check
(
s_python_function_title
)
||
!
PyFunction_Check
(
s_python_function_axis
)
||
!
PyFunction_Check
(
s_python_function_xlabel
)
||
!
PyFunction_Check
(
s_python_function_ylabel
)
||
!
PyFunction_Check
(
s_python_function_grid
)
||
!
PyFunction_Check
(
s_python_function_xlim
)
||
!
PyFunction_Check
(
s_python_function_ion
)
||
!
PyFunction_Check
(
s_python_function_ginput
)
||
!
PyFunction_Check
(
s_python_function_save
)
||
!
PyFunction_Check
(
s_python_function_clf
)
||
!
PyFunction_Check
(
s_python_function_tight_layout
)
||
!
PyFunction_Check
(
s_python_function_errorbar
)
||
!
PyFunction_Check
(
s_python_function_stem
)
||
!
PyFunction_Check
(
s_python_function_xkcd
)
||
!
PyFunction_Check
(
s_python_function_text
)
||
!
PyFunction_Check
(
s_python_function_suptitle
)
||
!
PyFunction_Check
(
s_python_function_bar
)
||
!
PyFunction_Check
(
s_python_function_subplots_adjust
)
)
{
throw
std
::
runtime_error
(
"Python object is unexpectedly not a PyFunction."
);
}
s_python_empty_tuple
=
PyTuple_New
(
0
);
}
~
_interpreter
()
{
Py_Finalize
();
}
};
}
// end namespace detail
// must be called before the first regular call to matplotlib to have any effect
inline
void
backend
(
const
std
::
string
&
name
)
{
detail
::
s_backend
=
name
;
}
inline
bool
annotate
(
std
::
string
annotation
,
double
x
,
double
y
)
{
PyObject
*
xy
=
PyTuple_New
(
2
);
PyObject
*
str
=
PyString_FromString
(
annotation
.
c_str
());
PyTuple_SetItem
(
xy
,
0
,
PyFloat_FromDouble
(
x
));
PyTuple_SetItem
(
xy
,
1
,
PyFloat_FromDouble
(
y
));
PyObject
*
kwargs
=
PyDict_New
();
PyDict_SetItemString
(
kwargs
,
"xy"
,
xy
);
PyObject
*
args
=
PyTuple_New
(
1
);
PyTuple_SetItem
(
args
,
0
,
str
);
PyObject
*
res
=
PyObject_Call
(
detail
::
_interpreter
::
get
().
s_python_function_annotate
,
args
,
kwargs
);
Py_DECREF
(
args
);
Py_DECREF
(
kwargs
);
if
(
res
)
Py_DECREF
(
res
);
return
res
;
}
#ifndef WITHOUT_NUMPY
// Type selector for numpy array conversion
template
<
typename
T
>
struct
select_npy_type
{
const
static
NPY_TYPES
type
=
NPY_NOTYPE
;
};
//Default
template
<
>
struct
select_npy_type
<
double
>
{
const
static
NPY_TYPES
type
=
NPY_DOUBLE
;
};
template
<
>
struct
select_npy_type
<
float
>
{
const
static
NPY_TYPES
type
=
NPY_FLOAT
;
};
template
<
>
struct
select_npy_type
<
bool
>
{
const
static
NPY_TYPES
type
=
NPY_BOOL
;
};
template
<
>
struct
select_npy_type
<
int8_t
>
{
const
static
NPY_TYPES
type
=
NPY_INT8
;
};
template
<
>
struct
select_npy_type
<
int16_t
>
{
const
static
NPY_TYPES
type
=
NPY_SHORT
;
};
template
<
>
struct
select_npy_type
<
int32_t
>
{
const
static
NPY_TYPES
type
=
NPY_INT
;
};
template
<
>
struct
select_npy_type
<
int64_t
>
{
const
static
NPY_TYPES
type
=
NPY_INT64
;
};
template
<
>
struct
select_npy_type
<
uint8_t
>
{
const
static
NPY_TYPES
type
=
NPY_UINT8
;
};
template
<
>
struct
select_npy_type
<
uint16_t
>
{
const
static
NPY_TYPES
type
=
NPY_USHORT
;
};
template
<
>
struct
select_npy_type
<
uint32_t
>
{
const
static
NPY_TYPES
type
=
NPY_ULONG
;
};
template
<
>
struct
select_npy_type
<
uint64_t
>
{
const
static
NPY_TYPES
type
=
NPY_UINT64
;
};
template
<
typename
Numeric
>
PyObject
*
get_array
(
const
std
::
vector
<
Numeric
>&
v
)
{
detail
::
_interpreter
::
get
();
//interpreter needs to be initialized for the numpy commands to work
NPY_TYPES
type
=
select_npy_type
<
Numeric
>::
type
;
if
(
type
==
NPY_NOTYPE
)
{
std
::
vector
<
double
>
vd
(
v
.
size
());
npy_intp
vsize
=
v
.
size
();
std
::
copy
(
v
.
begin
(),
v
.
end
(),
vd
.
begin
());
PyObject
*
varray
=
PyArray_SimpleNewFromData
(
1
,
&
vsize
,
NPY_DOUBLE
,
(
void
*
)(
vd
.
data
()));
return
varray
;
}
npy_intp
vsize
=
v
.
size
();
PyObject
*
varray
=
PyArray_SimpleNewFromData
(
1
,
&
vsize
,
type
,
(
void
*
)(
v
.
data
()));
return
varray
;
}
template
<
typename
Numeric
>
PyObject
*
get_2darray
(
const
std
::
vector
<::
std
::
vector
<
Numeric
>>&
v
)
{
detail
::
_interpreter
::
get
();
//interpreter needs to be initialized for the numpy commands to work
if
(
v
.
size
()
<
1
)
throw
std
::
runtime_error
(
"get_2d_array v too small"
);
npy_intp
vsize
[
2
]
=
{
static_cast
<
npy_intp
>
(
v
.
size
()),
static_cast
<
npy_intp
>
(
v
[
0
].
size
())};
PyArrayObject
*
varray
=
(
PyArrayObject
*
)
PyArray_SimpleNew
(
2
,
vsize
,
NPY_DOUBLE
);
double
*
vd_begin
=
static_cast
<
double
*>
(
PyArray_DATA
(
varray
));
for
(
const
::
std
::
vector
<
Numeric
>
&
v_row
:
v
)
{
if
(
v_row
.
size
()
!=
static_cast
<
size_t
>
(
vsize
[
1
]))
throw
std
::
runtime_error
(
"Missmatched array size"
);
std
::
copy
(
v_row
.
begin
(),
v_row
.
end
(),
vd_begin
);
vd_begin
+=
vsize
[
1
];
}
return
reinterpret_cast
<
PyObject
*>
(
varray
);
}
#else // fallback if we don't have numpy: copy every element of the given vector
template
<
typename
Numeric
>
PyObject
*
get_array
(
const
std
::
vector
<
Numeric
>&
v
)
{
PyObject
*
list
=
PyList_New
(
v
.
size
());
for
(
size_t
i
=
0
;
i
<
v
.
size
();
++
i
)
{
PyList_SetItem
(
list
,
i
,
PyFloat_FromDouble
(
v
.
at
(
i
)));
}
return
list
;
}
#endif // WITHOUT_NUMPY
template
<
typename
Numeric
>
bool
plot
(
const
std
::
vector
<
Numeric
>
&
x
,
const
std
::
vector
<
Numeric
>
&
y
,
const
std
::
map
<
std
::
string
,
std
::
string
>&
keywords
)
{
assert
(
x
.
size
()
==
y
.
size
());
// using numpy arrays
PyObject
*
xarray
=
get_array
(
x
);
PyObject
*
yarray
=
get_array
(
y
);
// construct positional args
PyObject
*
args
=
PyTuple_New
(
2
);
PyTuple_SetItem
(
args
,
0
,
xarray
);
PyTuple_SetItem
(
args
,
1
,
yarray
);
// construct keyword args
PyObject
*
kwargs
=
PyDict_New
();
for
(
std
::
map
<
std
::
string
,
std
::
string
>::
const_iterator
it
=
keywords
.
begin
();
it
!=
keywords
.
end
();
++
it
)
{
PyDict_SetItemString
(
kwargs
,
it
->
first
.
c_str
(),
PyString_FromString
(
it
->
second
.
c_str
()));
}
PyObject
*
res
=
PyObject_Call
(
detail
::
_interpreter
::
get
().
s_python_function_plot
,
args
,
kwargs
);
Py_DECREF
(
args
);
Py_DECREF
(
kwargs
);
if
(
res
)
Py_DECREF
(
res
);
return
res
;
}
template
<
typename
Numeric
>
void
plot_surface
(
const
std
::
vector
<::
std
::
vector
<
Numeric
>>
&
x
,
const
std
::
vector
<::
std
::
vector
<
Numeric
>>
&
y
,
const
std
::
vector
<::
std
::
vector
<
Numeric
>>
&
z
,
const
std
::
map
<
std
::
string
,
std
::
string
>
&
keywords
=
std
::
map
<
std
::
string
,
std
::
string
>
())
{
// We lazily load the modules here the first time this function is called
// because I'm not sure that we can assume "matplotlib installed" implies
// "mpl_toolkits installed" on all platforms, and we don't want to require
// it for people who don't need 3d plots.
static
PyObject
*
mpl_toolkitsmod
=
nullptr
,
*
axis3dmod
=
nullptr
;
if
(
!
mpl_toolkitsmod
)
{
detail
::
_interpreter
::
get
();
PyObject
*
mpl_toolkits
=
PyString_FromString
(
"mpl_toolkits"
);
PyObject
*
axis3d
=
PyString_FromString
(
"mpl_toolkits.mplot3d"
);
if
(
!
mpl_toolkits
||
!
axis3d
)
{
throw
std
::
runtime_error
(
"couldnt create string"
);
}
mpl_toolkitsmod
=
PyImport_Import
(
mpl_toolkits
);
Py_DECREF
(
mpl_toolkits
);
if
(
!
mpl_toolkitsmod
)
{
throw
std
::
runtime_error
(
"Error loading module mpl_toolkits!"
);
}
axis3dmod
=
PyImport_Import
(
axis3d
);
Py_DECREF
(
axis3d
);
if
(
!
axis3dmod
)
{
throw
std
::
runtime_error
(
"Error loading module mpl_toolkits.mplot3d!"
);
}
}
assert
(
x
.
size
()
==
y
.
size
());
assert
(
y
.
size
()
==
z
.
size
());
// using numpy arrays
PyObject
*
xarray
=
get_2darray
(
x
);
PyObject
*
yarray
=
get_2darray
(
y
);
PyObject
*
zarray
=
get_2darray
(
z
);
// construct positional args
PyObject
*
args
=
PyTuple_New
(
3
);
PyTuple_SetItem
(
args
,
0
,
xarray
);
PyTuple_SetItem
(
args
,
1
,
yarray
);