Skip to content

Commit 9de8583

Browse files
committed
Adding docstrings
1 parent acfe4b7 commit 9de8583

File tree

5 files changed

+156
-5
lines changed

5 files changed

+156
-5
lines changed

docs/source/api_reference.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,19 @@
77
API reference
88
=============
99

10+
Containers
11+
----------
12+
1013
.. toctree::
1114
:maxdepth: 2
1215

1316
pyarray
1417
pytensor
18+
19+
Numpy universal functions
20+
-------------------------
21+
22+
.. toctree::
23+
:maxdepth: 2
24+
25+
pyvectorize

include/xtensor-python/pyarray.hpp

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ namespace xt
6464
template <class A>
6565
class pyarray_backstrides
6666
{
67-
6867
public:
6968

7069
using array_type = A;
@@ -104,7 +103,13 @@ namespace xt
104103

105104
/**
106105
* @class pyarray
107-
* @brief Wrapper on the Python buffer protocol.
106+
* @brief Multidimensional container providing the xtensor container semantics to a numpy array.
107+
*
108+
* pyarray is similar to the xarray container in that it has a dynamic dimensionality. Reshapes of
109+
* a pyarray container are reflected in the underlying numpy array.
110+
*
111+
* @tparam T The type of the element stored in the pyarray.
112+
* @sa pytensor
108113
*/
109114
template <class T>
110115
class pyarray : public pycontainer<pyarray<T>>,
@@ -210,6 +215,10 @@ namespace xt
210215
* pyarray implementation *
211216
**************************/
212217

218+
/**
219+
* @name Constructors
220+
*/
221+
//@{
213222
template <class T>
214223
inline pyarray<T>::pyarray()
215224
{
@@ -220,6 +229,9 @@ namespace xt
220229
m_data[0] = T();
221230
}
222231

232+
/**
233+
* Allocates a pyarray with nested initializer lists.
234+
*/
223235
template <class T>
224236
inline pyarray<T>::pyarray(const value_type& t)
225237
{
@@ -283,6 +295,12 @@ namespace xt
283295
init_from_python();
284296
}
285297

298+
/**
299+
* Allocates an uninitialized pyarray with the specified shape and
300+
* layout.
301+
* @param shape the shape of the pyarray
302+
* @param l the layout of the pyarray
303+
*/
286304
template <class T>
287305
inline pyarray<T>::pyarray(const shape_type& shape, layout l)
288306
{
@@ -291,6 +309,13 @@ namespace xt
291309
init_array(shape, strides);
292310
}
293311

312+
/**
313+
* Allocates a pyarray with the specified shape and layout. Elements
314+
* are initialized to the specified value.
315+
* @param shape the shape of the pyarray
316+
* @param value the value of the elements
317+
* @param l the layout of the pyarray
318+
*/
294319
template <class T>
295320
inline pyarray<T>::pyarray(const shape_type& shape, const_reference value, layout l)
296321
{
@@ -300,32 +325,56 @@ namespace xt
300325
std::fill(m_data.begin(), m_data.end(), value);
301326
}
302327

328+
/**
329+
* Allocates an uninitialized pyarray with the specified shape and strides.
330+
* Elements are initialized to the specified value.
331+
* @param shape the shape of the pyarray
332+
* @param strides the strides of the pyarray
333+
* @param value the value of the elements
334+
*/
303335
template <class T>
304336
inline pyarray<T>::pyarray(const shape_type& shape, const strides_type& strides, const_reference value)
305337
{
306338
init_array(shape, strides);
307339
std::fill(m_data.begin(), m_data.end(), value);
308340
}
309341

342+
/**
343+
* Allocates an uninitialized pyarray with the specified shape and strides.
344+
* @param shape the shape of the pyarray
345+
* @param strides the strides of the pyarray
346+
*/
310347
template <class T>
311348
inline pyarray<T>::pyarray(const shape_type& shape, const strides_type& strides)
312349
{
313350
init_array(shape, strides);
314351
}
352+
//@}
315353

354+
/**
355+
* @name Extended copy semantic
356+
*/
357+
//@{
358+
/**
359+
* The extended copy constructor.
360+
*/
316361
template <class T>
317362
template <class E>
318363
inline pyarray<T>::pyarray(const xexpression<E>& e)
319364
{
320365
semantic_base::assign(e);
321366
}
322367

368+
/**
369+
* The extended assignment operator.
370+
*/
323371
template <class T>
324372
template <class E>
325373
inline auto pyarray<T>::operator=(const xexpression<E>& e) -> self_type&
326374
{
327375
return semantic_base::operator=(e);
328376
}
377+
//@}
329378

330379
template <class T>
331380
inline auto pyarray<T>::ensure(pybind11::handle h) -> self_type
@@ -397,8 +446,9 @@ namespace xt
397446
template <class T>
398447
inline auto pyarray<T>::backstrides_impl() const noexcept -> const inner_backstrides_type&
399448
{
400-
// The pyarray object may be copied, invalidating m_backstrides. Building
401-
// it each time it is needed avoids tricky bugs.
449+
// m_backstrides wraps the numpy array backstrides, which is a raw pointer.
450+
// The address of the raw pointer stored in the wrapper would be invalidated when the pyarray is copied.
451+
// Hence, we build a new backstrides object (cheap wrapper around the underlying pointer) upon access.
402452
m_backstrides = backstrides_type(*this);
403453
return m_backstrides;
404454
}

include/xtensor-python/pycontainer.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@
3131
namespace xt
3232
{
3333

34+
/**
35+
* @class pycontainer
36+
* @brief Base class for xtensor containers wrapping numpy arryays.
37+
*
38+
* The pycontainer class should not be instantiated directly. Instead, used should
39+
* use pytensor and pyarray instancs.
40+
*
41+
* @tparam D The derived type, i.e. the inheriting class for which pycontainer
42+
* provides the interface.
43+
*/
3444
template <class D>
3545
class pycontainer : public pybind11::object,
3646
public xcontainer<D>
@@ -191,6 +201,10 @@ namespace xt
191201
return reinterpret_cast<PyArrayObject*>(this->m_ptr);
192202
}
193203

204+
/**
205+
* Reshapes the container.
206+
* @param shape the new shape
207+
*/
194208
template <class D>
195209
inline void pycontainer<D>::reshape(const shape_type& shape)
196210
{
@@ -200,6 +214,11 @@ namespace xt
200214
}
201215
}
202216

217+
/**
218+
* Reshapes the container.
219+
* @param shape the new shape
220+
* @param l the new layout
221+
*/
203222
template <class D>
204223
inline void pycontainer<D>::reshape(const shape_type& shape, layout l)
205224
{
@@ -208,6 +227,11 @@ namespace xt
208227
reshape(shape, strides);
209228
}
210229

230+
/**
231+
* Reshapes the container.
232+
* @param shape the new shape
233+
* @param strides the new strides
234+
*/
211235
template <class D>
212236
inline void pycontainer<D>::reshape(const shape_type& shape, const strides_type& strides)
213237
{

include/xtensor-python/pytensor.hpp

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ namespace xt
8181
using temporary_type = pytensor<T, N>;
8282
};
8383

84+
/**
85+
* @class pytensor
86+
* @brief Multidimensional container providing the xtensor container semantics wrapping a numpy array.
87+
*
88+
* pytensor is similar to the xtensor container in that it has a static dimensionality.
89+
*
90+
* Unlike with the pyarray container, pytensor cannot be reshaped with a different number of dimensions
91+
* and reshapes are not reflected on the Python side. However, pytensor has benefits compared to pyarray
92+
* in terms of performances. pytensor shapes are stack-allocated which makes iteration upon pytensor
93+
* faster than with pyarray.
94+
*
95+
* @tparam T The type of the element stored in the pyarray.
96+
* @sa pyarray
97+
*/
8498
template <class T, std::size_t N>
8599
class pytensor : public pycontainer<pytensor<T, N>>,
86100
public xcontainer_semantic<pytensor<T, N>>
@@ -158,6 +172,13 @@ namespace xt
158172
* pytensor implementation *
159173
***************************/
160174

175+
/**
176+
* @name Constructors
177+
*/
178+
//@{
179+
/**
180+
* Allocates an uninitialized pytensor that holds 1 element.
181+
*/
161182
template <class T, std::size_t N>
162183
inline pytensor<T, N>::pytensor()
163184
{
@@ -167,6 +188,9 @@ namespace xt
167188
m_data[0] = T();
168189
}
169190

191+
/**
192+
* Allocates a pytensor with a nested initializer list.
193+
*/
170194
template <class T, std::size_t N>
171195
inline pytensor<T, N>::pytensor(nested_initializer_list_t<T, N> t)
172196
{
@@ -195,13 +219,26 @@ namespace xt
195219
init_from_python();
196220
}
197221

222+
/**
223+
* Allocates an uninitialized pytensor with the specified shape and
224+
* layout.
225+
* @param shape the shape of the pytensor
226+
* @param l the layout of the pytensor
227+
*/
198228
template <class T, std::size_t N>
199229
inline pytensor<T, N>::pytensor(const shape_type& shape, layout l)
200230
{
201231
compute_strides(shape, l, m_strides);
202232
init_tensor(shape, m_strides);
203233
}
204234

235+
/**
236+
* Allocates a pytensor with the specified shape and layout. Elements
237+
* are initialized to the specified value.
238+
* @param shape the shape of the pytensor
239+
* @param value the value of the elements
240+
* @param l the layout of the pytensor
241+
*/
205242
template <class T, std::size_t N>
206243
inline pytensor<T, N>::pytensor(const shape_type& shape,
207244
const_reference value,
@@ -212,6 +249,13 @@ namespace xt
212249
std::fill(m_data.begin(), m_data.end(), value);
213250
}
214251

252+
/**
253+
* Allocates an uninitialized pytensor with the specified shape and strides.
254+
* Elements are initialized to the specified value.
255+
* @param shape the shape of the pytensor
256+
* @param strides the strides of the pytensor
257+
* @param value the value of the elements
258+
*/
215259
template <class T, std::size_t N>
216260
inline pytensor<T, N>::pytensor(const shape_type& shape,
217261
const strides_type& strides,
@@ -221,26 +265,43 @@ namespace xt
221265
std::fill(m_data.begin(), m_data.end(), value);
222266
}
223267

268+
/**
269+
* Allocates an uninitialized pytensor with the specified shape and strides.
270+
* @param shape the shape of the pytensor
271+
* @param strides the strides of the pytensor
272+
*/
224273
template <class T, std::size_t N>
225274
inline pytensor<T, N>::pytensor(const shape_type& shape,
226275
const strides_type& strides)
227276
{
228277
init_tensor(shape, strides);
229278
}
230-
279+
//@}
280+
281+
/**
282+
* @name Extended copy semantic
283+
*/
284+
//@{
285+
/**
286+
* The extended copy constructor.
287+
*/
231288
template <class T, std::size_t N>
232289
template <class E>
233290
inline pytensor<T, N>::pytensor(const xexpression<E>& e)
234291
{
235292
semantic_base::assign(e);
236293
}
237294

295+
/**
296+
* The extended assignment operator.
297+
*/
238298
template <class T, std::size_t N>
239299
template <class E>
240300
inline auto pytensor<T, N>::operator=(const xexpression<E>& e) -> self_type&
241301
{
242302
return semantic_base::operator=(e);
243303
}
304+
//@}
244305

245306
template <class T, std::size_t N>
246307
inline auto pytensor<T, N>::ensure(pybind11::handle h) -> self_type

include/xtensor-python/pyvectorize.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,16 @@ namespace xt
3333
}
3434
};
3535

36+
/**
37+
* @brief Create numpy universal function from scalar function.
38+
*/
3639
template <class R, class... Args>
3740
inline pyvectorizer<R(*)(Args...), R, Args...> pyvectorize(R(*f) (Args...))
3841
{
3942
return pyvectorizer<R(*) (Args...), R, Args...>(f);
4043
}
4144

45+
/// @cond DOXYGEN_INCLUDE_OVERLOADS
4246
template <class F, class R, class... Args>
4347
inline pyvectorizer<F, R, Args...> pyvectorize(F&& f, R(*) (Args...))
4448
{
@@ -50,6 +54,7 @@ namespace xt
5054
{
5155
return pyvectorize(std::forward<F>(f), (detail::get_function_type<F>*)nullptr);
5256
}
57+
/// @endcond
5358
}
5459

5560
#endif

0 commit comments

Comments
 (0)