quatica 0.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
quatica-0.0.2/PKG-INFO ADDED
@@ -0,0 +1,1377 @@
1
+ Metadata-Version: 2.3
2
+ Name: quatica
3
+ Version: 0.0.2
4
+ Summary: Quatica core package
5
+ Author: Your Name
6
+ Author-email: Your Name <you@example.com>
7
+ License: MIT
8
+ Requires-Dist: matplotlib>=3.10.3
9
+ Requires-Dist: numpy>=2.3.2
10
+ Requires-Dist: numpy-quaternion>=2024.0.10
11
+ Requires-Dist: scikit-learn>=1.5.0
12
+ Requires-Dist: scipy>=1.16.1
13
+ Requires-Dist: seaborn>=0.13.0
14
+ Requires-Python: >=3.13
15
+ Description-Content-Type: text/markdown
16
+
17
+ # QuatIca: Quaternion Linear Algebra Library
18
+
19
+ <div align="center">
20
+ <img src="Logo.png" alt="QuatIca Logo" width="250">
21
+ </div>
22
+
23
+ **A comprehensive Python library for Numerical Linear Algebra with Quaternions**
24
+
25
+ ## πŸ€” What is QuatIca?
26
+
27
+ **QuatIca** is a Python library that extends traditional linear algebra to work with **quaternions** - a mathematical system that extends complex numbers to 4D space. Think of it as "linear algebra on steroids" for 3D and 4D data.
28
+
29
+ ### **🎯 What are Quaternions?**
30
+
31
+ - **Complex numbers** work in 2D (real + imaginary)
32
+ - **Quaternions** work in 4D (real + 3 imaginary components: i, j, k)
33
+ - **Perfect for**: 3D rotations, color images (RGB), 4D signals, and more
34
+ - **Why useful**: Can represent complex relationships in data that regular matrices can't
35
+
36
+ ### **πŸš€ What Can You Do With QuatIca?**
37
+
38
+ - **Matrix Operations**: Multiply, invert, and analyze quaternion matrices
39
+ - **Matrix Decompositions**: QR decomposition, Q-SVD (full and truncated), **Randomized Q-SVD**, **LU decomposition**, **Hessenberg form (upper Hessenberg reduction)**, **Schur decomposition**, and **Eigenvalue Decomposition** for quaternion matrices
40
+ - **Linear System Solving**: Solve quaternion systems A\*x = b using Q-GMRES (iterative Krylov subspace method) with **LU preconditioning** for enhanced convergence
41
+ - **Pseudoinverse Computation**: Newton–Schulz methods including a higher-order (third-order) variant with cubic local convergence
42
+ - **Image Processing**: Complete missing pixels in images using quaternion math
43
+ - **Signal Analysis**: Process 3D/4D signals with quaternion algebra
44
+ - **Data Science**: Extract complex patterns from multi-dimensional data
45
+
46
+ ### **πŸ§ͺ Preview: Quaternion Tensor Algebra (Experimental)**
47
+
48
+ - We added a preview of quaternion tensor tools (order-3) laying groundwork for tensor decompositions (e.g., HOSVD, TT, Tucker):
49
+ - Tensor Frobenius-like norm, entrywise |T| (quaternion magnitude)
50
+ - Mode-n unfolding and folding for order-3 tensors
51
+ - See the notebook section "13. Preview: Quaternion Tensor Algebra and Decompositions" in `QuatIca_Core_Functionality_Demo.ipynb`.
52
+ - Utilities live in `core/tensor.py`; unit tests in `tests/unit/test_tensor_quaternion_basics.py`.
53
+
54
+ ## 🌟 Motivation and Acknowledgments
55
+
56
+ QuatIca was inspired by the pioneering work in quaternion linear algebra, particularly the **QTFM (Quaternion Toolbox for MATLAB)** developed by Stephen J. Sangwine and Nicolas Le Bihan. Their comprehensive MATLAB implementation demonstrated the power and potential of quaternion-based numerical methods.
57
+
58
+ Recognizing the growing importance of Python in scientific computing and the need for robust quaternion tools in the Python ecosystem, we developed QuatIca to bring these capabilities to Python users. We extend our sincere gratitude to Sangwine and Le Bihan for providing the inspiration that drove us to create this library.
59
+
60
+ Our goal is to continue advancing the field of quaternion linear algebra while making these powerful tools accessible to the broader Python community, from researchers and engineers to students and practitioners across diverse domains.
61
+
62
+ ## ⚠️ CRITICAL PERFORMANCE INFORMATION
63
+
64
+ **numpy Version Requirement:**
65
+
66
+ - **REQUIRED**: numpy >= 2.3.2 for optimal performance
67
+ - **CRITICAL**: numpy 2.3.2 provides **10-15x speedup** for quaternion matrix operations compared to 2.2.6
68
+ - **WARNING**: Using older numpy versions will result in significantly slower performance
69
+
70
+ **Package Performance Warnings:**
71
+
72
+ - **opencv-python** and **tqdm** cause **3x performance degradation** and are NOT included in requirements.txt
73
+ - These packages pull in heavy dependencies that affect numpy performance
74
+ - If you need these for matrix completion features, install them separately but be aware of the performance cost
75
+
76
+ **Performance Benchmarks (Newton-Schulz Pseudoinverse Computation on 800x1000 matrices):**
77
+
78
+ - Dense matrices: ~16 seconds with numpy 2.3.2 (vs minutes/hours with 2.2.6)
79
+ - Sparse matrices: ~9 seconds with numpy 2.3.2
80
+ - Small matrices (200x200): ~0.4 seconds
81
+
82
+ ## πŸ“‹ System Requirements
83
+
84
+ ### **Minimum Requirements:**
85
+
86
+ - **Python**: 3.8 or higher (3.9+ recommended)
87
+ - **RAM**: 4GB minimum, 8GB recommended for large matrices
88
+ - **Storage**: 500MB free space
89
+ - **OS**: Windows, macOS, or Linux
90
+
91
+ ### **Recommended:**
92
+
93
+ - **Python**: 3.9 or 3.10
94
+ - **RAM**: 16GB for large-scale analysis
95
+ - **CPU**: Multi-core processor for faster computation
96
+
97
+ ## πŸš€ Quick Start Guide
98
+
99
+ ### **🎯 For Complete Beginners (Step-by-Step)**
100
+
101
+ #### **Step 1: Install [`uv`](https://docs.astral.sh/uv/)**
102
+
103
+ If you don't have Python installed:
104
+
105
+ 1. Go to [uv website](https://docs.astral.sh/uv/getting-started/installation/)
106
+ 2. Follow the installing guide
107
+ 3. Verify: Open terminal/command prompt and type `uv --version`
108
+
109
+ #### **Step 2: Download QuatIca**
110
+
111
+ ```bash
112
+ # Clone the repository (if you have git)
113
+ git clone https://github.com/vleplat/QuatIca.git
114
+ cd QuatIca
115
+
116
+ # OR download as ZIP and extract to a folder
117
+ ```
118
+
119
+ #### **Step 3: Set Up Environment**
120
+
121
+ ```bash
122
+ # Create a virtual environment (isolated Python environment)
123
+ uv sync --no-group dev
124
+ ```
125
+
126
+ Now you have two possibilities to run scripts:
127
+
128
+ ##### Using `uv` (recommended)
129
+
130
+ Just use
131
+
132
+ ```bash
133
+ uv run <script.py>
134
+ ```
135
+
136
+ instead of
137
+
138
+ ```bash
139
+ python <script.py>
140
+ ```
141
+
142
+ ##### Manually activate the environment
143
+
144
+ Firstly activate the environment (from the project folder):
145
+
146
+ ```bash
147
+ # Activate the environment
148
+ # On Mac/Linux:
149
+ source ./.venv/bin/activate
150
+ # On Windows:
151
+ .\.venv\Scripts\activate
152
+ ```
153
+
154
+ And then run scripts as usual:
155
+
156
+ ```bash
157
+ python <script.py>
158
+ ```
159
+
160
+ #### Alternative: Docker Setup (For Advanced Users)
161
+
162
+ For maximum reproducibility, you can also use Docker:
163
+
164
+ ```bash
165
+ # Build the Docker image
166
+ docker build -t quatica .
167
+
168
+ # Run the container
169
+ docker run -it --rm quatica
170
+
171
+ # Or run a specific script
172
+ docker run -it --rm quatica python run_analysis.py tutorial
173
+ ```
174
+
175
+ _Note: Docker setup is optional. The virtual environment approach above works perfectly for most users._
176
+
177
+ _Note: Hereafter, the 'uv approach' (`uv run <script.py>`). to run scripts is used in examples. However, when using Docker, the usual 'python way' (`python <script.py>`) should be used._
178
+
179
+ #### Step 4 [OPTIONAL]: Setup Tools for Development
180
+
181
+ Install dependencies
182
+
183
+ ```bash
184
+ uv sync
185
+ ```
186
+
187
+ Setup pre-commit hook
188
+
189
+ ```bash
190
+ uv run pre-commit install
191
+ ```
192
+
193
+ and test it
194
+
195
+ ```bash
196
+ uv run pre-commit run --all-files
197
+ ```
198
+
199
+ #### **Step 5: Verify Installation**
200
+
201
+ ```bash
202
+ # Test if everything works
203
+ uv run run_analysis.py
204
+
205
+ # You should see a list of available scripts
206
+ ```
207
+
208
+ ### **🎯 Super Simple: Run Any Analysis with One Command!**
209
+
210
+ The library provides a **super easy** way to run any analysis script. Just use `run_analysis.py`:
211
+
212
+ ```bash
213
+ # πŸš€ The Magic Command:
214
+ uv run run_analysis.py <script_name>
215
+ ```
216
+
217
+ #### **πŸ“‹ Available Scripts (Choose One):**
218
+
219
+ | Script Name | What It Does | Best For |
220
+ | -------------------- | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
221
+ | `tutorial` | **πŸŽ“ Quaternion Basics Tutorial** - Complete introduction with visualizations | **πŸš€ START HERE!** Learn the framework |
222
+ | `qgmres` | **Q-GMRES Solver Test** - Tests the iterative Krylov subspace solver | **Linear system solving** with quaternions |
223
+ | `qgmres_bench` | **πŸš€ Q-GMRES Performance Benchmark** - Comprehensive preconditioner benchmarking | **Algorithm performance** and LU preconditioning analysis |
224
+ | `lorenz_signal` | **Lorenz Attractor Signal Processing** - 3D signal processing with Q-GMRES | **Signal processing** applications |
225
+ | `lorenz_benchmark` | **πŸ† Method Comparison Benchmark** - Q-GMRES vs Newton-Schulz performance comparison | **Algorithm selection** and performance analysis |
226
+ | `ns_compare` | **NS vs Higher-Order NS** - Compares pseudoinverse solvers, saves residual/time plots | **Pseudoinverse** benchmarking |
227
+ | `pseudoinverse` | **Single Image Analysis** - Analyzes one image (kodim16.png) | Understanding pseudoinverse structure |
228
+ | `multiple_images` | **Multi-Image Analysis** - Compares multiple small images | Pattern comparison across images |
229
+ | `image_completion` | **Image Completion Demo** - Fills missing pixels in real images | **Practical application** |
230
+ | `image_deblurring` | **Quaternion Image Deblurring** - QSLST (Algorithm 2) vs NS/HON with FFT specialization | **Image restoration** |
231
+ | `synthetic` | **Synthetic Image Completion** - Matrix completion on generated test images | Controlled experiments |
232
+ | `synthetic_matrices` | **Synthetic Matrix Pseudoinverse Test** - Tests pseudoinverse on various matrix types | Algorithm validation |
233
+ | `eigenvalue_test` | **πŸ”¬ Eigenvalue Decomposition Test** - Tests tridiagonalization and eigendecomposition | **Matrix analysis** and eigenvalue computation |
234
+ | `schur_demo` | **🎯 Quaternion Schur Decomposition Demo** - Comprehensive comparison of rayleigh vs aed variants | **Matrix decomposition** and algorithm comparison |
235
+
236
+ #### **🎯 Quick Examples:**
237
+
238
+ ```bash
239
+ # πŸš€ START HERE: Learn the framework with interactive tutorial
240
+ uv run run_analysis.py tutorial
241
+
242
+ # Test Q-GMRES linear system solver
243
+ uv run run_analysis.py qgmres
244
+
245
+ # Test Q-GMRES with LU preconditioning benchmark
246
+ uv run run_analysis.py qgmres_bench
247
+
248
+ # Process 3D signals with Lorenz attractor (default quality)
249
+ uv run run_analysis.py lorenz_signal
250
+
251
+ # Process 3D signals with Lorenz attractor (fast testing)
252
+ uv run run_analysis.py lorenz_signal --num_points 100
253
+
254
+ # Compare Q-GMRES vs Newton-Schulz methods
255
+ uv run run_analysis.py lorenz_benchmark
256
+
257
+
258
+ # See image completion in action
259
+ uv run run_analysis.py image_completion
260
+
261
+ # Quaternion image deblurring (with optional parameters)
262
+ uv run run_analysis.py image_deblurring --size 32 --lam 1e-3
263
+ # Optional: add noise SNR in dB
264
+ uv run run_analysis.py image_deblurring --size 32 --lam 1e-3 --snr 30
265
+
266
+ # Test matrix completion on synthetic images
267
+ uv run run_analysis.py synthetic
268
+
269
+ # Test pseudoinverse on synthetic matrices
270
+ uv run run_analysis.py synthetic_matrices
271
+
272
+ # Test Schur decomposition with comprehensive comparison
273
+ uv run run_analysis.py schur_demo
274
+
275
+ # Test Schur decomposition with custom matrix size
276
+ uv run run_analysis.py schur_demo 15
277
+
278
+ # Compare Newton–Schulz variants (saves plots to output_figures)
279
+ uv run run_analysis.py ns_compare
280
+
281
+ # Get help and see all options
282
+ uv run run_analysis.py
283
+ ```
284
+
285
+ #### **πŸš€ Quick Reference - Most Common Commands:**
286
+
287
+ ```bash
288
+ # πŸŽ“ Learn the framework (START HERE)
289
+ uv run run_analysis.py tutorial
290
+
291
+ # ⚑ Test Q-GMRES solver
292
+ uv run run_analysis.py qgmres
293
+
294
+ # πŸŒͺ️ Lorenz attractor (fast testing)
295
+ uv run run_analysis.py lorenz_signal --num_points 100
296
+
297
+ # πŸŒͺ️ Lorenz attractor (default quality)
298
+ uv run run_analysis.py lorenz_signal
299
+
300
+ # πŸŒͺ️ Lorenz attractor (high quality)
301
+ uv run run_analysis.py lorenz_signal --num_points 500
302
+
303
+ # πŸ† Method comparison benchmark
304
+ uv run run_analysis.py lorenz_benchmark
305
+
306
+ # 🎯 Advanced analysis with real data
307
+ uv run run_analysis.py cifar10
308
+
309
+ # πŸ–ΌοΈ Image completion demo
310
+ uv run run_analysis.py image_completion
311
+ ```
312
+
313
+ #### **πŸ“Š What You Get:**
314
+
315
+ - **All plots saved** in `output_figures/` directory
316
+ - **Detailed analysis** printed to console
317
+ - **No need to navigate directories** - everything works from main folder
318
+
319
+ ## πŸ“ Project Structure
320
+
321
+ ```
322
+ QuatIca/
323
+ β”œβ”€β”€ core/ # Core library files
324
+ β”‚ β”œβ”€β”€ solver.py # Main algorithms (pseudoinverse computation, Q-GMRES with LU preconditioning)
325
+ β”‚ β”œβ”€β”€ utils.py # Quaternion operations, utilities, and power iteration
326
+ β”‚ β”œβ”€β”€ data_gen.py # Matrix generation functions
327
+ β”‚ β”œβ”€β”€ visualization.py # Plotting and visualization tools
328
+ β”‚ β”œβ”€β”€ tensor.py # Quaternion tensor utilities (norms, |T|, unfold/fold)
329
+ β”‚ └── decomp/ # Matrix decomposition algorithms
330
+ β”‚ β”œβ”€β”€ __init__.py
331
+ β”‚ β”œβ”€β”€ qsvd.py # QR and Q-SVD implementations
332
+ β”‚ β”œβ”€β”€ eigen.py # Eigenvalue decomposition for Hermitian matrices
333
+ β”‚ β”œβ”€β”€ LU.py # LU decomposition with partial pivoting
334
+ β”‚ β”œβ”€β”€ tridiagonalize.py # Tridiagonalization using Householder transformations
335
+ β”‚ β”œβ”€β”€ hessenberg.py # Upper Hessenberg reduction using Householder similarity
336
+ β”‚ └── schur.py # Schur decomposition (experimental)
337
+ β”œβ”€β”€ tests/
338
+ β”‚ β”œβ”€β”€ tutorial_quaternion_basics.py # πŸŽ“ Interactive tutorial with visualizations
339
+ β”‚ β”œβ”€β”€ schur_demo.py # 🎯 Comprehensive Schur decomposition demo with algorithm comparison
340
+ β”‚ β”œβ”€β”€ unit/ # Unit tests for core functionality
341
+ β”‚ β”‚ β”œβ”€β”€ test_tensor_quaternion_basics.py # Quaternion tensor basics (norms, |T|, unfold/fold)
342
+ β”‚ β”‚ β”œβ”€β”€ test_schur_synthetic.py # Synthetic Schur (|T| visuals saved)
343
+ β”‚ β”‚ β”œβ”€β”€ test_schur_power_synthetic.py # Schur vs power-iteration transversal check
344
+ β”‚ β”‚ └── [See tests/unit/README.md for complete list]
345
+ β”‚ β”œβ”€β”€ QGMRES/ # Q-GMRES solver tests
346
+ β”‚ β”‚ β”œβ”€β”€ test_qgmres_solver.py # Main Q-GMRES solver tests
347
+ β”‚ β”‚ β”œβ”€β”€ test_qgmres_large.py # Large-scale Q-GMRES performance tests
348
+ β”‚ β”‚ β”œβ”€β”€ benchmark_qgmres_preconditioner.py # Comprehensive Q-GMRES LU preconditioning benchmark
349
+ β”‚ β”‚ └── benchmark_qgmres_accuracy.py # Q-GMRES accuracy investigation and analysis
350
+ β”‚ β”œβ”€β”€ pseudoinverse/ # Pseudoinverse analysis scripts
351
+ β”‚ β”‚ β”œβ”€β”€ analyze_pseudoinverse.py # Single image pseudoinverse analysis
352
+ β”‚ β”‚ β”œβ”€β”€ analyze_multiple_images_pseudoinverse.py # Multiple images analysis
353
+ β”‚ β”‚ └── script_synthetic_matrices.py # Synthetic matrices testing
354
+ β”‚ β”œβ”€β”€ decomp/ # Matrix decomposition tests
355
+ β”‚ β”‚ β”œβ”€β”€ test_qsvd.py # QR and Q-SVD unit tests
356
+ β”‚ β”‚ β”œβ”€β”€ test_eigen.py # Eigenvalue decomposition unit tests
357
+ β”‚ β”‚ β”œβ”€β”€ test_LU.py # LU decomposition unit tests
358
+ β”‚ β”‚ β”œβ”€β”€ test_tridiagonalize.py # Tridiagonalization unit tests
359
+ β”‚ β”‚ β”œβ”€β”€ eigenvalue_demo.py # Demonstration of eigenvalue decomposition
360
+ β”‚ β”‚ └── test_hessenberg.py # Hessenberg reduction unit tests
361
+ β”œβ”€β”€ applications/
362
+ β”‚ β”œβ”€β”€ image_completion/ # Image processing applications
363
+ β”‚ β”‚ β”œβ”€β”€ script_real_image_completion.py # Real image completion
364
+ β”‚ β”‚ β”œβ”€β”€ script_synthetic_image_completion.py # Synthetic image completion
365
+ β”‚ β”‚ └── script_small_image_completion.py # Small image completion
366
+ β”‚ └── signal_processing/ # Signal processing applications
367
+ β”‚ β”œβ”€β”€ lorenz_attractor_qgmres.py # Lorenz attractor Q-GMRES application
368
+ β”‚ └── benchmark_lorenz_methods.py # Q-GMRES vs Newton-Schulz benchmark
369
+ β”œβ”€β”€ data/ # Sample data and datasets
370
+ β”‚ β”œβ”€β”€ images/ # Sample images for testing
371
+ β”‚ └── cifar-10-batches-py/ # CIFAR-10 dataset
372
+ β”œβ”€β”€ References_and_SuppMat/ # Research papers and supplementary materials
373
+ β”œβ”€β”€ output_figures/ # Generated plots and visualizations (auto-created)
374
+ β”œβ”€β”€ validation_output/ # Validation plots and analysis figures (auto-created)
375
+ β”œβ”€β”€ requirements.txt # Python dependencies
376
+ β”œβ”€β”€ run_analysis.py # Easy-to-use script runner
377
+ β”œβ”€β”€ QuatIca_Core_Functionality_Demo.py # Interactive demo script testing all core functionality
378
+ β”œβ”€β”€ QuatIca_Core_Functionality_Demo.ipynb # Jupyter notebook version for interactive exploration
379
+ └── README_Demo.md # Documentation for demo files
380
+ ```
381
+
382
+ ## πŸ“Š What Each Script Produces
383
+
384
+ ### **πŸŽ“ `tutorial` - Complete Framework Introduction**
385
+
386
+ - **What it is**: Interactive tutorial with beautiful visualizations
387
+ - **Perfect for**: Learning the framework from scratch
388
+ - **Duration**: ~2-3 minutes with visualizations
389
+ - **Output**: 7+ visualization files in `output_figures/`:
390
+ - Matrix component heatmaps (real, i, j, k components)
391
+ - Convergence plots showing Newton-Schulz algorithm performance
392
+ - Performance scaling analysis across different matrix sizes
393
+ - Creative tutorial summary flowchart
394
+ - **Covers**:
395
+ - Creating dense and sparse quaternion matrices
396
+ - **Custom matrix creation** (including Pauli matrices example)
397
+ - Basic matrix operations (multiplication, norms)
398
+ - Advanced pseudoinverse computation
399
+ - Solution verification (`||A*x - b||_F` analysis)
400
+ - Linear system solving with quaternions
401
+ - Performance benchmarking
402
+ - Best practices and key takeaways
403
+
404
+ ### **⚑ `qgmres` - Q-GMRES Linear System Solver**
405
+
406
+ - **What it is**: Comprehensive test suite for the Q-GMRES iterative solver
407
+ - **Perfect for**: Testing linear system solving with quaternions
408
+ - **Duration**: ~1-2 minutes
409
+ - **Output**: Detailed analysis and convergence plots in `output_figures/`:
410
+ - Q-GMRES convergence analysis for different matrix sizes
411
+ - Performance comparison with pseudoinverse method
412
+ - Accuracy verification on dense, sparse, and ill-conditioned matrices
413
+ - **Covers**:
414
+ - Basic Q-GMRES functionality (3x3 to 15x15 systems)
415
+ - Convergence testing across different matrix sizes
416
+ - Sparse matrix support verification
417
+ - Ill-conditioned system handling
418
+ - Solution accuracy comparison with pseudoinverse
419
+ - Performance analysis and timing
420
+
421
+ ### **πŸŒͺ️ `lorenz_signal` - Lorenz Attractor Signal Processing**
422
+
423
+ - **What it is**: 3D signal processing application using Q-GMRES with adaptive LU preconditioning
424
+ - **Perfect for**: Signal processing and dynamical systems analysis
425
+ - **Duration**: Configurable via `--num_points` parameter
426
+ - **Performance**: Automatic LU preconditioning for large systems (β‰₯200 points) for enhanced convergence
427
+ - **Output**: 6+ high-resolution visualization files in `output_figures/`:
428
+ - `lorenz_observed_components.png` - Noisy signal components (x, y, z)
429
+ - `lorenz_observed_trajectory.png` - 3D Lorenz attractor with noise
430
+ - `lorenz_reconstructed_components.png` - Cleaned signal components
431
+ - `lorenz_reconstructed_trajectory.png` - Reconstructed 3D trajectory
432
+ - `lorenz_rhs_components.png` - Right-hand side components
433
+ - `lorenz_rhs_trajectory.png` - RHS 3D trajectory
434
+ - `lorenz_residual_history.png` - Q-GMRES convergence plot
435
+
436
+ #### **πŸŽ›οΈ Parameter Configuration:**
437
+
438
+ The script accepts command-line arguments to control resolution and execution time:
439
+
440
+ ```bash
441
+ # Fast testing (100 points, ~30 seconds)
442
+ uv run run_analysis.py lorenz_signal --num_points 100
443
+
444
+ # Balanced performance (200 points, ~75 seconds) - DEFAULT
445
+ uv run run_analysis.py lorenz_signal
446
+
447
+ # High resolution (500 points, ~5-10 minutes)
448
+ uv run run_analysis.py lorenz_signal --num_points 500
449
+
450
+ # Research quality (1000 points, ~20-30 minutes)
451
+ uv run run_analysis.py lorenz_signal --num_points 1000
452
+
453
+ # Save plots without displaying them
454
+ uv run run_analysis.py lorenz_signal --no_show
455
+ ```
456
+
457
+ #### **πŸ“Š Performance Guide:**
458
+
459
+ | Points | Execution Time | Resolution | Solver Method | Use Case |
460
+ | ------ | --------------- | ---------- | ----------------------------- | --------------------------------- |
461
+ | 100 | ~30 seconds | Low | Standard Q-GMRES | Fast testing, development |
462
+ | 200 | ~20 seconds\* | Good | **LU Preconditioned Q-GMRES** | **Default, balanced performance** |
463
+ | 500 | ~2-5 minutes\* | High | **LU Preconditioned Q-GMRES** | Publication quality |
464
+ | 1000 | ~8-15 minutes\* | Very High | **LU Preconditioned Q-GMRES** | Research, detailed analysis |
465
+
466
+ **\*Significantly improved with LU preconditioning (5-10x faster for large systems)**
467
+
468
+ #### **πŸ”¬ What It Covers:**
469
+
470
+ - **Lorenz attractor signal generation** with configurable resolution
471
+ - **Time simulation**: 10-second simulation window (parameter `T` in script)
472
+ - **Noise addition and signal corruption** simulation
473
+ - **Quaternion matrix construction** for signal filtering
474
+ - **Q-GMRES-based signal reconstruction** with convergence analysis
475
+ - **3D trajectory visualization** (classic butterfly pattern)
476
+ - **Time series analysis** of signal components
477
+ - **Performance scaling** with different system sizes
478
+
479
+ #### **⏰ Time Parameter Configuration:**
480
+
481
+ The script simulates the Lorenz attractor for **10 seconds** by default. To modify the simulation time:
482
+
483
+ 1. **Open the script**: `applications/signal_processing/lorenz_attractor_qgmres.py`
484
+ 2. **Find line ~140**: `T, delta, seed = 10.0, 1.0, 0`
485
+ 3. **Change the first value**: `T = 20.0` for 20 seconds, `T = 5.0` for 5 seconds
486
+ 4. **Run the script** with your desired `num_points` parameter
487
+
488
+ **Note**: Longer simulation times require more `num_points` for good resolution.
489
+
490
+ ### **πŸ† `lorenz_benchmark` - Method Comparison Benchmark**
491
+
492
+ - **What it is**: Comprehensive performance comparison between Q-GMRES and Newton-Schulz methods
493
+ - **Perfect for**: Understanding method trade-offs and choosing the right algorithm
494
+ - **Duration**: ~5-10 minutes (comprehensive testing)
495
+ - **Output**: 2 high-quality analysis files in `output_figures/`:
496
+ - `lorenz_benchmark_performance.png` - Performance comparison plots (4 subplots)
497
+ - `lorenz_trajectory_comparison.png` - 3D trajectory reconstruction comparison
498
+
499
+ #### **πŸ“Š Benchmark Results:**
500
+
501
+ The benchmark tests both methods across different problem sizes (50-200 points) and provides:
502
+
503
+ **Performance Metrics:**
504
+
505
+ - Computational time comparison
506
+ - Iteration count analysis
507
+ - Solution accuracy (residual norms)
508
+ - Time vs accuracy trade-off analysis
509
+
510
+ **Visualization:**
511
+
512
+ - Side-by-side 3D trajectory reconstructions
513
+ - Clean signal vs reconstructed signal comparison
514
+ - Method performance across different problem sizes
515
+
516
+ #### **🎯 Key Findings:**
517
+
518
+ - **Newton-Schulz is ~100x faster** than Q-GMRES on average
519
+ - **Newton-Schulz is ~270x more accurate** than Q-GMRES on average
520
+ - **Newton-Schulz scales better** with problem size
521
+ - **Q-GMRES shows inconsistent accuracy** across different problem sizes
522
+
523
+ **Usage:**
524
+
525
+ ```bash
526
+ # Run the complete benchmark
527
+ uv run run_analysis.py lorenz_benchmark
528
+ ```
529
+
530
+ <!-- ### **🎯 `cifar10` - Most Comprehensive Analysis**
531
+ - **Input**: 250 CIFAR-10 images (50 per class from 5 classes)
532
+ - **Output**: 8 detailed plots in `output_figures/`:
533
+ - `pixel_reconstruction_filters.png` - How each pixel is reconstructed
534
+ - `spectral_analysis.png` - Singular value analysis
535
+ - `pseudoinverse_manifold.png` - Phase and magnitude visualization
536
+ - `channel_correlations.png` - Color channel relationships
537
+ - `class_average_filters.png` - Class-specific reconstruction filters
538
+ - `pca_analysis.png` - PCA and t-SNE analysis
539
+ - `class_spectral_analysis.png` - Class-specific spectral patterns
540
+ - `sample_images_verification.png` - Sample images for verification -->
541
+
542
+ ### **πŸ–ΌοΈ `pseudoinverse` - Single Image Analysis**
543
+
544
+ - **Input**: kodim16.png image
545
+ - **Output**: 4 analysis plots:
546
+ - `pseudoinverse_component_analysis.png`
547
+ - `reconstruction_error_map.png`
548
+ - `pseudoinverse_filter_bank.png`
549
+ - `pseudoinverse_distributions_interpreted.png`
550
+
551
+ ### **πŸ”„ `image_completion` - Practical Application**
552
+
553
+ - **Input**: Real RGB images with missing pixels
554
+ - **Output**: Completed images and PSNR metrics
555
+ - **Shows**: How quaternion matrix completion works in practice
556
+
557
+ ### **πŸ§ͺ `synthetic` - Controlled Experiments**
558
+
559
+ ### **πŸ–ΌοΈ `image_deblurring` - Quaternion Image Deblurring (QSLST vs NS/HON)**
560
+
561
+ - **What it is**: Compares QSLST (Algorithm 2) with our NS variants on restoring a blurred/noisy image. Two QSLST paths are provided: a literal matrix-based implementation and an efficient FFT specialization for convolution with periodic boundary (BCCB).
562
+ - **Why it matters**: The target solution is Tikhonov-regularized: x_Ξ» = (A^T A + Ξ»I)^{-1} A^T b. FFT diagonalization yields an O(N log N) filter; NS can match it via an augmented system or via inverse-NS on T in the frequency domain.
563
+ - **Output**: Side-by-side grid with Clean, Observed, QSLST-FFT, QSLST-Matrix, NS, and HON panels, including PSNR/SSIM and timing. Images saved to `output_figures/`.
564
+ - **Usage**:
565
+ ```bash
566
+ uv run run_analysis.py image_deblurring
567
+ # Options (when running the script directly):
568
+ # --size 32 # grid size (default 32)
569
+ # --lam 1e-3 # Tikhonov lambda (default 1e-3)
570
+ # --snr 30 # optional AWGN SNR in dB
571
+ # --ns_mode {dense,sparse,fftT,tikhonov_aug}
572
+ # --ns_iters K # iterations for fftT solver
573
+ # --fftT_order {2,3} # 2=Newton–Schulz, 3=Halley (cubic)
574
+ ```
575
+
576
+ #### Problem formulation
577
+
578
+ - Blur operator A is real (2D convolution, periodic boundary), b is the observed quaternion image (RGB mapped to q=(0,R,G,B)).
579
+ - Tikhonov-regularized LS: minimize ||A x βˆ’ b||^2 + Ξ»||x||^2 β‡’ (A^T A + Ξ»I) x = A^T b.
580
+ - With real A, quaternion components decouple; FFT diagonalizes A^T A.
581
+
582
+ #### Methods compared
583
+
584
+ - QSLST-FFT: XΜ‚ = conj(HΜ‚) BΜ‚ / (|HΜ‚|^2 + Ξ») per frequency.
585
+ - QSLST-Matrix: T = A^T A + Ξ»I; x = T^+ A^T b per component.
586
+ - NS (fftT, order-2): inverse-NS on T: y ← y (2 βˆ’ T y); x β‰ˆ y A^T b.
587
+ - HON-NS (fftT, order-3): cubic inverse-NS per frequency: y ← y (1 + r + r^2), r = 1 βˆ’ T y.
588
+ - NS (tikhonov_aug): augmented C = [A; √λ I], y = [b; 0]; x = C^† y (exact but slower when dense).
589
+
590
+ #### Examples
591
+
592
+ ```bash
593
+ # FFT inverse-NS (order-2)
594
+ uv run run_analysis.py image_deblurring --size 32 --lam 1e-3 --snr 30 \
595
+ --ns_mode fftT --fftT_order 2 --ns_iters 14
596
+
597
+ # FFT inverse-NS (order-3)
598
+ uv run run_analysis.py image_deblurring --size 32 --lam 1e-3 --snr 30 \
599
+ --ns_mode fftT --fftT_order 3 --ns_iters 10
600
+
601
+ # Augmented NS (dense; small sizes only)
602
+ uv run run_analysis.py image_deblurring --size 32 --lam 1e-3 --snr 30 --ns_mode tikhonov_aug
603
+ ```
604
+
605
+ #### Recommended default test
606
+
607
+ ```bash
608
+ uv run run_analysis.py image_deblurring --size 64 --lam 1e-3 --snr 40 --ns_mode fftT --fftT_order 3 --ns_iters 12
609
+ ```
610
+
611
+ #### Parameters
612
+
613
+ - --size N: resize `data/images/kodim16.png` to NΓ—N (default 32).
614
+ - --lam Ξ»: Tikhonov regularization (default 1e-3).
615
+ - --snr dB: add AWGN at the given SNR.
616
+ - --ns_mode: fftT (recommended), tikhonov_aug (exact), dense/sparse (unregularized reference).
617
+ - --ns_iters: iterations for fftT (12–20 typical).
618
+ - --fftT_order: 2 (quadratic) or 3 (cubic; fewer iterations).
619
+
620
+ - **Input**: Generated 16Γ—16 test images with known patterns
621
+ - **Output**: Matrix completion results and PSNR evolution
622
+ - **Shows**: Algorithm performance on controlled, reproducible test cases
623
+
624
+ ### **πŸ”¬ `synthetic_matrices` - Algorithm Validation**
625
+
626
+ - **Input**: Various synthetic matrices (dense, sparse, ill-conditioned) + validation example from literature
627
+ - **Output**: Pseudoinverse computation results, timing, accuracy validation, and interactive plots
628
+ - **Shows**: Algorithm performance on different matrix types, including known theoretical result from Huang et al. (2015)
629
+ - **Note**: Generates interactive plots (not saved to files) for convergence analysis
630
+
631
+ ### **🎯 `schur_demo` - Comprehensive Schur Decomposition Analysis**
632
+
633
+ - **What it is**: Educational demo comparing rayleigh vs aed variants for quaternion Schur decomposition
634
+ - **Perfect for**: Understanding algorithm behavior and performance differences
635
+ - **Duration**: ~2-5 minutes (depends on matrix size)
636
+ - **Input**: Configurable matrix size (default: 10, can specify up to 25+)
637
+ - **Output**: Comprehensive analysis and comparison tables:
638
+ - Convergence results for both rayleigh and aed variants
639
+ - Performance comparison across different matrix types
640
+ - Educational insights about algorithm selection
641
+ - Detailed eigenvalue analysis and structure verification
642
+ - **Covers**:
643
+ - **Hermitian matrices**: Guaranteed diagonal Schur form
644
+ - **Random matrices**: Gaussian, skew-symmetric, ill-conditioned, pure imaginary
645
+ - **Synthetic construction**: Upper triangular and diagonal test cases
646
+ - **Algorithm comparison**: rayleigh vs aed variant performance
647
+ - **Educational insights**: When to use which algorithm
648
+ - **Usage**:
649
+
650
+ ```bash
651
+ # Default size (10x10) - fast testing
652
+ uv run run_analysis.py schur_demo
653
+
654
+ # Custom size - comprehensive analysis
655
+ uv run run_analysis.py schur_demo 15
656
+
657
+ # Large size - full performance analysis
658
+ uv run run_analysis.py schur_demo 25
659
+ ```
660
+
661
+ ## πŸ”¬ Core Functionality
662
+
663
+ ### Quaternion Matrix Operations
664
+
665
+ ```python
666
+ import quaternion
667
+ from core.utils import (
668
+ quat_matmat,
669
+ quat_frobenius_norm,
670
+ quat_eye,
671
+ matrix_norm, # unified interface: 'fro', 1, 2, inf
672
+ induced_matrix_norm_1, # max column sum of |A_ij|
673
+ induced_matrix_norm_inf # max row sum of |A_ij|
674
+ )
675
+ from core.utils import power_iteration, power_iteration_nonhermitian # see notes below
676
+ from core.solver import NewtonSchulzPseudoinverse, HigherOrderNewtonSchulzPseudoinverse
677
+
678
+ # Create quaternion matrices
679
+ A = quaternion.as_quat_array(...)
680
+ B = quaternion.as_quat_array(...)
681
+
682
+ # Compute the Frobenius norm of matrix A
683
+ norm_A = quat_frobenius_norm(A)
684
+ print(f"Frobenius norm of matrix A: {norm_A:.6f}")
685
+
686
+ # Matrix multiplication
687
+ C = quat_matmat(A, B)
688
+
689
+ # Compute pseudoinverse (baseline damped Newton–Schulz)
690
+ ns_solver = NewtonSchulzPseudoinverse(gamma=0.5)
691
+ A_pinv_ns, ns_residuals, ns_metrics = ns_solver.compute(A)
692
+
693
+ # Compute pseudoinverse (higher-order third-order Newton–Schulz, cubic local rate)
694
+ hon_solver = HigherOrderNewtonSchulzPseudoinverse()
695
+ A_pinv_hon, hon_residuals, hon_metrics = hon_solver.compute(A)
696
+
697
+ # Solve linear system A*x = b using Q-GMRES
698
+ from core.solver import QGMRESSolver
699
+
700
+ # Create Q-GMRES solver without preconditioning
701
+ qgmres_solver = QGMRESSolver(tol=1e-6, max_iter=100, verbose=False, preconditioner='none')
702
+
703
+ # Solve the system
704
+ x, info = qgmres_solver.solve(A, b)
705
+ print(f"Solution found in {info['iterations']} iterations")
706
+ print(f"Final residual: {info['residual']:.2e}")
707
+
708
+ # Create Q-GMRES solver with LU preconditioning for enhanced convergence
709
+ qgmres_solver_lu = QGMRESSolver(tol=1e-6, max_iter=100, verbose=False, preconditioner='left_lu')
710
+ x_prec, info_prec = qgmres_solver_lu.solve(A, b)
711
+ print(f"With LU preconditioning: {info_prec['iterations']} iterations")
712
+ print(f"Preconditioned residual: {info_prec['residual']:.2e}")
713
+ ```
714
+
715
+ #### Matrix Norms (Quaternion Matrices)
716
+
717
+ ```python
718
+ import numpy as np
719
+ import quaternion
720
+ from core.utils import matrix_norm, quat_frobenius_norm, induced_matrix_norm_1, induced_matrix_norm_inf
721
+
722
+ # Random quaternion matrix (m x n)
723
+ m, n = 4, 5
724
+ A = quaternion.as_quat_array(np.random.randn(m, n, 4))
725
+
726
+ # Frobenius norm
727
+ nf = matrix_norm(A, 'fro') # same as quat_frobenius_norm(A)
728
+
729
+ # Induced 1-norm (max column sum of |A_ij|)
730
+ n1 = matrix_norm(A, 1) # or induced_matrix_norm_1(A)
731
+
732
+ # Induced infinity-norm (max row sum of |A_ij|)
733
+ ninf = matrix_norm(A, np.inf) # or induced_matrix_norm_inf(A)
734
+
735
+ # Spectral 2-norm (largest singular value) β€” square matrices
736
+ B = quaternion.as_quat_array(np.random.randn(5, 5, 4))
737
+ n2 = matrix_norm(B, 2) # via quaternion SVD (costlier)
738
+
739
+ print(nf, n1, ninf, n2)
740
+ ```
741
+
742
+ ### Matrix Generation
743
+
744
+ #### **🎲 Random Matrix Generation**
745
+
746
+ ```python
747
+ from core.data_gen import create_test_matrix, create_sparse_quat_matrix
748
+
749
+ # Generate random dense matrix
750
+ X = create_test_matrix(m=100, n=50, rank=20)
751
+
752
+ # Generate sparse matrix
753
+ X_sparse = create_sparse_quat_matrix(m=100, n=50, density=0.1)
754
+ ```
755
+
756
+ #### **πŸ”§ Creating Custom Quaternion Matrices**
757
+
758
+ **Step-by-Step Guide to Building Your Own Quaternion Matrices:**
759
+
760
+ ##### **1. Understanding Quaternion Format**
761
+
762
+ Quaternion matrices in QuatIca use the format: `[real, i, j, k]` components
763
+
764
+ - **Real component**: Scalar part (index 0)
765
+ - **i component**: First imaginary part (index 1)
766
+ - **j component**: Second imaginary part (index 2)
767
+ - **k component**: Third imaginary part (index 3)
768
+
769
+ ##### **2. Example: Pauli Matrices in Quaternion Format**
770
+
771
+ **What are Pauli Matrices?**
772
+ Pauli matrices are fundamental 2Γ—2 matrices in quantum mechanics:
773
+
774
+ - **σ₁ (sigma_x)**: `[[0, 1], [1, 0]]` - represents spin-x measurement
775
+ - **Οƒβ‚‚ (sigma_y)**: `[[0, -i], [i, 0]]` - represents spin-y measurement
776
+ - **σ₃ (sigma_z)**: `[[1, 0], [0, -1]]` - represents spin-z measurement
777
+ - **Οƒβ‚€ (identity)**: `[[1, 0], [0, 1]]` - identity matrix
778
+
779
+ **Building Pauli Matrices as Quaternion Matrices (Correct Method):**
780
+
781
+ ```python
782
+ import numpy as np
783
+ import quaternion
784
+
785
+ def create_pauli_matrices_quaternion():
786
+ """Create Pauli matrices in quaternion format using the correct pattern"""
787
+
788
+ # Step 1: Create numpy arrays with shape (rows, cols, 4) for [real, i, j, k]
789
+ # Each matrix is 2x2, so we need (2, 2, 4) arrays
790
+ sigma_0_array = np.zeros((2, 2, 4), dtype=float)
791
+ sigma_x_array = np.zeros((2, 2, 4), dtype=float)
792
+ sigma_y_array = np.zeros((2, 2, 4), dtype=float)
793
+ sigma_z_array = np.zeros((2, 2, 4), dtype=float)
794
+
795
+ # Step 2: Fill the components [real, i, j, k]
796
+ # sigma_0 (identity): [1, 0, 0, 0] for diagonal, [0, 0, 0, 0] for off-diagonal
797
+ sigma_0_array[0, 0, 0] = 1.0 # real component of (0,0)
798
+ sigma_0_array[1, 1, 0] = 1.0 # real component of (1,1)
799
+
800
+ # sigma_x: [0, 0, 0, 0] for diagonal, [0, 0, 0, 0] for (0,1), [1, 0, 0, 0] for (1,0)
801
+ sigma_x_array[0, 1, 0] = 1.0 # real component of (0,1)
802
+ sigma_x_array[1, 0, 0] = 1.0 # real component of (1,0)
803
+
804
+ # sigma_y: [0, 0, 0, 0] for diagonal, [0, -1, 0, 0] for (0,1), [0, 1, 0, 0] for (1,0)
805
+ sigma_y_array[0, 1, 1] = -1.0 # i component of (0,1)
806
+ sigma_y_array[1, 0, 1] = 1.0 # i component of (1,0)
807
+
808
+ # sigma_z: [1, 0, 0, 0] for (0,0), [-1, 0, 0, 0] for (1,1)
809
+ sigma_z_array[0, 0, 0] = 1.0 # real component of (0,0)
810
+ sigma_z_array[1, 1, 0] = -1.0 # real component of (1,1)
811
+
812
+ # Step 3: Convert to quaternion arrays using the correct pattern
813
+ # Pattern: quaternion.as_quat_array(array.reshape(-1, 4)).reshape(rows, cols)
814
+ sigma_0 = quaternion.as_quat_array(sigma_0_array.reshape(-1, 4)).reshape(2, 2)
815
+ sigma_x = quaternion.as_quat_array(sigma_x_array.reshape(-1, 4)).reshape(2, 2)
816
+ sigma_y = quaternion.as_quat_array(sigma_y_array.reshape(-1, 4)).reshape(2, 2)
817
+ sigma_z = quaternion.as_quat_array(sigma_z_array.reshape(-1, 4)).reshape(2, 2)
818
+
819
+ return sigma_0, sigma_x, sigma_y, sigma_z
820
+
821
+ # Usage example
822
+ sigma_0, sigma_x, sigma_y, sigma_z = create_pauli_matrices_quaternion()
823
+
824
+ print("Pauli matrices in quaternion format:")
825
+ print(f"Οƒβ‚€ (identity):\n{sigma_0}")
826
+ print(f"σ₁ (sigma_x):\n{sigma_x}")
827
+ print(f"Οƒβ‚‚ (sigma_y):\n{sigma_y}")
828
+ print(f"σ₃ (sigma_z):\n{sigma_z}")
829
+ ```
830
+
831
+ ##### **3. General Steps for Custom Matrices**
832
+
833
+ ```python
834
+ # Step 1: Create numpy array with shape (rows, cols, 4) for [real, i, j, k]
835
+ matrix_quat = np.zeros((rows, cols, 4), dtype=float)
836
+
837
+ # Step 2: Fill the components element by element
838
+ for i in range(rows):
839
+ for j in range(cols):
840
+ matrix_quat[i, j, 0] = real_part[i, j] # Real component
841
+ matrix_quat[i, j, 1] = i_part[i, j] # i component
842
+ matrix_quat[i, j, 2] = j_part[i, j] # j component
843
+ matrix_quat[i, j, 3] = k_part[i, j] # k component
844
+
845
+ # Step 3: Convert to quaternion array using the correct pattern
846
+ # Pattern: quaternion.as_quat_array(array.reshape(-1, 4)).reshape(rows, cols)
847
+ quat_matrix = quaternion.as_quat_array(matrix_quat.reshape(-1, 4)).reshape(rows, cols)
848
+ ```
849
+
850
+ ##### **4. Common Patterns**
851
+
852
+ ```python
853
+ # Real matrix: [real, 0, 0, 0]
854
+ real_matrix = np.zeros((2, 2, 4))
855
+ real_matrix[0, 0, 0] = 1.0 # (0,0) real component
856
+ real_matrix[0, 1, 0] = 2.0 # (0,1) real component
857
+ real_matrix[1, 0, 0] = 3.0 # (1,0) real component
858
+ real_matrix[1, 1, 0] = 4.0 # (1,1) real component
859
+ real_quat = quaternion.as_quat_array(real_matrix.reshape(-1, 4)).reshape(2, 2)
860
+
861
+ # Complex matrix: [real, i, 0, 0]
862
+ complex_matrix = np.zeros((2, 2, 4))
863
+ complex_matrix[0, 0, 0] = 1.0 # (0,0) real part
864
+ complex_matrix[0, 0, 1] = 0.0 # (0,0) i part
865
+ complex_matrix[0, 1, 0] = 0.0 # (0,1) real part
866
+ complex_matrix[0, 1, 1] = 1.0 # (0,1) i part
867
+ complex_matrix[1, 0, 0] = 0.0 # (1,0) real part
868
+ complex_matrix[1, 0, 1] = -1.0 # (1,0) i part
869
+ complex_matrix[1, 1, 0] = 1.0 # (1,1) real part
870
+ complex_matrix[1, 1, 1] = 0.0 # (1,1) i part
871
+ complex_quat = quaternion.as_quat_array(complex_matrix.reshape(-1, 4)).reshape(2, 2)
872
+
873
+ # Pure quaternion: [0, i, j, k]
874
+ pure_quat = np.zeros((2, 2, 4))
875
+ pure_quat[0, 0, 1] = 0.0 # (0,0) i part
876
+ pure_quat[0, 0, 2] = 0.0 # (0,0) j part
877
+ pure_quat[0, 0, 3] = 1.0 # (0,0) k part
878
+ pure_quat[0, 1, 1] = 1.0 # (0,1) i part
879
+ pure_quat[0, 1, 2] = 0.0 # (0,1) j part
880
+ pure_quat[0, 1, 3] = 0.0 # (0,1) k part
881
+ pure_quat[1, 0, 1] = 1.0 # (1,0) i part
882
+ pure_quat[1, 0, 2] = 0.0 # (1,0) j part
883
+ pure_quat[1, 0, 3] = 0.0 # (1,0) k part
884
+ pure_quat[1, 1, 1] = 0.0 # (1,1) i part
885
+ pure_quat[1, 1, 2] = 0.0 # (1,1) j part
886
+ pure_quat[1, 1, 3] = -1.0 # (1,1) k part
887
+ pure_quat_result = quaternion.as_quat_array(pure_quat.reshape(-1, 4)).reshape(2, 2)
888
+ ```
889
+
890
+ ## πŸ”§ Matrix Decompositions Included
891
+
892
+ QuatIca provides robust implementations of fundamental matrix decompositions for quaternion matrices:
893
+
894
+ **πŸ“– For a comprehensive overview of all decomposition methods, algorithms, and usage recommendations, see [`core/decomp/README.md`](core/decomp/README.md).**
895
+
896
+ ### **QR Decomposition**
897
+
898
+ ```python
899
+ from core.decomp.qsvd import qr_qua
900
+
901
+ # QR decomposition of quaternion matrix
902
+ Q, R = qr_qua(X_quat)
903
+ # X_quat = Q @ R, where Q has orthonormal columns and R is upper triangular
904
+ ```
905
+
906
+ ### **Quaternion SVD (Q-SVD)**
907
+
908
+ ```python
909
+ from core.decomp.qsvd import classical_qsvd, classical_qsvd_full
910
+
911
+ # Truncated Q-SVD for low-rank approximation
912
+ U, s, V = classical_qsvd(X_quat, R)
913
+ # X_quat β‰ˆ U @ diag(s) @ V^H
914
+
915
+ # Full Q-SVD for complete decomposition
916
+ U_full, s_full, V_full = classical_qsvd_full(X_quat)
917
+ # X_quat = U_full @ Ξ£ @ V_full^H
918
+ ```
919
+
920
+ **Features:**
921
+
922
+ - βœ… **Mathematically validated** with comprehensive tests
923
+ - βœ… **Perfect reconstruction** at full rank
924
+ - βœ… **Monotonic error decrease** with increasing rank
925
+ - βœ… **Robust across matrix sizes** (tested on 4Γ—3 to 8Γ—6 matrices)
926
+ - βœ… **Production-ready** with 10/10 tests passing
927
+
928
+ ### **Randomized Q-SVD (Fast Approximation)**
929
+
930
+ ```python
931
+ from core.decomp.qsvd import rand_qsvd
932
+
933
+ # Fast randomized Q-SVD for large matrices
934
+ U, s, V = rand_qsvd(X_quat, R, oversample=10, n_iter=2)
935
+ # X_quat β‰ˆ U @ diag(s) @ V^H (approximate, rank-R)
936
+ ```
937
+
938
+ **Features:**
939
+
940
+ - βœ… **Fast approximation** for large matrices
941
+ - βœ… **Configurable accuracy** via power iterations and oversampling
942
+ - βœ… **Memory efficient** compared to full Q-SVD
943
+ - βœ… **Production-ready** with comprehensive test suite
944
+ - βœ… **Based on Gaussian sketching** with power iterations
945
+
946
+ ### **Eigenvalue Decomposition (Hermitian Matrices)**
947
+
948
+ ```python
949
+ from core.decomp import quaternion_eigendecomposition, quaternion_eigenvalues, quaternion_eigenvectors
950
+
951
+ # Full eigendecomposition: A = V @ diag(Ξ») @ V^H
952
+ eigenvalues, eigenvectors = quaternion_eigendecomposition(A_quat)
953
+ # A_quat @ eigenvectors[:, i] = eigenvalues[i] * eigenvectors[:, i]
954
+
955
+ # Extract only eigenvalues
956
+ eigenvals = quaternion_eigenvalues(A_quat)
957
+
958
+ # Extract only eigenvectors
959
+ eigenvecs = quaternion_eigenvectors(A_quat)
960
+ ```
961
+
962
+ **Features:**
963
+
964
+ - βœ… **Hermitian matrices only** - specialized for real eigenvalues
965
+ - βœ… **Tridiagonalization approach** - efficient Householder transformations
966
+ - βœ… **High accuracy** - residuals < 10^-15
967
+ - βœ… **Production-ready** with 15/15 tests passing
968
+ - βœ… **Based on MATLAB QTFM** - follows established mathematical approach
969
+
970
+ ### Power Iteration (Hermitian vs Non-Hermitian)
971
+
972
+ ```python
973
+ from core.utils import power_iteration, power_iteration_nonhermitian
974
+
975
+ # Hermitian case (recommended): returns dominant eigenvector and a real eigenvalue estimate
976
+ v_dom, lambda_real = power_iteration(A_hermitian, return_eigenvalue=True, verbose=False)
977
+
978
+ # General (non-Hermitian) case (experimental): complex eigenvalue in a fixed complex subfield
979
+ q_vec, lambda_complex, residuals = power_iteration_nonhermitian(
980
+ A_general,
981
+ max_iterations=3000,
982
+ eig_tol=1e-12,
983
+ res_tol=1e-10,
984
+ seed=0,
985
+ return_vector=True,
986
+ )
987
+ ```
988
+
989
+ Notes:
990
+
991
+ - Use `power_iteration` for Hermitian quaternion matrices; eigenvalues are real and convergence behavior matches theory.
992
+ - If `power_iteration` is applied to non-Hermitian matrices, the returned scalar (when requested) is a real magnitude-based Rayleigh-quotient heuristic (not a true complex eigenvalue).
993
+ - For general (non-Hermitian) quaternion matrices, use `power_iteration_nonhermitian` (experimental). It maps to a 2nΓ—2n complex adjoint in a fixed complex subfield and returns a complex eigenvalue along with a quaternion eigenvector approximation. Residual `||Mv - Ξ» v||_2` is available for convergence diagnostics.
994
+
995
+ See the demo section β€œNon-Hermitian Complex Power Iteration (Experimental)” in `QuatIca_Core_Functionality_Demo.py` / `.ipynb` for a complete example and residual plots.
996
+
997
+ ### **LU Decomposition (Gaussian Elimination with Partial Pivoting)**
998
+
999
+ ```python
1000
+ from core.decomp import quaternion_lu
1001
+
1002
+ # LU decomposition with permutation: P @ A = L @ U
1003
+ L, U, P = quaternion_lu(A_quat, return_p=True)
1004
+ # A_quat = (P^T @ L) @ U, where L is lower triangular with unit diagonal
1005
+ # U is upper triangular, P is permutation matrix
1006
+
1007
+ # LU decomposition without permutation: A = L @ U
1008
+ L_perm, U_perm = quaternion_lu(A_quat, return_p=False)
1009
+ # A_quat = L_perm @ U_perm, where L_perm is permuted version of L
1010
+ ```
1011
+
1012
+ **Features:**
1013
+
1014
+ - βœ… **Partial pivoting** - numerically stable for ill-conditioned matrices
1015
+ - βœ… **Two output modes** - with/without permutation matrix
1016
+ - βœ… **Perfect reconstruction** - P*A = L*U or A = L\*U depending on mode
1017
+ - βœ… **Production-ready** with comprehensive test suite
1018
+ - βœ… **Based on MATLAB QTFM**
1019
+ - βœ… **Handles rectangular matrices** - works for mΓ—n matrices
1020
+
1021
+ ### **Tridiagonalization (Householder Transformations)**
1022
+
1023
+ ```python
1024
+ from core.decomp import tridiagonalize
1025
+
1026
+ # Tridiagonalize Hermitian matrix: P @ A @ P^H = B
1027
+ P, B = tridiagonalize(A_quat)
1028
+ # B is real tridiagonal with same eigenvalues as A
1029
+ # P is unitary transformation matrix
1030
+ ```
1031
+
1032
+ **Features:**
1033
+
1034
+ - βœ… **Householder transformations** - numerically stable
1035
+ - βœ… **Real tridiagonal output** - efficient for eigenvalue computation
1036
+ - βœ… **Unitary transformations** - preserves eigenvalues
1037
+ - βœ… **Production-ready** with 13/13 tests passing
1038
+ - βœ… **Recursive algorithm** - handles matrices of any size
1039
+
1040
+ ### **Hessenberg Form (Upper Hessenberg Reduction)**
1041
+
1042
+ ```python
1043
+ from core.decomp.hessenberg import hessenbergize, is_hessenberg
1044
+ from core.utils import quat_hermitian, quat_matmat
1045
+
1046
+ # Reduce a general quaternion matrix to Hessenberg form
1047
+ P, H = hessenbergize(X_quat)
1048
+ # Verify: H = P @ X_quat @ P^H and H is upper Hessenberg
1049
+ ```
1050
+
1051
+ **Features:**
1052
+
1053
+ - βœ… **Householder similarity transforms** - numerically stable
1054
+ - βœ… **Unitarity preserved** - P is unitary (P^H P = I)
1055
+ - βœ… **Structure** - H has zeros strictly below the first subdiagonal
1056
+ - βœ… **Works for general (non-Hermitian) matrices**
1057
+
1058
+ ### **πŸ“Š Visualization and Validation**
1059
+
1060
+ QuatIca includes a comprehensive visualization package for validating and demonstrating the correctness of our implementations:
1061
+
1062
+ #### **Q-SVD Reconstruction Error Analysis**
1063
+
1064
+ ```bash
1065
+ # Generate convincing visualizations of Q-SVD validation
1066
+ uv run tests/validation/qsvd_reconstruction_analysis.py
1067
+ ```
1068
+
1069
+ This creates professional-quality plots showing:
1070
+
1071
+ - **Perfect monotonicity**: Reconstruction error decreases as rank increases
1072
+ - **Perfect reconstruction**: Full rank achieves 0.000000 error
1073
+ - **Consistent behavior**: Same patterns across different matrix sizes
1074
+ - **Mathematical correctness**: Our Q-SVD follows proper SVD principles
1075
+
1076
+ **Generated plots:**
1077
+
1078
+ - `qsvd_reconstruction_error_vs_rank.png` - Detailed analysis for each matrix size
1079
+ - `qsvd_relative_error_summary.png` - Summary with log scale convergence
1080
+
1081
+ #### **Eigenvalue Decomposition Testing**
1082
+
1083
+ ```bash
1084
+ # Test eigenvalue decomposition functionality
1085
+ uv run run_analysis.py eigenvalue_test
1086
+
1087
+ # Run comprehensive unit tests
1088
+ uv run -m pytest tests/decomp/test_eigen.py -v
1089
+ uv run -m pytest tests/decomp/test_tridiagonalize.py -v
1090
+ ```
1091
+
1092
+ This validates:
1093
+
1094
+ - **Eigenvalue accuracy**: A @ v = Ξ» @ v for each eigenpair
1095
+ - **Hermitian properties**: Real eigenvalues for Hermitian matrices
1096
+ - **Tridiagonalization**: P @ A @ P^H = B transformation
1097
+ - **Numerical stability**: High precision with residuals < 10^-15
1098
+
1099
+ #### **Why This Visualization is Convincing**
1100
+
1101
+ 1. **Mathematical Validation**: Shows expected SVD behavior
1102
+ 2. **Visual Proof**: Clear graphs demonstrate monotonicity
1103
+ 3. **Comprehensive Testing**: Multiple matrix sizes tested
1104
+ 4. **Quantitative Results**: Exact error values provided
1105
+ 5. **Professional Quality**: High-resolution plots suitable for presentations
1106
+
1107
+ ## πŸ“Š Analysis and Visualization
1108
+
1109
+ The library includes comprehensive analysis tools:
1110
+
1111
+ - **Pseudoinverse Analysis**: Study the structure and properties of quaternion pseudoinverses
1112
+ - **Q-GMRES Solver**: Iterative Krylov subspace method for solving quaternion linear systems A\*x = b
1113
+ - **Class-aware Analysis**: Analyze pseudoinverses with respect to data classes (e.g., CIFAR-10)
1114
+ - **Spectral Analysis**: Examine singular value distributions and spectral properties
1115
+ - **Visualization**: Generate detailed plots of matrix properties, reconstruction filters, and more
1116
+
1117
+ ## 🎯 Core Functionality Demo Files
1118
+
1119
+ ### **πŸ“‹ `QuatIca_Core_Functionality_Demo.py` - Interactive Core Functionality Tests**
1120
+
1121
+ - **What it is**: Comprehensive Python script testing all 16 core functionality areas
1122
+ - **Perfect for**: Verifying that all README code examples work correctly
1123
+ - **Duration**: ~30 seconds
1124
+ - **Output**: Detailed verification of all core functions with numerical accuracy metrics
1125
+ - **Covers**:
1126
+ - Basic matrix operations (creation, multiplication, norms)
1127
+ - QR decomposition with reconstruction verification
1128
+ - Quaternion SVD (Q-SVD) - both truncated and full
1129
+ - Randomized Q-SVD for large matrix approximation
1130
+ - Eigenvalue decomposition for Hermitian matrices
1131
+ - LU decomposition with partial pivoting
1132
+ - Tridiagonalization using Householder transformations
1133
+ - Pseudoinverse computation using Newton-Schulz
1134
+ - Linear system solving with Q-GMRES
1135
+ - Matrix component visualization
1136
+ - Determinant and rank computation
1137
+ - Power iteration for dominant eigenvectors
1138
+ - Hessenberg form reduction
1139
+ - Advanced eigenvalue methods (Hermitian and synthetic cases)
1140
+ - Schur decomposition with synthetic validation
1141
+ - Tensor operations (Frobenius norm, unfolding/folding)
1142
+
1143
+ **Usage:**
1144
+
1145
+ ```bash
1146
+ uv run QuatIca_Core_Functionality_Demo.py
1147
+ ```
1148
+
1149
+ ### **πŸ““ `QuatIca_Core_Functionality_Demo.ipynb` - Jupyter Notebook Version**
1150
+
1151
+ - **What it is**: Interactive Jupyter notebook version of the core functionality tests
1152
+ - **Perfect for**: Step-by-step exploration and learning
1153
+ - **Features**:
1154
+ - Cell-by-cell execution for detailed understanding
1155
+ - Interactive visualizations
1156
+ - Easy modification and experimentation
1157
+ - Educational comments and explanations
1158
+
1159
+ **Usage:**
1160
+
1161
+ ```bash
1162
+ jupyter notebook QuatIca_Core_Functionality_Demo.ipynb
1163
+ ```
1164
+
1165
+ ### **πŸ“– `README_Demo.md` - Demo Documentation**
1166
+
1167
+ - **What it is**: Detailed documentation explaining how to use the demo files
1168
+ - **Perfect for**: Understanding the demo structure and troubleshooting
1169
+ - **Contains**: Usage instructions, expected outputs, and troubleshooting tips
1170
+
1171
+ ## 🎯 Applications
1172
+
1173
+ ### Image Processing
1174
+
1175
+ - **Matrix Completion**: Fill in missing pixels in images
1176
+ - **Image Inpainting**: Reconstruct damaged or occluded regions
1177
+ - **Feature Analysis**: Study quaternion representations of image features
1178
+
1179
+ ### Signal Processing
1180
+
1181
+ - **Quaternion Signal Analysis**: Process 3D/4D signals using quaternion algebra
1182
+ - **Spectral Analysis**: Analyze frequency domain properties
1183
+ - **Filter Design**: Design quaternion-based filters
1184
+
1185
+ ### Data Science
1186
+
1187
+ - **Dimensionality Reduction**: Use quaternion PCA and factorizations
1188
+ - **Clustering**: Apply quaternion-based clustering algorithms
1189
+ - **Feature Engineering**: Create quaternion-based features
1190
+
1191
+ ## πŸ”§ Advanced Usage
1192
+
1193
+ ### Direct Script Execution (Optional)
1194
+
1195
+ **πŸ’‘ Tip: Use the runner script above - it's much easier!**
1196
+
1197
+ If you need to run scripts directly or modify them:
1198
+
1199
+ ```bash
1200
+ # From main directory
1201
+ uv run tests/pseudoinverse/analyze_cifar10_pseudoinverse.py
1202
+ uv run applications/image_completion/script_real_image_completion.py
1203
+ ```
1204
+
1205
+ ### Running Tests
1206
+
1207
+ ```bash
1208
+ # Run pseudoinverse analysis
1209
+ uv run tests/pseudoinverse/analyze_cifar10_pseudoinverse.py
1210
+ ```
1211
+
1212
+ ### Adding New Features
1213
+
1214
+ 1. Add core functionality to `core/` directory
1215
+ 2. Create tests in `tests/unit/`
1216
+ 3. Add analysis scripts in `tests/pseudoinverse/`
1217
+ 4. Update `run_analysis.py` for new scripts
1218
+
1219
+ ## πŸ“š References
1220
+
1221
+ - **Quaternion Pseudoinverse**: Huang, L., Wang, Q.-W., & Zhang, Y. (2015). The Moore–Penrose inverses of matrices over quaternion polynomial rings. Linear Algebra and its Applications, 475, 45-61.
1222
+ - **Q-GMRES Solver**: Jia, Z., & Ng, M. K. (2021). Structure Preserving Quaternion Generalized Minimal Residual Method. SIAM Journal on Matrix Analysis and Applications (SIMAX), 42(2), 1-25.
1223
+ - **Advanced Q-SVD Method**: Ma, R.-R., & Bai, Z.-J. (2018). A Structure-Preserving One-Sided Jacobi Method for Computing the SVD of a Quaternion Matrix. arXiv preprint arXiv:1811.08671.
1224
+ - **QSLST Image Restoration**: Fei, W., Tang, J., & Shan, M. (2025). Quaternion special least squares with Tikhonov regularization method in image restoration. Numerical Algorithms. doi: 10.1007/s11075-025-02187-6.
1225
+ - **Pass-Efficient Randomized Algorithms**: Ahmadi-Asl, S., Nobakht Kooshkghazi, M., & Leplat, V. (2025). Pass-efficient Randomized Algorithms for Low-rank Approximation of Quaternion Matrices. arXiv preprint arXiv:2507.13731.
1226
+ - **Newton-Schulz Algorithm**: Newton's method for matrix inversion and pseudoinverse computation
1227
+
1228
+ ## πŸš€ Upcoming Features (Coming Soon!)
1229
+
1230
+ ### **πŸ”¬ Advanced Quaternion Matrix Algorithms**
1231
+
1232
+ QuatIca is actively being extended with cutting-edge algorithms from recent research. The following features will be released soon:
1233
+
1234
+ #### **πŸ“Š Efficient Q-SVD Computation**
1235
+
1236
+ - **High-performance SVD** for quaternion matrices based on **Ma & Bai (2018)**
1237
+ - **Structure-preserving one-sided Jacobi method** for computing Q-SVD
1238
+ - **Optimized memory usage** for large-scale matrices
1239
+ - **Parallel computation** support for multi-core systems
1240
+
1241
+ #### **🎡 Advanced Signal Processing Tools**
1242
+
1243
+ - **Quaternion Fourier Transform** for 3D/4D signal analysis
1244
+ - **Frequency domain processing** with quaternion algebra
1245
+ - **Spectral analysis** for multi-dimensional signals
1246
+ - **Filter design** and signal reconstruction capabilities
1247
+
1248
+ #### **πŸ”’ Numerical Linear Algebra (NLA) Tools**
1249
+
1250
+ - **Schur Decomposition** using QR algorithm for quaternion matrices
1251
+ - **Eigenvalue computation** via iterative QR method
1252
+ - **Matrix diagonalization** for non-Hermitian quaternion matrices
1253
+ - **Structured eigenvalue problems** with quaternion arithmetic
1254
+
1255
+ #### **πŸ”— Quaternion Tensor Decompositions (Preview to Full Release)**
1256
+
1257
+ - **Tensor models**: HOSVD, Tucker, Tensor-Train (TT) adapted to quaternion tensors
1258
+ - **Core utilities**: tensor norms, entrywise magnitudes, mode-n unfolding/folding (already available in `core/tensor.py`)
1259
+ - **Demos & tests**: Notebook preview section and `tests/unit/test_tensor_quaternion_basics.py`
1260
+
1261
+ **Stay tuned for these exciting new features!** πŸš€
1262
+
1263
+ ## πŸ”§ Troubleshooting
1264
+
1265
+ ### **Common Issues and Solutions:**
1266
+
1267
+ #### **❌ "Command not found: python"**
1268
+
1269
+ - **Solution**: Install Python from [python.org](https://python.org)
1270
+ - **Alternative**: Try `python3` instead of `python`
1271
+
1272
+ #### **❌ "pip: command not found"**
1273
+
1274
+ - **Solution**: Python comes with pip. Try `python -m pip` instead of `pip`
1275
+ - **Alternative**: Install pip separately: `python -m ensurepip --upgrade`
1276
+
1277
+ #### **❌ "Permission denied" when installing packages**
1278
+
1279
+ - **Solution**: Use virtual environment (see installation steps above)
1280
+ - **Alternative**: Add `--user` flag: `pip install --user -r requirements.txt`
1281
+
1282
+ #### **❌ "numpy version too old"**
1283
+
1284
+ - **Solution**: Upgrade numpy: `pip install --upgrade numpy>=2.3.2`
1285
+ - **Check version**: `python -c "import numpy; print(numpy.__version__)"`
1286
+
1287
+ #### **❌ "Script not found"**
1288
+
1289
+ - **Solution**: Make sure you're in the correct directory (`QuatIca`)
1290
+ - **Check**: Run `ls` or `dir` to see if `run_analysis.py` exists
1291
+
1292
+ #### **❌ "Import error"**
1293
+
1294
+ - **Solution**: Activate virtual environment: `source quatica/bin/activate` (Mac/Linux) or `quatica\Scripts\activate` (Windows)
1295
+ - **Check**: You should see `(quatica)` at the start of your command line
1296
+
1297
+ #### **❌ "Memory error"**
1298
+
1299
+ - **Solution**: Close other applications to free RAM
1300
+ - **Alternative**: Use smaller datasets or reduce matrix sizes in scripts
1301
+
1302
+ #### **❌ "Slow performance"**
1303
+
1304
+ - **Check numpy version**: Must be >= 2.3.2 for optimal performance
1305
+ - **Solution**: `pip install --upgrade numpy>=2.3.2`
1306
+
1307
+ #### **❌ "No visualizations appear"**
1308
+
1309
+ - **Solution**: Make sure matplotlib backend is working: `python -c "import matplotlib.pyplot as plt; plt.plot([1,2,3]); plt.show()"`
1310
+ - **Alternative**: Check if `output_figures/` directory exists and has write permissions
1311
+ - **Note**: Visualizations are automatically saved to `output_figures/` directory
1312
+
1313
+ #### **⚠️ "DeprecationWarning about seaborn"**
1314
+
1315
+ - **This is normal**: The warning about seaborn date parsing is harmless and doesn't affect functionality
1316
+ - **Solution**: Can be ignored - it's a known issue with seaborn and will be fixed in future versions
1317
+
1318
+ ### **πŸ” Verification Steps:**
1319
+
1320
+ After installation, run these commands to verify everything works:
1321
+
1322
+ ```bash
1323
+ # 1. Check Python version
1324
+ python --version
1325
+
1326
+ # 2. Check numpy version (should be >= 2.3.2)
1327
+ python -c "import numpy; print(f'numpy: {numpy.__version__}')"
1328
+
1329
+ # 3. Check if virtual environment is active (should see (quatica))
1330
+ # If not, activate it: source quatica/bin/activate
1331
+
1332
+ # 4. Test the runner script
1333
+ python run_analysis.py
1334
+
1335
+ # 5. Run the tutorial (recommended first step)
1336
+ python run_analysis.py tutorial
1337
+
1338
+ # 6. Run a simple test
1339
+ python run_analysis.py pseudoinverse
1340
+ ```
1341
+
1342
+ ## 🀝 Contributing
1343
+
1344
+ This library is designed to be a comprehensive framework for quaternion linear algebra. Contributions are welcome for:
1345
+
1346
+ - New quaternion matrix operations
1347
+ - Additional factorization algorithms
1348
+ - Performance optimizations
1349
+ - New applications and examples
1350
+ - Documentation improvements
1351
+
1352
+ ## πŸ“„ License
1353
+
1354
+ This project is licensed under the **CC0 1.0 Universal** license - a public domain dedication that allows you to use, modify, and distribute this software freely for any purpose, including commercial use, without any restrictions.
1355
+
1356
+ **Key Points:**
1357
+
1358
+ - βœ… **Public Domain**: You can use this software for any purpose
1359
+ - βœ… **No Attribution Required**: You don't need to credit the original authors
1360
+ - βœ… **Commercial Use**: You can use it in commercial projects
1361
+ - βœ… **Modification**: You can modify and distribute your changes
1362
+ - βœ… **No Warranty**: The software is provided "as-is" without any warranties
1363
+
1364
+ **Full License Text:** See [`LICENSE.txt`](LICENSE.txt) for the complete license terms.
1365
+
1366
+ **Why CC0?** This license promotes the ideal of a free culture and encourages the further production of creative, cultural, and scientific works by allowing maximum freedom of use and redistribution.
1367
+
1368
+ ## πŸ“§ Support and Contact
1369
+
1370
+ For questions, bug reports, or contributions, please contact:
1371
+ **v dot leplat [at] innopolis dot ru**
1372
+
1373
+ We welcome feedback, collaboration opportunities, and contributions to the QuatIca project.
1374
+
1375
+ ---
1376
+
1377
+ **QuatIca**: Empowering quaternion-based numerical linear algebra for modern applications.