Metadata-Version: 2.4
Name: rbca
Version: 0.1.0
Summary: Recursive Binary Cosine Approximation
Project-URL: Homepage, https://github.com/Imagination12357/rbca
Project-URL: Repository, https://github.com/Imagination12357/rbca
Project-URL: Issues, https://github.com/Imagination12357/rbca/issues
Author: imagination12357
License: MIT
License-File: LICENSE
Keywords: approximation,symbolic-math,sympy,trigonometry
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.10
Requires-Dist: sympy>=1.10.0
Description-Content-Type: text/markdown

# rbca

`rbca` (Recursive Binary Cosine Approximation) is a trigonometric approximation library with both symbolic and float APIs.

It computes `cos`, `sin`, and `tan` through recursive binary partitioning on angles.

The default APIs keep expressions in exact symbolic form (SymPy `Expr`) instead of forcing early floating-point evaluation. The `_float` APIs use float arithmetic internally for practical numeric calculation.

Current package version is `0.1.0`.

## Features

- Symbolic trig outputs using SymPy expressions
- Practical float trig outputs using float arithmetic
- Recursive midpoint-based approximation for angle intervals
- Angle normalization over full `0~360` degree input range
- Three API families:
  - `calc_*_pure`: mathematically pure symbolic recursion from `0` to `90`
  - `calc_*`: symbolic recursion seeded with well-known anchor angles (`0, 15, 30, 45, 60, 75`)
  - `calc_*_float`: practical float calculation using the same anchor strategy as `calc_*`

## Installation

### Using `pip`

```bash
pip install rbca
```

### Local development (this repository)

```bash
pip install -e .
```

Project requirements:
- Python `>=3.10`
- `sympy>=1.10.0`

## Quick Start

```python
from rbca import calc_cos, calc_cos_float, calc_sin, calc_sin_float, calc_tan
from sympy import sqrtdenest

depth = 5

cos_expr = calc_cos(37, depth)      # SymPy Expr
sin_expr = calc_sin(37, depth)      # SymPy Expr
tan_expr = calc_tan(37, depth)      # SymPy Expr

cos_value = calc_cos_float(37, depth)  # float
sin_value = calc_sin_float(37, depth)  # float

print(cos_expr)                     # symbolic expression
print(float(cos_expr))              # numeric projection
print(sqrtdenest(cos_expr))         # optional radical denesting
print(cos_value)                    # practical float result
```

## Choosing an API Family

- Use `calc_cos_pure`, `calc_sin_pure`, and `calc_tan_pure` when you want the mathematically pure symbolic path.
  - This path starts from `[0, 90]` only.
- Use `calc_cos`, `calc_sin`, and `calc_tan` when you want symbolic results with a more practical anchored start.
  - This path uses anchor angles (`0, 15, 30, 45, 60, 75, 90`) to start from a narrower interval.
- Use `calc_cos_float`, `calc_sin_float`, and `calc_tan_float` when you want practical float results.
  - This path is implemented with float arithmetic internally.

## Core API

- `calc_cos(angle, depth) -> Expr`
- `calc_sin(angle, depth) -> Expr`
- `calc_tan(angle, depth) -> Expr`

- `calc_cos_pure(angle, depth) -> Expr`
- `calc_sin_pure(angle, depth) -> Expr`
- `calc_tan_pure(angle, depth) -> Expr`

- `calc_cos_float(angle, depth) -> float`
- `calc_sin_float(angle, depth) -> float`
- `calc_tan_float(angle, depth) -> float`

For symbolic APIs, `angle` accepts `Rational | int | float | str` and is internally converted with `sympy.Rational` where needed.

Symbolic input note:
- `float` inputs are converted through `Rational(float_value)`, which can preserve binary-float artifacts.
- For exact decimal intent, prefer `str` or `Rational` directly.
  - Example: use `"0.1"` instead of `0.1`.

For float APIs, `angle` accepts `int | float | str` and is internally converted with `float(angle)`.

`depth` is recursion depth:
- `depth = 0`: return one of the current interval endpoints
- larger depth: finer binary partitioning and generally tighter approximation

## How It Works

1. Normalize input angle to first quadrant (`0~90`) and track output sign.
2. Choose initial bracket interval:
   - `calc_cos_pure`: `[0, 90]`
   - `calc_cos`: narrower interval between predefined anchor angles when possible.
   - `calc_cos_float`: same anchored interval strategy as `calc_cos`, but with float nodes and float values.
3. Recursively bisect the interval by midpoint angle.
4. Compute midpoint cosine via:
   - a product/half-angle style expression using endpoint cosine values.
5. Recurse until `depth == 0` (or exact angle hit), then apply sign flip if needed.

## Notes and Limitations

- This library is symbolic-first; expressions can grow quickly as depth increases.
- For angles where cosine is zero (e.g. `90 + 180k` degrees), `calc_tan` and `calc_tan_pure` return `sympy.zoo`.
- For the same tangent singularities, `calc_tan_float` lets Python's `ZeroDivisionError` propagate.
- Inputs with symbolic free variables are rejected during normalization.

## Maths
Condition:

$$
0^\circ \le A,B \le 90^\circ
$$

Using the half-angle formula,

$$
\cos\frac{A+B}{2}
=
\sqrt{\frac{1+\cos(A+B)}{2}}
$$

Also, by the angle addition formula,

$$
\cos(A+B)
=
\cos A\cos B-\sin A\sin B
$$

Since

$$
0^\circ \le A,B \le 90^\circ
$$

we can use

$$
\sin A=\sqrt{1-\cos^2 A}
$$

and

$$
\sin B=\sqrt{1-\cos^2 B}
$$

Therefore,

$$
\cos(A+B)
=
\cos A\cos B
-
\sqrt{(1-\cos^2 A)(1-\cos^2 B)}
$$

Substituting this into the half-angle formula finally gives

$$
\boxed{
\cos\frac{A+B}{2}
=
\sqrt{
\frac{
1+\cos A\cos B-\sqrt{(1-\cos^2 A)(1-\cos^2 B)}
}{2}
}
}
$$

## License

MIT License. See [`LICENSE`](./LICENSE).
