You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@singa.apache.org by wa...@apache.org on 2016/07/01 08:24:44 UTC
[1/6] incubator-singa git commit: SINGA-186 Create Python Tensor class
Repository: incubator-singa
Updated Branches:
refs/heads/dev f026b6050 -> cde7dcf6b
SINGA-186 Create Python Tensor class
- Update core_tensor.i, tensor.py to take care of the following methods
. Random operations
. Axpy
. Mult
. Pow
. AddColumn, SubColumn, MultColumn, DivColumn, and xxxRow, etc.
. SumColumns, SumRows
- Revised model_layer.i, layer.h to take care of Shape (std::vector)
TODO: from_array() in python
Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/7cfdb995
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/7cfdb995
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/7cfdb995
Branch: refs/heads/dev
Commit: 7cfdb995cd32624779330fb336a2771da9a5ba00
Parents: 62c6603
Author: chonho <le...@comp.nus.edu.sg>
Authored: Mon Jun 27 18:01:52 2016 +0800
Committer: chonho <le...@comp.nus.edu.sg>
Committed: Thu Jun 30 15:00:45 2016 +0800
----------------------------------------------------------------------
include/singa/model/layer.h | 5 +-
src/core/tensor/tensor.cc | 17 +--
src/python/swig/core_device.i | 2 +-
src/python/swig/core_tensor.i | 137 ++++++++++++++++++------
src/python/swig/model_layer.i | 13 ++-
src/python/tensor.py | 208 +++++++++++++++++++++++++++++++++----
6 files changed, 318 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/7cfdb995/include/singa/model/layer.h
----------------------------------------------------------------------
diff --git a/include/singa/model/layer.h b/include/singa/model/layer.h
index ce8007c..938b161 100644
--- a/include/singa/model/layer.h
+++ b/include/singa/model/layer.h
@@ -28,6 +28,7 @@
namespace singa {
+typedef vector<size_t> Shape;
/// The base layer class.
/// Generally, a layer conducts feature transformation against a set of Tensor
/// to generate a set of Tensor. Each layer may have some parameters.
@@ -37,14 +38,14 @@ class Layer {
/// Set meta data fields from a string representing a proto message.
/// 'in_shape' is the shape of the input feature for one sample
- void Setup(const vector<size_t>& in_shape, const string& proto_str) {
+ void Setup(const Shape& in_shape, const string& proto_str) {
LayerConf conf;
conf.ParseFromString(proto_str);
this->Setup(in_shape, conf);
}
/// 'in_shapes' is the shape of the input feature for one sample
- void Setup(const vector<vector<size_t>>& in_shapes, const string& proto_str) {
+ void Setup(const vector<Shape>& in_shapes, const string& proto_str) {
LayerConf conf;
conf.ParseFromString(proto_str);
this->Setup(in_shapes, conf);
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/7cfdb995/src/core/tensor/tensor.cc
----------------------------------------------------------------------
diff --git a/src/core/tensor/tensor.cc b/src/core/tensor/tensor.cc
index 3501ecd..4972a86 100644
--- a/src/core/tensor/tensor.cc
+++ b/src/core/tensor/tensor.cc
@@ -680,7 +680,7 @@ void AddColumn(const SType alpha, const SType beta, const Tensor &v,
AddRow(v, &X);
} else {
CHECK_EQ(M->nDim(), 2u);
- CHECK_EQ(v.nDim(), 1u);
+ // CHECK_EQ(v.nDim(), 1u); (chonho) shape of v is 2-element tuple
size_t nb_row = M->shape(0), nb_col = M->shape(1);
CHECK_EQ(nb_row, v.Size());
@@ -690,7 +690,7 @@ void AddColumn(const SType alpha, const SType beta, const Tensor &v,
Mult(alpha, vmat, one, beta, M);
}
}
-template <>
+template
void AddColumn(const float alpha, const float beta, const Tensor &v, Tensor *M);
void AddRow(const Tensor &v, Tensor *M) { AddRow(1, 1, v, M); }
@@ -703,7 +703,7 @@ void AddRow(const SType alpha, const SType beta, const Tensor &v, Tensor *M) {
AddColumn(v, &X);
} else {
CHECK_EQ(M->nDim(), 2u);
- CHECK_EQ(v.nDim(), 1u);
+ // CHECK_EQ(v.nDim(), 1u); (chonho) shape of v is 2-element tuple
size_t nb_row = M->shape(0), nb_col = M->shape(1);
CHECK_EQ(nb_col, v.Size());
@@ -804,7 +804,7 @@ void DivRow(const Tensor &v, Tensor *M) {
void MultColumn(const Tensor &v, Tensor *M) {
CHECK(!M->transpose()) << "Not supported yet";
CHECK_EQ(M->nDim(), 2u);
- CHECK_EQ(v.nDim(), 1u);
+ // CHECK_EQ(v.nDim(), 1u); (chonho) shape of v is 2-element tuple
CHECK_EQ(v.Size(), M->shape(0));
CheckDataTypeAndLang(*M, v);
TYPE_LANG_SWITCH(v.data_type(), DType, v.device()->lang(), Lang, {
@@ -819,7 +819,7 @@ void MultColumn(const Tensor &v, Tensor *M) {
void MultRow(const Tensor &v, Tensor *M) {
CHECK(!M->transpose()) << "Not supported yet";
CHECK_EQ(M->nDim(), 2u);
- CHECK_EQ(v.nDim(), 1u);
+ // CHECK_EQ(v.nDim(), 1u); (chonho) shape of v is 2-element tuple
CHECK_EQ(v.Size(), M->shape(1));
CheckDataTypeAndLang(*M, v);
TYPE_LANG_SWITCH(v.data_type(), DType, v.device()->lang(), Lang, {
@@ -857,7 +857,7 @@ void SumColumns(const Tensor &M, Tensor *v) {
SumRows(X, v);
} else {
CHECK_EQ(M.nDim(), 2u);
- CHECK_EQ(v->nDim(), 1u);
+ // CHECK_EQ(v->nDim(), 1u); (chonho) shape of v is 2-element tuple
size_t nb_row = M.shape().at(0), nb_col = M.shape().at(1);
CHECK_EQ(nb_row, v->Size());
@@ -872,7 +872,7 @@ void SumRows(const Tensor &M, Tensor *v) {
SumColumns(X, v);
} else {
CHECK_EQ(M.nDim(), 2u);
- CHECK_EQ(v->nDim(), 1u);
+ // CHECK_EQ(v->nDim(), 1u); (chonho) shape of v is 2-element tuple
size_t nb_row = M.shape(0), nb_col = M.shape(1);
CHECK_EQ(nb_col, v->Size());
@@ -929,7 +929,8 @@ void Axpy(const SType alpha, const Tensor &in, Tensor *out) {
}, {in.block(), out->block()}, {out->block()});
});
}
-template void Axpy(const float alpha, const Tensor &in, Tensor *out);
+template
+void Axpy<float>(const float alpha, const Tensor &in, Tensor *out);
Tensor Mult(const Tensor &A, const Tensor &B) {
Shape s;
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/7cfdb995/src/python/swig/core_device.i
----------------------------------------------------------------------
diff --git a/src/python/swig/core_device.i b/src/python/swig/core_device.i
index ab9abd8..50cee3e 100644
--- a/src/python/swig/core_device.i
+++ b/src/python/swig/core_device.i
@@ -35,7 +35,7 @@ namespace singa{
class Device {
public:
virtual void SetRandSeed(unsigned seed) = 0;
- Device* host();
+ std::shared_ptr<Device> host();
int id() const;
};
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/7cfdb995/src/python/swig/core_tensor.i
----------------------------------------------------------------------
diff --git a/src/python/swig/core_tensor.i b/src/python/swig/core_tensor.i
index 409ab0c..e30f2ef 100644
--- a/src/python/swig/core_tensor.i
+++ b/src/python/swig/core_tensor.i
@@ -32,6 +32,7 @@
%array_class(double, doubleArray);
%{
+#define SWIG_FILE_WITH_INIT
#include "singa/core/tensor.h"
#include "singa/core/device.h"
#include "singa/proto/core.pb.h"
@@ -51,6 +52,7 @@ namespace singa{
int start = 0, size_t len = 0);
inline size_t SizeOf(DataType t);
+
class Tensor {
public:
@@ -58,11 +60,11 @@ namespace singa{
explicit Tensor(const std::vector<size_t> &shape,
DataType dtype = kFloat32);
Tensor(const std::vector<size_t> &shape,
- singa::Device *dev, DataType dtype = kFloat32);
+ std::shared_ptr<singa::Device> dev, DataType dtype = kFloat32);
Tensor(const Tensor &from);
//Blob *blob() const;
- singa::Device *device() const;
+ std::shared_ptr<singa::Device> device() const;
template <typename DType> DType data() const;
%template(floatData) data<const float*>;
@@ -80,23 +82,24 @@ namespace singa{
void Reshape(const std::vector<size_t> &shape);
void ResetLike(const Tensor &t);
void AsType(DataType type);
- void ToDevice(singa::Device *dev);
+ void ToDevice(std::shared_ptr<singa::Device> dev);
void ToHost();
+ float L2();
template <typename SType> void SetValue(const SType x);
%template(floatSetValue) SetValue<float>;
// ...
- /* no need to expose this function
template <typename DType> void CopyDataFromHostPtr(const DType *src,
- size_t num);
- */
+ const size_t num,
+ const size_t offset);
+ %template(floatCopyData) CopyDataFromHostPtr<float>;
void CopyData(const Tensor &other);
Tensor Clone() const;
Tensor T() const;
- /* python has no assignment operator as c++
+ /* python has no assignment operator
Tensor &operator=(const Tensor &t); */
Tensor &operator+=(const Tensor &t);
Tensor &operator-=(const Tensor &t);
@@ -124,9 +127,17 @@ namespace singa{
/* TODO(chonho-01) for other types */
// ...
+
+ /*TODO(chonho-08-b)
+ amax
+ amin
+ asum
+ */
+
+
};
- /* TODO
+ /* TODO(chonho-02)
inline void CheckDataTypeAndLang(const Tensor &in1, const Tensor &in2);
*/
void CopyDataToFrom(Tensor *dst, const Tensor &src, size_t num,
@@ -147,22 +158,25 @@ namespace singa{
Tensor Sum(const Tensor &t, int axis);
template <typename SType> SType Sum(const Tensor &t);
%template(floatSum) Sum<float>;
- /* TODO(chonho-03) not implemented
- %template(intSum) Sum<int>;
- %template(charSum) Sum<char>;
- %template(doubleSum) Sum<double>;
- */
+ // --- other types
- /* TODO(chonho-04) not implemented
- need average of all elements ??? */
+ /* TODO(chonho-04)
+ need to implement the average of all elements ??? */
Tensor Average(const Tensor &t, int axis);
- Tensor SoftMax(const Tensor &t, int axis = 0);
- /* TODO(chonho-05) not implemented ???
- Tensor Pow(const Tensor &base, Tensor exp);
- template <typename DType>
- Tensor Pow(const Tensor &t, DType x);
- */
+
+ Tensor Pow(const Tensor &base, const Tensor &exp);
+ void Pow(const Tensor &base, const Tensor &exp, Tensor *out);
+
+ %rename(Pow_f) Pow(const Tensor &in, const float x);
+ template <typename SType>
+ Tensor Pow(const Tensor &in, const SType x);
+ %template(pow_temp) Pow<float>;
+
+ %rename(Pow_f_out) Pow(const Tensor &in, const float x, Tensor *out);
+ template <typename SType>
+ void Pow(const Tensor &in, const SType x, Tensor *out);
+ %template(pow_temp) Pow<float>;
/* rename comparison operators */
@@ -206,10 +220,10 @@ namespace singa{
*/
- /* rename operators */
+ /* ========== Arithmetic operations ========== */
%rename(Add_TT) operator+(const Tensor &lhs, const Tensor &rhs);
%rename(Sub_TT) operator-(const Tensor &lhs, const Tensor &rhs);
- %rename(Mul_TT) operator*(const Tensor &lhs, const Tensor &rhs);
+ %rename(EltwiseMul_TT) operator*(const Tensor &lhs, const Tensor &rhs);
%rename(Div_TT) operator/(const Tensor &lhs, const Tensor &rhs);
Tensor operator+(const Tensor &lhs, const Tensor &rhs);
Tensor operator-(const Tensor &lhs, const Tensor &rhs);
@@ -228,7 +242,7 @@ namespace singa{
%template(op) operator-<float>;
// --- other types
- %rename(Mul_Tf) operator*(const Tensor &t, float x);
+ %rename(EltwiseMul_Tf) operator*(const Tensor &t, float x);
template <typename DType>
Tensor operator*(const Tensor &t, DType x);
%template(op) operator*<float>;
@@ -240,10 +254,6 @@ namespace singa{
%template(op) operator/<float>;
// --- other types
- /* TODO(chonho-07)
- no need to include theses
- in python, these can be replaced with operators
-
void Add(const Tensor &lhs, const Tensor &rhs, Tensor *ret);
void Sub(const Tensor &lhs, const Tensor &rhs, Tensor *ret);
void EltwiseMult(const Tensor &lhs, const Tensor &rhs, Tensor *ret);
@@ -251,13 +261,82 @@ namespace singa{
template <typename DType>
void Add(const Tensor &t, DType x, Tensor *ret);
+ %template(Add_Tf_out) Add<float>;
+ // --- other types
+
template <typename DType>
void Sub(const Tensor &t, DType x, Tensor *ret);
+ %template(Sub_Tf_out) Sub<float>;
+ // --- other types
+
template <typename DType>
void EltwiseMult(const Tensor &t, DType x, Tensor *ret);
+ %template(EltwiseMult_Tf_out) EltwiseMult<float>;
+ // --- other types
+
template <typename DType>
void Div(const Tensor &t, DType x, Tensor *ret);
- */
+ %template(Div_Tf_out) Div<float>;
+ // --- other types
+
+
+ /* ========== Random operations ========== */
+ template <typename SType>
+ void Bernoulli(const SType p, Tensor *out);
+ %template(floatBernoulli) Bernoulli<float>;
+ /* TODO for other types */
+ // ...
+
+ template <typename SType>
+ void Gaussian(const SType mean, const SType std, Tensor *out);
+ %template(floatGaussian) Gaussian<float>;
+ /* TODO for other types */
+ // ...
+
+ template <typename SType>
+ void Uniform(const SType low, const SType high, Tensor *out);
+ %template(floatUniform) Uniform<float>;
+ /* TODO for other types */
+ // ...
+
+ /* ========== Blas operations ========== */
+ template <typename SType>
+ void Axpy(SType alpha, const Tensor &in, Tensor *out);
+ %template(floatAxpy) Axpy<float>;
+ /* TODO for other types */
+ // ...
+
+ Tensor Mult(const Tensor &A, const Tensor &B);
+ void Mult(const Tensor &A, const Tensor &B, Tensor *C);
+ template <typename SType>
+ void Mult(const SType alpha, const Tensor &A, const Tensor &B,
+ const SType beta, Tensor *C);
+ %template(floatMult) Mult<float>;
+
+ void AddColumn(const Tensor &v, Tensor *M);
+ template <typename SType>
+ void AddColumn(const SType alpha, const SType beta, const Tensor &v,
+ Tensor *M);
+ %template(floatAddColumn) AddColumn<float>;
+
+ void AddRow(const Tensor &v, Tensor *M);
+ template <typename SType>
+ void AddRow(const SType alpha, const SType beta, const Tensor &v,
+ Tensor *M);
+ %template(floatAddRow) AddRow<float>;
+
+ void DivColumn(const Tensor &v, Tensor *M);
+ void DivRow(const Tensor &v, Tensor *M);
+ void MultColumn(const Tensor &v, Tensor *M);
+ void MultRow(const Tensor &v, Tensor *M);
+ void SubColumn(const Tensor &v, Tensor *M);
+ void SubRow(const Tensor &v, Tensor *M);
+
+ void SumColumns(const Tensor &M, Tensor *v);
+ void SumRows(const Tensor &M, Tensor *v);
+
+ Tensor SoftMax(const Tensor &in);
+ void SoftMax(const Tensor &in, Tensor *out);
}
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/7cfdb995/src/python/swig/model_layer.i
----------------------------------------------------------------------
diff --git a/src/python/swig/model_layer.i b/src/python/swig/model_layer.i
index 3fb4917..15bd05f 100644
--- a/src/python/swig/model_layer.i
+++ b/src/python/swig/model_layer.i
@@ -21,7 +21,7 @@
/*interface file for swig */
-%module singa_layer
+%module model_layer
%include "std_vector.i"
%include "std_string.i"
%include "std_pair.i"
@@ -46,12 +46,14 @@ namespace std {
%template(tvectvecPair) pair<vector<Tensor>, vector<Tensor>>;
}
+
namespace singa {
class Layer {
public:
Layer();
- void Setup(const std::string& proto_str);
+ void Setup(const std::vector<size_t>&, const string&);
+ void Setup(const std::vector<vector<size_t>>&, const string&);
std::string ToProtoStr() const;
const std::vector<ParamSpec> param_specs();
@@ -64,8 +66,11 @@ namespace singa {
/* virtual functions */
virtual const std::string layer_type() const;
- virtual void Setup(const LayerConf& conf);
- virtual void ToDevice(Device* device);
+ virtual void Setup(const std::vector<size_t>&,
+ const LayerConf&);
+ virtual void Setup(const std::vector<std::vector<size_t>>&,
+ const LayerConf&);
+ virtual void ToDevice(std::shared_ptr<Device> device);
virtual void AsType(DataType dtype);
virtual void ToProto(LayerConf* conf) const;
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/7cfdb995/src/python/tensor.py
----------------------------------------------------------------------
diff --git a/src/python/tensor.py b/src/python/tensor.py
index 04e070d..d382aae 100644
--- a/src/python/tensor.py
+++ b/src/python/tensor.py
@@ -28,6 +28,7 @@ to call singa::Tensor and its methods
import sys
import os
import numpy as np
+import ctypes
sys.path.append(os.path.join(os.path.dirname(__file__),
'../../build/lib'))
@@ -62,7 +63,7 @@ class Tensor(object):
self.device = device
self.dtype = dtype
- def toarray(self):
+ def to_array(self):
# TODO(chonho) - need to think more efficient way to convert???
idx = self.singa_tensor.data_type()
if idx == kFloat32:
@@ -92,6 +93,21 @@ class Tensor(object):
data = np.array(data, dtype=dt).reshape(self.tuple_shape)
return data
+ def from_array(self, np_array):
+ # TODO(chonho)
+ test = np.array([[1,2],[3,4]], dtype=np.float32)
+ test = test.flatten()
+ self.singa_tensor.floatCopyData(test, 4, 0)
+ '''
+ c_float_ptr = ctypes.POINTER(ctypes.c_float)
+ data_ptr = test.ctypes.data_as(c_float_ptr)
+ self.singa_tensor.floatCopyData(data_ptr, 4, 0)
+ '''
+ '''
+ d = [1.0, 2.0, 3.0, 4.0]
+ self.singa_tensor.floatCopyData(d, 4, 0)
+ '''
+
def data_type(self):
return self.singa_tensor.data_type()
@@ -131,8 +147,12 @@ class Tensor(object):
def to_host(self):
self.singa_tensor.ToHost()
+ def nrm2(self):
+ self.singa_tensor.L2()
+
def set_value(self, x):
- self.singa_tensor.SetValue(x)
+ if type(x) == float:
+ self.singa_tensor.floatSetValue(x)
def copy_data(self, t):
self.singa_tensor.CopyData(t.singa_tensor)
@@ -161,6 +181,36 @@ class Tensor(object):
'''
return self.clone()
+ def bernoulli(self, p):
+ if type(p) == float:
+ singa.floatBernoulli(p, self.singa_tensor)
+
+ def gaussian(self, mean, std):
+ if type(mean) == float:
+ singa.floatGaussian(mean, std, self.singa_tensor)
+
+ def uniform(self, low, high):
+ if type(low) == float:
+ singa.floatUniform(low, high, self.singa_tensor)
+
+ def add_column(self, v):
+ singa.AddColumn(v.singa_tensor, self.singa_tensor)
+
+ def add_row(self, v):
+ singa.AddRow(v.singa_tensor, self.singa_tensor)
+
+ def div_column(self, v):
+ singa.DivColumn(v.singa_tensor, self.singa_tensor)
+
+ def div_row(self, v):
+ singa.DivRow(v.singa_tensor, self.singa_tensor)
+
+ def mult_column(self, v):
+ singa.MultColumn(v.singa_tensor, self.singa_tensor)
+
+ def mult_row(self, v):
+ singa.MultRow(v.singa_tensor, self.singa_tensor)
+
'''
python operators (+=, -=, *=, /=) for singa::Tensor unary operators
'''
@@ -213,10 +263,10 @@ class Tensor(object):
def __mul__(self, rhs):
if isinstance(rhs, Tensor):
- return _call_singa_func(singa.Mul_TT,
+ return _call_singa_func(singa.EltwiseMul_TT,
self.singa_tensor, rhs.singa_tensor)
else:
- return _call_singa_func(singa.Mul_Tf,
+ return _call_singa_func(singa.EltwiseMul_Tf,
self.singa_tensor, rhs)
def __div__(self, rhs):
@@ -296,16 +346,30 @@ def sum(t, axis=None):
return _call_singa_func(singa.Sum, t.singa_tensor, axis)
-def pow(t, x):
- print 'not implemented yet'
+def pow(t, x, out=None):
+ if out is None:
+ if isinstance(x, Tensor):
+ return _call_singa_func(singa.Pow, t.singa_tensor, x.singa_tensor)
+ else:
+ return _call_singa_func(singa.Pow_f, t.singa_tensor, x)
+ else:
+ if isinstance(x, Tensor):
+ singa.Pow(t.singa_tensor, x.singa_tensor, out.singa_tensor)
+ else:
+ singa.Pow_f_out(t.singa_tensor, x, out.singa_tensor)
+ return out
def average(t, axis=0):
return _call_singa_func(singa.Average, t.singa_tensor, axis)
-def softmax(t, axis=0):
- return _call_singa_func(singa.SoftMax, t.singa_tensor, axis)
+def softmax(t, out=None):
+ if out is None:
+ return _call_singa_func(singa.SoftMax, t.singa_tensor)
+ else:
+ singa.SoftMax(t.singa_tensor, out.singa_tensor)
+ return out
def lt(t, x):
@@ -324,24 +388,128 @@ def ge(t, x):
return t >= x
-def add(lhs, rhs):
- # call Tensor.__add__()
- return lhs + rhs
+def add(lhs, rhs, ret=None):
+ if ret is None:
+ # call Tensor.__add__()
+ return lhs + rhs
+ else:
+ if isinstance(rhs, Tensor):
+ singa.Add(lhs.singa_tensor, rhs.singa_tensor, ret.singa_tensor)
+ else:
+ singa.Add_Tf_out(lhs.singa_tensor, rhs, ret.singa_tensor)
+ return ret
+
+def sub(lhs, rhs, ret=None):
+ if ret is None:
+ # call Tensor.__sub__()
+ return lhs - rhs
+ else:
+ if isinstance(rhs, Tensor):
+ singa.Sub(lhs.singa_tensor, rhs.singa_tensor, ret.singa_tensor)
+ else:
+ singa.Sub_Tf_out(lhs.singa_tensor, rhs, ret.singa_tensor)
+ return ret
+
+
+def eltwise_mult(lhs, rhs, ret=None):
+ if ret is None:
+ # call Tensor.__mul__()
+ return lhs * rhs
+ else:
+ if isinstance(rhs, Tensor):
+ singa.EltwiseMult(lhs.singa_tensor, rhs.singa_tensor,
+ ret.singa_tensor)
+ else:
+ singa.EltwiseMult_Tf_out(lhs.singa_tensor, rhs,
+ ret.singa_tensor)
+ return ret
+
+
+def mult(A, B, C=None, alpha=1.0, beta=0.0):
+ if C is None:
+ return _call_singa_func(singa.Mult, A.singa_tensor, B.singa_tensor)
+ else:
+ singa.floatMult(alpha, A.singa_tensor, B.singa_tensor,
+ beta, C.singa_tensor)
+ return C
+
+
+'''
+TODO(chonho) combined into the above
+ delete later
+def mult(A, B, C=None):
+ if C is None:
+ return _call_singa_func(singa.Mult, A.singa_tensor, B.singa_tensor)
+ else:
+ singa_Mult(A.singa_tensor, B.singa_tensor, C.singa_tensor)
+ return C
+
+def axypbz(alpha, A, B, b, C):
+ singa.floatMult(alpha, A.singa_tensor, B.singa_tensor, b, C.singa_tensor)
+ return C
+'''
+
+
+def div(lhs, rhs, ret=None):
+ if ret is None:
+ # call Tensor.__div__()
+ return lhs / rhs
+ else:
+ if isinstance(rhs, Tensor):
+ singa.Div(lhs.singa_tensor, rhs.singa_tensor, ret.singa_tensor)
+ else:
+ singa.Div_Tf_out(lhs.singa_tensor, rhs, ret.singa_tensor)
+ return ret
+
+
+def axpy(alpha, x, y):
+ if type(alpha) == float:
+ singa.floatAxpy(alpha, x.singa_tensor, y.singa_tensor)
+ return y
+
+
+def bernoulli(p, t):
+ if type(p) == float:
+ singa.floatBernoulli(p, t.singa_tensor)
+ return t
+
+
+def gaussian(mean, std, t):
+ if type(mean) == float:
+ singa.floatGaussian(mean, std, t.singa_tensor)
+ return t
+
+
+def uniform(low, high, t):
+ if type(low) == float:
+ singa.floatUniform(low, high, t.singa_tensor)
+ return t
+
+
+def add_column(alpha, v, beta, M):
+ singa.floatAddColumn(alpha, beta, v.singa_tensor, M.singa_tensor)
+ return M
-def sub(lhs, rhs):
- # call Tensor.__sub__()
- return lhs - rhs
+def add_row(alpha, v, beta, M):
+ singa.floatAddRow(alpha, beta, v.singa_tensor, M.singa_tensor)
+ return M
-def eltwise_mult(lhs, rhs):
- # call Tensor.__mul__()
- return lhs * rhs
+def sum_columns(M):
+ assert M.ndim() == 2, 'M.nDim() is supposed to be 2'
+ nb_col = M.shape(0)
+ ret = Tensor((nb_col, 1))
+ singa.SumColumns(M.singa_tensor, ret.singa_tensor)
+ return ret
-def div(lhs, rhs):
- # call Tensor.__div__()
- return lhs / rhs
+def sum_rows(M):
+ assert M.ndim() == 2, 'M.nDim() is supposed to be 2'
+ nb_row = M.shape(1)
+ ret = Tensor((1, nb_row))
+ singa.SumRows(M.singa_tensor, ret.singa_tensor)
+ return ret
''' private functions, internally used
[2/6] incubator-singa git commit: SINGA-186 Create Python Tensor class
Posted by wa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/50f67226/src/python/tensor.py
----------------------------------------------------------------------
diff --git a/src/python/tensor.py b/src/python/tensor.py
index d382aae..b8abb5c 100644
--- a/src/python/tensor.py
+++ b/src/python/tensor.py
@@ -28,7 +28,6 @@ to call singa::Tensor and its methods
import sys
import os
import numpy as np
-import ctypes
sys.path.append(os.path.join(os.path.dirname(__file__),
'../../build/lib'))
@@ -64,7 +63,7 @@ class Tensor(object):
self.dtype = dtype
def to_array(self):
- # TODO(chonho) - need to think more efficient way to convert???
+ # TODO(chonho): depreciated (will be deleted later)
idx = self.singa_tensor.data_type()
if idx == kFloat32:
data_array = singa.floatArray_frompointer(
@@ -73,9 +72,6 @@ class Tensor(object):
elif idx == kFloat16:
print 'not implemented yet'
return
- # data_array = singa.floatArray_frompointer(
- # self.singa_tensor.floatData())
- # dt = np.float16
elif idx == kInt:
data_array = singa.intArray_frompointer(
self.singa_tensor.intData())
@@ -93,20 +89,28 @@ class Tensor(object):
data = np.array(data, dtype=dt).reshape(self.tuple_shape)
return data
- def from_array(self, np_array):
- # TODO(chonho)
- test = np.array([[1,2],[3,4]], dtype=np.float32)
- test = test.flatten()
- self.singa_tensor.floatCopyData(test, 4, 0)
+ def copy_to_numpy(self):
+ ''' this method gets the values of tensor data and
+ returns it as numpy array
'''
- c_float_ptr = ctypes.POINTER(ctypes.c_float)
- data_ptr = test.ctypes.data_as(c_float_ptr)
- self.singa_tensor.floatCopyData(data_ptr, 4, 0)
- '''
- '''
- d = [1.0, 2.0, 3.0, 4.0]
- self.singa_tensor.floatCopyData(d, 4, 0)
+ if self.dtype == kFloat32:
+ np_array = self.singa_tensor.floatGetValue(int(self.size()))
+ else:
+ print 'Not implemented yet for ', self.dtype
+ return np_array.reshape(self.tuple_shape)
+
+ def copy_from_numpy(self, np_array, offset=0):
+ ''' this method stores the values of numpy array into tensor data
+ from the position of offset
'''
+ assert np_array.size == self.size(), 'tensor shape should be the same'
+ if not np_array.ndim == 1:
+ np_array = np_array.flatten()
+ dt = np_array.dtype
+ if dt == np.float32:
+ self.singa_tensor.floatCopyDataFromHostPtr(np_array, offset)
+ else:
+ print 'Not implemented yet for ', dt
def data_type(self):
return self.singa_tensor.data_type()
@@ -306,9 +310,19 @@ def reshape(t, s):
return _call_singa_func(singa.Reshape, t.singa_tensor, s)
-def copy_data_to_from(dst, src, size, src_offset=0, dst_offset=0):
+def copy_data_to_from(dst, src, size, dst_offset=0, src_offset=0):
singa.CopyDataToFrom(dst.singa_tensor, src.singa_tensor, size,
- src_offset, dst_offset)
+ dst_offset, src_offset)
+
+
+def from_numpy(np_array):
+ ret = Tensor(np_array.shape)
+ ret.copy_from_numpy(np_array)
+ return ret
+
+
+def to_numpy(t):
+ return t.copy_to_numpy()
def abs(t):
@@ -426,6 +440,9 @@ def eltwise_mult(lhs, rhs, ret=None):
def mult(A, B, C=None, alpha=1.0, beta=0.0):
+ '''
+ This function returns C = alpha * A * B + beta * C
+ '''
if C is None:
return _call_singa_func(singa.Mult, A.singa_tensor, B.singa_tensor)
else:
@@ -434,22 +451,6 @@ def mult(A, B, C=None, alpha=1.0, beta=0.0):
return C
-'''
-TODO(chonho) combined into the above
- delete later
-def mult(A, B, C=None):
- if C is None:
- return _call_singa_func(singa.Mult, A.singa_tensor, B.singa_tensor)
- else:
- singa_Mult(A.singa_tensor, B.singa_tensor, C.singa_tensor)
- return C
-
-def axypbz(alpha, A, B, b, C):
- singa.floatMult(alpha, A.singa_tensor, B.singa_tensor, b, C.singa_tensor)
- return C
-'''
-
-
def div(lhs, rhs, ret=None):
if ret is None:
# call Tensor.__div__()
@@ -462,6 +463,12 @@ def div(lhs, rhs, ret=None):
return ret
+def axypbz(alpha, A, B, b, C):
+ # TODO(chonho): depreciated (will be deleted later)
+ singa.floatMult(alpha, A.singa_tensor, B.singa_tensor, b, C.singa_tensor)
+ return C
+
+
def axpy(alpha, x, y):
if type(alpha) == float:
singa.floatAxpy(alpha, x.singa_tensor, y.singa_tensor)
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/50f67226/test/python/unittest_python.py
----------------------------------------------------------------------
diff --git a/test/python/unittest_python.py b/test/python/unittest_python.py
index e1f4b64..569a7ad 100644
--- a/test/python/unittest_python.py
+++ b/test/python/unittest_python.py
@@ -54,86 +54,99 @@ class TestTensorMethods(unittest.TestCase):
self.assertEqual(t.size(), 2*3)
self.assertEqual(t.memsize(), 2*3*sizeof(kFloat32))
self.assertFalse(t.is_transpose())
+ print 'Done tensor fields'
def test_unary_operators(self):
t = self.t
- self.assertAlmostEqual(t.toarray()[0,0], 0.0)
+ arr = np.array([[1.0,2.0],[2.0,3.0],[3.0,4.0]], dtype=np.float32)
+ t.copy_data_from(arr)
+ self.assertAlmostEqual(t.to_array()[0,0], 1.0)
+ self.assertAlmostEqual(t.to_array()[0,1], 2.0)
t += 1.23
- self.assertAlmostEqual(t.toarray()[0,0], 1.23)
+ self.assertAlmostEqual(t.to_array()[0,0], 1.0+1.23)
t -= 0.23
- self.assertAlmostEqual(t.toarray()[0,0], 1.23-0.23)
+ self.assertAlmostEqual(t.to_array()[0,0], 2.23-0.23)
t *= 2.5
- self.assertAlmostEqual(t.toarray()[0,0], (1.23-0.23)*2.5)
+ self.assertAlmostEqual(t.to_array()[0,0], (2.23-0.23)*2.5)
t /= 2
- self.assertAlmostEqual(t.toarray()[0,0], (1.23-0.23)*2.5/2)
+ self.assertAlmostEqual(t.to_array()[0,0], (2.23-0.23)*2.5/2)
+ print 'Done unary_operators'
def test_binary_operators(self):
t = self.t
- t += 3.2
+ arr = np.array([[1.0,2.0],[2.0,3.0],[3.0,4.0]], dtype=np.float32)
+ t.copy_data_from(arr)
s = self.s
- s += 2.1
+ arr = np.array([[4.0,3.0],[3.0,2.0],[2.0,1.0]], dtype=np.float32)
+ s.from_array(arr)
a = t + s
- self.assertAlmostEqual(a.toarray()[0,0], 3.2+2.1, 5)
+ self.assertAlmostEqual(a.to_array()[0,0], 1.0+4.0)
a = t - s
- self.assertAlmostEqual(a.toarray()[0,0], 3.2-2.1, 5)
+ self.assertAlmostEqual(a.to_array()[0,0], 1.0-4.0)
a = t * s
- self.assertAlmostEqual(a.toarray()[0,0], 3.2*2.1, 5)
- ''' not implemented yet
+ self.assertAlmostEqual(a.to_array()[0,0], 1.0*4.0)
a = t / s
- self.assertAlmostEqual(a.toarray()[0,0], 3.2/2.1, 5)
- '''
+ self.assertAlmostEqual(a.to_array()[0,0], 1.0/4.0)
+ print 'Done binary_operators'
def test_comparison_operators(self):
t = self.t
t += 3.45
a = t < 3.45
- self.assertEqual(a.toarray()[0,0], 0)
+ self.assertEqual(a.to_array()[0,0], 0)
a = t <= 3.45
- self.assertEqual(a.toarray()[0,0], 1)
+ self.assertEqual(a.to_array()[0,0], 1)
a = t > 3.45
- self.assertEqual(a.toarray()[0,0], 0)
+ self.assertEqual(a.to_array()[0,0], 0)
a = t >= 3.45
- self.assertEqual(a.toarray()[0,0], 1)
+ self.assertEqual(a.to_array()[0,0], 1)
a = lt(t, 3.45)
- self.assertEqual(a.toarray()[0,0], 0)
+ self.assertEqual(a.to_array()[0,0], 0)
a = le(t, 3.45)
- self.assertEqual(a.toarray()[0,0], 1)
+ self.assertEqual(a.to_array()[0,0], 1)
a = gt(t, 3.45)
- self.assertEqual(a.toarray()[0,0], 0)
+ self.assertEqual(a.to_array()[0,0], 0)
a = ge(t, 3.45)
- self.assertEqual(a.toarray()[0,0], 1)
+ self.assertEqual(a.to_array()[0,0], 1)
+ def test_tensor_manipulation(self):
+ #TODO(chonho)
+ pass
+
+ def test_random_operations(self):
+ #TODO(chonho)
+ pass
def test_tensor_copy(self):
t = Tensor((2,3))
t += 1.23
- self.assertAlmostEqual(t.toarray()[0,0], 1.23)
+ self.assertAlmostEqual(t.to_array()[0,0], 1.23)
tc = t.copy()
tdc = t.deepcopy()
- self.assertAlmostEqual(tc.toarray()[0,0], 1.23)
- self.assertAlmostEqual(tdc.toarray()[0,0], 1.23)
+ self.assertAlmostEqual(tc.to_array()[0,0], 1.23)
+ self.assertAlmostEqual(tdc.to_array()[0,0], 1.23)
t += 1.23
- self.assertAlmostEqual(t.toarray()[0,0], 2.46)
- self.assertAlmostEqual(tc.toarray()[0,0], 2.46)
- self.assertAlmostEqual(tdc.toarray()[0,0], 1.23)
+ self.assertAlmostEqual(t.to_array()[0,0], 2.46)
+ self.assertAlmostEqual(tc.to_array()[0,0], 2.46)
+ self.assertAlmostEqual(tdc.to_array()[0,0], 1.23)
def test_copy_data(self):
t = self.t
t += 1.23
s = self.s
s += 5.43
- self.assertAlmostEqual(t.toarray()[0,0], 1.23)
+ self.assertAlmostEqual(t.to_array()[0,0], 1.23)
copy_data_to_from(t, s, 2)
- self.assertAlmostEqual(t.toarray()[0,0], 5.43, 5)
- self.assertAlmostEqual(t.toarray()[0,1], 5.43, 5)
- self.assertAlmostEqual(t.toarray()[0,2], 1.23)
+ self.assertAlmostEqual(t.to_array()[0,0], 5.43, 5)
+ self.assertAlmostEqual(t.to_array()[0,1], 5.43, 5)
+ self.assertAlmostEqual(t.to_array()[0,2], 1.23)
def test_global_method(self):
t = self.t
t += 12.34
a = log(t)
- self.assertAlmostEqual(a.toarray()[0,0], math.log(12.34))
+ self.assertAlmostEqual(a.to_array()[0,0], math.log(12.34))
if __name__ == '__main__':
unittest.main()
[6/6] incubator-singa git commit: Merge PR #185 for more py tensor
functions. remove Tensor member func to_numpy, and keep global to_numpy
Posted by wa...@apache.org.
Merge PR #185 for more py tensor functions.
remove Tensor member func to_numpy, and keep global to_numpy
Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/cde7dcf6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/cde7dcf6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/cde7dcf6
Branch: refs/heads/dev
Commit: cde7dcf6bbee2931ea14cac30edd639dd490c691
Parents: f026b60 d83f5d5
Author: Wei Wang <wa...@comp.nus.edu.sg>
Authored: Fri Jul 1 16:15:06 2016 +0800
Committer: Wei Wang <wa...@comp.nus.edu.sg>
Committed: Fri Jul 1 16:22:06 2016 +0800
----------------------------------------------------------------------
include/singa/core/device.h | 7 +-
include/singa/core/tensor.h | 7 +
include/singa/model/layer.h | 5 +-
src/core/device/device.cc | 2 +
src/core/tensor/tensor.cc | 17 +-
src/python/swig/core_device.i | 9 +-
src/python/swig/core_tensor.i | 167 +-
src/python/swig/model_layer.i | 13 +-
src/python/swig/numpy.i | 3119 +++++++++++++++++++++++++++++++++++
src/python/tensor.py | 225 ++-
test/python/unittest_python.py | 102 +-
11 files changed, 3545 insertions(+), 128 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/cde7dcf6/src/python/tensor.py
----------------------------------------------------------------------
diff --cc src/python/tensor.py
index 04e070d,35d6b1f..19af454
--- a/src/python/tensor.py
+++ b/src/python/tensor.py
@@@ -92,6 -89,29 +89,19 @@@ class Tensor(object)
data = np.array(data, dtype=dt).reshape(self.tuple_shape)
return data
- def to_numpy(self):
- ''' this method gets the values of tensor data and
- returns it as numpy array
- '''
- if self.dtype == kFloat32:
- np_array = self.singa_tensor.floatGetValue(int(self.size()))
- else:
- print 'Not implemented yet for ', self.dtype
- return np_array.reshape(self.tuple_shape)
-
+ def copy_from_numpy(self, np_array, offset=0):
+ ''' this method stores the values of numpy array into tensor data
+ from the position of offset
+ '''
+ assert np_array.size == self.size(), 'tensor shape should be the same'
+ if not np_array.ndim == 1:
+ np_array = np_array.flatten()
+ dt = np_array.dtype
+ if dt == np.float32:
+ self.singa_tensor.floatCopyDataFromHostPtr(np_array, offset)
+ else:
+ print 'Not implemented yet for ', dt
+
def data_type(self):
return self.singa_tensor.data_type()
@@@ -256,9 -310,19 +300,27 @@@ def reshape(t, s)
return _call_singa_func(singa.Reshape, t.singa_tensor, s)
- def copy_data_to_from(dst, src, size, src_offset=0, dst_offset=0):
+ def copy_data_to_from(dst, src, size, dst_offset=0, src_offset=0):
singa.CopyDataToFrom(dst.singa_tensor, src.singa_tensor, size,
- src_offset, dst_offset)
+ dst_offset, src_offset)
+
+
+ def from_numpy(np_array):
+ ret = Tensor(np_array.shape)
+ ret.copy_from_numpy(np_array)
+ return ret
+
+
+ def to_numpy(t):
- return t.to_numpy()
++ ''' this method gets the values of tensor data and
++ returns it as numpy array
++ TODO(wangwei) clone t to host
++ '''
++ if t.dtype == kFloat32:
++ np_array = t.singa_tensor.floatGetValue(int(t.size()))
++ else:
++ print 'Not implemented yet for ', t.dtype
++ return np_array.reshape(t.tuple_shape)
def abs(t):
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/cde7dcf6/test/python/unittest_python.py
----------------------------------------------------------------------
diff --cc test/python/unittest_python.py
index e1f4b64,320703d..86830a0
--- a/test/python/unittest_python.py
+++ b/test/python/unittest_python.py
@@@ -36,6 -36,6 +36,7 @@@ sys.path.append(os.path.join(os.path.di
'../../build/src'))
from core_pb2 import *
++
class TestTensorMethods(unittest.TestCase):
def setUp(self):
@@@ -57,83 -57,93 +58,98 @@@
def test_unary_operators(self):
t = self.t
- self.assertAlmostEqual(t.toarray()[0,0], 0.0)
- arr = np.array([[1.0,2.0],[2.0,3.0],[3.0,4.0]], dtype=np.float32)
++ arr = np.array([[1.0, 2.0], [2.0, 3.0], [3.0, 4.0]], dtype=np.float32)
+ t.copy_from_numpy(arr)
- self.assertAlmostEqual(t.to_numpy()[0,0], arr[0,0])
- self.assertAlmostEqual(t.to_numpy()[0,1], arr[0,1])
- self.assertAlmostEqual(t.to_numpy()[2,1], arr[2,1])
++ npary = to_numpy(t)
++ self.assertAlmostEqual(npary[0, 0], arr[0, 0])
++ self.assertAlmostEqual(npary[0, 1], arr[0, 1])
++ self.assertAlmostEqual(npary[2, 1], arr[2, 1])
t += 1.23
- self.assertAlmostEqual(t.toarray()[0,0], 1.23)
- self.assertAlmostEqual(to_numpy(t)[0,0], 1.0+1.23)
++ npary = to_numpy(t)
++ self.assertAlmostEqual(npary[0, 0], 1.0+1.23)
t -= 0.23
- self.assertAlmostEqual(t.toarray()[0,0], 1.23-0.23)
- self.assertAlmostEqual(to_numpy(t)[0,0], 2.23-0.23)
++ npary = to_numpy(t)
++ self.assertAlmostEqual(npary[0, 0], 2.23-0.23)
t *= 2.5
- self.assertAlmostEqual(t.toarray()[0,0], (1.23-0.23)*2.5)
- self.assertAlmostEqual(to_numpy(t)[0,0], (2.23-0.23)*2.5)
++ npary = to_numpy(t)
++ self.assertAlmostEqual(npary[0, 0], (2.23-0.23)*2.5)
t /= 2
- self.assertAlmostEqual(t.toarray()[0,0], (1.23-0.23)*2.5/2)
- self.assertAlmostEqual(to_numpy(t)[0,0], (2.23-0.23)*2.5/2)
++ npary = to_numpy(t)
++ self.assertAlmostEqual(npary[0, 0], (2.23-0.23)*2.5/2)
def test_binary_operators(self):
t = self.t
- t += 3.2
- arr = np.array([[1.0,2.0],[2.0,3.0],[3.0,4.0]], dtype=np.float32)
++ arr = np.array([[1.0, 2.0], [2.0, 3.0], [3.0, 4.0]], dtype=np.float32)
+ t.copy_from_numpy(arr)
s = self.s
- s += 2.1
- arr = np.array([[4.0,3.0],[3.0,2.0],[2.0,1.0]], dtype=np.float32)
++ arr = np.array([[4.0, 3.0], [3.0, 2.0], [2.0, 1.0]], dtype=np.float32)
+ s.copy_from_numpy(arr)
a = t + s
- self.assertAlmostEqual(a.toarray()[0,0], 3.2+2.1, 5)
- self.assertAlmostEqual(to_numpy(a)[0,0], 1.0+4.0)
++ self.assertAlmostEqual(to_numpy(a)[0, 0], 1.0+4.0)
a = t - s
- self.assertAlmostEqual(a.toarray()[0,0], 3.2-2.1, 5)
- self.assertAlmostEqual(to_numpy(a)[0,0], 1.0-4.0)
++ self.assertAlmostEqual(to_numpy(a)[0, 0], 1.0-4.0)
a = t * s
- self.assertAlmostEqual(a.toarray()[0,0], 3.2*2.1, 5)
- ''' not implemented yet
- self.assertAlmostEqual(to_numpy(a)[0,0], 1.0*4.0)
++ self.assertAlmostEqual(to_numpy(a)[0, 0], 1.0*4.0)
a = t / s
- self.assertAlmostEqual(a.toarray()[0,0], 3.2/2.1, 5)
- '''
- self.assertAlmostEqual(to_numpy(a)[0,0], 1.0/4.0)
++ self.assertAlmostEqual(to_numpy(a)[0, 0], 1.0/4.0)
def test_comparison_operators(self):
t = self.t
- t += 3.45
+ t.set_value(3.45)
a = t < 3.45
- self.assertEqual(a.toarray()[0,0], 0)
- self.assertEqual(to_numpy(a)[0,0], 0)
++ self.assertEqual(to_numpy(a)[0, 0], 0)
a = t <= 3.45
- self.assertEqual(a.toarray()[0,0], 1)
- self.assertEqual(to_numpy(a)[0,0], 1)
++ self.assertEqual(to_numpy(a)[0, 0], 1)
a = t > 3.45
- self.assertEqual(a.toarray()[0,0], 0)
- self.assertEqual(to_numpy(a)[0,0], 0)
++ self.assertEqual(to_numpy(a)[0, 0], 0)
a = t >= 3.45
- self.assertEqual(a.toarray()[0,0], 1)
- self.assertEqual(to_numpy(a)[0,0], 1)
++ self.assertEqual(to_numpy(a)[0, 0], 1)
a = lt(t, 3.45)
- self.assertEqual(a.toarray()[0,0], 0)
- self.assertEqual(to_numpy(a)[0,0], 0)
++ self.assertEqual(to_numpy(a)[0, 0], 0)
a = le(t, 3.45)
- self.assertEqual(a.toarray()[0,0], 1)
- self.assertEqual(to_numpy(a)[0,0], 1)
++ self.assertEqual(to_numpy(a)[0, 0], 1)
a = gt(t, 3.45)
- self.assertEqual(a.toarray()[0,0], 0)
- self.assertEqual(to_numpy(a)[0,0], 0)
++ self.assertEqual(to_numpy(a)[0, 0], 0)
a = ge(t, 3.45)
- self.assertEqual(a.toarray()[0,0], 1)
- self.assertEqual(to_numpy(a)[0,0], 1)
++ self.assertEqual(to_numpy(a)[0, 0], 1)
+
+ def test_tensor_manipulation(self):
- #TODO(chonho)
++ # TODO(chonho)
+ pass
+ def test_random_operations(self):
- #TODO(chonho)
++ # TODO(chonho)
+ pass
def test_tensor_copy(self):
-- t = Tensor((2,3))
- t += 1.23
- self.assertAlmostEqual(t.toarray()[0,0], 1.23)
++ t = Tensor((2, 3))
+ t.set_value(1.23)
- self.assertAlmostEqual(to_numpy(t)[0,0], 1.23)
++ self.assertAlmostEqual(to_numpy(t)[0, 0], 1.23)
tc = t.copy()
tdc = t.deepcopy()
- self.assertAlmostEqual(tc.toarray()[0,0], 1.23)
- self.assertAlmostEqual(tdc.toarray()[0,0], 1.23)
- self.assertAlmostEqual(to_numpy(tc)[0,0], 1.23)
- self.assertAlmostEqual(to_numpy(tdc)[0,0], 1.23)
++ self.assertAlmostEqual(to_numpy(tc)[0, 0], 1.23)
++ self.assertAlmostEqual(to_numpy(tdc)[0, 0], 1.23)
t += 1.23
- self.assertAlmostEqual(t.toarray()[0,0], 2.46)
- self.assertAlmostEqual(tc.toarray()[0,0], 2.46)
- self.assertAlmostEqual(tdc.toarray()[0,0], 1.23)
- self.assertAlmostEqual(to_numpy(t)[0,0], 2.46)
- self.assertAlmostEqual(to_numpy(tc)[0,0], 2.46)
- self.assertAlmostEqual(to_numpy(tdc)[0,0], 1.23)
++ self.assertAlmostEqual(to_numpy(t)[0, 0], 2.46)
++ self.assertAlmostEqual(to_numpy(tc)[0, 0], 2.46)
++ self.assertAlmostEqual(to_numpy(tdc)[0, 0], 1.23)
def test_copy_data(self):
t = self.t
- t += 1.23
+ t.set_value(1.23)
s = self.s
- s += 5.43
- self.assertAlmostEqual(t.toarray()[0,0], 1.23)
+ s.set_value(5.43)
- self.assertAlmostEqual(t.to_numpy()[0,0], 1.23)
++ self.assertAlmostEqual(to_numpy(t)[0, 0], 1.23)
copy_data_to_from(t, s, 2)
- self.assertAlmostEqual(t.toarray()[0,0], 5.43, 5)
- self.assertAlmostEqual(t.toarray()[0,1], 5.43, 5)
- self.assertAlmostEqual(t.toarray()[0,2], 1.23)
-
- self.assertAlmostEqual(t.to_numpy()[0,0], 5.43, 5)
- self.assertAlmostEqual(t.to_numpy()[0,1], 5.43, 5)
- self.assertAlmostEqual(t.to_numpy()[1,0], 1.23, 5)
++ self.assertAlmostEqual(to_numpy(t)[0, 0], 5.43, 5)
++ self.assertAlmostEqual(to_numpy(t)[0, 1], 5.43, 5)
++ self.assertAlmostEqual(to_numpy(t)[1, 0], 1.23, 5)
def test_global_method(self):
t = self.t
- t += 12.34
+ t.set_value(12.34)
a = log(t)
- self.assertAlmostEqual(a.toarray()[0,0], math.log(12.34))
- self.assertAlmostEqual(to_numpy(a)[0,0], math.log(12.34), 5)
++ self.assertAlmostEqual(to_numpy(a)[0, 0], math.log(12.34), 5)
if __name__ == '__main__':
unittest.main()
[4/6] incubator-singa git commit: SINGA-186 Create Python Tensor class
Posted by wa...@apache.org.
SINGA-186 Create Python Tensor class
- Add numpy.i in src/python/swig
. core_tensor.i is revised to include it
. GetValue method is added in singa::Tensor class (tensor.h)
. in tensor.py, the member methods are added to get/set numpy array from/to tensor data
. copy_from_numpy, which calls singa::Tensor::CopyDataFromHostPtr
. copy_to_numpy, which calls singa::Tensor::GetValue
. also global functions are added
. from_numpy
. to_numpy
NOTE: numpy.i is downloaded from https://github.com/numpy/numpy/tree/master/tools/swig
TODO: unittest_python.py
Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/50f67226
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/50f67226
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/50f67226
Branch: refs/heads/dev
Commit: 50f672267c8f2d88951c804cad6df833f89b0428
Parents: 7cfdb99
Author: chonho <le...@comp.nus.edu.sg>
Authored: Thu Jun 30 21:54:52 2016 +0800
Committer: chonho <le...@comp.nus.edu.sg>
Committed: Fri Jul 1 11:44:01 2016 +0800
----------------------------------------------------------------------
include/singa/core/tensor.h | 7 +
src/python/swig/core_tensor.i | 54 +-
src/python/swig/numpy.i | 3119 +++++++++++++++++++++++++++++++++++
src/python/tensor.py | 77 +-
test/python/unittest_python.py | 77 +-
5 files changed, 3243 insertions(+), 91 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/50f67226/include/singa/core/tensor.h
----------------------------------------------------------------------
diff --git a/include/singa/core/tensor.h b/include/singa/core/tensor.h
index 4ef3286..3b4304a 100644
--- a/include/singa/core/tensor.h
+++ b/include/singa/core/tensor.h
@@ -81,6 +81,13 @@ class Tensor {
return static_cast<const SType *>(block()->data());
}
+ template <typename SType>
+ void GetValue(SType *value, const size_t num) {
+ CHECK(device_ == defaultDevice);
+ const SType* ptr = data<SType>();
+ for(size_t i = 0; i < num; i++) value[i] = ptr[i];
+ }
+
/// data type, including kFloat16, kFloat32, kInt
const DataType data_type() const { return data_type_; }
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/50f67226/src/python/swig/core_tensor.i
----------------------------------------------------------------------
diff --git a/src/python/swig/core_tensor.i b/src/python/swig/core_tensor.i
index e30f2ef..f723d1b 100644
--- a/src/python/swig/core_tensor.i
+++ b/src/python/swig/core_tensor.i
@@ -40,6 +40,17 @@
using singa::DataType;
%}
+%include "numpy.i"
+%init %{
+ import_array();
+%}
+%apply (float *IN_ARRAY1, int DIM1) {
+ (const float *src, const size_t num)
+}
+%apply (float *ARGOUT_ARRAY1, int DIM1) {
+ (float *value, const size_t num)
+}
+
%template(Shape) std::vector<size_t>;
namespace singa{
@@ -72,6 +83,10 @@ namespace singa{
%template(charData) data<const char*>;
%template(doubleData) data<const double*>;
+ template <typename SType> void GetValue(SType* value, const size_t num);
+ %template(floatGetValue) GetValue<float>;
+ //void ToArray(float *value, const size_t num);
+
const DataType data_type() const;
const std::vector<size_t> &shape() const;
const size_t shape(size_t idx) const;
@@ -88,12 +103,14 @@ namespace singa{
template <typename SType> void SetValue(const SType x);
%template(floatSetValue) SetValue<float>;
- // ...
+ /* TODO(chonho-01) other types */
+ // --- other types
template <typename DType> void CopyDataFromHostPtr(const DType *src,
const size_t num,
const size_t offset);
- %template(floatCopyData) CopyDataFromHostPtr<float>;
+ %template(floatCopyDataFromHostPtr) CopyDataFromHostPtr<float>;
+ // --- other types
void CopyData(const Tensor &other);
Tensor Clone() const;
@@ -109,26 +126,22 @@ namespace singa{
template <typename DType> Tensor &operator+=(const DType x);
%template(iAdd_f) operator+=<float>;
- /* TODO(chonho-01) for other types */
- // ...
+ // --- other types
template <typename DType> Tensor &operator-=(DType x);
%template(iSub_f) operator-=<float>;
- /* TODO(chonho-01) for other types */
- // ...
+ // --- other types
template <typename DType> Tensor &operator*=(DType x);
%template(iMul_f) operator*=<float>;
- /* TODO(chonho-01) for other types */
- // ...
+ // --- other types
template <typename DType> Tensor &operator/=(DType x);
%template(iDiv_f) operator/=<float>;
- /* TODO(chonho-01) for other types */
- // ...
+ // --- other types
- /*TODO(chonho-08-b)
+ /*TODO(chonho-04)
amax
amin
asum
@@ -137,9 +150,6 @@ namespace singa{
};
- /* TODO(chonho-02)
- inline void CheckDataTypeAndLang(const Tensor &in1, const Tensor &in2);
- */
void CopyDataToFrom(Tensor *dst, const Tensor &src, size_t num,
size_t src_offset = 0, size_t dst_offset = 0);
@@ -160,7 +170,7 @@ namespace singa{
%template(floatSum) Sum<float>;
// --- other types
- /* TODO(chonho-04)
+ /* TODO(chonho-02)
need to implement the average of all elements ??? */
Tensor Average(const Tensor &t, int axis);
@@ -205,7 +215,7 @@ namespace singa{
%template(op) operator>= <float>;
// --- other types
- /* TODO(chonho-06)
+ /* NOTE(chonho)
no need to include theses
in python, these can be replaced with comparison operators
@@ -284,27 +294,23 @@ namespace singa{
template <typename SType>
void Bernoulli(const SType p, Tensor *out);
%template(floatBernoulli) Bernoulli<float>;
- /* TODO for other types */
- // ...
+ // --- other types
template <typename SType>
void Gaussian(const SType mean, const SType std, Tensor *out);
%template(floatGaussian) Gaussian<float>;
- /* TODO for other types */
- // ...
+ // --- other types
template <typename SType>
void Uniform(const SType low, const SType high, Tensor *out);
%template(floatUniform) Uniform<float>;
- /* TODO for other types */
- // ...
+ // --- other types
/* ========== Blas operations ========== */
template <typename SType>
void Axpy(SType alpha, const Tensor &in, Tensor *out);
%template(floatAxpy) Axpy<float>;
- /* TODO for other types */
- // ...
+ // --- other types
Tensor Mult(const Tensor &A, const Tensor &B);
void Mult(const Tensor &A, const Tensor &B, Tensor *C);
[5/6] incubator-singa git commit: SINGA-186 Create Python Tensor class
Posted by wa...@apache.org.
SINGA-186 Create Python Tensor class
- In tensor.py, Rename copy_to_numpy to to_numpy
- Revised core_device.i to avoid memory leak of std::shared_ptr<Device>
- Revised device.h to avoid non-virtual-desturcotr wanrning
TODO: still need to add more test cases
Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/d83f5d52
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/d83f5d52
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/d83f5d52
Branch: refs/heads/dev
Commit: d83f5d52d71447d9f8be5353fbeaa67766f6f767
Parents: 50f6722
Author: chonho <le...@comp.nus.edu.sg>
Authored: Fri Jul 1 13:40:10 2016 +0800
Committer: chonho <le...@comp.nus.edu.sg>
Committed: Fri Jul 1 13:40:10 2016 +0800
----------------------------------------------------------------------
include/singa/core/device.h | 7 ++-
src/core/device/device.cc | 2 +
src/python/swig/core_device.i | 7 ++-
src/python/tensor.py | 4 +-
test/python/unittest_python.py | 87 ++++++++++++++++++-------------------
5 files changed, 57 insertions(+), 50 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/d83f5d52/include/singa/core/device.h
----------------------------------------------------------------------
diff --git a/include/singa/core/device.h b/include/singa/core/device.h
index f2b77b6..8c4546f 100644
--- a/include/singa/core/device.h
+++ b/include/singa/core/device.h
@@ -84,6 +84,8 @@ class Device {
int id() const { return id_; }
+ virtual ~Device() = 0;
+
protected:
/// Execute one operation on one executor.
virtual void DoExec(function<void(Context*)>&& fn, int executor) = 0;
@@ -117,6 +119,7 @@ class Device {
/// It runs cpp code.
class CppCPU : public Device {
public:
+ ~CppCPU() {};
CppCPU(int id = -1, int num_executors = 1,
string scheduler = "sync", string vm = "gc-only");
@@ -148,7 +151,7 @@ class CudaGPU : public Device {
~CudaGPU();
CudaGPU(int id = 0, int num_executors = 1, string scheduler = "sync",
string vm = "gc-only");
- CudaGPU(const MemPoolConf& mem_conf,
+ CudaGPU(const MemPoolConf& mem_conf,
int id = 0, int num_executors = 1, string scheduler = "sync");
void SetRandSeed(unsigned seed) override;
@@ -183,7 +186,7 @@ class CudaGPU : public Device {
/// Free cpu memory.
void Free(void* ptr) override;
-
+
private:
DeviceMemPool* pool;
};
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/d83f5d52/src/core/device/device.cc
----------------------------------------------------------------------
diff --git a/src/core/device/device.cc b/src/core/device/device.cc
index 6775e40..071b891 100644
--- a/src/core/device/device.cc
+++ b/src/core/device/device.cc
@@ -25,6 +25,8 @@ Device::Device(int id, int num_executors, string scheduler, string vm)
host_ = defaultDevice;
}
+Device::~Device() {}
+
void Device::Exec(function<void(Context*)>&& fn, const vector<Block*> read_blocks,
const vector<Block*> write_blocks, bool use_rand_generator) {
// TODO(wangwei) execute operations scheduled by the scheduler.
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/d83f5d52/src/python/swig/core_device.i
----------------------------------------------------------------------
diff --git a/src/python/swig/core_device.i b/src/python/swig/core_device.i
index 50cee3e..7430620 100644
--- a/src/python/swig/core_device.i
+++ b/src/python/swig/core_device.i
@@ -24,14 +24,19 @@
%module core_device
%include "std_vector.i"
%include "std_string.i"
+%include "std_shared_ptr.i"
%{
#include "singa/core/device.h"
%}
+/* smart pointer to avoid memory leak */
+%shared_ptr(singa::Device);
+%shared_ptr(singa::CppCPU);
+%shared_ptr(singa::CudaGPU);
+
namespace singa{
- %nodefault Device;
class Device {
public:
virtual void SetRandSeed(unsigned seed) = 0;
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/d83f5d52/src/python/tensor.py
----------------------------------------------------------------------
diff --git a/src/python/tensor.py b/src/python/tensor.py
index b8abb5c..35d6b1f 100644
--- a/src/python/tensor.py
+++ b/src/python/tensor.py
@@ -89,7 +89,7 @@ class Tensor(object):
data = np.array(data, dtype=dt).reshape(self.tuple_shape)
return data
- def copy_to_numpy(self):
+ def to_numpy(self):
''' this method gets the values of tensor data and
returns it as numpy array
'''
@@ -322,7 +322,7 @@ def from_numpy(np_array):
def to_numpy(t):
- return t.copy_to_numpy()
+ return t.to_numpy()
def abs(t):
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/d83f5d52/test/python/unittest_python.py
----------------------------------------------------------------------
diff --git a/test/python/unittest_python.py b/test/python/unittest_python.py
index 569a7ad..320703d 100644
--- a/test/python/unittest_python.py
+++ b/test/python/unittest_python.py
@@ -39,7 +39,7 @@ from core_pb2 import *
class TestTensorMethods(unittest.TestCase):
def setUp(self):
- self.shape = (2, 3)
+ self.shape = (3, 2)
self.t = Tensor(self.shape)
self.s = Tensor(self.shape)
@@ -49,65 +49,63 @@ class TestTensorMethods(unittest.TestCase):
self.assertTupleEqual(t.shape(), shape)
self.assertEqual(t.shape(0), shape[0])
self.assertEqual(t.shape(1), shape[1])
- self.assertEqual(product(shape), 2*3)
+ self.assertEqual(product(shape), 3*2)
self.assertEqual(t.ndim(), 2)
- self.assertEqual(t.size(), 2*3)
- self.assertEqual(t.memsize(), 2*3*sizeof(kFloat32))
+ self.assertEqual(t.size(), 3*2)
+ self.assertEqual(t.memsize(), 3*2*sizeof(kFloat32))
self.assertFalse(t.is_transpose())
- print 'Done tensor fields'
def test_unary_operators(self):
t = self.t
arr = np.array([[1.0,2.0],[2.0,3.0],[3.0,4.0]], dtype=np.float32)
- t.copy_data_from(arr)
- self.assertAlmostEqual(t.to_array()[0,0], 1.0)
- self.assertAlmostEqual(t.to_array()[0,1], 2.0)
+ t.copy_from_numpy(arr)
+ self.assertAlmostEqual(t.to_numpy()[0,0], arr[0,0])
+ self.assertAlmostEqual(t.to_numpy()[0,1], arr[0,1])
+ self.assertAlmostEqual(t.to_numpy()[2,1], arr[2,1])
t += 1.23
- self.assertAlmostEqual(t.to_array()[0,0], 1.0+1.23)
+ self.assertAlmostEqual(to_numpy(t)[0,0], 1.0+1.23)
t -= 0.23
- self.assertAlmostEqual(t.to_array()[0,0], 2.23-0.23)
+ self.assertAlmostEqual(to_numpy(t)[0,0], 2.23-0.23)
t *= 2.5
- self.assertAlmostEqual(t.to_array()[0,0], (2.23-0.23)*2.5)
+ self.assertAlmostEqual(to_numpy(t)[0,0], (2.23-0.23)*2.5)
t /= 2
- self.assertAlmostEqual(t.to_array()[0,0], (2.23-0.23)*2.5/2)
- print 'Done unary_operators'
+ self.assertAlmostEqual(to_numpy(t)[0,0], (2.23-0.23)*2.5/2)
def test_binary_operators(self):
t = self.t
arr = np.array([[1.0,2.0],[2.0,3.0],[3.0,4.0]], dtype=np.float32)
- t.copy_data_from(arr)
+ t.copy_from_numpy(arr)
s = self.s
arr = np.array([[4.0,3.0],[3.0,2.0],[2.0,1.0]], dtype=np.float32)
- s.from_array(arr)
+ s.copy_from_numpy(arr)
a = t + s
- self.assertAlmostEqual(a.to_array()[0,0], 1.0+4.0)
+ self.assertAlmostEqual(to_numpy(a)[0,0], 1.0+4.0)
a = t - s
- self.assertAlmostEqual(a.to_array()[0,0], 1.0-4.0)
+ self.assertAlmostEqual(to_numpy(a)[0,0], 1.0-4.0)
a = t * s
- self.assertAlmostEqual(a.to_array()[0,0], 1.0*4.0)
+ self.assertAlmostEqual(to_numpy(a)[0,0], 1.0*4.0)
a = t / s
- self.assertAlmostEqual(a.to_array()[0,0], 1.0/4.0)
- print 'Done binary_operators'
+ self.assertAlmostEqual(to_numpy(a)[0,0], 1.0/4.0)
def test_comparison_operators(self):
t = self.t
- t += 3.45
+ t.set_value(3.45)
a = t < 3.45
- self.assertEqual(a.to_array()[0,0], 0)
+ self.assertEqual(to_numpy(a)[0,0], 0)
a = t <= 3.45
- self.assertEqual(a.to_array()[0,0], 1)
+ self.assertEqual(to_numpy(a)[0,0], 1)
a = t > 3.45
- self.assertEqual(a.to_array()[0,0], 0)
+ self.assertEqual(to_numpy(a)[0,0], 0)
a = t >= 3.45
- self.assertEqual(a.to_array()[0,0], 1)
+ self.assertEqual(to_numpy(a)[0,0], 1)
a = lt(t, 3.45)
- self.assertEqual(a.to_array()[0,0], 0)
+ self.assertEqual(to_numpy(a)[0,0], 0)
a = le(t, 3.45)
- self.assertEqual(a.to_array()[0,0], 1)
+ self.assertEqual(to_numpy(a)[0,0], 1)
a = gt(t, 3.45)
- self.assertEqual(a.to_array()[0,0], 0)
+ self.assertEqual(to_numpy(a)[0,0], 0)
a = ge(t, 3.45)
- self.assertEqual(a.to_array()[0,0], 1)
+ self.assertEqual(to_numpy(a)[0,0], 1)
def test_tensor_manipulation(self):
#TODO(chonho)
@@ -119,34 +117,33 @@ class TestTensorMethods(unittest.TestCase):
def test_tensor_copy(self):
t = Tensor((2,3))
- t += 1.23
- self.assertAlmostEqual(t.to_array()[0,0], 1.23)
+ t.set_value(1.23)
+ self.assertAlmostEqual(to_numpy(t)[0,0], 1.23)
tc = t.copy()
tdc = t.deepcopy()
- self.assertAlmostEqual(tc.to_array()[0,0], 1.23)
- self.assertAlmostEqual(tdc.to_array()[0,0], 1.23)
+ self.assertAlmostEqual(to_numpy(tc)[0,0], 1.23)
+ self.assertAlmostEqual(to_numpy(tdc)[0,0], 1.23)
t += 1.23
- self.assertAlmostEqual(t.to_array()[0,0], 2.46)
- self.assertAlmostEqual(tc.to_array()[0,0], 2.46)
- self.assertAlmostEqual(tdc.to_array()[0,0], 1.23)
+ self.assertAlmostEqual(to_numpy(t)[0,0], 2.46)
+ self.assertAlmostEqual(to_numpy(tc)[0,0], 2.46)
+ self.assertAlmostEqual(to_numpy(tdc)[0,0], 1.23)
def test_copy_data(self):
t = self.t
- t += 1.23
+ t.set_value(1.23)
s = self.s
- s += 5.43
- self.assertAlmostEqual(t.to_array()[0,0], 1.23)
+ s.set_value(5.43)
+ self.assertAlmostEqual(t.to_numpy()[0,0], 1.23)
copy_data_to_from(t, s, 2)
- self.assertAlmostEqual(t.to_array()[0,0], 5.43, 5)
- self.assertAlmostEqual(t.to_array()[0,1], 5.43, 5)
- self.assertAlmostEqual(t.to_array()[0,2], 1.23)
-
+ self.assertAlmostEqual(t.to_numpy()[0,0], 5.43, 5)
+ self.assertAlmostEqual(t.to_numpy()[0,1], 5.43, 5)
+ self.assertAlmostEqual(t.to_numpy()[1,0], 1.23, 5)
def test_global_method(self):
t = self.t
- t += 12.34
+ t.set_value(12.34)
a = log(t)
- self.assertAlmostEqual(a.to_array()[0,0], math.log(12.34))
+ self.assertAlmostEqual(to_numpy(a)[0,0], math.log(12.34), 5)
if __name__ == '__main__':
unittest.main()
[3/6] incubator-singa git commit: SINGA-186 Create Python Tensor class
Posted by wa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/50f67226/src/python/swig/numpy.i
----------------------------------------------------------------------
diff --git a/src/python/swig/numpy.i b/src/python/swig/numpy.i
new file mode 100644
index 0000000..e58090e
--- /dev/null
+++ b/src/python/swig/numpy.i
@@ -0,0 +1,3119 @@
+/* -*- C -*- (not really, but good for syntax highlighting) */
+
+/*
+ * Copyright (c) 2005-2015, NumPy Developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * * Neither the name of the NumPy Developers nor the names of any
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef SWIGPYTHON
+
+%{
+#ifndef SWIG_FILE_WITH_INIT
+#define NO_IMPORT_ARRAY
+#endif
+#include "stdio.h"
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#include <numpy/arrayobject.h>
+%}
+
+/**********************************************************************/
+
+%fragment("NumPy_Backward_Compatibility", "header")
+{
+%#if NPY_API_VERSION < 0x00000007
+%#define NPY_ARRAY_DEFAULT NPY_DEFAULT
+%#define NPY_ARRAY_FARRAY NPY_FARRAY
+%#define NPY_FORTRANORDER NPY_FORTRAN
+%#endif
+}
+
+/**********************************************************************/
+
+/* The following code originally appeared in
+ * enthought/kiva/agg/src/numeric.i written by Eric Jones. It was
+ * translated from C++ to C by John Hunter. Bill Spotz has modified
+ * it to fix some minor bugs, upgrade from Numeric to numpy (all
+ * versions), add some comments and functionality, and convert from
+ * direct code insertion to SWIG fragments.
+ */
+
+%fragment("NumPy_Macros", "header")
+{
+/* Macros to extract array attributes.
+ */
+%#if NPY_API_VERSION < 0x00000007
+%#define is_array(a) ((a) && PyArray_Check((PyArrayObject*)a))
+%#define array_type(a) (int)(PyArray_TYPE((PyArrayObject*)a))
+%#define array_numdims(a) (((PyArrayObject*)a)->nd)
+%#define array_dimensions(a) (((PyArrayObject*)a)->dimensions)
+%#define array_size(a,i) (((PyArrayObject*)a)->dimensions[i])
+%#define array_strides(a) (((PyArrayObject*)a)->strides)
+%#define array_stride(a,i) (((PyArrayObject*)a)->strides[i])
+%#define array_data(a) (((PyArrayObject*)a)->data)
+%#define array_descr(a) (((PyArrayObject*)a)->descr)
+%#define array_flags(a) (((PyArrayObject*)a)->flags)
+%#define array_enableflags(a,f) (((PyArrayObject*)a)->flags) = f
+%#else
+%#define is_array(a) ((a) && PyArray_Check(a))
+%#define array_type(a) PyArray_TYPE((PyArrayObject*)a)
+%#define array_numdims(a) PyArray_NDIM((PyArrayObject*)a)
+%#define array_dimensions(a) PyArray_DIMS((PyArrayObject*)a)
+%#define array_strides(a) PyArray_STRIDES((PyArrayObject*)a)
+%#define array_stride(a,i) PyArray_STRIDE((PyArrayObject*)a,i)
+%#define array_size(a,i) PyArray_DIM((PyArrayObject*)a,i)
+%#define array_data(a) PyArray_DATA((PyArrayObject*)a)
+%#define array_descr(a) PyArray_DESCR((PyArrayObject*)a)
+%#define array_flags(a) PyArray_FLAGS((PyArrayObject*)a)
+%#define array_enableflags(a,f) PyArray_ENABLEFLAGS((PyArrayObject*)a,f)
+%#endif
+%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS((PyArrayObject*)a))
+%#define array_is_native(a) (PyArray_ISNOTSWAPPED((PyArrayObject*)a))
+%#define array_is_fortran(a) (PyArray_ISFORTRAN((PyArrayObject*)a))
+}
+
+/**********************************************************************/
+
+%fragment("NumPy_Utilities",
+ "header")
+{
+ /* Given a PyObject, return a string describing its type.
+ */
+ const char* pytype_string(PyObject* py_obj)
+ {
+ if (py_obj == NULL ) return "C NULL value";
+ if (py_obj == Py_None ) return "Python None" ;
+ if (PyCallable_Check(py_obj)) return "callable" ;
+ if (PyString_Check( py_obj)) return "string" ;
+ if (PyInt_Check( py_obj)) return "int" ;
+ if (PyFloat_Check( py_obj)) return "float" ;
+ if (PyDict_Check( py_obj)) return "dict" ;
+ if (PyList_Check( py_obj)) return "list" ;
+ if (PyTuple_Check( py_obj)) return "tuple" ;
+%#if PY_MAJOR_VERSION < 3
+ if (PyFile_Check( py_obj)) return "file" ;
+ if (PyModule_Check( py_obj)) return "module" ;
+ if (PyInstance_Check(py_obj)) return "instance" ;
+%#endif
+
+ return "unkown type";
+ }
+
+ /* Given a NumPy typecode, return a string describing the type.
+ */
+ const char* typecode_string(int typecode)
+ {
+ static const char* type_names[25] = {"bool",
+ "byte",
+ "unsigned byte",
+ "short",
+ "unsigned short",
+ "int",
+ "unsigned int",
+ "long",
+ "unsigned long",
+ "long long",
+ "unsigned long long",
+ "float",
+ "double",
+ "long double",
+ "complex float",
+ "complex double",
+ "complex long double",
+ "object",
+ "string",
+ "unicode",
+ "void",
+ "ntypes",
+ "notype",
+ "char",
+ "unknown"};
+ return typecode < 24 ? type_names[typecode] : type_names[24];
+ }
+
+ /* Make sure input has correct numpy type. This now just calls
+ PyArray_EquivTypenums().
+ */
+ int type_match(int actual_type,
+ int desired_type)
+ {
+ return PyArray_EquivTypenums(actual_type, desired_type);
+ }
+
+%#ifdef SWIGPY_USE_CAPSULE
+ void free_cap(PyObject * cap)
+ {
+ void* array = (void*) PyCapsule_GetPointer(cap,SWIGPY_CAPSULE_NAME);
+ if (array != NULL) free(array);
+ }
+%#endif
+
+
+}
+
+/**********************************************************************/
+
+%fragment("NumPy_Object_to_Array",
+ "header",
+ fragment="NumPy_Backward_Compatibility",
+ fragment="NumPy_Macros",
+ fragment="NumPy_Utilities")
+{
+ /* Given a PyObject pointer, cast it to a PyArrayObject pointer if
+ * legal. If not, set the python error string appropriately and
+ * return NULL.
+ */
+ PyArrayObject* obj_to_array_no_conversion(PyObject* input,
+ int typecode)
+ {
+ PyArrayObject* ary = NULL;
+ if (is_array(input) && (typecode == NPY_NOTYPE ||
+ PyArray_EquivTypenums(array_type(input), typecode)))
+ {
+ ary = (PyArrayObject*) input;
+ }
+ else if is_array(input)
+ {
+ const char* desired_type = typecode_string(typecode);
+ const char* actual_type = typecode_string(array_type(input));
+ PyErr_Format(PyExc_TypeError,
+ "Array of type '%s' required. Array of type '%s' given",
+ desired_type, actual_type);
+ ary = NULL;
+ }
+ else
+ {
+ const char* desired_type = typecode_string(typecode);
+ const char* actual_type = pytype_string(input);
+ PyErr_Format(PyExc_TypeError,
+ "Array of type '%s' required. A '%s' was given",
+ desired_type,
+ actual_type);
+ ary = NULL;
+ }
+ return ary;
+ }
+
+ /* Convert the given PyObject to a NumPy array with the given
+ * typecode. On success, return a valid PyArrayObject* with the
+ * correct type. On failure, the python error string will be set and
+ * the routine returns NULL.
+ */
+ PyArrayObject* obj_to_array_allow_conversion(PyObject* input,
+ int typecode,
+ int* is_new_object)
+ {
+ PyArrayObject* ary = NULL;
+ PyObject* py_obj;
+ if (is_array(input) && (typecode == NPY_NOTYPE ||
+ PyArray_EquivTypenums(array_type(input),typecode)))
+ {
+ ary = (PyArrayObject*) input;
+ *is_new_object = 0;
+ }
+ else
+ {
+ py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_ARRAY_DEFAULT);
+ /* If NULL, PyArray_FromObject will have set python error value.*/
+ ary = (PyArrayObject*) py_obj;
+ *is_new_object = 1;
+ }
+ return ary;
+ }
+
+ /* Given a PyArrayObject, check to see if it is contiguous. If so,
+ * return the input pointer and flag it as not a new object. If it is
+ * not contiguous, create a new PyArrayObject using the original data,
+ * flag it as a new object and return the pointer.
+ */
+ PyArrayObject* make_contiguous(PyArrayObject* ary,
+ int* is_new_object,
+ int min_dims,
+ int max_dims)
+ {
+ PyArrayObject* result;
+ if (array_is_contiguous(ary))
+ {
+ result = ary;
+ *is_new_object = 0;
+ }
+ else
+ {
+ result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary,
+ array_type(ary),
+ min_dims,
+ max_dims);
+ *is_new_object = 1;
+ }
+ return result;
+ }
+
+ /* Given a PyArrayObject, check to see if it is Fortran-contiguous.
+ * If so, return the input pointer, but do not flag it as not a new
+ * object. If it is not Fortran-contiguous, create a new
+ * PyArrayObject using the original data, flag it as a new object
+ * and return the pointer.
+ */
+ PyArrayObject* make_fortran(PyArrayObject* ary,
+ int* is_new_object)
+ {
+ PyArrayObject* result;
+ if (array_is_fortran(ary))
+ {
+ result = ary;
+ *is_new_object = 0;
+ }
+ else
+ {
+ Py_INCREF(array_descr(ary));
+ result = (PyArrayObject*) PyArray_FromArray(ary,
+ array_descr(ary),
+ NPY_FORTRANORDER);
+ *is_new_object = 1;
+ }
+ return result;
+ }
+
+ /* Convert a given PyObject to a contiguous PyArrayObject of the
+ * specified type. If the input object is not a contiguous
+ * PyArrayObject, a new one will be created and the new object flag
+ * will be set.
+ */
+ PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
+ int typecode,
+ int* is_new_object)
+ {
+ int is_new1 = 0;
+ int is_new2 = 0;
+ PyArrayObject* ary2;
+ PyArrayObject* ary1 = obj_to_array_allow_conversion(input,
+ typecode,
+ &is_new1);
+ if (ary1)
+ {
+ ary2 = make_contiguous(ary1, &is_new2, 0, 0);
+ if ( is_new1 && is_new2)
+ {
+ Py_DECREF(ary1);
+ }
+ ary1 = ary2;
+ }
+ *is_new_object = is_new1 || is_new2;
+ return ary1;
+ }
+
+ /* Convert a given PyObject to a Fortran-ordered PyArrayObject of the
+ * specified type. If the input object is not a Fortran-ordered
+ * PyArrayObject, a new one will be created and the new object flag
+ * will be set.
+ */
+ PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input,
+ int typecode,
+ int* is_new_object)
+ {
+ int is_new1 = 0;
+ int is_new2 = 0;
+ PyArrayObject* ary2;
+ PyArrayObject* ary1 = obj_to_array_allow_conversion(input,
+ typecode,
+ &is_new1);
+ if (ary1)
+ {
+ ary2 = make_fortran(ary1, &is_new2);
+ if (is_new1 && is_new2)
+ {
+ Py_DECREF(ary1);
+ }
+ ary1 = ary2;
+ }
+ *is_new_object = is_new1 || is_new2;
+ return ary1;
+ }
+} /* end fragment */
+
+/**********************************************************************/
+
+%fragment("NumPy_Array_Requirements",
+ "header",
+ fragment="NumPy_Backward_Compatibility",
+ fragment="NumPy_Macros")
+{
+ /* Test whether a python object is contiguous. If array is
+ * contiguous, return 1. Otherwise, set the python error string and
+ * return 0.
+ */
+ int require_contiguous(PyArrayObject* ary)
+ {
+ int contiguous = 1;
+ if (!array_is_contiguous(ary))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "Array must be contiguous. A non-contiguous array was given");
+ contiguous = 0;
+ }
+ return contiguous;
+ }
+
+ /* Require that a numpy array is not byte-swapped. If the array is
+ * not byte-swapped, return 1. Otherwise, set the python error string
+ * and return 0.
+ */
+ int require_native(PyArrayObject* ary)
+ {
+ int native = 1;
+ if (!array_is_native(ary))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "Array must have native byteorder. "
+ "A byte-swapped array was given");
+ native = 0;
+ }
+ return native;
+ }
+
+ /* Require the given PyArrayObject to have a specified number of
+ * dimensions. If the array has the specified number of dimensions,
+ * return 1. Otherwise, set the python error string and return 0.
+ */
+ int require_dimensions(PyArrayObject* ary,
+ int exact_dimensions)
+ {
+ int success = 1;
+ if (array_numdims(ary) != exact_dimensions)
+ {
+ PyErr_Format(PyExc_TypeError,
+ "Array must have %d dimensions. Given array has %d dimensions",
+ exact_dimensions,
+ array_numdims(ary));
+ success = 0;
+ }
+ return success;
+ }
+
+ /* Require the given PyArrayObject to have one of a list of specified
+ * number of dimensions. If the array has one of the specified number
+ * of dimensions, return 1. Otherwise, set the python error string
+ * and return 0.
+ */
+ int require_dimensions_n(PyArrayObject* ary,
+ int* exact_dimensions,
+ int n)
+ {
+ int success = 0;
+ int i;
+ char dims_str[255] = "";
+ char s[255];
+ for (i = 0; i < n && !success; i++)
+ {
+ if (array_numdims(ary) == exact_dimensions[i])
+ {
+ success = 1;
+ }
+ }
+ if (!success)
+ {
+ for (i = 0; i < n-1; i++)
+ {
+ sprintf(s, "%d, ", exact_dimensions[i]);
+ strcat(dims_str,s);
+ }
+ sprintf(s, " or %d", exact_dimensions[n-1]);
+ strcat(dims_str,s);
+ PyErr_Format(PyExc_TypeError,
+ "Array must have %s dimensions. Given array has %d dimensions",
+ dims_str,
+ array_numdims(ary));
+ }
+ return success;
+ }
+
+ /* Require the given PyArrayObject to have a specified shape. If the
+ * array has the specified shape, return 1. Otherwise, set the python
+ * error string and return 0.
+ */
+ int require_size(PyArrayObject* ary,
+ npy_intp* size,
+ int n)
+ {
+ int i;
+ int success = 1;
+ int len;
+ char desired_dims[255] = "[";
+ char s[255];
+ char actual_dims[255] = "[";
+ for(i=0; i < n;i++)
+ {
+ if (size[i] != -1 && size[i] != array_size(ary,i))
+ {
+ success = 0;
+ }
+ }
+ if (!success)
+ {
+ for (i = 0; i < n; i++)
+ {
+ if (size[i] == -1)
+ {
+ sprintf(s, "*,");
+ }
+ else
+ {
+ sprintf(s, "%ld,", (long int)size[i]);
+ }
+ strcat(desired_dims,s);
+ }
+ len = strlen(desired_dims);
+ desired_dims[len-1] = ']';
+ for (i = 0; i < n; i++)
+ {
+ sprintf(s, "%ld,", (long int)array_size(ary,i));
+ strcat(actual_dims,s);
+ }
+ len = strlen(actual_dims);
+ actual_dims[len-1] = ']';
+ PyErr_Format(PyExc_TypeError,
+ "Array must have shape of %s. Given array has shape of %s",
+ desired_dims,
+ actual_dims);
+ }
+ return success;
+ }
+
+ /* Require the given PyArrayObject to to be Fortran ordered. If the
+ * the PyArrayObject is already Fortran ordered, do nothing. Else,
+ * set the Fortran ordering flag and recompute the strides.
+ */
+ int require_fortran(PyArrayObject* ary)
+ {
+ int success = 1;
+ int nd = array_numdims(ary);
+ int i;
+ npy_intp * strides = array_strides(ary);
+ if (array_is_fortran(ary)) return success;
+ /* Set the Fortran ordered flag */
+ array_enableflags(ary,NPY_ARRAY_FARRAY);
+ /* Recompute the strides */
+ strides[0] = strides[nd-1];
+ for (i=1; i < nd; ++i)
+ strides[i] = strides[i-1] * array_size(ary,i-1);
+ return success;
+ }
+}
+
+/* Combine all NumPy fragments into one for convenience */
+%fragment("NumPy_Fragments",
+ "header",
+ fragment="NumPy_Backward_Compatibility",
+ fragment="NumPy_Macros",
+ fragment="NumPy_Utilities",
+ fragment="NumPy_Object_to_Array",
+ fragment="NumPy_Array_Requirements")
+{
+}
+
+/* End John Hunter translation (with modifications by Bill Spotz)
+ */
+
+/* %numpy_typemaps() macro
+ *
+ * This macro defines a family of 74 typemaps that allow C arguments
+ * of the form
+ *
+ * 1. (DATA_TYPE IN_ARRAY1[ANY])
+ * 2. (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ * 3. (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ *
+ * 4. (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ * 5. (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * 6. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ * 7. (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * 8. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ *
+ * 9. (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ * 10. (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 11. (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 12. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+ * 13. (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 14. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+ *
+ * 15. (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+ * 16. (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 17. (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 18. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, , DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+ * 19. (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 20. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+ *
+ * 21. (DATA_TYPE INPLACE_ARRAY1[ANY])
+ * 22. (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ * 23. (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ *
+ * 24. (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ * 25. (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * 26. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ * 27. (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * 28. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ *
+ * 29. (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ * 30. (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 31. (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 32. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+ * 33. (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 34. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+ *
+ * 35. (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+ * 36. (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 37. (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 38. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+ * 39. (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 40. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+ *
+ * 41. (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ * 42. (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ * 43. (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ *
+ * 44. (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ *
+ * 45. (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ *
+ * 46. (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+ *
+ * 47. (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ * 48. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ *
+ * 49. (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ * 50. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ * 51. (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ * 52. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ *
+ * 53. (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ * 54. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ * 55. (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ * 56. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ *
+ * 57. (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ * 58. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
+ * 59. (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ * 60. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
+ *
+ * 61. (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+ * 62. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+ *
+ * 63. (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ * 64. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+ * 65. (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ * 66. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+ *
+ * 67. (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ * 68. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+ * 69. (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ * 70. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+ *
+ * 71. (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ * 72. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ * 73. (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ * 74. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ *
+ * where "DATA_TYPE" is any type supported by the NumPy module, and
+ * "DIM_TYPE" is any int-like type suitable for specifying dimensions.
+ * The difference between "ARRAY" typemaps and "FARRAY" typemaps is
+ * that the "FARRAY" typemaps expect Fortran ordering of
+ * multidimensional arrays. In python, the dimensions will not need
+ * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1"
+ * typemaps). The IN_ARRAYs can be a numpy array or any sequence that
+ * can be converted to a numpy array of the specified type. The
+ * INPLACE_ARRAYs must be numpy arrays of the appropriate type. The
+ * ARGOUT_ARRAYs will be returned as new numpy arrays of the
+ * appropriate type.
+ *
+ * These typemaps can be applied to existing functions using the
+ * %apply directive. For example:
+ *
+ * %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)};
+ * double prod(double* series, int length);
+ *
+ * %apply (int DIM1, int DIM2, double* INPLACE_ARRAY2)
+ * {(int rows, int cols, double* matrix )};
+ * void floor(int rows, int cols, double* matrix, double f);
+ *
+ * %apply (double IN_ARRAY3[ANY][ANY][ANY])
+ * {(double tensor[2][2][2] )};
+ * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
+ * {(double low[2][2][2] )};
+ * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
+ * {(double upp[2][2][2] )};
+ * void luSplit(double tensor[2][2][2],
+ * double low[2][2][2],
+ * double upp[2][2][2] );
+ *
+ * or directly with
+ *
+ * double prod(double* IN_ARRAY1, int DIM1);
+ *
+ * void floor(int DIM1, int DIM2, double* INPLACE_ARRAY2, double f);
+ *
+ * void luSplit(double IN_ARRAY3[ANY][ANY][ANY],
+ * double ARGOUT_ARRAY3[ANY][ANY][ANY],
+ * double ARGOUT_ARRAY3[ANY][ANY][ANY]);
+ */
+
+%define %numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE)
+
+/************************/
+/* Input Array Typemaps */
+/************************/
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY1[ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY1[ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY1[ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[1] = { $1_dim0 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 1) ||
+ !require_size(array, size, 1)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY1[ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[1] = { -1 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 1) ||
+ !require_size(array, size, 1)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[1] = {-1};
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 1) ||
+ !require_size(array, size, 1)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY2[ANY][ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { $1_dim0, $1_dim1 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY2[ANY][ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_fortran_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_fortran_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ /* for now, only concerned with lists */
+ $1 = PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL)
+{
+ npy_intp size[2] = { -1, -1 };
+ PyArrayObject* temp_array;
+ Py_ssize_t i;
+ int is_new_object;
+
+ /* length of the list */
+ $2 = PyList_Size($input);
+
+ /* the arrays */
+ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+ object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+ is_new_object_array = (int *)calloc($2,sizeof(int));
+
+ if (array == NULL || object_array == NULL || is_new_object_array == NULL)
+ {
+ SWIG_fail;
+ }
+
+ for (i=0; i<$2; i++)
+ {
+ temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object);
+
+ /* the new array must be stored so that it can be destroyed in freearg */
+ object_array[i] = temp_array;
+ is_new_object_array[i] = is_new_object;
+
+ if (!temp_array || !require_dimensions(temp_array, 2)) SWIG_fail;
+
+ /* store the size of the first array in the list, then use that for comparison. */
+ if (i == 0)
+ {
+ size[0] = array_size(temp_array,0);
+ size[1] = array_size(temp_array,1);
+ }
+
+ if (!require_size(temp_array, size, 2)) SWIG_fail;
+
+ array[i] = (DATA_TYPE*) array_data(temp_array);
+ }
+
+ $1 = (DATA_TYPE**) array;
+ $3 = (DIM_TYPE) size[0];
+ $4 = (DIM_TYPE) size[1];
+}
+%typemap(freearg)
+ (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ Py_ssize_t i;
+
+ if (array$argnum!=NULL) free(array$argnum);
+
+ /*freeing the individual arrays if needed */
+ if (object_array$argnum!=NULL)
+ {
+ if (is_new_object_array$argnum!=NULL)
+ {
+ for (i=0; i<$2; i++)
+ {
+ if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i])
+ { Py_DECREF(object_array$argnum[i]); }
+ }
+ free(is_new_object_array$argnum);
+ }
+ free(object_array$argnum);
+ }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* IN_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3) | !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* IN_FARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_fortran_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3};
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 4) ||
+ !require_size(array, size, 4)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[4] = { -1, -1, -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 4) ||
+ !require_size(array, size, 4)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+ $5 = (DIM_TYPE) array_size(array,3);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ /* for now, only concerned with lists */
+ $1 = PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ PyArrayObject* temp_array;
+ Py_ssize_t i;
+ int is_new_object;
+
+ /* length of the list */
+ $2 = PyList_Size($input);
+
+ /* the arrays */
+ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+ object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+ is_new_object_array = (int *)calloc($2,sizeof(int));
+
+ if (array == NULL || object_array == NULL || is_new_object_array == NULL)
+ {
+ SWIG_fail;
+ }
+
+ for (i=0; i<$2; i++)
+ {
+ temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object);
+
+ /* the new array must be stored so that it can be destroyed in freearg */
+ object_array[i] = temp_array;
+ is_new_object_array[i] = is_new_object;
+
+ if (!temp_array || !require_dimensions(temp_array, 3)) SWIG_fail;
+
+ /* store the size of the first array in the list, then use that for comparison. */
+ if (i == 0)
+ {
+ size[0] = array_size(temp_array,0);
+ size[1] = array_size(temp_array,1);
+ size[2] = array_size(temp_array,2);
+ }
+
+ if (!require_size(temp_array, size, 3)) SWIG_fail;
+
+ array[i] = (DATA_TYPE*) array_data(temp_array);
+ }
+
+ $1 = (DATA_TYPE**) array;
+ $3 = (DIM_TYPE) size[0];
+ $4 = (DIM_TYPE) size[1];
+ $5 = (DIM_TYPE) size[2];
+}
+%typemap(freearg)
+ (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ Py_ssize_t i;
+
+ if (array$argnum!=NULL) free(array$argnum);
+
+ /*freeing the individual arrays if needed */
+ if (object_array$argnum!=NULL)
+ {
+ if (is_new_object_array$argnum!=NULL)
+ {
+ for (i=0; i<$2; i++)
+ {
+ if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i])
+ { Py_DECREF(object_array$argnum[i]); }
+ }
+ free(is_new_object_array$argnum);
+ }
+ free(object_array$argnum);
+ }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ * DATA_TYPE* IN_ARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[4] = { -1, -1, -1 , -1};
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 4) ||
+ !require_size(array, size, 4)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DIM_TYPE) array_size(array,3);
+ $5 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[4] = { -1, -1, -1, -1 };
+ array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 4) ||
+ !require_size(array, size, 4) | !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+ $5 = (DIM_TYPE) array_size(array,3);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ * DATA_TYPE* IN_FARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[4] = { -1, -1, -1 , -1 };
+ array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 4) ||
+ !require_size(array, size, 4) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DIM_TYPE) array_size(array,3);
+ $5 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/***************************/
+/* In-Place Array Typemaps */
+/***************************/
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY1[ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY1[ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY1[ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[1] = { $1_dim0 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,1) || !require_size(array, size, 1) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ (PyArrayObject* array=NULL, int i=1)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,1) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = 1;
+ for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ (PyArrayObject* array=NULL, int i=0)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,1) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = 1;
+ for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i);
+ $2 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[2] = { $1_dim0, $1_dim1 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_size(array, size, 2) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
+ !require_native(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array)
+ || !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
+ !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_size(array, size, 3) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
+ !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+
+/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL)
+{
+ npy_intp size[2] = { -1, -1 };
+ PyArrayObject* temp_array;
+ Py_ssize_t i;
+
+ /* length of the list */
+ $2 = PyList_Size($input);
+
+ /* the arrays */
+ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+ object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+
+ if (array == NULL || object_array == NULL)
+ {
+ SWIG_fail;
+ }
+
+ for (i=0; i<$2; i++)
+ {
+ temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE);
+
+ /* the new array must be stored so that it can be destroyed in freearg */
+ object_array[i] = temp_array;
+
+ if ( !temp_array || !require_dimensions(temp_array, 2) ||
+ !require_contiguous(temp_array) ||
+ !require_native(temp_array) ||
+ !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE)
+ ) SWIG_fail;
+
+ /* store the size of the first array in the list, then use that for comparison. */
+ if (i == 0)
+ {
+ size[0] = array_size(temp_array,0);
+ size[1] = array_size(temp_array,1);
+ }
+
+ if (!require_size(temp_array, size, 2)) SWIG_fail;
+
+ array[i] = (DATA_TYPE*) array_data(temp_array);
+ }
+
+ $1 = (DATA_TYPE**) array;
+ $3 = (DIM_TYPE) size[0];
+ $4 = (DIM_TYPE) size[1];
+}
+%typemap(freearg)
+ (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ if (array$argnum!=NULL) free(array$argnum);
+ if (object_array$argnum!=NULL) free(object_array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* INPLACE_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
+ !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* INPLACE_FARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+ || !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,4) || !require_size(array, size, 4) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,4) || !require_contiguous(array) ||
+ !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+ $5 = (DIM_TYPE) array_size(array,3);
+}
+
+/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ $1 = PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ PyArrayObject* temp_array;
+ Py_ssize_t i;
+
+ /* length of the list */
+ $2 = PyList_Size($input);
+
+ /* the arrays */
+ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+ object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+
+ if (array == NULL || object_array == NULL)
+ {
+ SWIG_fail;
+ }
+
+ for (i=0; i<$2; i++)
+ {
+ temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE);
+
+ /* the new array must be stored so that it can be destroyed in freearg */
+ object_array[i] = temp_array;
+
+ if ( !temp_array || !require_dimensions(temp_array, 3) ||
+ !require_contiguous(temp_array) ||
+ !require_native(temp_array) ||
+ !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE)
+ ) SWIG_fail;
+
+ /* store the size of the first array in the list, then use that for comparison. */
+ if (i == 0)
+ {
+ size[0] = array_size(temp_array,0);
+ size[1] = array_size(temp_array,1);
+ size[2] = array_size(temp_array,2);
+ }
+
+ if (!require_size(temp_array, size, 3)) SWIG_fail;
+
+ array[i] = (DATA_TYPE*) array_data(temp_array);
+ }
+
+ $1 = (DATA_TYPE**) array;
+ $3 = (DIM_TYPE) size[0];
+ $4 = (DIM_TYPE) size[1];
+ $5 = (DIM_TYPE) size[2];
+}
+%typemap(freearg)
+ (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ if (array$argnum!=NULL) free(array$argnum);
+ if (object_array$argnum!=NULL) free(object_array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ * DATA_TYPE* INPLACE_ARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,4) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DIM_TYPE) array_size(array,3);
+ $5 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,4) || !require_contiguous(array) ||
+ !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+ $5 = (DIM_TYPE) array_size(array,3);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* INPLACE_FARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,4) || !require_contiguous(array)
+ || !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DIM_TYPE) array_size(array,3);
+ $5 = (DATA_TYPE*) array_data(array);
+}
+
+/*************************/
+/* Argout Array Typemaps */
+/*************************/
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ (PyObject* array = NULL)
+{
+ npy_intp dims[1] = { $1_dim0 };
+ array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY1[ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ */
+%typemap(in,numinputs=1,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ (PyObject* array = NULL)
+{
+ npy_intp dims[1];
+ if (!PyInt_Check($input))
+ {
+ const char* typestring = pytype_string($input);
+ PyErr_Format(PyExc_TypeError,
+ "Int dimension expected. '%s' given.",
+ typestring);
+ SWIG_fail;
+ }
+ $2 = (DIM_TYPE) PyInt_AsLong($input);
+ dims[0] = (npy_intp) $2;
+ array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ */
+%typemap(in,numinputs=1,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ (PyObject* array = NULL)
+{
+ npy_intp dims[1];
+ if (!PyInt_Check($input))
+ {
+ const char* typestring = pytype_string($input);
+ PyErr_Format(PyExc_TypeError,
+ "Int dimension expected. '%s' given.",
+ typestring);
+ SWIG_fail;
+ }
+ $1 = (DIM_TYPE) PyInt_AsLong($input);
+ dims[0] = (npy_intp) $1;
+ array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $2 = (DATA_TYPE*) array_data(array);
+}
+%typemap(argout)
+ (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ (PyObject* array = NULL)
+{
+ npy_intp dims[2] = { $1_dim0, $1_dim1 };
+ array = PyArray_SimpleNew(2, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ (PyObject* array = NULL)
+{
+ npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 };
+ array = PyArray_SimpleNew(3, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+ (PyObject* array = NULL)
+{
+ npy_intp dims[4] = { $1_dim0, $1_dim1, $1_dim2, $1_dim3 };
+ array = PyArray_SimpleNew(4, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/*****************************/
+/* Argoutview Array Typemaps */
+/*****************************/
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+{
+ npy_intp dims[1] = { *$2 };
+ PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ (DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim_temp;
+ $2 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+{
+ npy_intp dims[1] = { *$1 };
+ PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+ npy_intp dims[2] = { *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+{
+ npy_intp dims[2] = { *$1, *$2 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+ npy_intp dims[2] = { *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || !require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+{
+ npy_intp dims[2] = { *$1, *$2 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || !require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+ npy_intp dims[3] = { *$2, *$3, *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+ DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL)
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+{
+ npy_intp dims[3] = { *$1, *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+ npy_intp dims[3] = { *$2, *$3, *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || !require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+ DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+{
+ npy_intp dims[3] = { *$1, *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || !require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+ $5 = &dim4_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+ npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+ DATA_TYPE** ARGOUTVIEW_ARRAY4)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_ARRAY4)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &dim4_temp;
+ $5 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
+{
+ npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+ $5 = &dim4_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+ npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || !require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+ DATA_TYPE** ARGOUTVIEW_FARRAY4)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_FARRAY4)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &dim4_temp;
+ $5 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
+{
+ npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || !require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/*************************************/
+/* Managed Argoutview Array Typemaps */
+/*************************************/
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+{
+ npy_intp dims[1] = { *$2 };
+ PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+ (DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim_temp;
+ $2 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+ (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+{
+ npy_intp dims[1] = { *$1 };
+ PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE
<TRUNCATED>