94 Commits

Author SHA1 Message Date
Sergey B Kirpichev fb69943530 Use explicit kwargs in public API, where possible
Following functions kept:
```pycon
>>> import inspect
... with_args = []
... with_kwargs = []
... for n in dir(mpmath):
...     m = getattr(mpmath, n)
...     try:
...         s = inspect.signature(m)
...     except:
...         continue
...     if any(_.kind == inspect._ParameterKind.VAR_POSITIONAL for _ in s.parameters.values()):
...         for name in s.parameters:
...             if s.parameters[name].kind == inspect._ParameterKind.VAR_POSITIONAL and name == 'args':
...                 with_args.append(n)
...                 break
...     if any(_.kind == inspect._ParameterKind.VAR_KEYWORD for _ in s.parameters.values()):
...         with_kwargs.append(n)
... print(with_args)
... print(with_kwargs)
...
['arange', 'ellipe', 'ellippi', 'linspace', 'matrix', 'ones', 'timing', 'zeros']
['multiplicity', 'timing']
```

We need support for multiple signatures in the first case.  In the
second - it's impossible to implement these functions without kwargs.

Closes #1056
2026-08-04 06:40:53 +03:00
Sergey B Kirpichev d1e52ed28d Adapt doctests
Was:
```pycon
>>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]])
>>> Q, R = mp.schur(A)
>>> mp.norm(Q.T*A*Q-R, inf)
1.8166878507717441e-15
```

Now:
```pycon
>>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]])
>>> Q, R = mp.schur(A)
>>> mp.norm(Q.T*A*Q-R, inf)
1.3322676295501878e-15
```
2026-05-25 04:05:28 +03:00
Jam Balaya b5a075fa53 Fix qr_solve() failure on well-conditioned matrices with zero pivot (#1083)
* Fix qr_solve() failure on well-conditioned matrices with zero pivot

In householder(), the sign convention
    p[j] = -sign(Re(A[j,j])) * sqrt(s)
collapses to zero when A[j,j] is exactly zero, because ctx.sign(0) == 0.
A zero p[j] makes kappa = 1/(s - p[j]*A[j,j]) = 1/s instead of the
correct 2/||v||**2, corrupting the Householder reflection. The damage
propagates to subsequent columns and eventually trips the
"matrix is numerically singular" guard.

Default sign to ctx.one when A[j,j] is zero (matching LAPACK's dlarfg
convention) so the reflection is computed correctly. The existing
singularity check is left in place to catch genuinely zero column
slices.

Fixes #983.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 03:02:53 +03:00
Tim M f98636edf6 Added Moore-Penrose pseudoinverse. (#1030) 2026-03-10 18:37:22 +03:00
Sergey B Kirpichev 82e0a49593 Drop DeprecationWarning for force_type kwarg for matrix()
(Note that kwargs now aren't used.)
2026-03-04 07:28:50 +03:00
Sergey B Kirpichev 3c8119eeb2 Use pretty-printing in det() docstring 2026-02-22 08:08:10 +03:00
Sergey B Kirpichev e95bf2a22a Fix some found formatting issues with docs 2026-02-22 07:42:46 +03:00
baranwalayush e8aa7a0bd9 Fix infinite loop in case of zero matrix in logm function 2025-10-22 15:14:30 +05:30
Ayush Baranwal 0d8b0e0b8c Fix #1003: sinm and cosm can accept list as arguments, similar to expm and other functions (#1006) 2025-10-08 11:04:34 +03:00
baranwalayush de1e15d49f Fix matrix should raise ValueError and Add unit tests 2025-10-03 19:21:30 +05:30
Sergey B Kirpichev 2cad89428e Move references to docs/references.rst
Closes #224
2025-06-18 18:03:46 +03:00
Sergey B Kirpichev 8778568951 Avoid using ";" in doctests, esp with side effects
The new CPython repl hide all output, except for the last statement.
See https://github.com/python/cpython/issues/131217.
2025-05-01 10:41:48 +03:00
Riccardo Orsi 0671d642fd Support negative indexes in matrix
Made possible single extraction or assignment of values with negative
indexes.  Closes #835.

Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
2025-01-18 10:28:13 +03:00
Sergey B Kirpichev 144b69ff15 Fix DeprecationWarning coming with numpy>=2.1 2024-08-21 10:10:58 +03:00
Sergey B Kirpichev 5def5939c9 Consistently use "floating-point" 2024-07-20 12:51:08 +03:00
Sergey B Kirpichev b5e582649b Support matrix.__array__() dunder method 2024-03-04 10:05:40 +03:00
Sergey B Kirpichev 1acd3ef7c6 Support pickling for matrices
Closes #380
2024-02-29 07:46:43 +03:00
Sergey B Kirpichev 6ca30e8de4 Update _matrix.rows/cols 2024-02-26 12:38:20 +03:00
Sergey B Kirpichev 4345422802 Don't use private name mangling in the matrices.py 2024-02-26 12:38:20 +03:00
Sergey B Kirpichev 57a5ec0bc3 Drop globals row/colsep from the matrices module 2024-02-26 09:03:54 +03:00
Sergey B Kirpichev 57a9e0d49d Fix few more py2 remnants (__truediv__ vs __div__) 2024-02-26 08:57:27 +03:00
mart-mihkel 49e16e0bac Fix several issues with empty matrices
* make det of null matrix return 1, see e.g.
  https://en.wikipedia.org/wiki/Matrix_(mathematics)#Empty_matrix
* fix str/repr

Closes #745

Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
2024-02-24 14:11:47 +03:00
Sergey B Kirpichev 5fa35e0096 Use cholesky_solve() for overdetermined complex linear systems
Closes #227
2024-02-24 06:29:45 +03:00
Sergey B Kirpichev 85b16c61ab Change warning category for force_type to DeprecationWarning
Closes #156
2024-02-23 17:40:24 +03:00
Qiming Sun 8d91e11511 Fix choleksy_solve for complex matrix (#755) 2024-02-19 13:09:24 +03:00
Sergey B Kirpichev 91ccdd4a80 Merge pull request #610 from jan-philipp-hoffmann/pre_master
(Update on PR #543) Fixed TypeError in `LU_comp`, updated `determinant` docs and added `rank` function for matrices
2023-08-06 12:28:52 +03:00
Sergey B Kirpichev c7331400d5 Skip eigenvectors if left=right=False for one-dimentional matrix
Closes #712
2023-07-25 09:36:56 +03:00
sonntagsgesicht 7b59bb8248 rank function (with tests)
update imports in test_linalg.py

custom `iszerofunc` in rank determination

adding rank of matrix via counting eigenvalues form svd_r
2023-06-02 08:20:56 +02:00
sonntagsgesicht 0347d87598 determinant documentation 2023-06-01 08:37:42 +02:00
sonntagsgesicht 1868261e8b fixing issue: Determinant issue inside of LU_decomp 2023-06-01 08:37:42 +02:00
sonntagsgesicht 79d99ff700 fixing: Determinant function raises TypeError on simple matrix #542 2023-06-01 08:36:55 +02:00
Sergey B Kirpichev 96e66fc074 Default file encoding is utf-8 for py3... 2023-05-18 14:25:27 +03:00
Sergey B Kirpichev 5ec9d07dee Reorganize imports in doctests (no star imports) 2023-05-09 07:27:20 +03:00
Sergey B Kirpichev fda71a8ee3 Drop doctest:+SKIP pragmas, where possible 2023-04-30 08:54:51 +03:00
Sergey B Kirpichev 945ca7c281 Add doctest:+ELLIPSIS 2023-04-30 08:54:49 +03:00
Sergey B Kirpichev 088e27eca1 Drop runtests.py and doctests() function
We use pytest for tests, it has everything that runtests.py has,
including support for profiling (pytest-profiling plugin).

So, let's drop this legacy stuff to avoid bugs like #579.
2023-04-30 08:53:44 +03:00
Sergey B Kirpichev 57efbdc101 Drop resetting globals (mp.prec and so on) in doctests 2023-04-20 12:55:47 +03:00
Sergey B Kirpichev a9637115e5 Raise IndexError if matrix index out of bounds
Closes #318
2023-04-20 06:21:21 +03:00
Tyler Chen ae610886c2 update generator used for sparse matrix vector product (#450) 2023-04-20 05:47:32 +03:00
Sergey B Kirpichev 867c7a04c1 Catch AttributeError in matrix.__eq__ to return NotImplemented
Closes #283
2023-04-04 12:31:11 +03:00
Sergey B Kirpichev bd46981e99 Run doctests in mpmath/matrices/linalg.py (adjust doctest for iv.matrix) 2023-04-02 04:16:57 +03:00
Fangchen Li dfc289289d Drop py2 support (#629)
* remove xrange compat shim
* remove str compat shim
* remove exec compat shim
* remove object from class defination
* remove misc workarounds for python versions <3.5
* remove __future__ imports
* update readme
* Update setup.cfg

Closes #594

Co-authored-by: Fredrik Johansson <fredrik.johansson@gmail.com>
Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
Co-authored-by: Colin B. Macdonald <cbm@m.fsf.org>
2023-03-30 04:50:18 +03:00
Christian Clauss 6489ed3bc1 Fix pycodestyle errors E703, E712, E713 (#665) 2023-03-28 10:29:30 +03:00
Fredrik Johansson 1258e33e16 fix failing doctests 2022-11-07 11:27:20 +01:00
Clemens Hofreither 8d8f842d84 support QR for matrices of width 0 and 1 2021-09-30 12:16:31 +02:00
Sergey B Kirpichev 25700e23b4 Drop support for CPython 3.4
Reason: test failure for the master.  GA has no such version
support anymore, e.g.:
https://github.com/fredrik-johansson/mpmath/runs/2005546465
2021-03-02 17:55:09 +03:00
fredrik 35d15f7048 simple matrix multiplication speedup 2021-03-01 17:13:32 +01:00
Maximilian Gaukler 4b5f1e3735 remove force_type arguments, they were broken
Make matrices type-stable, not allowing mixed types in one matrix. Always use the type of the context.
Therefore, specifying an element type by the "force_type" argument does not make sense.

It did not work properly before either, the data was not stored in the given type:
```
>>> M = mpmath.matrix(mpmath.matrix([[0,1,2]]), force_type=bool)
>>> M
matrix(
[['0.0', '1.0', '1.0']])
>>> type(M[0,0])
<class 'mpmath.ctx_mp_python.mpf'>
>>> M._matrix__data
{(0, 1): mpf('1.0'), (0, 2): mpf('1.0')}
```

Now the argument is removed and gives a warning instead:
>>> mpmath.matrix(mpmath.matrix([[0,1,2]]), force_type=bool)
/mpmath/mpmath/matrices/matrices.py:288: UserWarning: The force_type argument was removed, it did not work properly anyway. If you want to force floating-point or interval computations, use the respective methods from `fp` or `mp` instead, e.g., `fp.matrix()` or `iv.matrix()`. If you want to truncate values to integer, use .apply(int) instead.
  warnings.warn("The force_type argument was removed, it did not work"
matrix([['0.0', '1.0', '2.0']])
2021-01-22 20:18:22 +01:00
Maximilian Gaukler 58a597d5a1 Fix initialization of iv.matrix from non-interval matrix
Non-interval datatypes were not converted to intervals, resulting in unexpected behavior. For example, M[i, j] didn't return mpi interval objects, but mpf floats, so M[i, j] * M[k, l] and, under certain conditions, M * M, was not performed as interval multiplication.

This could have unexpected consequences, as outlined below.

"Exact" computation for reference:
>>> import mpmath
>>> x = mpmath.convert('1.00000000000001') # 1.0000...001 rounded to the next mpf floating point value
>>> mpmath.mp.dps=1000
>>> x*x # Good approximation of x*x
mpf('1.00000000000001998401444325291756783368705994138804689654360263219301518944348572404123842716217041015625')

Interval arithmetic should return an interval containing that value, with some uncertainty.

Restart python to reset mp.dps.
Before this commit, the following occurs:
>>> import mpmath
>>> x = mpmath.convert('1.00000000000001')
>>> x
mpf('1.00000000000001')
>>> A = mpmath.matrix([[x]])
>>> B = mpmath.iv.matrix(A)
>>> C = mpmath.iv.matrix([[x]])
>>> A*A
matrix(
[['1.00000000000002']])
>>> B*B
matrix(
[['[1.000000000000019984, 1.000000000000019984]']])
>>> (B*B)[0,0].delta
mpi('0.0', '0.0')
>>> C*C
matrix(
[['[1.000000000000019984, 1.0000000000000202061]']])

B*B is wrong, the interval width must be nonzero at the default precision of 15 digits.
B*B is different from C*C, although both were initialized from the same numerical value and computed the same way.

After this commit, the result is valid:
>>> B*B
matrix(
[['[1.000000000000019984, 1.0000000000000202061]']])
>>> (B*B)[0,0].delta
mpi('2.2204460492503131e-16', '2.2204460492503131e-16')

Some more insight:

Old incorrect behavior:
>>> mpmath.iv.matrix(mpmath.eye(1))[0,0]
mpf('1.0')

New correct behavior:
>>> mpmath.iv.matrix(mpmath.eye(1))[0,0]
mpf('1.0')
>>> mpmath.iv.eye(1)[0,0]
mpi('1.0', '1.0')

>>> import mpmath
>>> mpmath.iv.matrix(mpmath.eye(1))
matrix(
[['[1.0, 1.0]']])
>>> mpmath.iv.matrix(mpmath.eye(1))[0,0]
mpi('1.0', '1.0')
>>> mpmath.fp.matrix(mpmath.eye(1))[0,0]
1.0
>>> mpmath.matrix(mpmath.eye(1))[0,0]
mpf('1.0')

The type now exactly matches the type returned by the context's matrix functions such as eye():
>>> mpmath.matrix(mpmath.eye(1))[0,0]
mpf('1.0')
>>> mpmath.eye(1)[0,0]
mpf('1.0')
>>> mpmath.iv.matrix(mpmath.eye(1))[0,0]
mpi('1.0', '1.0')
>>> mpmath.iv.eye(1)[0,0]
mpi('1.0', '1.0')
>>> mpmath.fp.matrix(mpmath.eye(1))[0,0]
1.0
>>> mpmath.fp.eye(1)[0,0]
1.0
2021-01-22 08:28:37 +01:00
Fredrik Johansson 718b4a1457 Merge pull request #526 from MaxGaukler/pos
Implement unary plus for matrices (+M == M)
2020-06-08 09:27:59 +02:00