Implement `Mat::fromArray()`. Add tests.
This commit is contained in:
parent
c3402e0abe
commit
6cf646a6d0
50
src/mat.cc
50
src/mat.cc
|
@ -48,10 +48,60 @@ namespace php_arma
|
|||
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 (idx_col > num_cols - 1) {
|
||||
break;
|
||||
}
|
||||
if (UNEXPECTED(!zval_check_scalar<T>(elem))) {
|
||||
break;
|
||||
}
|
||||
native->at(idx_row, idx_col++) = zval_get_scalar<T>(elem);
|
||||
ZEND_HASH_FOREACH_END();
|
||||
++idx_row;
|
||||
idx_col = 0;
|
||||
ZEND_HASH_FOREACH_END();
|
||||
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>
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace php_arma
|
|||
|
||||
static PHP_FUNCTION(init);
|
||||
static PHP_FUNCTION(fromString);
|
||||
static PHP_FUNCTION(fromArray);
|
||||
|
||||
static void ce_init(zend_class_entry*);
|
||||
};
|
||||
|
|
|
@ -80,11 +80,14 @@
|
|||
Z_PARAM_LONG_EX2(dest, _dummy, 0, 1, 0)
|
||||
#define Z_PARAM_STR_DEREF(dest) \
|
||||
Z_PARAM_STR_EX2(dest, 0, 1, 0)
|
||||
#define Z_PARAM_ARRAY_DEREF(dest) \
|
||||
Z_PARAM_ARRAY_EX2(dest, 0, 1, 0)
|
||||
#else
|
||||
// Before PHP 7.2, parameter is dereferenced by default here.
|
||||
#define Z_PARAM_DOUBLE_DEREF Z_PARAM_DOUBLE
|
||||
#define Z_PARAM_LONG_DEREF Z_PARAM_LONG
|
||||
#define Z_PARAM_STR_DEREF Z_PARAM_STR
|
||||
#define Z_PARAM_ARRAY_DEREF Z_PARAM_ARRAY
|
||||
#endif
|
||||
|
||||
#ifdef PHP_ARMA_OPERATORS
|
||||
|
|
|
@ -30,4 +30,14 @@ abstract class Mat implements Internal\DenseResizableMatrix
|
|||
static function fromString($text) {
|
||||
return new static;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the matrix from a PHP array.
|
||||
*
|
||||
* @param array $arr
|
||||
* @return Mat
|
||||
*/
|
||||
static function fromArray($arr) {
|
||||
return new static;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,14 @@ interface Vector
|
|||
*/
|
||||
static function fromString($text);
|
||||
|
||||
/**
|
||||
* Create the vector from a PHP array.
|
||||
*
|
||||
* @param array $arr
|
||||
* @return static
|
||||
*/
|
||||
static function fromArray($arr);
|
||||
|
||||
// Vector subview
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
--TEST--
|
||||
Test for initialization of `Mat`
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once 'includes/loaded.php';
|
||||
is_php_arma_loaded();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once 'includes/assert.php';
|
||||
|
||||
$mat = Arma\DMat::init(3, 4, Arma\Fill::ZEROS);
|
||||
batch_assert('initialization of `Arma\\Mat`',
|
||||
[3, $mat->nRows()],
|
||||
[4, $mat->nCols()],
|
||||
[3 * 4, $mat->nElem()],
|
||||
[0., $mat->max()],
|
||||
[0., $mat->min()]
|
||||
);
|
||||
|
||||
$mat1 = Arma\IMat::fromString('1 2; 3 4');
|
||||
batch_assert('initialization from string of `Arma\\Mat`',
|
||||
[2, $mat1->nRows()],
|
||||
[2, $mat1->nCols()],
|
||||
[2 * 2, $mat1->nElem()],
|
||||
[1, $mat1(0, 0)->val()],
|
||||
[2, $mat1(0, 1)->val()],
|
||||
[3, $mat1(1, 0)->val()],
|
||||
[4, $mat1(1, 1)->val()]
|
||||
);
|
||||
|
||||
$mat2 = Arma\IMat::fromArray([
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
]);
|
||||
batch_assert('initialization from array of `Arma\\Mat`',
|
||||
[2, $mat2->nRows()],
|
||||
[2, $mat2->nCols()],
|
||||
[2 * 2, $mat2->nElem()],
|
||||
[1, $mat2(0, 0)->val()],
|
||||
[2, $mat2(0, 1)->val()],
|
||||
[3, $mat2(1, 0)->val()],
|
||||
[4, $mat2(1, 1)->val()]
|
||||
);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
Reference in New Issue