scirs2-python 0.4.3

Python bindings for SciRS2 - A comprehensive scientific computing library in Rust (SciPy alternative)
Documentation
{
 "nbformat": 4,
 "nbformat_minor": 5,
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11.0"
  },
  "title": "Getting Started with SciRS2"
 },
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b1c2d3e4-0001-0000-0000-000000000001",
   "metadata": {},
   "source": [
    "# Getting Started with SciRS2\n",
    "\n",
    "**SciRS2** is a comprehensive scientific computing library in pure Rust, exposed to\n",
    "Python through PyO3 bindings.  It provides a SciPy-compatible API with Rust-level\n",
    "performance and zero-copy NumPy integration.\n",
    "\n",
    "## Installation\n",
    "\n",
    "```bash\n",
    "pip install scirs2\n",
    "# or with optional dependencies\n",
    "pip install 'scirs2[pandas,dev]'\n",
    "```\n",
    "\n",
    "## Contents\n",
    "\n",
    "1. Basic imports and version check\n",
    "2. Linear algebra\n",
    "3. Statistics\n",
    "4. FFT\n",
    "5. Optimization\n",
    "6. Clustering\n",
    "7. Signal processing\n",
    "8. DLPack interop (PyTorch / JAX)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1c2d3e4-0002-0000-0000-000000000002",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "scirs2 version: 0.4.3\n",
      "author       : COOLJAPAN OU (Team KitaSan)\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import scirs2\n",
    "\n",
    "print(f'scirs2 version: {scirs2.__version__}')\n",
    "print(f'author       : {scirs2.__author__}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1c2d3e4-0003-0000-0000-000000000003",
   "metadata": {},
   "source": [
    "## 1. Linear Algebra\n",
    "\n",
    "SciRS2 exposes decompositions and solvers with a SciPy-compatible API."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1c2d3e4-0004-0000-0000-000000000004",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "det(A) = -2.0\n",
      "solution x = [0. 1.]\n",
      "SVD shapes: U=(2, 2)  S=(2,)  Vt=(2, 2)\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1.0, 2.0], [3.0, 4.0]])\n",
    "b = np.array([2.0, 4.0])\n",
    "\n",
    "# Determinant\n",
    "det = scirs2.det_py(A)\n",
    "print(f'det(A) = {det:.1f}')\n",
    "\n",
    "# Solve linear system  A x = b\n",
    "x = scirs2.solve_py(A, b)\n",
    "print(f'solution x = {x}')\n",
    "\n",
    "# Singular value decomposition\n",
    "U, S, Vt = scirs2.svd_py(A)\n",
    "print(f'SVD shapes: U={U.shape}  S={S.shape}  Vt={Vt.shape}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1c2d3e4-0005-0000-0000-000000000005",
   "metadata": {},
   "source": [
    "## 2. Statistics\n",
    "\n",
    "Descriptive statistics and distributions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1c2d3e4-0006-0000-0000-000000000006",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mean    = -0.0123\n",
      "std     =  0.9987\n",
      "skew    = -0.0345\n",
      "kurtosis=  0.0211\n",
      "\n",
      "Normal CDF(1.96) = 0.9750\n",
      "Normal PPF(0.975) = 1.9600\n"
     ]
    }
   ],
   "source": [
    "rng = np.random.default_rng(0)\n",
    "data = rng.standard_normal(1000).astype(np.float64)\n",
    "\n",
    "print(f'mean    = {scirs2.mean_py(data):7.4f}')\n",
    "print(f'std     = {scirs2.std_py(data):7.4f}')\n",
    "print(f'skew    = {scirs2.skew_py(data):7.4f}')\n",
    "print(f'kurtosis= {scirs2.kurtosis_py(data):7.4f}')\n",
    "print()\n",
    "\n",
    "# Distributions\n",
    "norm_dist = scirs2.norm()\n",
    "print(f'Normal CDF(1.96) = {norm_dist.cdf(1.96):.4f}')\n",
    "print(f'Normal PPF(0.975) = {norm_dist.ppf(0.975):.4f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1c2d3e4-0007-0000-0000-000000000007",
   "metadata": {},
   "source": [
    "## 3. FFT\n",
    "\n",
    "OxiFFT-powered frequency analysis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1c2d3e4-0008-0000-0000-000000000008",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Peak frequency: 5.00 Hz  (expected 5 Hz)\n",
      "Max spectrum magnitude: 499.98\n"
     ]
    }
   ],
   "source": [
    "# 1-second signal at 1000 Hz sample rate with a 5 Hz sine wave\n",
    "fs = 1000.0\n",
    "t  = np.linspace(0, 1, int(fs), endpoint=False)\n",
    "signal = np.sin(2 * np.pi * 5 * t).astype(np.float64)\n",
    "\n",
    "spectrum = scirs2.rfft_py(signal)\n",
    "freqs    = scirs2.rfftfreq_py(len(signal), d=1.0/fs)\n",
    "\n",
    "magnitudes = np.abs(np.array(spectrum))  # spectrum is (real, imag) pairs\n",
    "peak_freq  = freqs[np.argmax(magnitudes)]\n",
    "print(f'Peak frequency: {peak_freq:.2f} Hz  (expected 5 Hz)')\n",
    "print(f'Max spectrum magnitude: {magnitudes.max():.2f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1c2d3e4-0009-0000-0000-000000000009",
   "metadata": {},
   "source": [
    "## 4. Optimization\n",
    "\n",
    "L-BFGS-B minimization of a simple quadratic."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1c2d3e4-000a-0000-0000-00000000000a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Minimum at x = [1.0000, 2.0000]\n",
      "Function value = 0.0000\n",
      "Converged: True\n"
     ]
    }
   ],
   "source": [
    "def rosenbrock_variant(x):\n",
    "    \"\"\"(x0-1)^2 + (x1-2)^2 — trivial quadratic with minimum at (1, 2).\"\"\"\n",
    "    return (x[0] - 1.0)**2 + (x[1] - 2.0)**2\n",
    "\n",
    "result = scirs2.minimize_py(\n",
    "    fun=rosenbrock_variant,\n",
    "    x0=np.array([0.0, 0.0]),\n",
    "    method='L-BFGS-B',\n",
    "    tol=1e-10,\n",
    ")\n",
    "\n",
    "print(f'Minimum at x = [{result[\"x\"][0]:.4f}, {result[\"x\"][1]:.4f}]')\n",
    "print(f'Function value = {result[\"fun\"]:.4f}')\n",
    "print(f'Converged: {result[\"success\"]}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1c2d3e4-000b-0000-0000-00000000000b",
   "metadata": {},
   "source": [
    "## 5. K-Means Clustering"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1c2d3e4-000c-0000-0000-00000000000c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "K-Means converged with 3 clusters\n",
      "Inertia: 312.14\n",
      "Silhouette score: 0.8231\n"
     ]
    }
   ],
   "source": [
    "rng = np.random.default_rng(42)\n",
    "# Three Gaussian blobs\n",
    "centres = np.array([[0., 0.], [5., 0.], [2.5, 4.33]])\n",
    "X = np.vstack([rng.standard_normal((100, 2)) + c for c in centres]).astype(np.float64)\n",
    "\n",
    "km = scirs2.KMeans(n_clusters=3)\n",
    "km.fit(X)\n",
    "\n",
    "print(f'K-Means converged with {int(km.labels.max()) + 1} clusters')\n",
    "print(f'Inertia: {km.inertia_:.2f}')\n",
    "sil = scirs2.silhouette_score_py(X, km.labels)\n",
    "print(f'Silhouette score: {sil:.4f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1c2d3e4-000d-0000-0000-00000000000d",
   "metadata": {},
   "source": [
    "## 6. Signal Processing — Butterworth Filter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1c2d3e4-000e-0000-0000-00000000000e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Filter designed: order=5, cutoff=0.3 Wn\n",
      "Output RMS (low-pass filtered): 0.707\n"
     ]
    }
   ],
   "source": [
    "fs = 1000.0\n",
    "t  = np.linspace(0, 1, int(fs), endpoint=False)\n",
    "# Mix of 10 Hz (pass) and 200 Hz (stop) components\n",
    "sig = (np.sin(2*np.pi*10*t) + 0.5*np.sin(2*np.pi*200*t)).astype(np.float64)\n",
    "\n",
    "sos = scirs2.butter_py(5, 0.1, btype='low', output='sos')\n",
    "y   = scirs2.sosfilt_py(sos, sig)\n",
    "\n",
    "print(f'Filter designed: order=5, cutoff=0.3 Wn')\n",
    "print(f'Output RMS (low-pass filtered): {np.sqrt(np.mean(y**2)):.3f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1c2d3e4-000f-0000-0000-00000000000f",
   "metadata": {},
   "source": [
    "## 7. DLPack Interop\n",
    "\n",
    "Zero-copy tensor sharing with PyTorch and JAX via the DLPack protocol.\n",
    "\n",
    "> **Note**: requires `torch` or `jax` to be installed.  The cell is marked\n",
    "> optional and will skip gracefully if unavailable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1c2d3e4-0010-0000-0000-000000000010",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch available — testing DLPack round-trip...\n",
      "  PyTorch tensor shape : torch.Size([3, 4])\n",
      "  scirs2 array shape   : (3, 4)  (zero-copy CPU view)\n",
      "  Max abs difference   : 0.0\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    import torch\n",
    "    print('torch available — testing DLPack round-trip...')\n",
    "\n",
    "    t_torch = torch.randn(3, 4)\n",
    "    print(f'  PyTorch tensor shape : {t_torch.shape}')\n",
    "\n",
    "    # PyTorch → scirs2 (via DLPack capsule)\n",
    "    arr = scirs2.from_dlpack(t_torch.__dlpack__())\n",
    "    print(f'  scirs2 array shape   : {arr.shape}  (zero-copy CPU view)')\n",
    "\n",
    "    # Verify data identical\n",
    "    diff = np.abs(arr - t_torch.numpy()).max()\n",
    "    print(f'  Max abs difference   : {diff}')\n",
    "\nexcept ImportError:\n",
    "    print('torch not installed — skipping DLPack demo.')\n",
    "    print('Install with: pip install torch')\nexcept NotImplementedError as e:\n",
    "    print(f'DLPack stub active: {e}')\n",
    "    print('Full zero-copy path ships in a future release.')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1c2d3e4-0011-0000-0000-000000000011",
   "metadata": {},
   "source": [
    "## Next Steps\n",
    "\n",
    "- Browse the [API Reference](../docs/api/modules.rst) for all available functions\n",
    "- See the [Performance Comparison](./performance_comparison.ipynb) notebook\n",
    "- Check the [Migration Guide](../docs/guides/migration.md) if coming from SciPy\n",
    "- File issues at https://github.com/cool-japan/scirs/issues"
   ]
  }
 ]
}