Implement `insertRows()` and `insertCols()`

This commit is contained in:
CismonX 2019-07-29 00:28:46 +08:00
parent 1c3d64740e
commit e042ca2900
6 changed files with 123 additions and 23 deletions

View File

@ -63,16 +63,74 @@ namespace php_arma
RETVAL_THIS();
}
template <typename T, typename T1>
PHP_ARMA_METHOD(dense_resizable_matrix, insertRows, T, T1)
template <typename T, typename ChildT>
PHP_ARMA_METHOD(dense_resizable_matrix, insertRows, T, ChildT)
{
zend_long row_idx;
zval *rows;
zend_bool set_to_zero = true;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_LONG(row_idx)
Z_PARAM_ZVAL(rows)
Z_PARAM_OPTIONAL
Z_PARAM_BOOL(set_to_zero)
ZEND_PARSE_PARAMETERS_END();
auto native = THIS_NATIVE;
try {
if (Z_TYPE_P(rows) == IS_LONG) {
native->insert_rows(row_idx, Z_LVAL_P(rows), set_to_zero);
} else if (Z_TYPE_P(rows) == IS_OBJECT) {
if (Z_OBJCE_P(rows) == ChildT::ce) {
auto rows_obj = to_native_object<typename ChildT::native_t>(Z_OBJ_P(rows));
native->insert_rows(row_idx, *rows_obj);
} else if (Z_OBJCE_P(rows) == ChildT::subview_t::ce) {
auto rows_obj = to_native_object<typename ChildT::subview_t::native_t>(Z_OBJ_P(rows));
native->insert_rows(row_idx, *rows_obj);
} else {
ex_bad_type(ZSTR_VAL(dense_matrix_ce->name), zval_get_type_name(rows));
}
} else {
ex_bad_type("int or object", zval_get_type_name(rows));
}
} catch (const std::logic_error& err) {
throw_error(err.what());
}
}
template <typename T, typename T1>
PHP_ARMA_METHOD(dense_resizable_matrix, insertCols, T, T1)
template <typename T, typename ChildT>
PHP_ARMA_METHOD(dense_resizable_matrix, insertCols, T, ChildT)
{
zend_long col_idx;
zval *cols;
zend_bool set_to_zero = true;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_LONG(col_idx)
Z_PARAM_ZVAL(cols)
Z_PARAM_OPTIONAL
Z_PARAM_BOOL(set_to_zero)
ZEND_PARSE_PARAMETERS_END();
auto native = THIS_NATIVE;
try {
if (Z_TYPE_P(cols) == IS_LONG) {
native->insert_cols(col_idx, Z_LVAL_P(cols), set_to_zero);
} else if (Z_TYPE_P(cols) == IS_OBJECT) {
if (Z_OBJCE_P(cols) == ChildT::ce) {
auto cols_obj = to_native_object<typename ChildT::native_t>(Z_OBJ_P(cols));
native->insert_cols(col_idx, *cols_obj);
} else if (Z_OBJCE_P(cols) == ChildT::subview_t::ce) {
auto cols_obj = to_native_object<typename ChildT::subview_t::native_t>(Z_OBJ_P(cols));
native->insert_cols(col_idx, *cols_obj);
} else {
ex_bad_type(ZSTR_VAL(dense_matrix_ce->name), zval_get_type_name(cols));
}
} else {
ex_bad_type("int or object", zval_get_type_name(cols));
}
} catch (const std::logic_error& err) {
throw_error(err.what());
}
}
template <typename T, typename ChildT>

View File

@ -52,9 +52,9 @@ interface DenseResizableMatrix extends DenseMatrix, ResizableMatrix
* whether to initialize new elements to zero, or insert a copy of specified object
* (whose column size is the same as the recipient object),
*
* @param int $row_idx
* @param Dense|int $rows
* @param bool $set_to_zero[optional]
* @param int $row_idx
* @param DenseMatrix|int $rows
* @param bool $set_to_zero[optional]
* @return void
*/
function insertRows($row_idx, $rows, $set_to_zero = true);
@ -64,9 +64,9 @@ interface DenseResizableMatrix extends DenseMatrix, ResizableMatrix
* whether to initialize new elements to zero, or insert a copy of specified object
* (whose row size is the same as the recipient object),
*
* @param int $col_idx
* @param Dense|int $cols
* @param bool $set_to_zero[optional]
* @param int $col_idx
* @param DenseMatrix|int $cols
* @param bool $set_to_zero[optional]
* @return void
*/
function insertCols($col_idx, $cols, $set_to_zero = true);

View File

@ -16,12 +16,7 @@ require_once 'includes/assert.php';
$mat0 = Arma\DMat::init(3, 3, Arma\Fill::RANDU);
$mat1 = Arma\DMat::init(3, 3, Arma\Fill::RANDU);
$comp = function ($expected, $got) {
$compare_result = $expected->equals($got);
return $compare_result->max() == 1 && $compare_result->min() == 1;
};
batch_assert_ex('operator overloading for comparisons', $comp,
batch_assert_mat('operator overloading for comparisons',
[$mat0->equals($mat1), $mat0 == $mat1],
[$mat0->notEquals($mat1), $mat0 != $mat1],
[$mat0->smallerThan($mat1), $mat0 < $mat1],

View File

@ -26,11 +26,7 @@ $mat1 = Arma\IMat::fromArray([
$mat->imbue(function () use (&$cnt) {
return ++$cnt;
});
$comp = function ($expected, $got) {
$compare_result = $expected->equals($got);
return $compare_result->max() == 1 && $compare_result->min() == 1;
};
batch_assert_ex('method `imbue()`', $comp,
batch_assert_mat('method `imbue()`',
[$mat1, $mat]
);

View File

@ -0,0 +1,36 @@
--TEST--
Test for methods `insertRows()` and `insertCols()`.
--SKIPIF--
<?php
require_once 'includes/loaded.php';
is_php_arma_loaded();
?>
--FILE--
<?php
require_once 'includes/assert.php';
$mat = Arma\IMat::init(3, 3, Arma\Fill::RANDN);
$rows = Arma\Imat::init(2, 3, Arma\Fill::RANDN);
$cols = Arma\Imat::init(5, 2, Arma\Fill::RANDN);
$mat->insertRows(1, $rows);
batch_assert('method `insertRows()`',
[5, $mat->nRows()],
[3, $mat->nCols()]
);
batch_assert_mat('method `insertRows()`',
[$rows->rows(0, 1), $mat->rows(1, 2)]
);
$mat->insertCols(2, $cols);
batch_assert('method `insertCols()`',
[5, $mat->nRows()],
[5, $mat->nCols()]
);
batch_assert_mat('method `insertCols()`',
[$cols->cols(0, 1), $mat->cols(2, 3)]
);
?>
--EXPECT--

View File

@ -38,3 +38,18 @@ function batch_assert($test, ...$cases) {
return $expected == $got;
}, ...$cases);
}
/**
* Batch assert for matrix equality.
*
* @param $test
* @param array $cases
* @return bool
*/
function batch_assert_mat($test, ...$cases) {
$comp = function ($expected, $got) {
$compare_result = $expected->equals($got);
return $compare_result->max() == 1 && $compare_result->min() == 1;
};
return batch_assert_ex($test, $comp, ...$cases);
}