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

feat: introduce semantic prs, codespell and add some type hints #130

Merged
merged 2 commits into from
Jun 22, 2024
Merged
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
20 changes: 20 additions & 0 deletions .github/workflows/semantic-pr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: "Semantic PR Check"

on:
pull_request_target:
types:
- opened
- edited
- synchronize

permissions:
pull-requests: read

jobs:
main:
name: Validate PR title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36 changes: 22 additions & 14 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.1.0
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-added-large-files
- id: check-toml
- id: check-yaml
- repo: https://github.com/psf/black
rev: 23.7.0
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-added-large-files
- id: check-toml
- id: check-yaml
- id: mixed-line-ending
- repo: https://github.com/psf/black
rev: 24.4.2
hooks:
- id: black
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.287
- id: black
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.10
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- id: ruff
args: [ --fix, --exit-non-zero-on-fix ]
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
additional_dependencies:
- tomli
args: [ --write-changes ]
2 changes: 1 addition & 1 deletion docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ Bug fixes
---------

- Rotation in 3D now returns the correct transformation if the axis is not a normalized vector
- Line.perpendicular now also works for points tha lie on the line
- Line.perpendicular now also works for points that lie on the line

0.1.1 - released (2.2.2019)
---------------------------
3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import geometer

project = "geometer"
copyright = "2022, Jan Müller"
copyright = "2024, Jan Müller"
author = "Jan Müller"

# The short X.Y version
Expand Down Expand Up @@ -246,3 +246,4 @@ def linkcode_resolve(domain, info):
# -- Extension configuration -------------------------------------------------
autodoc_typehints = "description"
autodoc_typehints_description_target = "documented"
autodoc_type_aliases = {"npt.ArrayLike": "npt.ArrayLike"}
15 changes: 8 additions & 7 deletions geometer/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ def __init__(

if len(args) == 1:
if isinstance(args[0], Tensor):
self.array = np.array(args[0].array, **kwargs)
self.array = np.array(args[0].array, **kwargs) # type: ignore[call-overload]
self._covariant_indices = args[0]._covariant_indices
self._contravariant_indices = args[0]._contravariant_indices
return
else:
self.array = np.array(args[0], **kwargs)
self.array = np.array(args[0], **kwargs) # type: ignore[call-overload]
else:
self.array = np.array(args, **kwargs)
self.array = np.array(args, **kwargs) # type: ignore[call-overload]

if tensor_rank is None:
tensor_rank = self.rank
Expand Down Expand Up @@ -271,7 +271,8 @@ def _get_index_mapping(self, index: TensorIndex) -> list[int | None]:
# create advanced indices in front
for i in advanced_indices:
index_mapping.remove(i)
return [None] * b.ndim + index_mapping
new_indices: list[int | None] = [None] * b.ndim
return new_indices + index_mapping
else:
# replace indices with broadcast shape
return index_mapping[:a0] + [None] * b.ndim + index_mapping[a1 + 1 :]
Expand Down Expand Up @@ -365,7 +366,7 @@ def __eq__(self, other: object) -> bool:
if isinstance(other, Tensor):
other = other.array
try:
return np.allclose(self.array, other, rtol=EQ_TOL_REL, atol=EQ_TOL_ABS)
return np.allclose(self.array, other, rtol=EQ_TOL_REL, atol=EQ_TOL_ABS) # type: ignore[arg-type]
except TypeError:
return NotImplemented

Expand Down Expand Up @@ -442,7 +443,7 @@ def from_tensor(cls, tensor: Tensor, **kwargs: Unpack[NDArrayParameters]) -> Sel
if tensor.free_indices > 0:
return cls(tensor, **kwargs)
else:
return cls._element_class(tensor, **kwargs)
return cls._element_class(tensor, **kwargs) # type: ignore[return-value]

@classmethod
def from_array(cls, array: npt.ArrayLike, **kwargs: Unpack[NDArrayParameters]) -> Self | T:
Expand All @@ -462,7 +463,7 @@ def from_array(cls, array: npt.ArrayLike, **kwargs: Unpack[NDArrayParameters]) -
try:
return cls(array, **kwargs)
except IncompatibleShapeError:
return cls._element_class(array, **kwargs)
return cls._element_class(array, **kwargs) # type: ignore[return-value]

def expand_dims(self, axis: int) -> Self:
"""Add a new index as a free index.
Expand Down
9 changes: 6 additions & 3 deletions geometer/curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import math
from abc import ABC
from itertools import combinations
from typing import TYPE_CHECKING, Union, cast
from typing import TYPE_CHECKING, Union, cast, overload

import numpy as np
import numpy.typing as npt
Expand Down Expand Up @@ -41,7 +41,7 @@
if TYPE_CHECKING:
from typing_extensions import Unpack

from geometer.utils.typing import NDArrayParameters
from geometer.utils.typing import NDArrayParameters, TensorParameters


class QuadricTensor(ProjectiveTensor, ABC):
Expand Down Expand Up @@ -69,7 +69,7 @@ def __init__(
matrix: Tensor | npt.ArrayLike,
is_dual: bool = False,
normalize_matrix: bool = False,
**kwargs: Unpack[NDArrayParameters],
**kwargs: Unpack[TensorParameters],
) -> None:
self.is_dual = is_dual

Expand Down Expand Up @@ -401,6 +401,9 @@ def from_crossratio(cls, cr: float, a: Point, b: Point, c: Point, d: Point) -> C

return cls(matrix, normalize_matrix=True)

@overload
def intersect(self, other: LineCollection) -> list[PointCollection]: ...

def intersect(self, other: Line | Conic) -> list[Point]:
"""Calculates points of intersection with the conic.

Expand Down
6 changes: 3 additions & 3 deletions geometer/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def harmonic_set(a: PointTensor, b: PointTensor, c: PointTensor) -> PointTensor:
return result


def angle(*args: PointTensor | LineTensor | PlaneTensor) -> npt.NDArray[np.float_]:
def angle(*args: PointTensor | LineTensor | PlaneTensor) -> npt.NDArray[np.float64]:
r"""Calculates the (oriented) angle between given points, lines or planes.

The function uses the Laguerre formula to calculate angles in two or three-dimensional projective space
Expand Down Expand Up @@ -271,7 +271,7 @@ def angle_bisectors(l: LineTensor, m: LineTensor) -> tuple[LineTensor, LineTenso
return join(o, r), join(o, s)


def _point_dist(p: PointTensor, q: PointTensor) -> npt.NDArray[np.float_]:
def _point_dist(p: PointTensor, q: PointTensor) -> npt.NDArray[np.float64]:
if p.dim > 2:
x = np.stack(np.broadcast_arrays(p.normalized_array, q.normalized_array), axis=-2)
z = x[..., -1]
Expand All @@ -294,7 +294,7 @@ def _point_dist(p: PointTensor, q: PointTensor) -> npt.NDArray[np.float_]:

def dist(
p: PointTensor | SubspaceTensor | PolytopeTensor, q: PointTensor | SubspaceTensor | PolytopeTensor
) -> npt.NDArray[np.float_]:
) -> npt.NDArray[np.float64]:
r"""Calculates the (euclidean) distance between two objects.

Instead of the usual formula for the euclidean distance this function uses
Expand Down
59 changes: 21 additions & 38 deletions geometer/point.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
if TYPE_CHECKING:
from typing_extensions import Literal, Unpack

from geometer.utils.typing import NDArrayParameters, TensorIndex
from geometer.utils.typing import NDArrayParameters, TensorIndex, TensorParameters

from geometer.base import (
EQ_TOL_ABS,
Expand All @@ -28,41 +28,37 @@
@overload
def _join_meet_duality(
*args: Unpack[tuple[SubspaceTensor, LineTensor]],
intersect_lines: Literal[True],
intersect_lines: Literal[True] = True,
check_dependence: bool = True,
normalize_result: bool = True,
) -> PointTensor:
...
) -> PointTensor: ...


@overload
def _join_meet_duality(
*args: Unpack[tuple[LineTensor, SubspaceTensor]],
intersect_lines: Literal[True],
intersect_lines: Literal[True] = True,
check_dependence: bool = True,
normalize_result: bool = True,
) -> PointTensor:
...
) -> PointTensor: ...


@overload
def _join_meet_duality(
*args: Unpack[tuple[PointTensor, PointTensor]],
intersect_lines: Literal[True],
intersect_lines: Literal[True] = True,
check_dependence: bool = True,
normalize_result: bool = True,
) -> LineTensor:
...
) -> LineTensor: ...


@overload
def _join_meet_duality(
*args: PointTensor | SubspaceTensor,
intersect_lines: Literal[False],
intersect_lines: Literal[False] = False,
check_dependence: bool = True,
normalize_result: bool = True,
) -> SubspaceTensor:
...
) -> SubspaceTensor: ...


def _join_meet_duality(
Expand Down Expand Up @@ -190,15 +186,13 @@ def _divide_by_power_of_two(array: np.ndarray, power: int) -> np.ndarray:
@overload
def join(
*args: Unpack[tuple[PointTensor, PointTensor]], _check_dependence: bool = True, _normalize_result: bool = True
) -> LineTensor:
...
) -> LineTensor: ...


@overload
def join(
*args: PointTensor | SubspaceTensor, _check_dependence: bool = True, _normalize_result: bool = True
) -> SubspaceTensor:
...
) -> SubspaceTensor: ...


def join(
Expand All @@ -223,22 +217,19 @@ def join(


@overload
def meet(*args: LineTensor, _check_dependence: bool = True, _normalize_result: bool = True) -> PointTensor:
...
def meet(*args: LineTensor, _check_dependence: bool = True, _normalize_result: bool = True) -> PointTensor: ...


@overload
def meet(
*args: Unpack[tuple[SubspaceTensor, LineTensor]], _check_dependence: bool = True, _normalize_result: bool = True
) -> PointTensor:
...
) -> PointTensor: ...


@overload
def meet(
*args: Unpack[tuple[LineTensor, SubspaceTensor]], _check_dependence: bool = True, _normalize_result: bool = True
) -> PointTensor:
...
) -> PointTensor: ...


def meet(
Expand Down Expand Up @@ -365,14 +356,12 @@ def __repr__(self) -> str:
return f"PointCollection({self.normalized_array.tolist()})"

@overload
def join(self, *others: Unpack[tuple[PointTensor, PointTensor]]) -> LineTensor:
...
def join(self, *others: Unpack[tuple[PointTensor, PointTensor]]) -> LineTensor: ...

@overload
def join(
self, *others: Unpack[tuple[PointTensor, SubspaceTensor]] | Unpack[tuple[SubspaceTensor, PointTensor]]
) -> SubspaceTensor:
...
) -> SubspaceTensor: ...

def join(self, *others: PointTensor | LineTensor) -> SubspaceTensor:
return join(self, *others)
Expand Down Expand Up @@ -419,19 +408,15 @@ class SubspaceTensor(ProjectiveTensor, ABC):

"""

def __init__(
self, *args: Tensor | npt.ArrayLike, tensor_rank: int = 1, **kwargs: Unpack[NDArrayParameters]
) -> None:
def __init__(self, *args: Tensor | npt.ArrayLike, tensor_rank: int = 1, **kwargs: Unpack[TensorParameters]) -> None:
kwargs.setdefault("covariant", False)
super().__init__(*args, tensor_rank=tensor_rank, **kwargs)

@overload
def meet(self, other: LineTensor) -> PointTensor:
...
def meet(self, other: LineTensor) -> PointTensor: ...

@overload
def meet(self, other: SubspaceTensor) -> PointTensor | SubspaceTensor:
...
def meet(self, other: SubspaceTensor) -> PointTensor | SubspaceTensor: ...

def meet(self, other: SubspaceTensor) -> PointTensor | SubspaceTensor:
return meet(self, other)
Expand Down Expand Up @@ -883,12 +868,10 @@ def mirror(self, pt: PointTensor) -> PointTensor:
return m1.meet(m2)

@overload
def perpendicular(self, through: PointTensor) -> LineTensor:
...
def perpendicular(self, through: PointTensor) -> LineTensor: ...

@overload
def perpendicular(self, through: LineTensor) -> PlaneTensor:
...
def perpendicular(self, through: LineTensor) -> PlaneTensor: ...

def perpendicular(self, through: PointTensor | LineTensor) -> LineTensor | PlaneTensor:
"""Construct the perpendicular lines though the given points or the perpendicular planes through the given lines.
Expand Down
Loading
Loading