// // 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" namespace php_arma { template 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(n_rows) Z_PARAM_LONG(n_cols) Z_PARAM_LONG(fill) ZEND_PARSE_PARAMETERS_END(); auto zobj = mat::create(n_rows, n_cols); fill::invoke(ZOBJ_NATIVE(zobj), fill); RETVAL_OBJ(zobj); } template PHP_ARMA_METHOD(mat, fromString, T) { zend_string *text; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STR(text) ZEND_PARSE_PARAMETERS_END(); auto zobj = mat::create(ZSTR_VAL(text)); RETVAL_OBJ(zobj); } template PHP_ARMA_METHOD(mat, fromArray, T) { zval *arr; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_ARRAY(arr) ZEND_PARSE_PARAMETERS_END(); auto num_rows = zend_hash_num_elements(Z_ARR_P(arr)); if (UNEXPECTED(num_rows == 0)) { RETURN_OBJ(mat::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)) { throw_exception("bad input matrix"); return; } auto num_cols = zend_hash_num_elements(Z_ARR_P(first_row)); if (UNEXPECTED(num_rows == 0)) { RETURN_OBJ(mat::create()); } auto zobj = mat::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)) { throw_exception("bad input matrix"); break; } ZEND_HASH_FOREACH_VAL(Z_ARR_P(row), zval *elem) if (UNEXPECTED(idx_col > num_cols - 1)) { break; } if (UNEXPECTED(!zval_check_scalar(elem))) { goto end_loop; } native->at(idx_row, idx_col++) = zval_get_scalar(elem); ZEND_HASH_FOREACH_END(); ++idx_row; idx_col = 0; ZEND_HASH_FOREACH_END(); end_loop: RETVAL_OBJ(zobj); } template 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 void mat::ce_init(zend_class_entry *parent_ce) { ce = class_register(parent_ce, fentry_list_concat( PHP_ARMA_FENTRY((base ::me)), PHP_ARMA_FENTRY((dense ::me)), PHP_ARMA_FENTRY((matrix ::me)), PHP_ARMA_FENTRY((dense_matrix ::me)), PHP_ARMA_FENTRY((resizable ::me)), PHP_ARMA_FENTRY((resizable_matrix ::me)), PHP_ARMA_FENTRY((dense_resizable_matrix::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; handlers.count_elements = base::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 = abstract_class_register(dense_resizable_matrix_ce); mat::ce_init(mat_ce); mat::ce_init(mat_ce); mat::ce_init(mat_ce); } }