///////////////////////////////////////////////////////////////////// // = NMatrix // // A linear algebra library for scientific computation in Ruby. // NMatrix is part of SciRuby. // // NMatrix was originally inspired by and derived from NArray, by // Masahiro Tanaka: http://narray.rubyforge.org // // == Copyright Information // // SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation // NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation // // Please see LICENSE.txt for additional copyright notices. // // == Contributing // // By contributing source code to SciRuby, you agree to be bound by // our Contributor Agreement: // // * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement // // == data.h // // Header file for dealing with data types. #ifndef DATA_H #define DATA_H /* * Standard Includes */ #include /* * Project Includes */ #include "nmatrix.h" #include "types.h" #include "complex.h" #include "ruby_object.h" namespace nm { /* * Constants */ const int NUM_DTYPES = 10; const int NUM_ITYPES = 4; const int NUM_EWOPS = 12; const int NUM_UNARYOPS = 24; const int NUM_NONCOM_EWOPS = 3; enum ewop_t { EW_ADD, EW_SUB, EW_MUL, EW_DIV, EW_POW, EW_MOD, EW_EQEQ, EW_NEQ, EW_LT, EW_GT, EW_LEQ, EW_GEQ, }; enum noncom_ewop_t { NONCOM_EW_ATAN2, NONCOM_EW_LDEXP, NONCOM_EW_HYPOT }; enum unaryop_t { UNARY_SIN, UNARY_COS, UNARY_TAN, UNARY_ASIN, UNARY_ACOS, UNARY_ATAN, UNARY_SINH, UNARY_COSH, UNARY_TANH, UNARY_ASINH, UNARY_ACOSH, UNARY_ATANH, UNARY_EXP, UNARY_LOG2, UNARY_LOG10, UNARY_SQRT, UNARY_ERF, UNARY_ERFC, UNARY_CBRT, UNARY_GAMMA, UNARY_NEGATE, UNARY_FLOOR, UNARY_CEIL, UNARY_ROUND }; // element-wise and scalar operators extern const char* const EWOP_OPS[nm::NUM_EWOPS]; extern const std::string EWOP_NAMES[nm::NUM_EWOPS]; extern const std::string UNARYOPS[nm::NUM_UNARYOPS]; extern const std::string NONCOM_EWOP_NAMES[nm::NUM_NONCOM_EWOPS]; template Complex::Complex(const RubyObject& other) { switch(TYPE(other.rval)) { case T_COMPLEX: r = NUM2DBL(rb_funcall(other.rval, rb_intern("real"), 0)); i = NUM2DBL(rb_funcall(other.rval, rb_intern("imag"), 0)); break; case T_FLOAT: case T_FIXNUM: case T_BIGNUM: r = NUM2DBL(other.rval); i = 0.0; break; default: rb_raise(rb_eTypeError, "not sure how to convert this type of VALUE to a complex"); } } } // end of namespace nm /* * Macros */ #define STYPE_MARK_TABLE(name) \ static void (*(name)[nm::NUM_STYPES])(STORAGE*) = { \ nm_dense_storage_mark, \ nm_list_storage_mark, \ nm_yale_storage_mark \ }; #define STYPE_REGISTER_TABLE(name) \ static void (*(name)[nm::NUM_STYPES])(const STORAGE*) = { \ nm_dense_storage_register, \ nm_list_storage_register, \ nm_yale_storage_register \ }; #define STYPE_UNREGISTER_TABLE(name) \ static void (*(name)[nm::NUM_STYPES])(const STORAGE*) = { \ nm_dense_storage_unregister, \ nm_list_storage_unregister, \ nm_yale_storage_unregister \ }; #define CAST_TABLE(name) \ static STORAGE* (*(name)[nm::NUM_STYPES][nm::NUM_STYPES])(const STORAGE*, nm::dtype_t, void*) = { \ { nm_dense_storage_cast_copy, nm_dense_storage_from_list, nm_dense_storage_from_yale }, \ { nm_list_storage_from_dense, nm_list_storage_cast_copy, nm_list_storage_from_yale }, \ { nm_yale_storage_from_dense, nm_yale_storage_from_list, nm_yale_storage_cast_copy } \ }; /* * Defines a static array that hold function pointers to dtype templated * versions of the specified function. */ #define DTYPE_TEMPLATE_TABLE(fun, ret, ...) NAMED_DTYPE_TEMPLATE_TABLE(ttable, fun, ret, __VA_ARGS__) #define NAMED_DTYPE_TEMPLATE_TABLE(name, fun, ret, ...) \ static ret (*(name)[nm::NUM_DTYPES])(__VA_ARGS__) = { \ fun, \ fun, \ fun, \ fun, \ fun, \ fun, \ fun, \ fun, \ fun, \ fun \ }; #define DTYPE_OBJECT_STATIC_TABLE(obj, fun, ret, ...) \ static ret (*(ttable)[nm::NUM_DTYPES])(__VA_ARGS__) = { \ obj::fun, \ obj::fun, \ obj::fun, \ obj::fun, \ obj::fun, \ obj::fun, \ obj::fun, \ obj::fun, \ obj::fun, \ obj::fun \ }; #define NAMED_DTYPE_TEMPLATE_TABLE_NO_ROBJ(name, fun, ret, ...) \ static ret (*(name)[nm::NUM_DTYPES])(__VA_ARGS__) = { \ fun, \ fun, \ fun, \ fun, \ fun, \ fun, \ fun, \ fun, \ fun \ }; /* * Same as DTYPE_TEMPLATE_TABLE but for functions that have two template * parameters. * * The left-hand DType is used as the first index, and the right-hand side is * the second index. Not all left- and right-hand side combinations are valid, * and an invalid combination will result in a NULL pointer. */ #define LR_DTYPE_TEMPLATE_TABLE(fun, ret, ...) NAMED_LR_DTYPE_TEMPLATE_TABLE(ttable, fun, ret, __VA_ARGS__) #define NAMED_LR_DTYPE_TEMPLATE_TABLE(name, fun, ret, ...) \ static ret (*(name)[nm::NUM_DTYPES][nm::NUM_DTYPES])(__VA_ARGS__) = { \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, fun}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, fun}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, fun}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, fun}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, fun}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, fun}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, fun}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, fun}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, fun}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, fun} \ }; /* * Defines a static array that holds function pointers to operation, and left- * and right-side dtype templated version sof the specified function. */ #define OP_LR_DTYPE_TEMPLATE_TABLE(fun, ret, ...) NAMED_OP_LR_DTYPE_TEMPLATE_TABLE(ttable, fun, ret, __VA_ARGS__) #define NAMED_OP_LR_DTYPE_TEMPLATE_TABLE(name, fun, ret, ...) \ static ret (*(name)[nm::NUM_EWOPS][nm::NUM_DTYPES][nm::NUM_DTYPES])(__VA_ARGS__) = { \ { \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun} \ }, \ \ { \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun} \ }, \ \ { \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ \ { \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun} \ }, \ \ { \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun} \ }, \ \ { \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, fun, \ fun, fun, fun, fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun} \ }, \ \ { \ {fun, fun, fun, fun, \ fun, fun, fun, fun, \ fun, \ NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun} \ }, \ {{fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun}}, \ {{fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun}}, \ {{fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun}}, \ {{fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun}}, \ {{fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {fun, fun, fun, fun, fun, fun, fun, fun, fun, NULL}, \ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, fun} \ } \ }; /* * Defines a static array that holds function pointers to an elementwise op, * itype, dtype templated versions of the specified function. */ #define OP_ITYPE_DTYPE_TEMPLATE_TABLE(fun, ret, ...) NAMED_OP_ITYPE_DTYPE_TEMPLATE_TABLE(ttable, fun, ret, __VA_ARGS__) #define NAMED_OP_ITYPE_DTYPE_TEMPLATE_TABLE(name, fun, ret, ...) \ static ret (*(name)[nm::NUM_EWOPS][nm::NUM_ITYPES][nm::NUM_DTYPES])(__VA_ARGS__) = \ {{{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}},\ {{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}},\ {{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}},\ {{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}},\ {{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}},\ {{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}},\ {{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}},\ {{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}},\ {{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}},\ {{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}},\ {{fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun},\ {fun,fun,fun,fun,fun,fun,fun,fun,fun,fun}}}; extern "C" { /* * Data */ // regular data types extern const char* const DTYPE_NAMES[nm::NUM_DTYPES]; extern const size_t DTYPE_SIZES[nm::NUM_DTYPES]; extern const nm::dtype_t Upcast[nm::NUM_DTYPES][nm::NUM_DTYPES]; /* * Functions */ void* rubyobj_to_cval(VALUE val, nm::dtype_t dtype); void rubyval_to_cval(VALUE val, nm::dtype_t dtype, void* loc); nm::RubyObject rubyobj_from_cval(void* val, nm::dtype_t dtype); void nm_init_data(); } // end of extern "C" block #endif // DATA_H