Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
144 commits
Select commit Hold shift + click to select a range
6fffb43
add fixpoint_damped
HugoMVale Apr 13, 2026
f1c277e
fix docstring g(x)
HugoMVale Apr 13, 2026
0823e3b
fix test_fixpoint_damped
HugoMVale Apr 13, 2026
a52619b
add fixpoint steffensen
HugoMVale Apr 14, 2026
a7ca8c9
add fixpoint steffensen
HugoMVale Apr 14, 2026
86b74c9
update "see also"
HugoMVale Apr 14, 2026
e61cae7
fix doctest
HugoMVale Apr 14, 2026
0db4336
update description
HugoMVale Apr 14, 2026
739aa56
expand documentation for root solvers and vector root solver
HugoMVale Apr 15, 2026
a0a327e
rename omega to q
HugoMVale Apr 15, 2026
87d2ff5
rename omega to q
HugoMVale Apr 15, 2026
5cc7452
change order of method-specific args
HugoMVale Apr 15, 2026
0fde60f
change order of method-specific args
HugoMVale Apr 15, 2026
bf68a88
flip q
HugoMVale Apr 15, 2026
e6aadc7
fix: rename loop variable for clarity in fixpoint_steffensen function
HugoMVale Apr 16, 2026
fadc678
fix: update damping formula and rename loop variable for clarity in f…
HugoMVale Apr 16, 2026
52a684d
fix: update fixed-point iteration formula and rename loop variable fo…
HugoMVale Apr 16, 2026
74949b1
fix: rename loop variable for clarity in fixpoint_anderson function
HugoMVale Apr 16, 2026
f75157d
add callback feature
HugoMVale Apr 16, 2026
fbebf1c
move callback
HugoMVale Apr 16, 2026
260fe01
add callback to wegstein
HugoMVale Apr 16, 2026
64ea122
fix: clarify callback behavior in fixpoint_damped and fixpoint_wegste…
HugoMVale Apr 16, 2026
6579b17
feat: add callback support to fixpoint_steffensen function
HugoMVale Apr 16, 2026
19bcc67
fix: remove redundant test case for initial guess in test_fixpoint_an…
HugoMVale Apr 17, 2026
d61cc05
feat: add callback support to root_newton and root_secant functions
HugoMVale Apr 17, 2026
fdf6062
feat: add callback support to root_brent function and update tests
HugoMVale Apr 17, 2026
d553946
feat: add callback support to fixpoint_anderson and update tests
HugoMVale Apr 17, 2026
e9d2cf0
add fmin_brent
HugoMVale Apr 17, 2026
13bc0d4
rename optimum to optimization
HugoMVale Apr 17, 2026
fd1a26b
add example
HugoMVale Apr 17, 2026
22189d4
feat: add documentation for optimization solvers and update navigation
HugoMVale Apr 17, 2026
5687666
add optimization
HugoMVale Apr 17, 2026
99f03c6
update method description
HugoMVale Apr 17, 2026
99604f5
polish doc text
HugoMVale Apr 17, 2026
3df9efe
add brent's reference
HugoMVale Apr 18, 2026
d9fd696
fix: update documentation for fixpoint methods to clarify usage
HugoMVale Apr 18, 2026
a021e0c
update docstring
HugoMVale Apr 18, 2026
0932366
update headings
HugoMVale Apr 19, 2026
f9d89d0
refactor: improve iteration handling in fixpoint_wegstein function
HugoMVale Apr 19, 2026
45945ff
fix: improve iteration handling in fixpoint_damped function
HugoMVale Apr 19, 2026
a7b17ee
add fixpoint_dem
HugoMVale Apr 19, 2026
204cbb7
add doc fixpoint_dem
HugoMVale Apr 19, 2026
5fb9f69
add doc fixpoint method overview
HugoMVale Apr 19, 2026
02ad6f8
fix doc g(x)
HugoMVale Apr 19, 2026
cf9bf18
add fixpoint_dem to SUMMARY.md
HugoMVale Apr 19, 2026
981dd50
add BoolVector type alias for 1D boolean NumPy arrays
HugoMVale Apr 19, 2026
4c5a598
add VectorOptimumResult
HugoMVale Apr 20, 2026
e4de9a8
add VectorOptimumResult documentation and update SUMMARY.md
HugoMVale Apr 20, 2026
df1e386
refactor rootvec_qnewton to handle scaling factors more robustly
HugoMVale Apr 23, 2026
07c164d
refactor fmin_brent docstring for clarity
HugoMVale Apr 23, 2026
e28f133
refactor: ensure sclx is non-negative in fixpoint methods
HugoMVale Apr 23, 2026
d62bac3
refactor: ensure sclx is non-negative in jacobian_forward and hessian…
HugoMVale Apr 23, 2026
5187e9e
add fmin_nelder_mead
HugoMVale Apr 23, 2026
a5eb5ec
feat: add optional callback parameter to fmin_nelder_mead for iterati…
HugoMVale Apr 24, 2026
bd67ccf
feat: rename submodule vector to qnewton
HugoMVale Apr 24, 2026
415441d
add gradient_forward
HugoMVale Apr 24, 2026
2fc0505
feat: update Python version requirements to 3.11 in configuration files
HugoMVale Apr 24, 2026
9e43ef2
fix: add exclusion for Python 3.14 in test matrix due to numba 0.60 c…
HugoMVale Apr 24, 2026
cfba011
feat: enhance OptimumResult and VectorOptimumResult with additional a…
HugoMVale Apr 25, 2026
013e4af
refactor: replace eps import from utils.math to math.machine for cons…
HugoMVale Apr 25, 2026
1408e73
fix import from polykin.math.machine
HugoMVale Apr 25, 2026
0146b49
refactor: update import of 'huge' from utils.math to math.machine for…
HugoMVale Apr 25, 2026
9168145
refactor: update math function calls to use the math module for consi…
HugoMVale Apr 25, 2026
f4ac399
refactor: improve code readability and formatting in rootvec_qnewton …
HugoMVale Apr 26, 2026
3372f98
refactor: rename _update_broyden_qr to _update_broyden_factored for c…
HugoMVale Apr 26, 2026
010749a
fix: correct spelling errors in documentation comments
HugoMVale Apr 26, 2026
2cc737a
add test for nelder-mead+callback
HugoMVale Apr 26, 2026
a61cd5f
rename module brent to scalar
HugoMVale Apr 27, 2026
b26db24
move global methods to own file
HugoMVale Apr 27, 2026
e1cef2e
fix: improve documentation comment for f_example65 function
HugoMVale Apr 29, 2026
6497151
refactor global methods to enable flexible use in roots and optimization
HugoMVale Apr 29, 2026
46e08d1
delete; replaced by _globalm
HugoMVale Apr 29, 2026
8eec214
fix: update import path for optimization methods in qnewton.py
HugoMVale Apr 29, 2026
50cf1b8
add ty
HugoMVale Apr 29, 2026
96d2999
fix: streamline output formatting in line_search and dogleg functions
HugoMVale Apr 29, 2026
abc50bd
fix: update docstring formatting for parameters in fmin_nelder_mead f…
HugoMVale Apr 30, 2026
7f0d09d
fix: update attribute name from 'jac' to 'J' in VectorRootResult class
HugoMVale Apr 30, 2026
c8bc334
feat: add jac_check parameter to rootvec_qnewton for Jacobian validation
HugoMVale Apr 30, 2026
fae567b
fix: update language server settings in VSCode configuration
HugoMVale Apr 30, 2026
ed75102
fix: adjust step calculation in fmin_nelder_mead function for improve…
HugoMVale Apr 30, 2026
4bfbe0e
rename unit tests for scalar and vector optimization functions
HugoMVale Apr 30, 2026
d2b2e58
fix: update tolerance values in rootvec_qnewton
HugoMVale Apr 30, 2026
e171e81
improve error message for global step failure in rootvec_qnewton
HugoMVale Apr 30, 2026
ae27ef6
fix: update type hint for sclx parameter to FloatVectorLike in fmin_n…
HugoMVale May 1, 2026
132dced
fix: update type hints for x0, sclx, and sclf parameters to FloatVect…
HugoMVale May 1, 2026
fbd4e7b
feat: add ngeval and nheval attributes to VectorOptimumResult for gra…
HugoMVale May 1, 2026
7487edb
feat: enhance return structure of fmin_nelder_mead with gradient and …
HugoMVale May 1, 2026
e958cb9
fix: correct typo in docstring for global_method parameter in rootvec…
HugoMVale May 2, 2026
bb30f99
fix: clarify docstring for njeval attribute in VectorRootResult
HugoMVale May 2, 2026
ab3d4c9
fix: update docstring for J attribute in VectorRootResult to clarify …
HugoMVale May 2, 2026
8b8b883
fix: clarify docstring for ngeval and nheval attributes in VectorOpti…
HugoMVale May 2, 2026
8a1a957
fix: enhance method name construction and global method handling in r…
HugoMVale May 2, 2026
4ec015b
fix: enhance global method representation in rootvec_qnewton
HugoMVale May 2, 2026
5e9834e
rename file. update callback logic.
HugoMVale May 3, 2026
f464af3
fix: add callback functionality to fmin_brent tests
HugoMVale May 3, 2026
5a9e65b
fix: update success message for function value spread condition in fm…
HugoMVale May 3, 2026
70860a6
add fmin_secant
HugoMVale May 3, 2026
dfe1724
update
HugoMVale May 3, 2026
c5be92a
update description of scalar methods
HugoMVale May 3, 2026
5069777
update callback logic
HugoMVale May 3, 2026
6cd0c50
update callback logic
HugoMVale May 3, 2026
99769c5
rename to test_simplex
HugoMVale May 3, 2026
0ee90ba
refactor dogleg function to initialize variables more concisely
HugoMVale May 3, 2026
d992e99
update callback logic
HugoMVale May 3, 2026
7331265
update callback logic in fixpoint
HugoMVale May 3, 2026
3fc6311
update callback checks to ensure callback is not None
HugoMVale May 3, 2026
c622e52
add docstrings for machine epsilon, huge, tiny, and sqrt_eps constants
HugoMVale May 3, 2026
c40a9e7
update tolerances in fmin_secant and enhance test cases with noise ha…
HugoMVale May 3, 2026
5f7bc37
refactor: replace ndigit with epsf for machine precision in optimizat…
HugoMVale May 6, 2026
7ef8704
fix: update hessian2_centered call to use epsf
HugoMVale May 6, 2026
04164a2
fix: adjust tolerance calculation in test_fmin_secant_with_noise
HugoMVale May 6, 2026
24cb1dd
fix: update documentation for gradient, jacobian, and hessian functio…
HugoMVale May 6, 2026
b94a02b
fix: update tolerance documentation in fmin_secant to use epsf notation
HugoMVale May 6, 2026
00dbb8b
fix: update jac_check default value to True and improve documentation…
HugoMVale May 6, 2026
6549743
fix: update section titles for clarity in optimization documentation
HugoMVale May 8, 2026
f194eab
fix: update section titles for clarity in roots documentation
HugoMVale May 8, 2026
d9887d1
fix: update function parameter types and improve numerical stability …
HugoMVale May 8, 2026
d1e9b81
fix types in rootvec_qnewton
HugoMVale May 8, 2026
fa48f44
fix: remove unused parameters g and H from fmin_nelder_mead function
HugoMVale May 9, 2026
91132e8
fix: add Hinv and L attributes to VectorOptimumResult for improved He…
HugoMVale May 9, 2026
ca053ee
add doc fmin_qnewton
HugoMVale May 10, 2026
945f29a
fix: update tolerance descriptions in fmin_secant and rootvec_qnewton…
HugoMVale May 10, 2026
cc1ec8a
fix: update example functions in fmin_brent and fmin_secant for accuracy
HugoMVale May 10, 2026
a96fc60
fix: update numerical output formatting in fmin_brent and fmin_secant…
HugoMVale May 10, 2026
25742e7
fix: add descriptions for fmin_qnewton and fmin_nelder_mead in optimi…
HugoMVale May 10, 2026
24f8d01
fix: update documentation for fmin_nelder_mead with improved example …
HugoMVale May 10, 2026
d1a2624
fix: improve string representation of VectorOptimumResult for better …
HugoMVale May 10, 2026
c9ee69d
remove redundant abs(1/sclx)
HugoMVale May 10, 2026
9dfcfec
add optimization tuto
HugoMVale May 13, 2026
732d38b
fix: adjust step calculation in fmin_nelder_mead for improved optimiz…
HugoMVale May 13, 2026
b4b42c7
fix: enhance documentation for fmin_nelder_mead with detailed scaling…
HugoMVale May 14, 2026
fd6a9ee
add: implement optimization test functions for benchmarking
HugoMVale May 14, 2026
0886e16
fix: reorder jac0 and jac_check parameters in rootvec_qnewton for cla…
HugoMVale May 14, 2026
cdf1929
fix: rename jac0 parameter to J0 in rootvec_qnewton for consistency
HugoMVale May 14, 2026
cb86fc8
fix: update documentation formatting for clarity in to_html and add_d…
HugoMVale May 14, 2026
213f671
add: create __init__.py for optimization tests and reorganize test fu…
HugoMVale May 14, 2026
fa53c4f
add: implement fmin_qnewton function and corresponding tests for opti…
HugoMVale May 14, 2026
9c77f66
fix: enhance string representation in VectorOptimumResult to exclude …
HugoMVale May 14, 2026
843a59a
fix: update default global_method to 'dogleg' in fmin_qnewton and adj…
HugoMVale May 14, 2026
4ee584a
add further example
HugoMVale May 24, 2026
6549984
update tolerances
HugoMVale May 24, 2026
1f3bd1f
rename f to fe
HugoMVale May 25, 2026
fe665d6
rename kpp to kpp1
HugoMVale May 25, 2026
ded48c7
fix: ensure python.analysis.diagnosticMode is set to 'openFilesOnly'
HugoMVale May 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ jobs:
fail-fast: false
matrix:
resolution: ["lowest-direct", "highest"]
python-version: ["3.10", "3.11", "3.12", "3.13"]
python-version: ["3.11", "3.12", "3.13", "3.14"]
exclude:
- python-version: "3.12"
resolution: "lowest-direct"
- python-version: "3.13"
resolution: "lowest-direct" #numba 0.60 requires python < 3.13
- python-version: "3.14"
resolution: "lowest-direct" #numba 0.60 requires python < 3.13
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand Down
3 changes: 2 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"recommendations": [
"ms-python.python",
"charliermarsh.ruff"
"charliermarsh.ruff",
"astral-sh.ty"
]
}
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.languageServer": "Pylance",
"python.analysis.diagnosticMode": "openFilesOnly",
"ty.disableLanguageServices": true,
"[python]": {
"editor.rulers": [
90
],
"editor.inlayHints.enabled": "off",
"editor.formatOnSave": true,
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
![PyPI - Downloads](https://img.shields.io/pypi/dm/polykin?label=PyPI%20downloads)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/HugoMVale/polykin)

PolyKin is an open-source polymerization kinetics library for Python. It is still at an early
PolyKin is an open-source Python library for polymerization kinetics and related chemical engineering calculations. It is still at an early
development stage, but the following modules can already be used:

- Activity coefficient models
Expand Down Expand Up @@ -53,8 +53,8 @@ development stage, but the following modules can already be used:
- [x] Termination composite model
- Math
- [x] Joint confidence regions
- [x] Root and fixed-point solvers
- [ ] Models
- [x] Fixed-point solvers (scalar and vector)
- [x] Root solvers (scalar end vector)
- Physical property correlations
- [x] Antoine
- [x] DIPPR
Expand Down
2 changes: 1 addition & 1 deletion docs/installation.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Installation

`PolyKin` requires Python >= 3.10, because it makes use of recent type hint syntax. It further relies on a number of mature and well-maintained mathematical/scientific libraries:
`PolyKin` requires Python >= 3.11. It further relies on a number of mature and well-maintained mathematical/scientific libraries:
`matplotlib`, `mpmath`, `numba`, `numpy`, `pydantic`, `scipy`, etc.

## Install from PyPI
Expand Down
1 change: 1 addition & 0 deletions docs/reference/math/derivatives/_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
* [](index.md)
* [derivative_centered](derivative_centered.md)
* [derivative_complex](derivative_complex.md)
* [gradient_forward](gradient_forward.md)
* [hessian_forward](hessian_forward.md)
* [hessian2_centered](hessian2_centered.md)
* [jacobian_forward](jacobian_forward.md)
Expand Down
6 changes: 6 additions & 0 deletions docs/reference/math/derivatives/gradient_forward.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# polykin.math.derivatives

::: polykin.math.derivatives
options:
members:
- gradient_forward
3 changes: 3 additions & 0 deletions docs/reference/math/fixpoint/_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
* [](index.md)
* [fixpoint_anderson](fixpoint_anderson.md)
* [fixpoint_damped](fixpoint_damped.md)
* [fixpoint_dem](fixpoint_dem.md)
* [fixpoint_steffensen](fixpoint_steffensen.md)
* [fixpoint_wegstein](fixpoint_wegstein.md)
6 changes: 6 additions & 0 deletions docs/reference/math/fixpoint/fixpoint_damped.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# polykin.math.fixpoint

::: polykin.math.fixpoint
options:
members:
- fixpoint_damped
6 changes: 6 additions & 0 deletions docs/reference/math/fixpoint/fixpoint_dem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# polykin.math.fixpoint

::: polykin.math.fixpoint
options:
members:
- fixpoint_dem
6 changes: 6 additions & 0 deletions docs/reference/math/fixpoint/fixpoint_steffensen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# polykin.math.fixpoint

::: polykin.math.fixpoint
options:
members:
- fixpoint_steffensen
20 changes: 20 additions & 0 deletions docs/reference/math/fixpoint/index.md
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
# Fixed-Point Solvers (polykin.math.fixpoint)

## Scalar Problems

[fixpoint_steffensen] is the only solver in this group specialized for scalar fixed-point problems $g(x)=x$. It accelerates direct substitution through Aitken's delta-squared process, often converging significantly faster than plain fixed-point iteration when the fixed-point sequence is smooth and locally contractive.

## Multivariable Problems

[fixpoint_damped] is the most basic option for systems $\mathbf{g}(\mathbf{x})$. It applies direct substitution with optional damping, making each iteration inexpensive and easy to interpret. This is a reasonable first choice when the mapping is already contractive or only mildly unstable, especially if function evaluations are cheap.

[fixpoint_wegstein] improves on direct substitution by estimating a componentwise secant slope and converting it into a bounded acceleration factor. In practice, it often offers a favorable balance between robustness and speed for weakly to moderately coupled systems. It is usually more effective than simple damping, but because the acceleration is applied componentwise, performance can degrade when the variables are strongly coupled.

[fixpoint_dem] targets problems whose slow convergence is dominated by a single eigenvalue of the fixed-point iteration. By estimating that dominant mode and periodically applying a promotion step, it can reduce iteration counts for recycle-type problems and other slowly convergent systems. It is more specialized than Wegstein's method and is most useful when there is a clear dominant convergence mode.

[fixpoint_anderson] is generally the most powerful solver in this family for difficult coupled systems. It combines several previous iterates through a least-squares acceleration step, often delivering substantially better convergence than direct substitution-based methods. The additional linear algebra introduces some overhead, but this cost is usually justified when evaluating $\mathbf{g}(\mathbf{x})$ is expensive or when simpler accelerators stall.

[fixpoint_steffensen]: fixpoint_steffensen.md
[fixpoint_damped]: fixpoint_damped.md
[fixpoint_wegstein]: fixpoint_wegstein.md
[fixpoint_dem]: fixpoint_dem.md
[fixpoint_anderson]: fixpoint_anderson.md
6 changes: 6 additions & 0 deletions docs/reference/math/optimization/OptimumResult.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# polykin.math.optimization

::: polykin.math.optimization
options:
members:
- OptimumResult
6 changes: 6 additions & 0 deletions docs/reference/math/optimization/VectorOptimumResult.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# polykin.math.optimization

::: polykin.math.optimization
options:
members:
- VectorOptimumResult
7 changes: 7 additions & 0 deletions docs/reference/math/optimization/_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* [](index.md)
* [fmin_brent](fmin_brent.md)
* [fmin_nelder_mead](fmin_nelder_mead.md)
* [fmin_qnewton](fmin_qnewton.md)
* [fmin_secant](fmin_secant.md)
* [OptimumResult](OptimumResult.md)
* [VectorOptimumResult](VectorOptimumResult.md)
6 changes: 6 additions & 0 deletions docs/reference/math/optimization/fmin_brent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# polykin.math.optimization

::: polykin.math.optimization
options:
members:
- fmin_brent
6 changes: 6 additions & 0 deletions docs/reference/math/optimization/fmin_nelder_mead.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# polykin.math.optimization

::: polykin.math.optimization
options:
members:
- fmin_nelder_mead
6 changes: 6 additions & 0 deletions docs/reference/math/optimization/fmin_qnewton.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# polykin.math.optimization

::: polykin.math.optimization
options:
members:
- fmin_qnewton
6 changes: 6 additions & 0 deletions docs/reference/math/optimization/fmin_secant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# polykin.math.optimization

::: polykin.math.optimization
options:
members:
- fmin_secant
22 changes: 22 additions & 0 deletions docs/reference/math/optimization/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Optimization Solvers (polykin.math.optimization)

## Univariate Optimization

These solvers cover the typical trade-off between local speed and global robustness for minimization of scalar objective functions $f(x)$. They differ in the use of derivatives and whether a bounded interval is required.

[fmin_secant] is a fast local method for smooth problems when two reasonable initial guesses are available. It uses a secant approximation of the first derivative, evaluated via centered finite differences or complex-step differentiation. It typically converges quickly near a well-behaved minimum but is not robust to poor initial guesses, weak curvature, or nonsmooth objectives.

[fmin_brent] is a robust bounded method for cases where an interval containing a minimum is known. It combines golden-section search with inverse parabolic interpolation, achieving reliable convergence while exploiting smoothness when present. It does not require derivatives and is the preferred choice for safe one-dimensional minimization within a bracketed interval.

## Multivariate Optimization

These solvers provide different trade-offs between robustness, efficiency, and derivative requirements for unconstrained minimization of multivariate objective functions, $f(\mathbf{x})$.

[fmin_nelder_mead] is a derivative-free method for unconstrained minimization of multivariate functions. It evolves a simplex of trial points through reflection, expansion, contraction, and shrink operations, making it useful when derivatives are unavailable, unreliable, or too expensive to compute. In exchange for this flexibility, convergence is usually slower than with gradient-based methods, and performance may degrade for poorly scaled or high-dimensional problems.

[fmin_qnewton] is a fast local method for smooth unconstrained problems when gradient information is available analytically or can be estimated accurately. It combines Newton-type curvature information with optional BFGS Hessian updates and supports either a line-search or dogleg globalization strategy to improve robustness from remote initial guesses. This is generally the preferred solver when the objective is differentiable and a reasonably good starting point is available. As with other quasi-Newton methods, however, convergence remains fundamentally local.

[fmin_secant]: fmin_secant.md
[fmin_brent]: fmin_brent.md
[fmin_nelder_mead]: fmin_nelder_mead.md
[fmin_qnewton]: fmin_qnewton.md
23 changes: 23 additions & 0 deletions docs/reference/math/roots/index.md
Original file line number Diff line number Diff line change
@@ -1 +1,24 @@
# Root Solvers (polykin.math.roots)

## Single Equation

These three solvers span the usual tradeoff between local speed and global robustness for real-valued equations $f(x)=0$. They differ mainly in how much information they require and how sensitive they are to the initial guess.

[root_newton] is the fastest option for smooth problems with a good initial guess. It uses a Newton–Raphson update and estimates derivatives via complex-step differentiation, so no user-supplied derivative is needed. Convergence is typically very rapid, but the function must accept complex inputs, and—as with any Newton method—it may fail or converge to the wrong root if initialized poorly.

[root_secant] removes the need for derivatives by approximating the slope from two initial guesses. It retains fast local convergence on well-behaved problems and works when complex-step differentiation is not applicable. It is generally less robust than Brent’s method and less decisive than Newton near difficult roots, but provides a useful middle ground between simplicity and speed.

[root_brent] is the safest choice when a bracketing interval is available. By combining bisection, secant steps, and inverse quadratic interpolation, it maintains the reliability of bracketed methods while recovering much of the speed of open methods. The only requirement is an interval where the function changes sign; when this is available, Brent’s method is typically the best choice for robust production use.

## System of Equations

[rootvec_qnewton] targets systems of nonlinear equations $\boldsymbol{F}(\boldsymbol{x})=\boldsymbol{0}$, which are inherently more challenging than scalar problems. There is no multidimensional analogue of bracketing, and thus no method combining global guarantees with high efficiency comparable to Brent’s method.

Instead, such solvers rely on local linearization. Classical Newton methods use the full Jacobian, but forming and factorizing it can be expensive for large systems. `rootvec_qnewton` supports two approaches: recomputing the full Jacobian at each iteration (either user-supplied or via finite differences), or updating an approximate Jacobian using Broyden’s rank-1 formula. In this sense, Broyden’s method plays a role analogous to the secant method in the scalar case.

Full Jacobian updates improve robustness at higher cost, while Broyden updates reduce per-iteration cost at the expense of reliability, especially with poor initial guesses or strong nonlinearity. As with other quasi-Newton methods, convergence is local, so good initial guesses remain important.

[root_newton]: root_newton.md
[root_secant]: root_secant.md
[root_brent]: root_brent.md
[rootvec_qnewton]: rootvec_qnewton.md
1 change: 1 addition & 0 deletions docs/tutorials/_SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* [Distributions](distributions.ipynb)
* [Equations of State](equations_of_state.ipynb)
* [Kinetic Coefficients](kinetic_coefficients.ipynb)
* [Optimization](optimization.ipynb)
* [Physical Property Equations](physprop_equations.ipynb)
* [Thermal Conductivity](thermal_conductivity.ipynb)
* [Viscosity](viscosity.ipynb)
857 changes: 857 additions & 0 deletions docs/tutorials/optimization.ipynb

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ nav:
- Derivatives: reference/math/derivatives/
- Miscellaneous: reference/math/misc/
- Fixed-Point Solvers: reference/math/fixpoint/
- Optimization Solvers: reference/math/optimization/
- Root Solvers: reference/math/roots/
- Special Functions: reference/math/special/
- Properties:
Expand Down
14 changes: 12 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ classifiers = [
"Topic :: Scientific/Engineering :: Chemistry",
]

requires-python = ">=3.10.0"
requires-python = ">=3.11.0"

dependencies = [
"matplotlib>=3.8",
Expand All @@ -34,6 +34,7 @@ dev = [
"pytest-cov>=6.0.0",
"pytest-xdist>=3.6.1",
"ruff>=0.14.9",
"ty>=0.0.33",
]
docs = [
"black>=26.1.0",
Expand All @@ -58,7 +59,7 @@ addopts = ["-v", "-s", "-n=2"]

[tool.ruff]
line-length = 90
target-version = "py310"
target-version = "py311"

[tool.ruff.lint]
select = ["E", "F", "W", "I", "UP", "D", "NPY201"]
Expand All @@ -72,6 +73,15 @@ pydocstyle = { convention = 'numpy' }
[tool.ruff.format]
line-ending = "auto"

[tool.ty.environment]
root = ["./src"]

[tool.ty.src]
include = ["src", "tests"]

[tool.ty.terminal]
output-format = "concise"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
2 changes: 1 addition & 1 deletion src/polykin/copolymerization/binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from numba import jit
from scipy.integrate import solve_ivp

from polykin.math.machine import eps
from polykin.utils.exceptions import ODESolverError
from polykin.utils.math import eps
from polykin.utils.typing import FloatArray, FloatArrayLike, FloatMatrix, FloatVectorLike

__all__ = [
Expand Down
2 changes: 1 addition & 1 deletion src/polykin/copolymerization/fitting.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ def sse(r: tuple[float, float], atol=1e-4, rtol=1e-4) -> float:
npar = 2
if ndata > npar:
s_sq = sse_opt / (ndata - npar)
H = hessian2_centered(sse, r_opt, h=1e-4)
H = hessian2_centered(sse, r_opt, epsf=1e-6)
Hinv = np.linalg.inv(H)
cov = 2 * Hinv * s_sq
else:
Expand Down
2 changes: 1 addition & 1 deletion src/polykin/copolymerization/multicomponent.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from numpy import exp
from scipy.integrate import solve_ivp

from polykin.math.machine import eps
from polykin.utils.exceptions import ODESolverError, ShapeError
from polykin.utils.math import eps
from polykin.utils.typing import (
FloatArray,
FloatArrayLike,
Expand Down
2 changes: 1 addition & 1 deletion src/polykin/copolymerization/penultimate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import numpy as np

from polykin.kinetics import Arrhenius
from polykin.utils.math import eps
from polykin.math.machine import eps
from polykin.utils.tools import check_bounds
from polykin.utils.typing import FloatArray, FloatArrayLike, IntArrayLike

Expand Down
5 changes: 3 additions & 2 deletions src/polykin/copolymerization/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
from scipy.integrate import solve_ivp

from polykin.kinetics import Arrhenius
from polykin.math import root_brent
from polykin.utils.math import convert_FloatOrVectorLike_to_FloatVector, eps
from polykin.math.machine import eps
from polykin.math.roots import root_brent
from polykin.utils.math import convert_FloatOrVectorLike_to_FloatVector
from polykin.utils.tools import check_bounds, check_in_set, custom_repr
from polykin.utils.typing import (
FloatArray,
Expand Down
2 changes: 1 addition & 1 deletion src/polykin/distributions/gold.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from polykin.distributions.analyticaldistributions import poisson
from polykin.math import root_brent
from polykin.utils.math import eps
from polykin.math.machine import eps
from polykin.utils.typing import FloatArray, IntArrayLike


Expand Down
14 changes: 4 additions & 10 deletions src/polykin/hmt/diffusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from numpy import cos, exp, pi, sin, sqrt
from scipy.special import erfc

from polykin.math.machine import eps
from polykin.math.special import ierfc, roots_xcotx, roots_xtanx
from polykin.utils.math import eps

__all__ = [
"profile_constc_semiinf",
Expand Down Expand Up @@ -299,9 +299,7 @@ def uptake_constc_sheet(Fo: float) -> float:
else:
# Solution for normal times
B = -(Fo * pi**2) / 4
S = sum(
1 / (2 * n + 1) ** 2 * exp(B * (2 * n + 1) ** 2) for n in range(0, N - 1)
)
S = sum(1 / (2 * n + 1) ** 2 * exp(B * (2 * n + 1) ** 2) for n in range(0, N - 1))
result = 1 - (8 / pi**2) * S

return result
Expand Down Expand Up @@ -433,9 +431,7 @@ def uptake_convection_sheet(Fo: float, Bi: float) -> float:
N = 4 # Number of terms in series expansion (optimal value)
x = roots_xtanx(Bi, N)
b2 = x**2
S = sum(
exp(-b2[n] * Fo) / (b2[n] * (b2[n] + Bi * (Bi + 1))) for n in range(0, N)
)
S = sum(exp(-b2[n] * Fo) / (b2[n] * (b2[n] + Bi * (Bi + 1))) for n in range(0, N))
return 1 - (2 * Bi**2) * S
else:
return 0
Expand Down Expand Up @@ -501,9 +497,7 @@ def uptake_convection_sphere(Fo: float, Bi: float) -> float:
N = 4 # Number of terms in series expansion (optimal value)
x = roots_xcotx(Bi, N)
b2 = x**2
S = sum(
exp(-b2[n] * Fo) / (b2[n] * (b2[n] + Bi * (Bi - 1))) for n in range(0, N)
)
S = sum(exp(-b2[n] * Fo) / (b2[n] * (b2[n] + Bi * (Bi - 1))) for n in range(0, N))
return 1 - (6 * Bi**2) * S
else:
return 0
Expand Down
Loading
Loading