Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Absence of some utility methods for Matrix #16816

Open
czgdp1807 opened this issue May 12, 2019 · 7 comments
Open

Absence of some utility methods for Matrix #16816

czgdp1807 opened this issue May 12, 2019 · 7 comments
Labels

Comments

@czgdp1807
Copy link
Member

czgdp1807 commented May 12, 2019

Problem

I think that following utility methods aren't there for Matrices:

  1. is_positive - To check whether each element of the Matrix is greater than 0.
  2. is_positive_definite - To check whether the matrix is positive definite.
  3. is_positive_semidefinite - To check whether the matrix is positive semi-definite

Example of problem

Below is given the dir of Matrix.

Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from sympy import *
>>> M = Matrix([[1, 1, 2], [2 ,1 , 3], [3 , 1, 4]])
>>> dir(M)
['C', 'D', 'H', 'LDLdecomposition', 'LDLsolve', 'LUdecomposition', 'LUdecompositionFF', 'LUdecomposition_Simple', 'LUsolve', 'QRdecomposition', 'QRsolve', 'T', '_LDLdecomposition', '__abs__', '__add__', '__array__', '__array_priority__', '__class__', '__delattr__', '__dict__', '__dir__', '__div__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__mathml__', '__matmul__', '__mod__', '__module__', '__mul__', '__ne__', '__neg__', '__new__', '__pow__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rmatmul__', '__rmul__', '__rsub__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__weakref__', '_accept_eval_derivative', '_cache_eigenvects', '_cache_is_diagonalizable', '_cholesky', '_class_priority', '_diagonal_solve', '_diagonalize_clear_subproducts', '_diff_wrt', '_eval_Abs', '_eval_Mod', '_eval_add', '_eval_adjoint', '_eval_applyfunc', '_eval_as_real_imag', '_eval_atoms', '_eval_berkowitz_toeplitz_matrix', '_eval_berkowitz_vector', '_eval_col_del', '_eval_col_insert', '_eval_col_join', '_eval_col_op_add_multiple_to_other_col', '_eval_col_op_multiply_col_by_const', '_eval_col_op_swap', '_eval_conjugate', '_eval_derivative', '_eval_det_bareiss', '_eval_det_berkowitz', '_eval_det_lu', '_eval_determinant', '_eval_diag', '_eval_echelon_form', '_eval_extract', '_eval_eye', '_eval_free_symbols', '_eval_get_diag_blocks', '_eval_has', '_eval_inverse', '_eval_is_Identity', '_eval_is_anti_symmetric', '_eval_is_diagonal', '_eval_is_echelon', '_eval_is_lower', '_eval_is_lower_hessenberg', '_eval_is_matrix_hermitian', '_eval_is_symbolic', '_eval_is_symmetric', '_eval_is_upper_hessenberg', '_eval_is_zero', '_eval_jordan_block', '_eval_matrix_mul', '_eval_matrix_mul_elementwise', '_eval_matrix_rmul', '_eval_ones', '_eval_permute_cols', '_eval_permute_rows', '_eval_pow_by_recursion', '_eval_row_del', '_eval_row_insert', '_eval_row_join', '_eval_row_op_add_multiple_to_other_row', '_eval_row_op_multiply_row_by_const', '_eval_row_op_swap', '_eval_rref', '_eval_scalar_mul', '_eval_scalar_rmul', '_eval_simplify', '_eval_tolist', '_eval_trace', '_eval_transpose', '_eval_trigsimp', '_eval_values', '_eval_vec', '_eval_zeros', '_format_str', '_handle_creation_inputs', '_legacy_array_dot', '_lower_triangular_solve', '_mat', '_matrix_pow_by_jordan_blocks', '_new', '_normalize_op_args', '_op_priority', '_permute_complexity_right', '_repr_latex_', '_repr_latex_orig', '_row_reduce', '_setitem', '_simplify', '_sympify', '_upper_triangular_solve', '_visit_eval_derivative_array', '_visit_eval_derivative_scalar', 'add', 'adjoint', 'adjugate', 'applyfunc', 'as_immutable', 'as_mutable', 'as_real_imag', 'atoms', 'berkowitz', 'berkowitz_charpoly', 'berkowitz_det', 'berkowitz_eigenvals', 'berkowitz_minors', 'charpoly', 'cholesky', 'cholesky_solve', 'cofactor', 'cofactorMatrix', 'cofactor_matrix', 'col', 'col_del', 'col_insert', 'col_join', 'col_op', 'col_swap', 'cols', 'columnspace', 'condition_number', 'conjugate', 'copy', 'copyin_list', 'copyin_matrix', 'cross', 'det', 'det_LU_decomposition', 'det_bareis', 'det_bareiss', 'diag', 'diagonal', 'diagonal_solve', 'diagonalize', 'diff', 'doit', 'dot', 'dual', 'echelon_form', 'eigenvals', 'eigenvects', 'elementary_col_op', 'elementary_row_op', 'equals', 'evalf', 'exp', 'expand', 'extract', 'eye', 'fill', 'free_symbols', 'gauss_jordan_solve', 'get_diag_blocks', 'has', 'hstack', 'integrate', 'inv', 'inv_mod', 'inverse_ADJ', 'inverse_GE', 'inverse_LU', 'irregular', 'is_Identity', 'is_Matrix', 'is_MatrixExpr', 'is_anti_symmetric', 'is_diagonal', 'is_diagonalizable', 'is_echelon', 'is_hermitian', 'is_lower', 'is_lower_hessenberg', 'is_nilpotent', 'is_square', 'is_symbolic', 'is_symmetric', 'is_upper', 'is_upper_hessenberg', 'is_zero', 'jacobian', 'jordan_block', 'jordan_cell', 'jordan_cells', 'jordan_form', 'key2bounds', 'key2ij', 'left_eigenvects', 'limit', 'lower_triangular_solve', 'minor', 'minorEntry', 'minorMatrix', 'minor_submatrix', 'multiply', 'multiply_elementwise', 'n', 'norm', 'normalized', 'nullspace', 'ones', 'orthogonalize', 'permute', 'permuteBkwd', 'permuteFwd', 'permute_cols', 'permute_rows', 'pinv', 'pinv_solve', 'print_nonzero', 'project', 'rank', 'rank_decomposition', 'refine', 'replace', 'reshape', 'row', 'row_del', 'row_insert', 'row_join', 'row_op', 'row_swap', 'rows', 'rowspace', 'rref', 'shape', 'simplify', 'singular_values', 'solve', 'solve_least_squares', 'subs', 'table', 'tolist', 'trace', 'transpose', 'upper_triangular_solve', 'values', 'vec', 'vech', 'vstack', 'xreplace', 'zeros', 'zip_row_op']

Other comments/references

I observed that this line checks that whether the matrix is positive definite. It would be better if a utility method is provided for such cases.
If there is a way to check all the above mentioned properties using the currently available Matrix methods then please comment in the section and close the issue.
Thanks.

@sylee957
Copy link
Member

I was aware of that problem for a long time, but things like #15883 had bothered to continue working on.
If there is any need for the computation, then it should be time to add some methods.

@oscarbenjamin
Copy link
Contributor

oscarbenjamin commented May 12, 2019

I don't think matrices should have is_positive unless maybe it is always set to False. Positive should be reserved for a positive real number and a matrix cannot be a real number.

@czgdp1807
Copy link
Member Author

@oscarbenjamin I have no issues for not including is_positive but I firmly support is_positive_definite and is_positive_semidefinite as they are quite popular in mathematical literature and statistical literature too.

@sylee957
Copy link
Member

There already is is_zero used in matrix for zero matrix.
Generally, suffix would have to be added like is_zero_matrix or is_positive_definite_matrix to make it less confusing

@czgdp1807
Copy link
Member Author

@sylee957 Wouldn't it be too long method name. Moreover, I think, it's intuitive for a user that when he/she is using, is_zero or hypothetically say, is_positive via a Matrix then it applies on each and every element of that Matrix, but when the same properties or methods are being used, with a Symbol then it applies on that Symbol.

@sylee957
Copy link
Member

We always have an option to use things with is_Matrix to test out the context which it belongs to.

@oscarbenjamin
Copy link
Contributor

We always have an option to use things with is_Matrix to test out the context which it belongs to.

That isn't very helpful for the common case where you want to test if something is equal to the number zero. When someone writes e.g.

    if x.is_zero:
        return S.Zero

they are unlikely to consider that is_zero might also be true for non-numbers. If every type of object is allowed to invent its own meaning for is_zero then the above would need to become

    if x.is_zero and not x.is_Matrix and not x.is_Tensor and not x.is_Operator and not x.is_Function ...

The assumptions system treats is_zero as meaning that something is the number zero. Hence zero implies even, real, complex, nonnegative etc. Allowing is_zero=True for a matrix breaks the understanding given to is_zero everywhere else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants