pymathutils


Namepymathutils JSON
Version 0.1.3 PyPI version JSON
download
home_pageNone
SummaryFast mathematical utilities
upload_time2025-07-29 22:24:26
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseMIT
keywords mathematics scientific-computing numerical-methods
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # MathUtils

mathematical utilities with C++ backend for high-performance numerical computations.



# Create build venv
python -m venv .venv/mathutils_build
source .venv/mathutils_build/bin/activate
pip install build twine
# Clean previous builds
rm -rf dist/ build/ *.egg-info .venv/mathutils_test
# Build source distribution and wheel
python -m build
# Verify files were created
ls -la dist/
# Check package validity
python -m twine check dist/*
# Upload only .tar.gz to avoid platform-specific wheel issues
python -m twine upload dist/*.tar.gz
# test
deactivate
python -m venv .venv/mathutils_test
source .venv/mathutils_test/bin/activate
pip install -r requirements_testing.txt




<!-- # MathUtils

Fast mathematical utilities with optimized C++ backend for high-performance numerical computations.

## Features

- **Fast factorial computations**: Optimized log-factorial with lookup tables
- **Spherical harmonics**: High-performance Ylm calculations  
- **C++ backend**: Optimized implementations with Python bindings
- **NumPy integration**: Seamless array operations
- **Vectorized operations**: Process arrays efficiently

## Installation

```bash
pip install mathutils-fast
```

## Quick Start

```python
import mathutils
import numpy as np

# Fast log factorial
result = mathutils.log_factorial(100)
print(f"log(100!) = {result}")

# Vectorized spherical harmonics
theta = np.linspace(0, np.pi, 100)
phi = np.linspace(0, 2*np.pi, 100)
ylm = mathutils.Ylm_vectorized(2, 1, theta, phi)
print(f"Y_2^1 shape: {ylm.shape}, dtype: {ylm.dtype}")
```

## Spherical Harmonics

The spherical harmonics $Y_{\ell}^m(\theta, \phi)$ are defined as:

$$
Y_{\ell}^m(\theta, \phi) = \sqrt{\frac{2\ell+1}{4\pi} \frac{(\ell-|m|)!}{(\ell+|m|)!}} P_{\ell}^{|m|}(\cos\theta) e^{im\phi}
$$

where:
- $\ell \geq 0$ is the degree (angular momentum quantum number)
- $-\ell \leq m \leq \ell$ is the order (magnetic quantum number)  
- $P_{\ell}^{|m|}$ are the associated Legendre polynomials
- $\theta \in [0, \pi]$ is the polar angle
- $\phi \in [0, 2\pi]$ is the azimuthal angle

From the Herglotz generating function, we find
$$
e^{-im\phi}Y_{\ell}^m(\theta, \phi)
= 
r_{\ell, m, \theta}
\sum_{k=1}^{k_{max}}
Q_{k}
$$

$$
\log(q_0)
=
(1/2)\log(2\ell+1)
+
(1/2)\log((\ell+|m|)!)
-(1/2)\log((\ell-|m|)!)
-\log(|m|!)
-|m|\log(2)
$$

$$
\log(q_k)
=
(\ell-|m|)\log|\cos\theta|
+
|m|\log|\sin\theta|
$$

where:
- $k_{max} = \lfloor(\ell-|m|)/2\rfloor$ 

$$
e^{-im\phi}Y_{\ell}^m(\theta, \phi)
= 
(-1)^{(m+|m|)/2}
\sqrt{
\frac{
(2\ell+1)(\ell+|m|)!(\ell-|m|)!
}{
4^{|m|+1}
\pi
}
}
\sum_{k=0?}^{\lfloor(\ell-m)/2\rfloor}
\frac{
(-1)^k
\cos[k](\theta)
}
{
4^k
(\ell-|m|-2k)!
(|m|+k)!
k!
}
$$




### Special Properties

- **Orthonormality**: $\int_0^{2\pi} d\phi \int_0^{\pi} \sin\theta \, d\theta \, Y_{\ell}^m(\theta,\phi)^* Y_{\ell'}^{m'}(\theta,\phi) = \delta_{\ell\ell'}\delta_{mm'}$
- **Completeness**: Any function on the sphere can be expanded in spherical harmonics
- **Symmetry**: $Y_{\ell}^{-m}(\theta,\phi) = (-1)^m [Y_{\ell}^m(\theta,\phi)]^*$

## API Reference

### Core Functions

#### `log_factorial(n)`
Compute the natural logarithm of n!

```python
result = mathutils.log_factorial(50)  # Uses optimized C++ implementation
```

**Parameters:**
- `n` (int): Non-negative integer

**Returns:**
- `float`: ln(n!)

#### `Ylm_vectorized(l, m, theta, phi)`
Compute spherical harmonics for arrays of angles

```python
theta = np.linspace(0, np.pi, 50)
phi = np.linspace(0, 2*np.pi, 100)
ylm = mathutils.Ylm_vectorized(3, 2, theta, phi)
```

**Parameters:**
- `l` (int): Degree (l ≥ 0)
- `m` (int): Order (-l ≤ m ≤ l)
- `theta` (array_like): Polar angles in radians
- `phi` (array_like): Azimuthal angles in radians

**Returns:**
- `ndarray`: Complex array of Y_l^m values

### Indexing Functions

#### `spherical_harmonic_index_n_LM(l, m)`
Convert (l,m) quantum numbers to linear index

```python
index = mathutils.spherical_harmonic_index_n_LM(2, 1)  # Returns 5
```

#### `spherical_harmonic_index_lm_N(n)`
Convert linear index back to (l,m) quantum numbers

```python
l, m = mathutils.spherical_harmonic_index_lm_N(5)  # Returns (2, 1)
```

## Performance

MathUtils provides significant speedups over pure Python implementations:

```python
import time
import numpy as np
import mathutils

# Benchmark log_factorial
n = 1000
start = time.time()
for i in range(10000):
    result = mathutils.log_factorial(n)
cpp_time = time.time() - start

# Compare with Python
import math
start = time.time()
for i in range(10000):
    result = math.lgamma(n + 1)
python_time = time.time() - start

print(f"Speedup: {python_time/cpp_time:.2f}x")
```

## Examples

### Plotting Spherical Harmonics

```python
import numpy as np
import matplotlib.pyplot as plt
import mathutils

# Create sphere coordinates
theta = np.linspace(0, np.pi, 100)
phi = np.linspace(0, 2*np.pi, 200)
theta_grid, phi_grid = np.meshgrid(theta, phi, indexing='ij')

# Compute Y_2^1
l, m = 2, 1
ylm = mathutils.Ylm_vectorized(l, m, theta_grid.flatten(), phi_grid.flatten())
ylm = ylm.reshape(theta_grid.shape)

# Plot real part
fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
x = np.sin(theta_grid) * np.cos(phi_grid)
y = np.sin(theta_grid) * np.sin(phi_grid)  
z = np.cos(theta_grid)

colors = plt.cm.seismic(ylm.real / np.max(np.abs(ylm.real)))
ax.plot_surface(x, y, z, facecolors=colors, alpha=0.8)
ax.set_title(f'$Y_{{{l}}}^{{{m}}}$ (Real Part)')
plt.show()
```

### Spherical Harmonic Analysis

```python
import numpy as np
import mathutils

def analyze_function_on_sphere(func, l_max=10):
    """Decompose a function into spherical harmonic coefficients."""
    
    # Create integration grid
    n_theta, n_phi = 2*l_max+1, 4*l_max+1
    theta = np.linspace(0, np.pi, n_theta)
    phi = np.linspace(0, 2*np.pi, n_phi)
    theta_grid, phi_grid = np.meshgrid(theta, phi, indexing='ij')
    
    # Evaluate function on grid
    f_values = func(theta_grid, phi_grid)
    
    # Compute coefficients
    coefficients = {}
    for l in range(l_max + 1):
        for m in range(-l, l + 1):
            ylm = mathutils.Ylm_vectorized(l, m, theta_grid.flatten(), phi_grid.flatten())
            ylm = ylm.reshape(theta_grid.shape)
            
            # Numerical integration
            integrand = f_values * np.conj(ylm) * np.sin(theta_grid)
            coeff = np.trapz(np.trapz(integrand, phi), theta)
            coefficients[(l, m)] = coeff
    
    return coefficients

# Example: analyze a simple function
def my_function(theta, phi):
    return np.cos(theta) + np.sin(theta) * np.cos(phi)

coeffs = analyze_function_on_sphere(my_function, l_max=5)
print("Dominant coefficients:")
for (l, m), coeff in sorted(coeffs.items(), key=lambda x: abs(x[1]), reverse=True)[:5]:
    print(f"Y_{l}^{m}: {coeff:.6f}")
```

## Requirements

- Python ≥ 3.8
- NumPy ≥ 1.20.0
- C++17 compatible compiler (for building from source)

## Building from Source

```bash
git clone https://github.com/yourusername/mathutils.git
cd mathutils
pip install -e .
```

### Dependencies for Building
- CMake ≥ 3.15
- Eigen3 library
- pybind11

## Testing

```bash
# Install test dependencies
pip install pytest numpy

# Run tests
pytest tests/
```

## Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Citation

If you use MathUtils in your research, please cite:

```bibtex
@software{mathutils2024,
  title={MathUtils: Fast Mathematical Utilities with C++ Backend},
  author={Your Name},
  year={2024},
  url={https://github.com/yourusername/mathutils}
}
```

## Acknowledgments

- Built with [pybind11](https://github.com/pybind/pybind11)
- Uses [Eigen](https://eigen.tuxfamily.org/) for linear algebra
- Inspired by [SciPy](https://scipy.org/) special functions


# Step-by-Step Guide: Publishing Python Package with C++ Extensions to PyPI

## Prerequisites
- Python package with C++ extensions (using pybind11)
- GitHub repository
- C++ code compiles successfully locally

## Step 1: Package Configuration

### 1.1 Create/Update `pyproject.toml`
```toml
[build-system]
requires = ["setuptools>=61.0", "pybind11", "numpy"]
build-backend = "setuptools.build_meta"

[project]
name = "your-unique-package-name"  # Check if name is available on PyPI
version = "0.1.0"
description = "Your package description"
authors = [{ name = "Your Name", email = "your.email@example.com" }]
license = {text = "MIT"}
readme = "README.md"
requires-python = ">=3.7"
dependencies = ["numpy", "scipy"]  # Add your dependencies
keywords = ["mathematics", "scientific-computing"]
classifiers = [
    "Development Status :: 3 - Alpha",
    "Intended Audience :: Science/Research",
    "Programming Language :: Python :: 3",
    "Topic :: Scientific/Engineering :: Mathematics",
]

[project.urls]
Homepage = "https://github.com/yourusername/yourrepo"
Repository = "https://github.com/yourusername/yourrepo"
Issues = "https://github.com/yourusername/yourrepo/issues"

[project.optional-dependencies]
dev = ["pytest", "build", "twine"]

[tool.setuptools]
packages = ["your_module_name"]

[tool.setuptools.package-dir]
your_module_name = "your_module_name"
```

### 1.2 Create `MANIFEST.in`
```plaintext
include README.md
include pyproject.toml
recursive-include include *.hpp
recursive-include src *.cpp
```

### 1.3 Fix `__init__.py` imports
```python
"""Your Package - Description."""

try:
    from .your_backend import *
except ImportError as e:
    raise ImportError(f"Failed to import C++ backend: {e}")

__version__ = "0.1.0"
```

### 1.4 Ensure `setup.py` has correct paths
```python
from setuptools import setup, Extension
from pybind11.setup_helpers import Pybind11Extension, build_ext
import pybind11

ext_modules = [
    Pybind11Extension(
        "your_module.your_backend",
        ["src/cpp/bindings.cpp"],
        include_dirs=[
            "include",
            "/usr/include/eigen3",  # If using Eigen
        ],
        cxx_std=17,
        define_macros=[("VERSION_INFO", '"dev"')],
    ),
]

setup(
    ext_modules=ext_modules,
    cmdclass={"build_ext": build_ext},
    zip_safe=False,
)
```

## Step 2: Build Setup

### 2.1 Install build tools
```bash
pip install build twine
```

### 2.2 Clean and build package
```bash
# Clean previous builds
rm -rf dist/ build/ *.egg-info

# Build source distribution and wheel
python -m build
```

### 2.3 Check build results
```bash
# Verify files were created
ls -la dist/

# Check package validity
python -m twine check dist/*
```

## Step 3: PyPI Account Setup

### 3.1 Create PyPI account
- Go to https://pypi.org/account/register/
- Create account and verify email

### 3.2 Create API token
- Go to https://pypi.org/manage/account/token/
- Create new token with scope "Entire account"
- Copy the token (starts with `pypi-`)

## Step 4: Upload to PyPI

### 4.1 Upload source distribution only
```bash
# Upload only .tar.gz to avoid platform-specific wheel issues
python -m twine upload dist/*.tar.gz
```

### 4.2 Enter credentials when prompted
- Username: `__token__`
- Password: Your API token

## Step 5: Test Installation

### 5.1 Test install
```bash
pip install your-package-name
```

### 5.2 Test import
```python
import your_module
print("Success!")
```

## Step 6: (Optional) GitHub Actions for Automated Publishing

### 6.1 Create `.github/workflows/publish.yml`
```yaml
name: Publish to PyPI

on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.11'
    
    - name: Install system dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y libeigen3-dev  # If using Eigen
    
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install build twine
    
    - name: Build package
      run: python -m build
    
    - name: Publish to PyPI
      env:
        TWINE_USERNAME: __token__
        TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
      run: twine upload dist/*.tar.gz
```

### 6.2 Add PyPI token to GitHub secrets
- Go to GitHub repo → Settings → Secrets and variables → Actions
- Add secret: `PYPI_API_TOKEN` = your PyPI token

## Step 7: Future Releases

### 7.1 For new versions
```bash
# 1. Update version in pyproject.toml
# 2. Clean and rebuild
rm -rf dist/ build/ *.egg-info
python -m build

# 3. Upload
python -m twine upload dist/*.tar.gz
```

### 7.2 Or use GitHub releases (if using Actions)
- Create new GitHub release with tag like `v0.2.0`
- GitHub Actions will automatically publish to PyPI

## Common Issues and Solutions

### Issue: "Binary wheel has unsupported platform tag"
**Solution**: Upload only source distribution (`*.tar.gz`)

### Issue: "Invalid authentication"
**Solutions**:
- Verify email on PyPI
- Create fresh API token
- Use `__token__` as username

### Issue: "Package name already exists"
**Solution**: Choose unique name like `yourpackage-username`

### Issue: C++ compilation fails
**Solutions**:
- Check `include_dirs` in `setup.py`
- Ensure `MANIFEST.in` includes all necessary files
- Install system dependencies (like Eigen)

## Verification Checklist

- [ ] Package builds successfully (`python -m build`)
- [ ] Package checks pass (`python -m twine check dist/*`)
- [ ] PyPI account created and email verified
- [ ] API token created and saved
- [ ] Package name is unique
- [ ] Upload successful
- [ ] Package installs via pip
- [ ] Package imports correctly

## Result

Your package will be available at:
`https://pypi.org/project/your-package-name/`

Users can install with:
```bash
pip install your-package-name
``` -->



            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "pymathutils",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "mathematics, scientific-computing, numerical-methods",
    "author": null,
    "author_email": "wlough <wilson.lough@colorado.edu>",
    "download_url": "https://files.pythonhosted.org/packages/12/99/75bbabb1f0875e0013fb4e4789ef5d09b5720ba3900fb5afa3bac34a2b02/pymathutils-0.1.3.tar.gz",
    "platform": null,
    "description": "# MathUtils\n\nmathematical utilities with C++ backend for high-performance numerical computations.\n\n\n\n# Create build venv\npython -m venv .venv/mathutils_build\nsource .venv/mathutils_build/bin/activate\npip install build twine\n# Clean previous builds\nrm -rf dist/ build/ *.egg-info .venv/mathutils_test\n# Build source distribution and wheel\npython -m build\n# Verify files were created\nls -la dist/\n# Check package validity\npython -m twine check dist/*\n# Upload only .tar.gz to avoid platform-specific wheel issues\npython -m twine upload dist/*.tar.gz\n# test\ndeactivate\npython -m venv .venv/mathutils_test\nsource .venv/mathutils_test/bin/activate\npip install -r requirements_testing.txt\n\n\n\n\n<!-- # MathUtils\n\nFast mathematical utilities with optimized C++ backend for high-performance numerical computations.\n\n## Features\n\n- **Fast factorial computations**: Optimized log-factorial with lookup tables\n- **Spherical harmonics**: High-performance Ylm calculations  \n- **C++ backend**: Optimized implementations with Python bindings\n- **NumPy integration**: Seamless array operations\n- **Vectorized operations**: Process arrays efficiently\n\n## Installation\n\n```bash\npip install mathutils-fast\n```\n\n## Quick Start\n\n```python\nimport mathutils\nimport numpy as np\n\n# Fast log factorial\nresult = mathutils.log_factorial(100)\nprint(f\"log(100!) = {result}\")\n\n# Vectorized spherical harmonics\ntheta = np.linspace(0, np.pi, 100)\nphi = np.linspace(0, 2*np.pi, 100)\nylm = mathutils.Ylm_vectorized(2, 1, theta, phi)\nprint(f\"Y_2^1 shape: {ylm.shape}, dtype: {ylm.dtype}\")\n```\n\n## Spherical Harmonics\n\nThe spherical harmonics $Y_{\\ell}^m(\\theta, \\phi)$ are defined as:\n\n$$\nY_{\\ell}^m(\\theta, \\phi) = \\sqrt{\\frac{2\\ell+1}{4\\pi} \\frac{(\\ell-|m|)!}{(\\ell+|m|)!}} P_{\\ell}^{|m|}(\\cos\\theta) e^{im\\phi}\n$$\n\nwhere:\n- $\\ell \\geq 0$ is the degree (angular momentum quantum number)\n- $-\\ell \\leq m \\leq \\ell$ is the order (magnetic quantum number)  \n- $P_{\\ell}^{|m|}$ are the associated Legendre polynomials\n- $\\theta \\in [0, \\pi]$ is the polar angle\n- $\\phi \\in [0, 2\\pi]$ is the azimuthal angle\n\nFrom the Herglotz generating function, we find\n$$\ne^{-im\\phi}Y_{\\ell}^m(\\theta, \\phi)\n= \nr_{\\ell, m, \\theta}\n\\sum_{k=1}^{k_{max}}\nQ_{k}\n$$\n\n$$\n\\log(q_0)\n=\n(1/2)\\log(2\\ell+1)\n+\n(1/2)\\log((\\ell+|m|)!)\n-(1/2)\\log((\\ell-|m|)!)\n-\\log(|m|!)\n-|m|\\log(2)\n$$\n\n$$\n\\log(q_k)\n=\n(\\ell-|m|)\\log|\\cos\\theta|\n+\n|m|\\log|\\sin\\theta|\n$$\n\nwhere:\n- $k_{max} = \\lfloor(\\ell-|m|)/2\\rfloor$ \n\n$$\ne^{-im\\phi}Y_{\\ell}^m(\\theta, \\phi)\n= \n(-1)^{(m+|m|)/2}\n\\sqrt{\n\\frac{\n(2\\ell+1)(\\ell+|m|)!(\\ell-|m|)!\n}{\n4^{|m|+1}\n\\pi\n}\n}\n\\sum_{k=0?}^{\\lfloor(\\ell-m)/2\\rfloor}\n\\frac{\n(-1)^k\n\\cos[k](\\theta)\n}\n{\n4^k\n(\\ell-|m|-2k)!\n(|m|+k)!\nk!\n}\n$$\n\n\n\n\n### Special Properties\n\n- **Orthonormality**: $\\int_0^{2\\pi} d\\phi \\int_0^{\\pi} \\sin\\theta \\, d\\theta \\, Y_{\\ell}^m(\\theta,\\phi)^* Y_{\\ell'}^{m'}(\\theta,\\phi) = \\delta_{\\ell\\ell'}\\delta_{mm'}$\n- **Completeness**: Any function on the sphere can be expanded in spherical harmonics\n- **Symmetry**: $Y_{\\ell}^{-m}(\\theta,\\phi) = (-1)^m [Y_{\\ell}^m(\\theta,\\phi)]^*$\n\n## API Reference\n\n### Core Functions\n\n#### `log_factorial(n)`\nCompute the natural logarithm of n!\n\n```python\nresult = mathutils.log_factorial(50)  # Uses optimized C++ implementation\n```\n\n**Parameters:**\n- `n` (int): Non-negative integer\n\n**Returns:**\n- `float`: ln(n!)\n\n#### `Ylm_vectorized(l, m, theta, phi)`\nCompute spherical harmonics for arrays of angles\n\n```python\ntheta = np.linspace(0, np.pi, 50)\nphi = np.linspace(0, 2*np.pi, 100)\nylm = mathutils.Ylm_vectorized(3, 2, theta, phi)\n```\n\n**Parameters:**\n- `l` (int): Degree (l \u2265 0)\n- `m` (int): Order (-l \u2264 m \u2264 l)\n- `theta` (array_like): Polar angles in radians\n- `phi` (array_like): Azimuthal angles in radians\n\n**Returns:**\n- `ndarray`: Complex array of Y_l^m values\n\n### Indexing Functions\n\n#### `spherical_harmonic_index_n_LM(l, m)`\nConvert (l,m) quantum numbers to linear index\n\n```python\nindex = mathutils.spherical_harmonic_index_n_LM(2, 1)  # Returns 5\n```\n\n#### `spherical_harmonic_index_lm_N(n)`\nConvert linear index back to (l,m) quantum numbers\n\n```python\nl, m = mathutils.spherical_harmonic_index_lm_N(5)  # Returns (2, 1)\n```\n\n## Performance\n\nMathUtils provides significant speedups over pure Python implementations:\n\n```python\nimport time\nimport numpy as np\nimport mathutils\n\n# Benchmark log_factorial\nn = 1000\nstart = time.time()\nfor i in range(10000):\n    result = mathutils.log_factorial(n)\ncpp_time = time.time() - start\n\n# Compare with Python\nimport math\nstart = time.time()\nfor i in range(10000):\n    result = math.lgamma(n + 1)\npython_time = time.time() - start\n\nprint(f\"Speedup: {python_time/cpp_time:.2f}x\")\n```\n\n## Examples\n\n### Plotting Spherical Harmonics\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport mathutils\n\n# Create sphere coordinates\ntheta = np.linspace(0, np.pi, 100)\nphi = np.linspace(0, 2*np.pi, 200)\ntheta_grid, phi_grid = np.meshgrid(theta, phi, indexing='ij')\n\n# Compute Y_2^1\nl, m = 2, 1\nylm = mathutils.Ylm_vectorized(l, m, theta_grid.flatten(), phi_grid.flatten())\nylm = ylm.reshape(theta_grid.shape)\n\n# Plot real part\nfig, ax = plt.subplots(subplot_kw=dict(projection='3d'))\nx = np.sin(theta_grid) * np.cos(phi_grid)\ny = np.sin(theta_grid) * np.sin(phi_grid)  \nz = np.cos(theta_grid)\n\ncolors = plt.cm.seismic(ylm.real / np.max(np.abs(ylm.real)))\nax.plot_surface(x, y, z, facecolors=colors, alpha=0.8)\nax.set_title(f'$Y_{{{l}}}^{{{m}}}$ (Real Part)')\nplt.show()\n```\n\n### Spherical Harmonic Analysis\n\n```python\nimport numpy as np\nimport mathutils\n\ndef analyze_function_on_sphere(func, l_max=10):\n    \"\"\"Decompose a function into spherical harmonic coefficients.\"\"\"\n    \n    # Create integration grid\n    n_theta, n_phi = 2*l_max+1, 4*l_max+1\n    theta = np.linspace(0, np.pi, n_theta)\n    phi = np.linspace(0, 2*np.pi, n_phi)\n    theta_grid, phi_grid = np.meshgrid(theta, phi, indexing='ij')\n    \n    # Evaluate function on grid\n    f_values = func(theta_grid, phi_grid)\n    \n    # Compute coefficients\n    coefficients = {}\n    for l in range(l_max + 1):\n        for m in range(-l, l + 1):\n            ylm = mathutils.Ylm_vectorized(l, m, theta_grid.flatten(), phi_grid.flatten())\n            ylm = ylm.reshape(theta_grid.shape)\n            \n            # Numerical integration\n            integrand = f_values * np.conj(ylm) * np.sin(theta_grid)\n            coeff = np.trapz(np.trapz(integrand, phi), theta)\n            coefficients[(l, m)] = coeff\n    \n    return coefficients\n\n# Example: analyze a simple function\ndef my_function(theta, phi):\n    return np.cos(theta) + np.sin(theta) * np.cos(phi)\n\ncoeffs = analyze_function_on_sphere(my_function, l_max=5)\nprint(\"Dominant coefficients:\")\nfor (l, m), coeff in sorted(coeffs.items(), key=lambda x: abs(x[1]), reverse=True)[:5]:\n    print(f\"Y_{l}^{m}: {coeff:.6f}\")\n```\n\n## Requirements\n\n- Python \u2265 3.8\n- NumPy \u2265 1.20.0\n- C++17 compatible compiler (for building from source)\n\n## Building from Source\n\n```bash\ngit clone https://github.com/yourusername/mathutils.git\ncd mathutils\npip install -e .\n```\n\n### Dependencies for Building\n- CMake \u2265 3.15\n- Eigen3 library\n- pybind11\n\n## Testing\n\n```bash\n# Install test dependencies\npip install pytest numpy\n\n# Run tests\npytest tests/\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Citation\n\nIf you use MathUtils in your research, please cite:\n\n```bibtex\n@software{mathutils2024,\n  title={MathUtils: Fast Mathematical Utilities with C++ Backend},\n  author={Your Name},\n  year={2024},\n  url={https://github.com/yourusername/mathutils}\n}\n```\n\n## Acknowledgments\n\n- Built with [pybind11](https://github.com/pybind/pybind11)\n- Uses [Eigen](https://eigen.tuxfamily.org/) for linear algebra\n- Inspired by [SciPy](https://scipy.org/) special functions\n\n\n# Step-by-Step Guide: Publishing Python Package with C++ Extensions to PyPI\n\n## Prerequisites\n- Python package with C++ extensions (using pybind11)\n- GitHub repository\n- C++ code compiles successfully locally\n\n## Step 1: Package Configuration\n\n### 1.1 Create/Update `pyproject.toml`\n```toml\n[build-system]\nrequires = [\"setuptools>=61.0\", \"pybind11\", \"numpy\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"your-unique-package-name\"  # Check if name is available on PyPI\nversion = \"0.1.0\"\ndescription = \"Your package description\"\nauthors = [{ name = \"Your Name\", email = \"your.email@example.com\" }]\nlicense = {text = \"MIT\"}\nreadme = \"README.md\"\nrequires-python = \">=3.7\"\ndependencies = [\"numpy\", \"scipy\"]  # Add your dependencies\nkeywords = [\"mathematics\", \"scientific-computing\"]\nclassifiers = [\n    \"Development Status :: 3 - Alpha\",\n    \"Intended Audience :: Science/Research\",\n    \"Programming Language :: Python :: 3\",\n    \"Topic :: Scientific/Engineering :: Mathematics\",\n]\n\n[project.urls]\nHomepage = \"https://github.com/yourusername/yourrepo\"\nRepository = \"https://github.com/yourusername/yourrepo\"\nIssues = \"https://github.com/yourusername/yourrepo/issues\"\n\n[project.optional-dependencies]\ndev = [\"pytest\", \"build\", \"twine\"]\n\n[tool.setuptools]\npackages = [\"your_module_name\"]\n\n[tool.setuptools.package-dir]\nyour_module_name = \"your_module_name\"\n```\n\n### 1.2 Create `MANIFEST.in`\n```plaintext\ninclude README.md\ninclude pyproject.toml\nrecursive-include include *.hpp\nrecursive-include src *.cpp\n```\n\n### 1.3 Fix `__init__.py` imports\n```python\n\"\"\"Your Package - Description.\"\"\"\n\ntry:\n    from .your_backend import *\nexcept ImportError as e:\n    raise ImportError(f\"Failed to import C++ backend: {e}\")\n\n__version__ = \"0.1.0\"\n```\n\n### 1.4 Ensure `setup.py` has correct paths\n```python\nfrom setuptools import setup, Extension\nfrom pybind11.setup_helpers import Pybind11Extension, build_ext\nimport pybind11\n\next_modules = [\n    Pybind11Extension(\n        \"your_module.your_backend\",\n        [\"src/cpp/bindings.cpp\"],\n        include_dirs=[\n            \"include\",\n            \"/usr/include/eigen3\",  # If using Eigen\n        ],\n        cxx_std=17,\n        define_macros=[(\"VERSION_INFO\", '\"dev\"')],\n    ),\n]\n\nsetup(\n    ext_modules=ext_modules,\n    cmdclass={\"build_ext\": build_ext},\n    zip_safe=False,\n)\n```\n\n## Step 2: Build Setup\n\n### 2.1 Install build tools\n```bash\npip install build twine\n```\n\n### 2.2 Clean and build package\n```bash\n# Clean previous builds\nrm -rf dist/ build/ *.egg-info\n\n# Build source distribution and wheel\npython -m build\n```\n\n### 2.3 Check build results\n```bash\n# Verify files were created\nls -la dist/\n\n# Check package validity\npython -m twine check dist/*\n```\n\n## Step 3: PyPI Account Setup\n\n### 3.1 Create PyPI account\n- Go to https://pypi.org/account/register/\n- Create account and verify email\n\n### 3.2 Create API token\n- Go to https://pypi.org/manage/account/token/\n- Create new token with scope \"Entire account\"\n- Copy the token (starts with `pypi-`)\n\n## Step 4: Upload to PyPI\n\n### 4.1 Upload source distribution only\n```bash\n# Upload only .tar.gz to avoid platform-specific wheel issues\npython -m twine upload dist/*.tar.gz\n```\n\n### 4.2 Enter credentials when prompted\n- Username: `__token__`\n- Password: Your API token\n\n## Step 5: Test Installation\n\n### 5.1 Test install\n```bash\npip install your-package-name\n```\n\n### 5.2 Test import\n```python\nimport your_module\nprint(\"Success!\")\n```\n\n## Step 6: (Optional) GitHub Actions for Automated Publishing\n\n### 6.1 Create `.github/workflows/publish.yml`\n```yaml\nname: Publish to PyPI\n\non:\n  release:\n    types: [published]\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v4\n    \n    - name: Set up Python\n      uses: actions/setup-python@v4\n      with:\n        python-version: '3.11'\n    \n    - name: Install system dependencies\n      run: |\n        sudo apt-get update\n        sudo apt-get install -y libeigen3-dev  # If using Eigen\n    \n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install build twine\n    \n    - name: Build package\n      run: python -m build\n    \n    - name: Publish to PyPI\n      env:\n        TWINE_USERNAME: __token__\n        TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}\n      run: twine upload dist/*.tar.gz\n```\n\n### 6.2 Add PyPI token to GitHub secrets\n- Go to GitHub repo \u2192 Settings \u2192 Secrets and variables \u2192 Actions\n- Add secret: `PYPI_API_TOKEN` = your PyPI token\n\n## Step 7: Future Releases\n\n### 7.1 For new versions\n```bash\n# 1. Update version in pyproject.toml\n# 2. Clean and rebuild\nrm -rf dist/ build/ *.egg-info\npython -m build\n\n# 3. Upload\npython -m twine upload dist/*.tar.gz\n```\n\n### 7.2 Or use GitHub releases (if using Actions)\n- Create new GitHub release with tag like `v0.2.0`\n- GitHub Actions will automatically publish to PyPI\n\n## Common Issues and Solutions\n\n### Issue: \"Binary wheel has unsupported platform tag\"\n**Solution**: Upload only source distribution (`*.tar.gz`)\n\n### Issue: \"Invalid authentication\"\n**Solutions**:\n- Verify email on PyPI\n- Create fresh API token\n- Use `__token__` as username\n\n### Issue: \"Package name already exists\"\n**Solution**: Choose unique name like `yourpackage-username`\n\n### Issue: C++ compilation fails\n**Solutions**:\n- Check `include_dirs` in `setup.py`\n- Ensure `MANIFEST.in` includes all necessary files\n- Install system dependencies (like Eigen)\n\n## Verification Checklist\n\n- [ ] Package builds successfully (`python -m build`)\n- [ ] Package checks pass (`python -m twine check dist/*`)\n- [ ] PyPI account created and email verified\n- [ ] API token created and saved\n- [ ] Package name is unique\n- [ ] Upload successful\n- [ ] Package installs via pip\n- [ ] Package imports correctly\n\n## Result\n\nYour package will be available at:\n`https://pypi.org/project/your-package-name/`\n\nUsers can install with:\n```bash\npip install your-package-name\n``` -->\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Fast mathematical utilities",
    "version": "0.1.3",
    "project_urls": {
        "Homepage": "https://github.com/wlough/MathUtils",
        "Issues": "https://github.com/wlough/MathUtils/issues",
        "Repository": "https://github.com/wlough/MathUtils"
    },
    "split_keywords": [
        "mathematics",
        " scientific-computing",
        " numerical-methods"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "129975bbabb1f0875e0013fb4e4789ef5d09b5720ba3900fb5afa3bac34a2b02",
                "md5": "139a2e3121422f4decb5048fff9d09ac",
                "sha256": "cbd598d12d56077419e57107cb6297470d94c337e9eb78c41454c3cd8552fac0"
            },
            "downloads": -1,
            "filename": "pymathutils-0.1.3.tar.gz",
            "has_sig": false,
            "md5_digest": "139a2e3121422f4decb5048fff9d09ac",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 22523,
            "upload_time": "2025-07-29T22:24:26",
            "upload_time_iso_8601": "2025-07-29T22:24:26.939047Z",
            "url": "https://files.pythonhosted.org/packages/12/99/75bbabb1f0875e0013fb4e4789ef5d09b5720ba3900fb5afa3bac34a2b02/pymathutils-0.1.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-29 22:24:26",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "wlough",
    "github_project": "MathUtils",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "pymathutils"
}
        
Elapsed time: 0.53362s