143 lines
4.4 KiB
C++
143 lines
4.4 KiB
C++
//
|
|
// php-armadillo/mat.cc
|
|
//
|
|
// @Author CismonX
|
|
//
|
|
|
|
#include "mat.hh"
|
|
#include "constants.hh"
|
|
#include "base.hh"
|
|
#include "dense.hh"
|
|
#include "matrix.hh"
|
|
#include "dense_matrix.hh"
|
|
#include "resizable.hh"
|
|
#include "resizable_matrix.hh"
|
|
#include "dense_resizable_matrix.hh"
|
|
|
|
#include <armadillo>
|
|
|
|
namespace php_arma
|
|
{
|
|
template <typename T>
|
|
PHP_ARMA_METHOD(mat, init, T)
|
|
{
|
|
zend_long n_rows = 0;
|
|
zend_long n_cols = 0;
|
|
zend_long fill = fill::none;
|
|
ZEND_PARSE_PARAMETERS_START(0, 3)
|
|
Z_PARAM_OPTIONAL
|
|
Z_PARAM_LONG_DEREF(n_rows)
|
|
Z_PARAM_LONG_DEREF(n_cols)
|
|
Z_PARAM_LONG_DEREF(fill)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
auto zobj = create(n_rows, n_cols);
|
|
fill::invoke(ZOBJ_NATIVE(zobj), fill);
|
|
RETVAL_OBJ(zobj);
|
|
}
|
|
|
|
template <typename T>
|
|
PHP_ARMA_METHOD(mat, fromString, T)
|
|
{
|
|
zend_string *text;
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_STR_DEREF(text)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
auto zobj = create(ZSTR_VAL(text));
|
|
RETVAL_OBJ(zobj);
|
|
}
|
|
|
|
template <typename T>
|
|
PHP_ARMA_METHOD(mat, fromArray, T)
|
|
{
|
|
zval *arr;
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_ARRAY_DEREF(arr)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
auto num_rows = zend_hash_num_elements(Z_ARR_P(arr));
|
|
if (UNEXPECTED(num_rows == 0)) {
|
|
RETURN_OBJ(create());
|
|
}
|
|
auto first_row = zend_hash_index_find(Z_ARR_P(arr), 0);
|
|
if (UNEXPECTED(first_row == nullptr || Z_TYPE_P(first_row) != IS_ARRAY)) {
|
|
zend_throw_exception(zend_ce_error, "bad input matrix", 0);
|
|
RETURN_NULL();
|
|
}
|
|
auto num_cols = zend_hash_num_elements(Z_ARR_P(first_row));
|
|
if (UNEXPECTED(num_rows == 0)) {
|
|
RETURN_OBJ(create());
|
|
}
|
|
|
|
auto zobj = create(num_rows, num_cols);
|
|
auto native = ZOBJ_NATIVE(zobj);
|
|
size_t idx_row = 0;
|
|
size_t idx_col = 0;
|
|
ZEND_HASH_FOREACH_VAL(Z_ARR_P(arr), zval *row)
|
|
if (idx_row > num_rows - 1) {
|
|
break;
|
|
}
|
|
if (UNEXPECTED(Z_TYPE_P(row) != IS_ARRAY)) {
|
|
zend_throw_exception(zend_ce_error, "bad input matrix", 0);
|
|
break;
|
|
}
|
|
ZEND_HASH_FOREACH_VAL(Z_ARR_P(row), zval *elem)
|
|
if (UNEXPECTED(idx_col > num_cols - 1)) {
|
|
break;
|
|
}
|
|
if (UNEXPECTED(!zval_check_scalar<T>(elem))) {
|
|
goto end_loop;
|
|
}
|
|
native->at(idx_row, idx_col++) = zval_get_scalar<T>(elem);
|
|
ZEND_HASH_FOREACH_END();
|
|
++idx_row;
|
|
idx_col = 0;
|
|
ZEND_HASH_FOREACH_END();
|
|
end_loop:
|
|
RETVAL_OBJ(zobj);
|
|
}
|
|
|
|
template <typename T>
|
|
PHP_ARMA_START_ME(mat, T)
|
|
PHP_ARMA_ME(init, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
|
PHP_ARMA_ME(fromString, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
|
PHP_ARMA_ME(fromArray, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
|
PHP_ARMA_END_ME();
|
|
|
|
template <typename T>
|
|
void mat<T>::ce_init(zend_class_entry *parent_ce)
|
|
{
|
|
ce = class_register<php_name::val>(parent_ce, fentry_list_concat(
|
|
PHP_ARMA_FENTRY((base <T, mat>::me)),
|
|
PHP_ARMA_FENTRY((dense <T, mat>::me)),
|
|
PHP_ARMA_FENTRY((matrix <T, mat>::me)),
|
|
PHP_ARMA_FENTRY((dense_matrix <T, mat>::me)),
|
|
PHP_ARMA_FENTRY((resizable <T, mat>::me)),
|
|
PHP_ARMA_FENTRY((resizable_matrix <T, mat>::me)),
|
|
PHP_ARMA_FENTRY((dense_resizable_matrix<T, mat>::me)),
|
|
PHP_ARMA_FENTRY(me)
|
|
));
|
|
ce->create_object = object_non_constructible;
|
|
|
|
object_handlers_init(&handlers);
|
|
handlers.offset = sizeof(native_t);
|
|
handlers.clone_obj = nullptr;
|
|
handlers.dtor_obj = object_destroy<native_t>;
|
|
handlers.count_elements = base<T, mat>::count_elements;
|
|
}
|
|
|
|
PHP_ARMA_NAME_DECLARE(mat, "DMat", double);
|
|
PHP_ARMA_NAME_DECLARE(mat, "IMat", zend_long);
|
|
PHP_ARMA_NAME_DECLARE(mat, "CxDMat", cx_double);
|
|
|
|
void mat_init()
|
|
{
|
|
mat_ce = interface_register<mat_php_name>();
|
|
|
|
mat<double >::ce_init(mat_ce);
|
|
mat<zend_long>::ce_init(mat_ce);
|
|
mat<cx_double>::ce_init(mat_ce);
|
|
}
|
|
}
|