Function Analysis
CI & Test Status |
|
Code Quality |
|
Code Style |
|
Dependencies |
|
Usage |
|
PyPI |
This library uses concepts typically taught in an introductory Calculus class to describe properties of continuous, differentiable, single-variable functions.
Using this library
The func_analysis module defines the class AnalyzedFunc. An instance of this class has several attributes describing the behavior of this function.
Required data include:
A range
The function to be analyzed
Special points include zeros, critical numbers, extrema, and points of inflection. It’s possible to calculate these when given the number of points wanted.
Optional data can be provided to improve precision and performance. Such data include:
Any derivatives of the function
Any known zeros, critical numbers, extrema, points of inflection
Intervals of concavity, convexity, increase, decrease
Any vertical axis of symmetry
Any of the above data can be calculated by an instance of AnalyzedFunc.
Example Usage
This paste from an interactive Python session showcases all the functionality of AnalyzedFunc:
>>> from func_analysis import AnalyzedFunc
>>> import mpmath as mp; import numpy as np
>>> mp.pretty = True
>>> def example_func(x):
... return mp.cos(x ** 2) - mp.sin(x) + (x / 68)
...
>>> analyzed_example = AnalyzedFunc(
... func=example_func,
... x_range=(-47.05, -46.3499),
... zeros_wanted=21,
... crits_wanted=21,
... pois_wanted=21,
... zeros=[-47.038289673236127, -46.406755885040056],
... )
>>> analyzed_example.zeros
array([mpf('-47.038289673236127'), mpf('-47.018473233395284'),
mpf('-46.972318087653945'), mpf('-46.950739626397913'),
mpf('-46.906204518117636'), mpf('-46.882958270910017'),
mpf('-46.839955720658347'), mpf('-46.815121707485004'),
mpf('-46.77357601136889'), mpf('-46.747224922729004'),
mpf('-46.707068062964038'), mpf('-46.679264553080846'),
mpf('-46.640433373296687'), mpf('-46.611238416225623'),
mpf('-46.57367255467036'), mpf('-46.543145221101676'),
mpf('-46.506785519620839'), mpf('-46.474984380574834'),
mpf('-46.439771604599501'), mpf('-46.406755885040056'),
mpf('-46.372629655875102')], dtype=object)
>>> analyzed_example.crits
array([mpf('-47.028400867252276'), mpf('-46.995216177440788'),
mpf('-46.961552135996999'), mpf('-46.928318300227147'),
mpf('-46.894608617023608'), mpf('-46.861324416365338'),
mpf('-46.827569901478539'), mpf('-46.794234116960419'),
mpf('-46.760435575283916'), mpf('-46.72704699248236'),
mpf('-46.693205219083057'), mpf('-46.659762632756908'),
mpf('-46.625878408195688'), mpf('-46.592380626945829'),
mpf('-46.558454712583136'), mpf('-46.524900563516225'),
mpf('-46.490933696823733'), mpf('-46.457322030198712'),
mpf('-46.42331492009863'), mpf('-46.389644613934263'),
mpf('-46.355597936188148')], dtype=object)
>>> analyzed_example.pois
array([mpf('-47.04521505151731'), mpf('-47.011813891641338'),
mpf('-46.978389522478297'), mpf('-46.944940655832212'),
mpf('-46.911468800195282'), mpf('-46.877972023301726'),
mpf('-46.844452476333207'), mpf('-46.81090758498618'),
mpf('-46.777340139630388'), mpf('-46.743746928888186'),
mpf('-46.710131375870707'), mpf('-46.676489640045468'),
mpf('-46.64282576785548'), mpf('-46.60913530049924'),
mpf('-46.575422895374974'), mpf('-46.541683489262155'),
mpf('-46.507922335179564'), mpf('-46.474133782285819'),
mpf('-46.440323660950513'), mpf('-46.406485752427894'),
mpf('-46.372626443270374')], dtype=object)
>>> analyzed_example.increasing
[Interval(start=-47.05, stop=mpf('-47.028400867252276')),
Interval(start=mpf('-46.995216177440788'), stop=mpf('-46.961552135996999')),
Interval(start=mpf('-46.928318300227147'), stop=mpf('-46.894608617023608')),
Interval(start=mpf('-46.861324416365338'), stop=mpf('-46.827569901478539')),
Interval(start=mpf('-46.794234116960419'), stop=mpf('-46.760435575283916')),
Interval(start=mpf('-46.72704699248236'), stop=mpf('-46.693205219083057')),
Interval(start=mpf('-46.659762632756908'), stop=mpf('-46.625878408195688')),
Interval(start=mpf('-46.592380626945829'), stop=mpf('-46.558454712583136')),
Interval(start=mpf('-46.524900563516225'), stop=mpf('-46.490933696823733')),
Interval(start=mpf('-46.457322030198712'), stop=mpf('-46.42331492009863')),
Interval(start=mpf('-46.389644613934263'), stop=mpf('-46.355597936188148'))]
>>> analyzed_example.decreasing
[Interval(start=mpf('-47.028400867252276'), stop=mpf('-46.995216177440788')),
Interval(start=mpf('-46.961552135996999'), stop=mpf('-46.928318300227147')),
Interval(start=mpf('-46.894608617023608'), stop=mpf('-46.861324416365338')),
Interval(start=mpf('-46.827569901478539'), stop=mpf('-46.794234116960419')),
Interval(start=mpf('-46.760435575283916'), stop=mpf('-46.72704699248236')),
Interval(start=mpf('-46.693205219083057'), stop=mpf('-46.659762632756908')),
Interval(start=mpf('-46.625878408195688'), stop=mpf('-46.592380626945829')),
Interval(start=mpf('-46.558454712583136'), stop=mpf('-46.524900563516225')),
Interval(start=mpf('-46.490933696823733'), stop=mpf('-46.457322030198712')),
Interval(start=mpf('-46.42331492009863'), stop=mpf('-46.389644613934263')),
Interval(start=mpf('-46.355597936188148'), stop=-46.3499)]
>>> analyzed_example.concave
[Interval(start=-47.05, stop=mpf('-47.04521505151731')),
Interval(start=mpf('-47.011813891641338'), stop=mpf('-46.978389522478297')),
Interval(start=mpf('-46.944940655832212'), stop=mpf('-46.911468800195282')),
Interval(start=mpf('-46.877972023301726'), stop=mpf('-46.844452476333207')),
Interval(start=mpf('-46.81090758498618'), stop=mpf('-46.777340139630388')),
Interval(start=mpf('-46.743746928888186'), stop=mpf('-46.710131375870707')),
Interval(start=mpf('-46.676489640045468'), stop=mpf('-46.64282576785548')),
Interval(start=mpf('-46.60913530049924'), stop=mpf('-46.575422895374974')),
Interval(start=mpf('-46.541683489262155'), stop=mpf('-46.507922335179564')),
Interval(start=mpf('-46.474133782285819'), stop=mpf('-46.440323660950513')),
Interval(start=mpf('-46.406485752427894'), stop=mpf('-46.372626443270374'))]
>>> analyzed_example.convex
[Interval(start=mpf('-47.04521505151731'), stop=mpf('-47.011813891641338')),
Interval(start=mpf('-46.978389522478297'), stop=mpf('-46.944940655832212')),
Interval(start=mpf('-46.911468800195282'), stop=mpf('-46.877972023301726')),
Interval(start=mpf('-46.844452476333207'), stop=mpf('-46.81090758498618')),
Interval(start=mpf('-46.777340139630388'), stop=mpf('-46.743746928888186')),
Interval(start=mpf('-46.710131375870707'), stop=mpf('-46.676489640045468')),
Interval(start=mpf('-46.64282576785548'), stop=mpf('-46.60913530049924')),
Interval(start=mpf('-46.575422895374974'), stop=mpf('-46.541683489262155')),
Interval(start=mpf('-46.507922335179564'), stop=mpf('-46.474133782285819')),
Interval(start=mpf('-46.440323660950513'), stop=mpf('-46.406485752427894')),
Interval(start=mpf('-46.372626443270374'), stop=-46.3499)]
>>> analyzed_example.relative_maxima
array([mpf('-47.028400867252276'), mpf('-46.961552135996999'),
mpf('-46.894608617023608'), mpf('-46.827569901478539'),
mpf('-46.760435575283916'), mpf('-46.693205219083057'),
mpf('-46.625878408195688'), mpf('-46.558454712583136'),
mpf('-46.490933696823733'), mpf('-46.42331492009863'),
mpf('-46.355597936188148')], dtype=object)
>>> analyzed_example.relative_minima
array([mpf('-46.995216177440788'), mpf('-46.928318300227147'),
mpf('-46.861324416365338'), mpf('-46.794234116960419'),
mpf('-46.72704699248236'), mpf('-46.659762632756908'),
mpf('-46.592380626945829'), mpf('-46.524900563516225'),
mpf('-46.457322030198712'), mpf('-46.389644613934263')],
dtype=object)
>>> analyzed_example.absolute_maximum
Coordinate(x_val=mpf('-46.355597936188148'), y_val=mpf('1.0131766438615282'))
>>> analyzed_example.absolute_minimum
Coordinate(x_val=mpf('-46.995216177440788'), y_val=mpf('-1.5627299417380764'))
>>> analyzed_example.signed_area
mpf('-0.1835790011406907')
>>> analyzed_example.unsigned_area
mpf('0.46577475660746492')
We can see that the inflection points of a function, the critical points of its first derivative, and the zeros of its second derivative are identical.
>>> np.array_equal(
... analyzed_example.pois, analyzed_example.rooted_first_derivative.crits
... )
True
>>> np.array_equal(
... analyzed_example.pois, analyzed_example.rooted_second_derivative.zeros
... )
True
Other examples to demonstrate the relationship between derivatives:
>>> np.array_equal(analyzed_example.concave, analyzed_example.rooted_first_derivative.increasing)
True
>>> np.array_equal(analyzed_example.first_derivative.convex, analyzed_example.rooted_second_derivative.decreasing)
True
A work-in-progress feature is listing x-values of vertical axes of symmetry. Here’s an example of a function that’s symmetric about the y-axis:
>>> def symmetric_func(x):
return mp.power(x, 2) - 4
>>> analyzed_symmetric_example = AnalyzedFunc(
... func=lambda x: mp.power(x, 2) - 4,
... x_range=(-8,8),
... zeros_wanted=2
... )
>>> analyzed_symmetric_example.vertical_axis_of_symmetry
[0.0]
License
This program is licensed under the GNU Affero General Public License v3 or later.
Metadata
Release files for func-analysis 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| func-analysis-0.3.0.tar.gz | 19.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| func_analysis-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.5 kB
Release files / func-analysis-0.3.0.tar.gz
| Download URL | func-analysis-0.3.0.tar.gz |
|---|---|
| Size | 19.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3d952ec57f4fb8ed72c2aed0ce065c0a67f44bb7bc5dcca1b6e1a89f08308175
|
|
BLAKE2b-256 checksum How to use checksums |
563b91560abfb4bca9d22bb55e26f2620893a515fec1fb6bde0ab286faa84951
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.7.3
|
Release files / func_analysis-0.3.0-py3-none-any.whl
| Download URL | func_analysis-0.3.0-py3-none-any.whl |
|---|---|
| Size | 31.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c7fd2682212f84425d9b51419bceb67c860b6970c0ef807977081714c49a5235
|
|
BLAKE2b-256 checksum How to use checksums |
2d6a6ba3cd7f725a122234d81ac66ba4519dcd074bf17d0db4230efd0e635c88
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.7.3
|
Security for func-analysis 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.