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

Release v0.19.0 #126

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ version: 2
build:
os: ubuntu-22.04
tools:
python: "3.11"
python: "3.13"

# You can also specify other tool versions:
# nodejs: "20"
Expand Down
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ keywords:
- real numbers

license: MPL-2.0
version: 0.18.0
date-released: 2024-10-25
version: 0.19.0
date-released: 2024-11-01
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ includes Ruff linting, unit tests, Python doctests, and in that order.
## Versioning and Releases

The [PyPI package](https://pypi.org/project/continuedfractions/) is
currently at version `0.18.0` - the goal is to use [semantic
currently at version `0.19.0` - the goal is to use [semantic
versioning](https://semver.org/) consistently for all future releases,
but some earlier releases do not comply with strict semantic versioning.

Expand Down
2 changes: 1 addition & 1 deletion docs/sources/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ The CI pipelines are defined in the `CI YML <https://github.com/sr-murthy/contin
Versioning and Releases :fas:`upload`
=====================================

The `PyPI package <https://pypi.org/project/continuedfractions/>`_ is currently at version ``0.18.0`` - the goal is to use `semantic versioning <https://semver.org/>`_ consistently for all future releases, but some earlier releases do not comply with strict semantic versioning.
The `PyPI package <https://pypi.org/project/continuedfractions/>`_ is currently at version ``0.19.0`` - the goal is to use `semantic versioning <https://semver.org/>`_ consistently for all future releases, but some earlier releases do not comply with strict semantic versioning.

There is currently no dedicated pipeline for releases - both `GitHub releases <https://github.com/sr-murthy/continuedfractions/releases>`_ and `PyPI packages <https://pypi.org/project/continuedfractions>`_ are published manually, but both have the same version tag.

Expand Down
32 changes: 24 additions & 8 deletions docs/sources/creating-continued-fractions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,33 @@ This is derived by repeatedly applying `Euclid's division lemma <https://en.wiki
.. math::

\begin{align}
\frac{649}{200} &= 3 + \cfrac{49}{200} \\
\frac{649}{200} &= \cfrac{3 \times 200 + 49}{200} \\
&= 3 + \cfrac{49}{200} \\
&= 3 + \cfrac{1}{\cfrac{200}{49}} \\
&= 3 + \cfrac{1}{\cfrac{4 \times 49 + 4}{49}} \\
&= 3 + \cfrac{1}{4 + \cfrac{4}{49}} \\
&= 3 + \cfrac{1}{4 + \cfrac{1}{\cfrac{49}{4}}} \\
&= 3 + \cfrac{1}{4 + \cfrac{1}{\cfrac{4 \times 12 + 1}{4}}} \\
&= 3 + \cfrac{1}{4 + \cfrac{1}{12 + \cfrac{1}{4}}}
\end{align}

The numbers :math:`3, 4, 12, 4` are called **elements** (or **coefficients**) of the continued fraction :math:`[3; 4, 12, 4]`, and the number of elements after the first - in this case :math:`3` - is defined to be its **order**.
The numbers :math:`3, 4, 12, 4` are called **elements** (or **coefficients**) of the continued fraction :math:`[3; 4, 12, 4]`, and the number of elements after the first - in this case :math:`3` - is defined to be its **order**. The order can be finite or infinite depending on whether the number represented is rational or irrational, as will be discussed later.

The representation :math:`[3; 4, 12, 4]` is called **simple** (or **regular**) because all of the numerators in the fractional terms are equal to :math:`1`, which makes the fractions irreducible (cannot be simplified further). Mathematically, the continued fraction is written as :math:`[3; 4, 12, 4]`. The representation is also unique - the only other representation is :math:`[3; 4, 12, 3, 1]`, which can be rewritten as :math:`[3; 4, 12, 4]`.

.. note::

All references to continued fractions are to the simple forms where the last element :math:`> 1`.

Support for non-simple, generalised continued fractions is planned to be included in future releases.
All references to "continued fraction" are to the simple forms. Support for non-simple, generalised continued fractions is planned to be included in future releases.

We can think of :math:`3`, which is the integer part of :math:`\frac{649}{200} = 3.245`, as the "head" of the continued fraction, and the integers :math:`4, 12, 4`, which determine the fractional part :math:`\cfrac{1}{4 + \cfrac{1}{12 + \cfrac{1}{4}}} = \frac{49}{200} = 0.245` of the continued fraction, as its "tail".

In general, a simple continued fraction is denoted by a tuple of integers, enclosed in square brackets:
The generally used notation for a simple continued fraction is a tuple of integers :math:`[a_0; a_1, a_2, \ldots, a_n, \ldots]`, which stands for the fraction:

.. math::

[a_0; a_1, a_2, \ldots, a_n, \ldots] = a_0 + \cfrac{1}{a_1 + \cfrac{1}{a_2 + \ddots \cfrac{1}{a_n + \ddots}}}
a_0 + \cfrac{1}{a_1 + \cfrac{1}{a_2 + \ddots \cfrac{1}{a_n + \ddots}}}

where :math:`a_0` is the integer part, and :math:`a_1,a_2,\ldots` are (positive) integers defining the fractional part, in the representation.
where :math:`a_0` is the integer part, and :math:`a_1,a_2,\ldots` are (positive) integers defining the fractional part, in the representation. If the order is finite, i.e. :math:`n < \infty`, then we may assume the last element :math:`a_n > 1` because :math:`[a_0; a_1, a_2, \ldots a_{n - 1}, a_n = 1] = [a_0; a_1, a_2, \ldots a_{n - 1} + 1]`.

.. _creating-continued-fractions.from-numeric-types:

Expand Down Expand Up @@ -260,6 +261,21 @@ A :py:class:`ValueError` is raised if the tail elements provided are invalid, e.
...
ValueError: The elements/coefficients to be added to the tail must be positive integers.

.. note::

If the last of the new elements passed to :py:meth:`~continuedfractions.continuedfraction.ContinuedFraction.extend` happens to be :math:`1` then it is added to the previous element to ensure uniqueness of the new sequence of elements of the resulting continued fraction, e.g.:

.. code:: python

>>> cf = ContinuedFraction.from_elements(3, 4, 12, 3)
>>> cf
ContinuedFraction(490, 151)
>>> cf.extend(1)
>>> cf
ContinuedFraction(649, 200)
>>> cf.elements
(3, 4, 12, 4)

.. _creating-continued-fractions.inplace-truncation:

In-place Truncation of Tail Elements
Expand Down
10 changes: 5 additions & 5 deletions docs/sources/exploring-continued-fractions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -171,23 +171,23 @@ Convergents have a stronger version of this property: namely a rational number :

The current implementation of :py:class:`~continuedfractions.continuedfraction.ContinuedFraction` can only represent finite (simple) continued fractions, which means that the convergents in its instances will always be finite in number, regardless of whether the real numbers they approximate are rational or irrational. Support for infinite, generalised continued fractions will be added in future releases.

We know, for example, that the square root :math:`\sqrt{n}` of any non-square (positive) integer :math:`n` is irrational. This can be seen by writing :math:`n = a^2 + r`, for integers :math:`a, r > 0`, from which we have:
We can show, for example, that the square root :math:`\sqrt{n}` of any non-square (positive) integer :math:`n` is irrational by considering positive integers of the form :math:`n = (ka)^2 + r`, for integers :math:`k, a, r > 0` and :math:`(k, a) = 1`. From this we have:

.. math::
:nowrap:

\begin{alignat*}{1}
& r &&= n - a^2 = \left(\sqrt{n} + a\right)\left(\sqrt{n} - a\right) \\
& \sqrt{n} &&= a + \frac{r}{a + \sqrt{n}}
& r &&= n - (ka)^2 = \left(\sqrt{n} + ka\right)\left(\sqrt{n} - ka\right) \\
& \sqrt{n} &&= ka + \frac{r}{2ka + \sqrt{n}}
\end{alignat*}

Expanding the expression for :math:`\sqrt{n}` recursively we have the following infinite periodic continued fraction for :math:`\sqrt{n}`:

.. math::

\sqrt{n} = a + \cfrac{r}{2a + \cfrac{r}{2a + \cfrac{r}{2a + \ddots}}}
\sqrt{n} = ka + \cfrac{r}{2ka + \cfrac{r}{2ka + \cfrac{r}{2ka + \ddots}}}

With :math:`a = r = 1` we can represent :math:`\sqrt{2}` as the continued fraction:
With :math:`k = a = r = 1` we can represent :math:`\sqrt{2}` as the continued fraction:

.. math::

Expand Down
4 changes: 2 additions & 2 deletions docs/sources/sequences.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Here are some examples of constructing left-mediants:
>>> cf1 = ContinuedFraction('1/2')
>>> cf2 = ContinuedFraction(3, 5)
# The default `k = 1` gives you the common, simple mediant of the two rationals
>>> cf1.left_mediant(c2)
>>> cf1.left_mediant(cf2)
ContinuedFraction(4, 7)
>>> cf1.left_mediant(cf2, k=2)
ContinuedFraction(5, 9)
Expand All @@ -124,7 +124,7 @@ and right-mediants:
>>> cf1 = ContinuedFraction('1/2')
>>> cf2 = ContinuedFraction(3, 5)
# The default `k = 1` gives you the common, simple mediant of the two rationals
>>> cf1.right_mediant(c2)
>>> cf1.right_mediant(cf2)
ContinuedFraction(4, 7)
>>> cf1.right_mediant(cf2, k=2)
ContinuedFraction(7, 12)
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Development Status :: 5 - Production/Stable",
"Operating System :: POSIX :: Linux",
"Operating System :: MacOS",
Expand Down
10 changes: 10 additions & 0 deletions src/continuedfractions/continuedfraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,17 @@ def extend(self, *new_elements: int) -> None:
)

elements = self._elements + new_elements

# A step to ensure uniqueness of the simple form of the continued
# fraction - if the last of the new elements is ``1`` it can be
# "absorbed" by adding it to the second last element, thereby
# shortening the sequence by one element. The resulting simple
# continued fraction becomes unique for the number that is represented.
if len(elements) > 1 and elements[-1] == 1:
elements = elements[:-2] + (elements[-2] + 1,)

fraction = fraction_from_elements(*elements)

self._numerator, self._denominator = fraction.as_integer_ratio()
self._elements = elements

Expand Down
2 changes: 1 addition & 1 deletion src/continuedfractions/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.18.0"
__version__ = "0.19.0"
5 changes: 5 additions & 0 deletions tests/units/test_continuedfraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,13 @@ def test_ContinuedFraction__extend__invalid_elements__value_error_raised(self, i
@pytest.mark.parametrize(
"instance, new_elements, expected_comparative_instance",
[
(ContinuedFraction(0, 1), (1,), ContinuedFraction(1, 1)),
(ContinuedFraction(0, 1), (2,), ContinuedFraction(1, 2)),
(ContinuedFraction(0, 1), (2, 1,), ContinuedFraction(1, 3)),
(ContinuedFraction(0, 1), (3,), ContinuedFraction(1, 3)),
(ContinuedFraction(1, 1), (2,), ContinuedFraction(3, 2)),
(ContinuedFraction(1, 1), (2, 1), ContinuedFraction(4, 3)),
(ContinuedFraction(1, 1), (3,), ContinuedFraction(4, 3)),
(ContinuedFraction(3, 2), (3,), ContinuedFraction(10, 7)),
(ContinuedFraction(649, 200), (5, 2), ContinuedFraction(7457, 2298)),
(ContinuedFraction(-415, 93), (2, 1, 5), ContinuedFraction(-7403, 1659))
Expand Down
Loading