Commit 6a431f25 authored by Christoph Groth's avatar Christoph Groth
Browse files

add docstrings and update README

parent 53168e7d
=========
Tinyarray
=========
Tinyarray is a numerical array module for Python. The multi-dimensional arrays
it provides are best thought of as (possibly nested) tuples of numbers that,
unlike Python's built-in tuples, support mathematical operations. Like tuples,
tinyarrays are hashable and immutable and thus can be used as dictionary keys.
The module's interface is a subset of that of NumPy and hence should be familiar
to many Python programmers. Tinyarray has been heavily optimized for small
arrays: For example, common operations on 1-d arrays of length 3 run up to 35
times faster than with NumPy. When storing many small arrays, memory
consumption is reduced by a factor of 3. In summary, Tinyarray is a more
efficient alternative to NumPy when many separate small numerical arrays are to
be used.
Tinyarrays are similar to NumPy arrays, but optimized for small sizes. Common
operations on very small arrays are up to 35 times faster than with NumPy, and 3
times less memory is used to store them. Tinyarrays are useful if you need many
small arrays of numbers, and cannot combine them into a few large ones. (The
resulting code is still much slower than C, but it may now be fast enough.)
Unlike Python's built-in tuples, Tinyarrays support mathematical operations like
element-wise addition and matrix multiplication. Unlike Numpy arrays,
Tinyarrays can be used as dictionary keys because they are hashable and
immutable.
License
-------
The module's interface is a subset of that of NumPy and thus should be familiar
to many. Whenever an operation is missing from Tinyarray, NumPy functions can
be used directly with Tinyarrays.
Tinyarray is licensed under the "simplified BSD License". The license is
included in the file LICENSE in this directory.
Tinyarray is licensed under the "simplified BSD License". See `<LICENSE>`_.
Authors
-------
Website: http://git.kwant-project.org/tinyarray/about
The principal developer of Tinyarray is Christoph Groth (SPSMS-INAC-CEA
Grenoble). His contributions are part of his work at `CEA <http://cea.fr/>`_,
the French Commissariat à l'énergie atomique et aux énergies alternatives.
The author can be reached at christoph.groth@cea.fr.
Installation
------------
Other people that have contributed to Tinyarray include
Prepared packages exist for Debian, Ubuntu, Windows, and Mac OS X. Follow the
`installation instructions for "Kwant" <http://kwant-project/install>`_ up to
the point where Tinyarray has been installed.
* Michael Wimmer (Leiden University)
* Joseph Weston (SPSMS-INAC-CEA Grenoble)
``pip install tinyarray`` should also work.
To find out who exactly wrote a certain part of Tinyarray, please use the
"blame" feature of `git <http://git-scm.com/>`_, the version control system.
Source
------
Installation
------------
Source tarballs are available at http://downloads.kwant-project.org/tinyarray/
Clone the Git repository with ::
git clone http://git.kwant-project.org/tinyarray
Tinyarray requires Python 2.6 or 2.7.
To install, run::
Usage example
-------------
python setup.py build
python setup.py install
The following example shows that in simple cases Tinyarray works just as
NumPy. ::
If `nose <http://nose.readthedocs.org/>`_ is installed, the included tests can
be run with::
from math import sin, cos, sqrt
import tinyarray as ta
python setup.py test
# Make a vector.
v = ta.array([1.0, 2.0, 3.0])
# Make a rotation matrix.
alpha = 0.77
c, s = cos(alpha), sin(alpha)
rot_z = ta.array([[c, -s, 0],
[s, c, 0],
[0, 0, 1]])
Usage
-----
# Rotate the vector, normalize, and print it.
v = ta.dot(rot_z, v)
v /= sqrt(ta.dot(v, v))
print v
At this stage, tinyarray does not provide documentation beyond this file. See
the module docstring for a list of all the available functions and methods. All
of them are simplified versions of their NumPy counterparts.
For example, arrays can be created with::
Documentation
-------------
tinyarray.array(arraylike, [dtype])
The module's interface is a basic subset of NumPy and hence should be familiar
to many Python programmers. All functions are simplified versions of their
NumPy counterparts. The module's docstring serves as main documentation. To
see it, run in Python::
where `arraylike` can be a nested sequence of numbers or an object supporting
the buffer protocol. The `dtype` parameter is optional and can only take the
values `int`, 'float`, and `complex`. Note that `dtype` is a positional
argument and cannot be used as a keyword argument. Arrays can be also created
with the functions `identity`, `zeros`, and `ones`.
import tinyarray as ta
help(ta)
Tinyarrays support iteration and indexing (currently without slicing), as well
as vectorized elementwise arithmetics. A small number of operations like `dot`,
`floor`, and `transpose` are provided. Printing works as well as pickling and
unpickling. Whenever an operation is missing from Tinyarray, NumPy can be used
directly, e.g.: `numpy.linalg.det(my_tinyarray)`.
Or in the system shell::
pydoc tinyarray
Authors
-------
The principal developer of Tinyarray is Christoph Groth (SPSMS-INAC-CEA
Grenoble). His contributions are part of his work at `CEA <http://cea.fr/>`_,
the French Commissariat à l'énergie atomique et aux énergies alternatives.
The author can be reached at christoph.groth@cea.fr.
Other people that have contributed to Tinyarray include
* Michael Wimmer (Leiden University)
* Joseph Weston (SPSMS-INAC-CEA Grenoble)
......@@ -97,13 +97,15 @@ def long_description():
if skip:
skip = False
continue
else:
elif text[-1] == '\n':
text.pop()
break
if not skip:
text.append(line.rstrip())
text.append(line)
except:
return ''
return '\n'.join(text)
text[-1] = text[-1].rstrip()
return ''.join(text)
class test(Command):
......
......@@ -621,8 +621,6 @@ PyObject *str(PyObject *obj)
return to_pystring(self, PyObject_Str, "", "", "", "");
}
PyDoc_STRVAR(doc, "array docstring: to be written\n");
Py_ssize_t len(Array_base *self)
{
int ndim;
......@@ -1149,6 +1147,43 @@ template PyObject *seq_getitem<Complex>(PyObject*, Py_ssize_t);
// **************** Public interface ****************
PyDoc_STRVAR(tinyarray_doc,
"Arrays of numbers for Python, optimized for small sizes\n\n\
\n\
The tinyarray module provides multi-dimensional arrays of numbers, similar to\n\
NumPy, but with the following differences:\n\
\n\
* Optimized for small sizes: Compared to NumPy, common operations on small\n\
arrays (e.g. length 3) are up to 35 times faster, and 3 times less memory is\n\
used to store them.\n\
\n\
* Arrays are immutable and hashable, and can be thus used as dictionary keys.\n\
\n\
* The tinyarray module provides only the functionality that is deemed essential\n\
with small arrays. For example, there exists a fast tinyarray.dot function,\n\
but there is no fancy indexing or slicing.\n\
\n\
The module's interface is a basic subset of that of NumPy and hence should be\n\
familiar to many Python programmers. All functions are simplified versions of\n\
their NumPy counterparts.\n\
\n\
For example, arrays can be created with:\n\
\n\
tinyarray.array(arraylike, [dtype])\n\
\n\
where arraylike can be a number, a sequence (of sequences, ...) of numbers,\n\
a NumPy or tinyarray array, or another object supporting the buffer protocol.\n\
The dtype parameter is optional and can only take the values int, float, and\n\
complex. Note that dtype is a positional argument and cannot be used as a\n\
keyword argument. Arrays can be also created with the functions identity,\n\
zeros, and ones.\n\
\n\
Tinyarrays support iteration and indexing (currently without slicing), as well\n\
as vectorized elementwise arithmetics. A small number of operations like dot,\n\
floor, and transpose are provided. Printing works as well as pickling.\n\
Whenever an operation is missing from Tinyarray, NumPy can be used directly,\n\
e.g.: numpy.linalg.det(my_tinyarray).");
extern "C"
void inittinyarray()
{
......@@ -1173,7 +1208,7 @@ void inittinyarray()
if (PyType_Ready(&Array<double>::pytype) < 0) return;
if (PyType_Ready(&Array<Complex>::pytype) < 0) return;
PyObject *m = Py_InitModule("tinyarray", functions);
PyObject *m = Py_InitModule3("tinyarray", functions, tinyarray_doc);
reconstruct = PyObject_GetAttrString(m, "_reconstruct");
......@@ -1183,6 +1218,15 @@ void inittinyarray()
PyModule_AddObject(m, "__version__", PyString_FromString(VERSION));
PyObject *all = PyList_New(0);
for (const PyMethodDef *f = functions; f->ml_name; ++f) {
if (f->ml_name[0] == '_') continue;
PyObject *f_py = PyObject_GetAttrString(m, f->ml_name);
PyList_Append(all, PyObject_GetAttrString(f_py, "__name__"));
Py_DECREF(f_py);
}
PyModule_AddObject(m, "__all__", all);
PyModule_AddObject(m, "ndarray_int",
(PyObject *)&Array<long>::pytype);
PyModule_AddObject(m, "ndarray_float",
......@@ -1665,7 +1709,7 @@ PyTypeObject Array<T>::pytype = {
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_HAVE_NEWBUFFER |
Py_TPFLAGS_CHECKTYPES, // tp_flags
doc, // tp_doc
0, // tp_doc
0, // tp_traverse
0, // tp_clear
(richcmpfunc)richcompare, // tp_richcompare
......
......@@ -17,6 +17,7 @@ const int max_ndim = 16;
// First constant must be 0, the last one must be `NONE'.
enum Dtype {LONG = 0, DOUBLE, COMPLEX, NONE};
const Dtype default_dtype = DOUBLE;
#define DEFAULT_DTYPE "float"
extern const char *dtype_names[];
......
......@@ -121,11 +121,19 @@ PyObject *zeros(PyObject *, PyObject *args)
return filled(args, 0);
}
PyDoc_STRVAR(zeros_doc,
"zeros(shape, dtype="DEFAULT_DTYPE")\n\n\
Return an array of given shape and type, filled with zeros.");
PyObject *ones(PyObject *, PyObject *args)
{
return filled(args, 1);
}
PyDoc_STRVAR(ones_doc,
"ones(shape, dtype="DEFAULT_DTYPE")\n\n\
Return an array of given shape and type, filled with ones.");
template <typename T>
PyObject *identity(size_t n)
{
......@@ -161,6 +169,10 @@ PyObject *identity(PyObject *, PyObject *args)
return identity_dtable[int(dtype)](n);
}
PyDoc_STRVAR(identity_doc,
"identity(n, dtype="DEFAULT_DTYPE")\n\n\
Return an identity matrix of given size and dtype.");
PyObject *array(PyObject *, PyObject *args)
{
PyObject *src;
......@@ -170,6 +182,12 @@ PyObject *array(PyObject *, PyObject *args)
return array_from_arraylike(src, &dtype);
}
PyDoc_STRVAR(array_doc,
"array(object, [dtype])\n\n\
Create an array from something array-like.\n\
Valid inputs are numbers, sequences (of sequences, ...) of numbers, NumPy\n\
and tinyarray arrays, and objects supporting the buffer protocol.");
PyObject *matrix(PyObject *, PyObject *args)
{
PyObject *src;
......@@ -179,6 +197,12 @@ PyObject *matrix(PyObject *, PyObject *args)
return matrix_from_arraylike(src, &dtype);
}
PyDoc_STRVAR(matrix_doc,
"matrix(object, [dtype])\n\n\
Create an 2-d array from something array-like.\n\
Valid inputs are the same as for array(), however the input is promoted to 2-d.\n\
A ``ValueError`` is raised if the input has more than 2 dimensions.");
PyObject *(*transpose_dtable[])(PyObject*, PyObject *) =
DTYPE_DISPATCH(transpose);
......@@ -192,6 +216,10 @@ PyObject *transpose(PyObject *, PyObject *args)
return transpose_dtable[int(dtype)](a, 0);
}
PyDoc_STRVAR(transpose_doc,
"transpose(a)\n\n\
Return a copy of the given array with reversed order of dimensions.");
PyObject *dot(PyObject *, PyObject *args)
{
PyObject *a, *b;
......@@ -199,6 +227,14 @@ PyObject *dot(PyObject *, PyObject *args)
return dot_product(a, b);
}
PyDoc_STRVAR(dot_doc,
"dot(a, b)\n\n\
Return the dot product of two arrays.\n\n\
For 2-d arrays, the dot product is equivalent to matrix multiplication; for 1-d\n\
arrays, to a scalar product of vectors. In the general case, it is equivalent\n\
to a sum over the last axis of a and the second-to-last of b, e.g.::\n\n\
dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])");
template <template <typename> class Op>
PyObject *binary_ufunc(PyObject *, PyObject *args)
{
......@@ -245,32 +281,39 @@ PyObject *unary_ufunc_round(PyObject *, PyObject *args)
return result;
}
PyDoc_STRVAR(binary_ufunc_doc,
"Operates elementwise on two arrays, returns an array of the same shape.");
PyDoc_STRVAR(unary_ufunc_doc,
"Operates elementwise on an array, returns an array of the same shape.");
} // Anonymous namespace
PyMethodDef functions[] = {
{"_reconstruct", reconstruct, METH_VARARGS},
{"zeros", zeros, METH_VARARGS},
{"ones", ones, METH_VARARGS},
{"identity", identity, METH_VARARGS},
{"array", array, METH_VARARGS},
{"matrix", matrix, METH_VARARGS},
{"transpose", transpose, METH_VARARGS},
{"dot", dot, METH_VARARGS},
{"add", binary_ufunc<Add>, METH_VARARGS},
{"subtract", binary_ufunc<Subtract>, METH_VARARGS},
{"multiply", binary_ufunc<Multiply>, METH_VARARGS},
{"divide", binary_ufunc<Divide>, METH_VARARGS},
{"remainder", binary_ufunc<Remainder>, METH_VARARGS},
{"floor_divide", binary_ufunc<Floor_divide>, METH_VARARGS},
{"negative", unary_ufunc<Negative>, METH_VARARGS},
{"abs", unary_ufunc<Absolute>, METH_VARARGS},
{"absolute", unary_ufunc<Absolute>, METH_VARARGS},
{"conjugate", unary_ufunc<Conjugate>, METH_VARARGS},
{"round", unary_ufunc_round<Nearest>, METH_VARARGS},
{"floor", unary_ufunc_round<Floor>, METH_VARARGS},
{"ceil", unary_ufunc_round<Ceil>, METH_VARARGS},
{"zeros", zeros, METH_VARARGS, zeros_doc},
{"ones", ones, METH_VARARGS, ones_doc},
{"identity", identity, METH_VARARGS, identity_doc},
{"array", array, METH_VARARGS, array_doc},
{"matrix", matrix, METH_VARARGS, matrix_doc},
{"transpose", transpose, METH_VARARGS, transpose_doc},
{"dot", dot, METH_VARARGS, dot_doc},
{"add", binary_ufunc<Add>, METH_VARARGS, binary_ufunc_doc},
{"subtract", binary_ufunc<Subtract>, METH_VARARGS, binary_ufunc_doc},
{"multiply", binary_ufunc<Multiply>, METH_VARARGS, binary_ufunc_doc},
{"divide", binary_ufunc<Divide>, METH_VARARGS, binary_ufunc_doc},
{"remainder", binary_ufunc<Remainder>, METH_VARARGS, binary_ufunc_doc},
{"floor_divide", binary_ufunc<Floor_divide>, METH_VARARGS,
binary_ufunc_doc},
{"negative", unary_ufunc<Negative>, METH_VARARGS, unary_ufunc_doc},
{"abs", unary_ufunc<Absolute>, METH_VARARGS, unary_ufunc_doc},
{"absolute", unary_ufunc<Absolute>, METH_VARARGS, unary_ufunc_doc},
{"conjugate", unary_ufunc<Conjugate>, METH_VARARGS, unary_ufunc_doc},
{"round", unary_ufunc_round<Nearest>, METH_VARARGS, unary_ufunc_doc},
{"floor", unary_ufunc_round<Floor>, METH_VARARGS, unary_ufunc_doc},
{"ceil", unary_ufunc_round<Ceil>, METH_VARARGS, unary_ufunc_doc},
{0, 0, 0, 0} // Sentinel
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment