Skip to content

Commit 5751ad8

Browse files
authored
Merge pull request #45 from rust-numpy/add-docs
Add some api docs
2 parents 4b8c568 + 76c7b67 commit 5751ad8

File tree

6 files changed

+81
-24
lines changed

6 files changed

+81
-24
lines changed

src/array.rs

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::ptr::null_mut;
1010
use super::error::ArrayCastError;
1111
use super::*;
1212

13-
/// Untyped safe interface for NumPy ndarray.
13+
/// Interface for [NumPy ndarray](https://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html).
1414
pub struct PyArray<T>(PyObject, PhantomData<T>);
1515

1616
pyobject_native_type_convert!(
@@ -53,16 +53,18 @@ impl<T> IntoPyObject for PyArray<T> {
5353
}
5454

5555
impl<T> PyArray<T> {
56-
/// Get raw pointer for PyArrayObject
56+
/// Gets a raw `PyArrayObject` pointer.
5757
pub fn as_array_ptr(&self) -> *mut npyffi::PyArrayObject {
5858
self.as_ptr() as _
5959
}
6060

61+
/// Constructs `PyArray` from raw python object without incrementing reference counts.
6162
pub unsafe fn from_owned_ptr(py: Python, ptr: *mut pyo3::ffi::PyObject) -> Self {
6263
let obj = PyObject::from_owned_ptr(py, ptr);
6364
PyArray(obj, PhantomData)
6465
}
6566

67+
/// Constructs PyArray from raw python object and increments reference counts.
6668
pub unsafe fn from_borrowed_ptr(py: Python, ptr: *mut pyo3::ffi::PyObject) -> Self {
6769
let obj = PyObject::from_borrowed_ptr(py, ptr);
6870
PyArray(obj, PhantomData)
@@ -135,8 +137,6 @@ impl<T> PyArray<T> {
135137
}
136138

137139
/// Same as [shape](./struct.PyArray.html#method.shape)
138-
///
139-
/// Reserved for backward compatibility.
140140
#[inline]
141141
pub fn dims(&self) -> &[usize] {
142142
self.shape()
@@ -294,6 +294,7 @@ impl<T: TypeNum> PyArray<T> {
294294
IntoPyArray::into_pyarray(arr, py, np)
295295
}
296296

297+
/// Returns the pointer to the first element of the inner array.
297298
unsafe fn data(&self) -> *mut T {
298299
let ptr = self.as_array_ptr();
299300
(*ptr).data as *mut T
@@ -310,13 +311,14 @@ impl<T: TypeNum> PyArray<T> {
310311
shape.strides(Dim(st))
311312
}
312313

313-
pub fn typenum(&self) -> i32 {
314+
fn typenum(&self) -> i32 {
314315
unsafe {
315316
let descr = (*self.as_array_ptr()).descr;
316317
(*descr).type_num
317318
}
318319
}
319320

321+
/// Returns the scalar type of the array.
320322
pub fn data_type(&self) -> NpyDataType {
321323
NpyDataType::from_i32(self.typenum())
322324
}
@@ -360,6 +362,9 @@ impl<T: TypeNum> PyArray<T> {
360362
unsafe { Ok(::std::slice::from_raw_parts_mut(self.data(), self.len())) }
361363
}
362364

365+
/// Construct a new PyArray given a raw pointer and dimensions.
366+
///
367+
/// Please use `new` or from methods instead.
363368
pub unsafe fn new_(
364369
py: Python,
365370
np: &PyArrayModule,
@@ -382,27 +387,69 @@ impl<T: TypeNum> PyArray<T> {
382387
Self::from_owned_ptr(py, ptr)
383388
}
384389

385-
/// a wrapper of [PyArray_SimpleNew](https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_SimpleNew)
390+
/// Creates a new uninitialized array.
391+
///
392+
/// See also [PyArray_SimpleNew](https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_SimpleNew).
393+
///
394+
/// # Example
395+
/// ```
396+
/// # extern crate pyo3; extern crate numpy; #[macro_use] extern crate ndarray; fn main() {
397+
/// use numpy::{PyArray, PyArrayModule};
398+
/// let gil = pyo3::Python::acquire_gil();
399+
/// let np = PyArrayModule::import(gil.python()).unwrap();
400+
/// let pyarray = PyArray::new(gil.python(), &np, &[2, 2]);
401+
/// assert_eq!(pyarray.as_array().unwrap(), array![[0, 0], [0, 0]].into_dyn());
402+
/// # }
403+
/// ```
386404
pub fn new(py: Python, np: &PyArrayModule, dims: &[usize]) -> Self {
387405
unsafe { Self::new_(py, np, dims, null_mut(), null_mut()) }
388406
}
389407

390-
/// a wrapper of [PyArray_ZEROS](https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_ZEROS)
391-
pub fn zeros(py: Python, np: &PyArrayModule, dims: &[usize], order: NPY_ORDER) -> Self {
408+
/// Construct a new nd-dimensional array filled with 0. If `is_fortran` is true, then
409+
/// a fortran order array is created, otherwise a C-order array is created.
410+
///
411+
/// See also [PyArray_Zeros](https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_Zeros)
412+
///
413+
/// # Example
414+
/// ```
415+
/// # extern crate pyo3; extern crate numpy; #[macro_use] extern crate ndarray; fn main() {
416+
/// use numpy::{PyArray, PyArrayModule};
417+
/// let gil = pyo3::Python::acquire_gil();
418+
/// let np = PyArrayModule::import(gil.python()).unwrap();
419+
/// let pyarray = PyArray::zeros(gil.python(), &np, &[2, 2], false);
420+
/// assert_eq!(pyarray.as_array().unwrap(), array![[0, 0], [0, 0]].into_dyn());
421+
/// # }
422+
/// ```
423+
pub fn zeros(py: Python, np: &PyArrayModule, dims: &[usize], is_fortran: bool) -> Self {
392424
let dims: Vec<npy_intp> = dims.iter().map(|d| *d as npy_intp).collect();
393425
unsafe {
394426
let descr = np.PyArray_DescrFromType(T::typenum());
395427
let ptr = np.PyArray_Zeros(
396428
dims.len() as i32,
397429
dims.as_ptr() as *mut npy_intp,
398430
descr,
399-
order as i32,
431+
if is_fortran { -1 } else { 0 },
400432
);
401433
Self::from_owned_ptr(py, ptr)
402434
}
403435
}
404436

405-
/// a wrapper of [PyArray_Arange](https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_Arange)
437+
/// Return evenly spaced values within a given interval.
438+
/// Same as [numpy.arange](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arange.html).
439+
///
440+
/// See also [PyArray_Arange](https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_Arange).
441+
///
442+
/// # Example
443+
/// ```
444+
/// # extern crate pyo3; extern crate numpy; fn main() {
445+
/// use numpy::{PyArray, PyArrayModule, IntoPyArray};
446+
/// let gil = pyo3::Python::acquire_gil();
447+
/// let np = PyArrayModule::import(gil.python()).unwrap();
448+
/// let pyarray = PyArray::<f64>::arange(gil.python(), &np, 2.0, 4.0, 0.5);
449+
/// assert_eq!(pyarray.as_slice().unwrap(), &[2.0, 2.5, 3.0, 3.5]);
450+
/// let pyarray = PyArray::<i32>::arange(gil.python(), &np, -2.0, 4.0, 3.0);
451+
/// assert_eq!(pyarray.as_slice().unwrap(), &[-2, 1]);
452+
/// # }
406453
pub fn arange(py: Python, np: &PyArrayModule, start: f64, stop: f64, step: f64) -> Self {
407454
unsafe {
408455
let ptr = np.PyArray_Arange(start, stop, step, T::typenum());

src/convert.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ use std::ptr::null_mut;
88

99
use super::*;
1010

11+
/// Covversion trait from rust types to `PyArray`.
12+
///
13+
/// # Example
14+
/// ```
15+
/// # extern crate pyo3; extern crate numpy; fn main() {
16+
/// use numpy::{PyArray, PyArrayModule, IntoPyArray};
17+
/// let gil = pyo3::Python::acquire_gil();
18+
/// let np = PyArrayModule::import(gil.python()).unwrap();
19+
/// let py_array = vec![1, 2, 3].into_pyarray(gil.python(), &np);
20+
/// assert_eq!(py_array.as_slice().unwrap(), &[1, 2, 3]);
21+
/// # }
22+
/// ```
1123
pub trait IntoPyArray {
1224
type Item: TypeNum;
1325
fn into_pyarray(self, Python, &PyArrayModule) -> PyArray<Self::Item>;

src/error.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,20 @@ impl<T, E: IntoPyErr> IntoPyResult for Result<T, E> {
2121
}
2222
}
2323

24-
/// Error for casting `PyArray` into `ArrayView` or `ArrayViewMut`
24+
/// Represents a casting error between rust types and numpy array.
2525
#[derive(Debug)]
2626
pub enum ArrayCastError {
27+
/// Error for casting `PyArray` into `ArrayView` or `ArrayViewMut`
2728
ToRust {
2829
from: NpyDataType,
2930
to: NpyDataType,
3031
},
32+
/// Error for casting rust's `Vec` into numpy array.
3133
FromVec,
3234
}
3335

3436
impl ArrayCastError {
35-
pub fn to_rust(from: i32, to: i32) -> Self {
37+
pub(crate) fn to_rust(from: i32, to: i32) -> Self {
3638
ArrayCastError::ToRust {
3739
from: NpyDataType::from_i32(from),
3840
to: NpyDataType::from_i32(to),

src/npyffi/array.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
//! Low-Level binding for Array API
2-
//!
3-
//! https://docs.scipy.org/doc/numpy/reference/c-api.array.html
1+
//! Low-Level binding for [Array API](https://docs.scipy.org/doc/numpy/reference/c-api.array.html)
42
53
use libc::FILE;
64
use std::ops::Deref;
@@ -13,10 +11,9 @@ use pyo3::{ObjectProtocol, PyModule, PyResult, Python, ToPyPointer};
1311

1412
use npyffi::*;
1513

16-
/// Low-Level binding for Array API
17-
/// https://docs.scipy.org/doc/numpy/reference/c-api.array.html
14+
/// Low-Level binding for [Array API](https://docs.scipy.org/doc/numpy/reference/c-api.array.html)
1815
///
19-
/// Most of Array API is exposed as the related function of this module object.
16+
/// Most of the Array APIs are exposed as related functions of this module object.
2017
/// Some APIs (including most accessor) in the above URL are not implemented
2118
/// since they are defined as C macro, and cannot be called from rust.
2219
/// Some of these are implemented on the high-level interface as a Rust function.
@@ -61,7 +58,7 @@ impl<'py> PyArrayModule<'py> {
6158
}
6259

6360
/// Returns internal `PyModule` type, which includes `numpy.core.multiarray`,
64-
/// so that you can use `PyArrayModule` with some pyo3 functions.
61+
/// so that you can use `PyArrayModule` with some functions.
6562
///
6663
/// # Example
6764
///

src/npyffi/ufunc.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ use pyo3::{ObjectProtocol, PyModule, PyResult, Python, ToPyPointer};
1313
use super::objects::*;
1414
use super::types::*;
1515

16-
/// Low-Level binding for UFunc API
17-
/// https://docs.scipy.org/doc/numpy/reference/c-api.ufunc.html
16+
/// Low-Level binding for [UFunc API](https://docs.scipy.org/doc/numpy/reference/c-api.ufunc.html)
1817
///
1918
/// Most of UFunc API is exposed as the related function of this module object.
2019
pub struct PyUFuncModule<'py> {

tests/array.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ fn zeros() {
2424
let np = PyArrayModule::import(gil.python()).unwrap();
2525
let n = 3;
2626
let m = 5;
27-
let arr = PyArray::<f64>::zeros(gil.python(), &np, &[n, m], NPY_CORDER);
27+
let arr = PyArray::<f64>::zeros(gil.python(), &np, &[n, m], false);
2828
assert!(arr.ndim() == 2);
2929
assert!(arr.dims() == [n, m]);
3030
assert!(arr.strides() == [m as isize * 8, 8]);
3131

32-
let arr = PyArray::<f64>::zeros(gil.python(), &np, &[n, m], NPY_FORTRANORDER);
32+
let arr = PyArray::<f64>::zeros(gil.python(), &np, &[n, m], true);
3333
assert!(arr.ndim() == 2);
3434
assert!(arr.dims() == [n, m]);
3535
assert!(arr.strides() == [8, n as isize * 8]);
@@ -49,7 +49,7 @@ fn arange() {
4949
fn as_array() {
5050
let gil = pyo3::Python::acquire_gil();
5151
let np = PyArrayModule::import(gil.python()).unwrap();
52-
let arr = PyArray::<f64>::zeros(gil.python(), &np, &[3, 2, 4], NPY_CORDER);
52+
let arr = PyArray::<f64>::zeros(gil.python(), &np, &[3, 2, 4], false);
5353
let a = arr.as_array().unwrap();
5454
assert_eq!(arr.shape(), a.shape());
5555
assert_eq!(

0 commit comments

Comments
 (0)