Implement diagview
This commit is contained in:
parent
1e992fe67b
commit
c95c44399a
88
src/base.cc
88
src/base.cc
|
@ -8,6 +8,7 @@
|
|||
#include "dense.hh"
|
||||
#include "mat.hh"
|
||||
#include "subview_mat.hh"
|
||||
#include "diagonal.hh"
|
||||
#include "mapval.hh"
|
||||
#include "stream_utils.hh"
|
||||
|
||||
|
@ -118,8 +119,8 @@ namespace php_arma
|
|||
native->replace(zval_get_scalar<T>(old_value), zval_get_scalar<T>(new_value));
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
PHP_ARMA_METHOD(base, transform, T, T1)
|
||||
template <typename T, typename ChildT>
|
||||
PHP_ARMA_METHOD(base, transform, T, ChildT)
|
||||
{
|
||||
zend_fcall_info fci;
|
||||
zend_fcall_info_cache fcc;
|
||||
|
@ -127,38 +128,43 @@ namespace php_arma
|
|||
Z_PARAM_FUNC(fci, fcc);
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
zval params[1], retval;
|
||||
fci.param_count = 1;
|
||||
fci.params = params;
|
||||
fci.retval = &retval;
|
||||
if constexpr (util::is_any_v<ChildT, diagview<T>, spdiagview<T>>) {
|
||||
throw_error("This method is not yet supported on diagview");
|
||||
return;
|
||||
} else {
|
||||
zval params[1], retval;
|
||||
fci.param_count = 1;
|
||||
fci.params = params;
|
||||
fci.retval = &retval;
|
||||
|
||||
if constexpr (std::is_same_v<T, cx_double>) {
|
||||
// prevent segfault in `zval_set_scalar()`..
|
||||
ZVAL_UNDEF(¶ms[0]);
|
||||
}
|
||||
|
||||
auto native = THIS_NATIVE;
|
||||
native->transform([&fci, &fcc](auto&& val) {
|
||||
zval_set_scalar(&fci.params[0], val);
|
||||
zend_call_function(&fci, &fcc);
|
||||
if (!zval_check_scalar<T>(fci.retval)) {
|
||||
zval_ptr_dtor(fci.retval);
|
||||
return T();
|
||||
}
|
||||
T retval = zval_get_scalar<T>(fci.retval);
|
||||
if constexpr (std::is_same_v<T, cx_double>) {
|
||||
zval_ptr_dtor(fci.retval);
|
||||
// prevent segfault in `zval_set_scalar()`..
|
||||
ZVAL_UNDEF(¶ms[0]);
|
||||
}
|
||||
return retval;
|
||||
});
|
||||
|
||||
if constexpr (std::is_same_v<T, cx_double>) {
|
||||
zval_ptr_dtor(¶ms[0]);
|
||||
auto native = THIS_NATIVE;
|
||||
native->transform([&fci, &fcc](auto&& val) {
|
||||
zval_set_scalar(&fci.params[0], val);
|
||||
zend_call_function(&fci, &fcc);
|
||||
if (!zval_check_scalar<T>(fci.retval)) {
|
||||
zval_ptr_dtor(fci.retval);
|
||||
return T();
|
||||
}
|
||||
T retval = zval_get_scalar<T>(fci.retval);
|
||||
if constexpr (std::is_same_v<T, cx_double>) {
|
||||
zval_ptr_dtor(fci.retval);
|
||||
}
|
||||
return retval;
|
||||
});
|
||||
|
||||
if constexpr (std::is_same_v<T, cx_double>) {
|
||||
zval_ptr_dtor(¶ms[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
PHP_ARMA_METHOD(base, forEach, T, T1)
|
||||
template <typename T, typename ChildT>
|
||||
PHP_ARMA_METHOD(base, forEach, T, ChildT)
|
||||
{
|
||||
zend_fcall_info fci;
|
||||
zend_fcall_info_cache fcc;
|
||||
|
@ -166,18 +172,23 @@ namespace php_arma
|
|||
Z_PARAM_FUNC(fci, fcc);
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
zval params[1], retval;
|
||||
fci.param_count = 1;
|
||||
fci.params = params;
|
||||
fci.retval = &retval;
|
||||
if constexpr (util::is_any_v<ChildT, diagview<T>, spdiagview<T>>) {
|
||||
throw_error("This method is not yet supported on diagview");
|
||||
return;
|
||||
} else {
|
||||
zval params[1], retval;
|
||||
fci.param_count = 1;
|
||||
fci.params = params;
|
||||
fci.retval = &retval;
|
||||
|
||||
auto native = THIS_NATIVE;
|
||||
native->for_each([&fci, &fcc](auto&& val) {
|
||||
ZVAL_OBJ(&fci.params[0], mapval_dense<T>::create(&val));
|
||||
zend_call_function(&fci, &fcc);
|
||||
zval_ptr_dtor(&fci.params[0]);
|
||||
zval_ptr_dtor(fci.retval);
|
||||
});
|
||||
auto native = THIS_NATIVE;
|
||||
native->for_each([&fci, &fcc](auto&& val) {
|
||||
ZVAL_OBJ(&fci.params[0], mapval_dense<T>::create(&val));
|
||||
zend_call_function(&fci, &fcc);
|
||||
zval_ptr_dtor(&fci.params[0]);
|
||||
zval_ptr_dtor(fci.retval);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
|
@ -336,4 +347,5 @@ namespace php_arma
|
|||
|
||||
PHP_ARMA_INSTANTIATE(base, mat);
|
||||
PHP_ARMA_INSTANTIATE(base, subview_mat);
|
||||
PHP_ARMA_INSTANTIATE(base, diagview);
|
||||
}
|
||||
|
|
41
src/dense.cc
41
src/dense.cc
|
@ -8,6 +8,7 @@
|
|||
#include "base.hh"
|
||||
#include "mat.hh"
|
||||
#include "subview_mat.hh"
|
||||
#include "diagonal.hh"
|
||||
|
||||
#include <armadillo>
|
||||
|
||||
|
@ -95,8 +96,8 @@ namespace php_arma
|
|||
native->fill(zval_get_scalar<T>(value));
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
PHP_ARMA_METHOD(dense, imbue, T, T1)
|
||||
template <typename T, typename ChildT>
|
||||
PHP_ARMA_METHOD(dense, imbue, T, ChildT)
|
||||
{
|
||||
zend_fcall_info fci;
|
||||
zend_fcall_info_cache fcc;
|
||||
|
@ -104,22 +105,27 @@ namespace php_arma
|
|||
Z_PARAM_FUNC(fci, fcc);
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
zval retval;
|
||||
fci.retval = &retval;
|
||||
if constexpr (std::is_same_v<ChildT, diagview<T>>) {
|
||||
throw_error("This method is not yet supported on diagview");
|
||||
return;
|
||||
} else {
|
||||
zval retval;
|
||||
fci.retval = &retval;
|
||||
|
||||
auto native = THIS_NATIVE;
|
||||
native->imbue([&fci, &fcc]() {
|
||||
zend_call_function(&fci, &fcc);
|
||||
if (!zval_check_scalar<T>(fci.retval)) {
|
||||
zval_ptr_dtor(fci.retval);
|
||||
return T();
|
||||
}
|
||||
T retval = zval_get_scalar<T>(fci.retval);
|
||||
if constexpr (std::is_same_v<T, cx_double>) {
|
||||
zval_ptr_dtor(fci.retval);
|
||||
}
|
||||
return retval;
|
||||
});
|
||||
auto native = THIS_NATIVE;
|
||||
native->imbue([&fci, &fcc]() {
|
||||
zend_call_function(&fci, &fcc);
|
||||
if (!zval_check_scalar<T>(fci.retval)) {
|
||||
zval_ptr_dtor(fci.retval);
|
||||
return T();
|
||||
}
|
||||
T retval = zval_get_scalar<T>(fci.retval);
|
||||
if constexpr (std::is_same_v<T, cx_double>) {
|
||||
zval_ptr_dtor(fci.retval);
|
||||
}
|
||||
return retval;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
|
@ -141,4 +147,5 @@ namespace php_arma
|
|||
|
||||
PHP_ARMA_INSTANTIATE(dense, mat);
|
||||
PHP_ARMA_INSTANTIATE(dense, subview_mat);
|
||||
PHP_ARMA_INSTANTIATE(dense, diagview);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mapval.hh"
|
||||
#include "mat.hh"
|
||||
#include "subview_mat.hh"
|
||||
#include "diagonal.hh"
|
||||
|
||||
#include <armadillo>
|
||||
|
||||
|
@ -129,7 +130,23 @@ namespace php_arma
|
|||
template <typename T, typename T1>
|
||||
PHP_ARMA_METHOD(dense_matrix, diag, T, T1)
|
||||
{
|
||||
|
||||
zend_long k = 0;
|
||||
ZEND_PARSE_PARAMETERS_START(0, 1)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_LONG(k)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
auto native = THIS_NATIVE;
|
||||
|
||||
zend_object *zobj;
|
||||
try {
|
||||
zobj = diagview<T>::create(std::move(native->diag(k)));
|
||||
} catch (const std::logic_error& err) {
|
||||
// requested diagonal out of bounds
|
||||
throw_exception(err.what());
|
||||
return;
|
||||
}
|
||||
RETVAL_OBJ(zobj);
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// php-armadillo/diagonal.cc
|
||||
//
|
||||
// @Author CismonX
|
||||
//
|
||||
|
||||
#include "diagonal.hh"
|
||||
#include "base.hh"
|
||||
#include "non_resizable.hh"
|
||||
#include "subview.hh"
|
||||
#include "dense.hh"
|
||||
// #include "sparse.hh"
|
||||
|
||||
#include <armadillo>
|
||||
|
||||
namespace php_arma
|
||||
{
|
||||
template <typename T, bool B>
|
||||
PHP_ARMA_START_ME(diagonal, T, B)
|
||||
PHP_ARMA_ME_EX(linear, __invoke, ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER)
|
||||
PHP_ARMA_ME_EX(linear, at, ZEND_ACC_PUBLIC)
|
||||
PHP_ARMA_END_ME();
|
||||
|
||||
template <typename T, bool IsSparse>
|
||||
void diagonal<T, IsSparse>::ce_init(zend_class_entry *parent_ce)
|
||||
{
|
||||
// TODO: edit this line when sparse is added.
|
||||
using parent_t = std::conditional_t<IsSparse, dense<T, diagonal>, dense<T, diagonal>>;
|
||||
|
||||
ce = class_register<php_name::val>(parent_ce, fentry_list_concat(
|
||||
PHP_ARMA_FENTRY((base <T, diagonal>::me)),
|
||||
PHP_ARMA_FENTRY((parent_t ::me)),
|
||||
PHP_ARMA_FENTRY((non_resizable<T, diagonal>::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.count_elements = base<T, diagonal>::count_elements;
|
||||
}
|
||||
|
||||
PHP_ARMA_NAME_DECLARE(diagview, "DDiagView", double);
|
||||
PHP_ARMA_NAME_DECLARE(diagview, "IDiagView", zend_long);
|
||||
PHP_ARMA_NAME_DECLARE(diagview, "CxDDiagView", cx_double);
|
||||
|
||||
PHP_ARMA_NAME_DECLARE(spdiagview, "SpDDiagView", double);
|
||||
PHP_ARMA_NAME_DECLARE(spdiagview, "SpIDiagView", zend_long);
|
||||
PHP_ARMA_NAME_DECLARE(spdiagview, "SpCxDDiagView", cx_double);
|
||||
|
||||
void diagonal_init()
|
||||
{
|
||||
diagonal_ce = interface_register<diagonal_php_name>(base_ce, non_resizable_ce, subview_ce);
|
||||
|
||||
diagview_ce = abstract_class_register<diagview_php_name>(diagonal_ce, dense_ce);
|
||||
diagview<double >::ce_init(diagview_ce);
|
||||
diagview<zend_long>::ce_init(diagview_ce);
|
||||
diagview<cx_double>::ce_init(diagview_ce);
|
||||
|
||||
// spdiagview_ce = abstract_class_register<spdiagview_php_name>(diagonal_ce, sparse_ce);
|
||||
// spdiagview<double >::ce_init(spdiagview_ce);
|
||||
// spdiagview<zend_long>::ce_init(spdiagview_ce);
|
||||
// spdiagview<cx_double>::ce_init(spdiagview_ce);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// php-armadillo/diagonal.hh
|
||||
//
|
||||
// @Author CismonX
|
||||
//
|
||||
|
||||
#ifndef PHP_ARMA_DIAGONAL_HH
|
||||
#define PHP_ARMA_DIAGONAL_HH
|
||||
|
||||
#include "php_arma.hh"
|
||||
#include "complex.hh"
|
||||
#include "shared_methods.hh"
|
||||
|
||||
namespace arma
|
||||
{
|
||||
template <typename T> class diagview;
|
||||
template <typename T> class spdiagview;
|
||||
template <typename T> class get_pod_type;
|
||||
}
|
||||
|
||||
namespace php_arma
|
||||
{
|
||||
template <typename T> struct mat;
|
||||
template <typename T, typename T1> struct linear;
|
||||
|
||||
template <typename T, bool IsSparse>
|
||||
struct diagonal
|
||||
{
|
||||
using native_t = std::conditional_t<IsSparse, arma::spdiagview<T>, arma::diagview<T>>;
|
||||
using orig_t = mat<T>;
|
||||
using subview_t = mat<T>;
|
||||
using with_int_elem_t = mat<zend_long>;
|
||||
|
||||
friend void diagonal_init();
|
||||
|
||||
template <typename... Ts>
|
||||
zend_always_inline
|
||||
static zend_object *create(Ts&&... args)
|
||||
{
|
||||
return object_create_ctor<native_t>(ce, &handlers, args...);
|
||||
}
|
||||
|
||||
PHP_ARMA_CE_HANDLRES_DECLARE();
|
||||
|
||||
private:
|
||||
PHP_ARMA_COMMON_DECLARE();
|
||||
|
||||
using linear = linear_element_acccess<T, diagonal>;
|
||||
|
||||
static void ce_init(zend_class_entry*);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using diagview = diagonal<T, false>;
|
||||
|
||||
template <typename T>
|
||||
using spdiagview = diagonal<T, true>;
|
||||
|
||||
void diagonal_init();
|
||||
|
||||
constexpr const char diagonal_php_name[] = "Diagonal";
|
||||
constexpr const char diagview_php_name[] = "DiagView";
|
||||
constexpr const char spdiagview_php_name[] = "SpDiagView";
|
||||
|
||||
inline zend_class_entry *diagonal_ce;
|
||||
inline zend_class_entry *diagview_ce;
|
||||
inline zend_class_entry *spdiagview_ce;
|
||||
}
|
||||
|
||||
#endif // !PHP_ARMA_DIAGONAL_HH
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "non_resizable.hh"
|
||||
#include "subview_mat.hh"
|
||||
#include "diagonal.hh"
|
||||
|
||||
#include <armadillo>
|
||||
|
||||
|
@ -30,4 +31,5 @@ namespace php_arma
|
|||
}
|
||||
|
||||
PHP_ARMA_INSTANTIATE(non_resizable, subview_mat);
|
||||
PHP_ARMA_INSTANTIATE(non_resizable, diagview);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "functions.hh"
|
||||
#include "mat.hh"
|
||||
#include "subview_mat.hh"
|
||||
#include "diagonal.hh"
|
||||
|
||||
#ifdef PHP_ARMA_OPERATORS
|
||||
#include "operators.hh"
|
||||
|
@ -49,6 +50,7 @@ namespace php_arma
|
|||
dense_non_resizable_matrix_init();
|
||||
mat_init();
|
||||
subview_mat_init();
|
||||
diagonal_init();
|
||||
|
||||
#ifdef PHP_ARMA_OPERATORS
|
||||
operators_init();
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
#define PHP_ARMA_ME(func, flags) \
|
||||
ZEND_FENTRY(func, zif_##func, nullptr, flags)
|
||||
|
||||
#define PHP_ARMA_ME_EX(cls, func, flags) \
|
||||
ZEND_FENTRY(func, cls::zif_##func, nullptr, flags)
|
||||
|
||||
#define PHP_ARMA_METHOD(cls, func, ...) \
|
||||
void ZEND_FASTCALL cls<__VA_ARGS__>::zif_##func(INTERNAL_FUNCTION_PARAMETERS)
|
||||
|
||||
|
@ -88,7 +91,7 @@
|
|||
|
||||
#define PHP_ARMA_OPERATOR_EX2(base, child, func) \
|
||||
if (instanceof_function(ce, child::ce)) { \
|
||||
using base_t = arg_type<void(base)>::type; \
|
||||
using base_t = util::arg_type<void(base)>::type; \
|
||||
return base_t::operators::func(zv1, zv2, rv); \
|
||||
}
|
||||
|
||||
|
@ -97,7 +100,7 @@
|
|||
|
||||
#define PHP_ARMA_ASSIGN_OPERATOR_EX2(base, child, func) \
|
||||
if (instanceof_function(ce, child::ce)) { \
|
||||
using base_t = arg_type<void(base)>::type; \
|
||||
using base_t = util::arg_type<void(base)>::type; \
|
||||
auto v = base_t::operators::func(zv1, zv2, zv1); \
|
||||
if (rv) { \
|
||||
ZVAL_COPY(rv, zv1); \
|
||||
|
@ -127,12 +130,27 @@ namespace php_arma
|
|||
{
|
||||
extern zend_module_entry module_entry;
|
||||
|
||||
/// Utilities.
|
||||
namespace util
|
||||
{
|
||||
/// Hack for extracting type from a parentheses-enclosed macro argument.
|
||||
template <typename T>
|
||||
struct arg_type;
|
||||
template <typename T, typename U>
|
||||
struct arg_type<T(U)>
|
||||
{
|
||||
using type = U;
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
constexpr auto is_any_v = std::disjunction_v<std::is_same<T, Ts>...>;
|
||||
}
|
||||
|
||||
/// Helpers for compile-time string concatenation for better module startup performance.
|
||||
namespace str
|
||||
{
|
||||
template <size_t... S>
|
||||
using seq = std::integer_sequence<size_t, S...>;
|
||||
|
||||
template <size_t N>
|
||||
using seq_impl = std::make_integer_sequence<size_t, N>;
|
||||
|
||||
|
@ -145,7 +163,6 @@ namespace php_arma
|
|||
|
||||
template <const char*, typename, const char*, typename>
|
||||
struct concat_impl;
|
||||
|
||||
template <const char *Str1, size_t... Len1, const char *Str2, size_t... Len2>
|
||||
struct concat_impl<Str1, seq<Len1...>, Str2, seq<Len2...>>
|
||||
{
|
||||
|
@ -177,17 +194,6 @@ namespace php_arma
|
|||
};
|
||||
}
|
||||
|
||||
/// Hack for extracting type from a parentheses-enclosed macro argument.
|
||||
|
||||
template <typename T>
|
||||
struct arg_type;
|
||||
|
||||
template <typename T, typename U>
|
||||
struct arg_type<T(U)>
|
||||
{
|
||||
using type = U;
|
||||
};
|
||||
|
||||
/// Helper functions for throwing exceptions when errors occur.
|
||||
|
||||
zend_always_inline
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// php-armadillo/shared_methods.cc
|
||||
//
|
||||
// @Author CismonX
|
||||
//
|
||||
|
||||
#include "shared_methods.hh"
|
||||
#include "mapval.hh"
|
||||
#include "diagonal.hh"
|
||||
|
||||
#include <armadillo>
|
||||
|
||||
namespace php_arma
|
||||
{
|
||||
template <typename T, typename ChildT>
|
||||
PHP_ARMA_METHOD(linear_element_acccess, __invoke, T, ChildT)
|
||||
{
|
||||
zend_long i;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_LONG(i)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
auto native = THIS_NATIVE;
|
||||
|
||||
zend_object *zobj;
|
||||
try {
|
||||
zobj = mapval_dense<T>::create(&native->operator()(i));
|
||||
} catch (const std::logic_error& err) {
|
||||
// Index out of bounds.
|
||||
throw_exception(err.what());
|
||||
return;
|
||||
}
|
||||
|
||||
RETVAL_OBJ(zobj);
|
||||
}
|
||||
|
||||
template <typename T, typename ChildT>
|
||||
PHP_ARMA_METHOD(linear_element_acccess, at, T, ChildT)
|
||||
{
|
||||
zend_long i;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_LONG(i)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
auto native = THIS_NATIVE;
|
||||
|
||||
auto zobj = mapval_dense<T>::create(&native->operator[](i));
|
||||
RETVAL_OBJ(zobj);
|
||||
}
|
||||
|
||||
PHP_ARMA_INSTANTIATE(linear_element_acccess, diagview);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// php-armadillo/shared_methods.hh
|
||||
//
|
||||
// @Author CismonX
|
||||
//
|
||||
|
||||
#ifndef PHP_ARMA_SHARED_METHODS_HH
|
||||
#define PHP_ARMA_SHARED_METHODS_HH
|
||||
|
||||
#include "php_arma.hh"
|
||||
|
||||
namespace php_arma
|
||||
{
|
||||
template <typename T, typename ChildT>
|
||||
struct linear_element_acccess
|
||||
{
|
||||
using native_t = typename ChildT::native_t;
|
||||
|
||||
static PHP_FUNCTION(__invoke);
|
||||
static PHP_FUNCTION(at);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !PHP_ARMA_SHARED_METHODS_HH
|
|
@ -9,5 +9,21 @@ namespace Arma\Internal;
|
|||
*/
|
||||
interface Diagonal extends Base, NonResizable, Subview
|
||||
{
|
||||
/**
|
||||
* Read/write access to the n-th element.
|
||||
*
|
||||
* @param int $idx
|
||||
* @return Scalar
|
||||
*/
|
||||
function __invoke($idx);
|
||||
|
||||
/**
|
||||
* Read/write access to the n-th element.
|
||||
*
|
||||
* Without a bounds check. Not recommended for use unless your code has been thoroughly debugged.
|
||||
*
|
||||
* @param int $idx
|
||||
* @return Scalar
|
||||
*/
|
||||
function at($idx);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
--TEST--
|
||||
Test for class `DiagView`.
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once 'includes/loaded.php';
|
||||
is_php_arma_loaded();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once 'includes/assert.php';
|
||||
|
||||
$mat = Arma\IMat::fromString("1 2; 3 4");
|
||||
|
||||
$diag = $mat->diag();
|
||||
$diag->rawPrint();
|
||||
|
||||
$diag->at(1)->setTo($diag->at(0)->val());
|
||||
$mat->rawPrint();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
4
|
||||
1 2
|
||||
3 1
|
Reference in New Issue