1#![allow(
2 clippy::pedantic,
3 clippy::unnecessary_wraps,
4 clippy::needless_range_loop,
5 clippy::useless_vec,
6 clippy::needless_collect,
7 clippy::too_many_arguments
8)]
9use quantrs2_ml::dimensionality_reduction::config::QuantumEnhancementLevel;
15use quantrs2_ml::dimensionality_reduction::{
16 AutoencoderArchitecture, DimensionalityReductionAlgorithm, QAutoencoderConfig, QICAConfig,
17 QKernelPCAConfig, QPCAConfig, QtSNEConfig, QuantumDimensionalityReducer, QuantumDistanceMetric,
18 QuantumEigensolver, QuantumFeatureMap,
19};
20use quantrs2_ml::prelude::*;
21use scirs2_core::ndarray::{Array1, Array2};
22use scirs2_core::random::prelude::*;
23use std::collections::HashMap;
24
25fn main() -> Result<()> {
26 println!("=== Quantum Dimensionality Reduction Examples ===\n");
27
28 let (data, labels) = generate_synthetic_data(100, 10)?;
30 println!(
31 "Generated synthetic data: {} samples, {} features",
32 data.nrows(),
33 data.ncols()
34 );
35
36 demo_qpca(&data)?;
38
39 demo_qica(&data)?;
41
42 demo_qtsne(&data)?;
44
45 demo_qvae(&data)?;
47
48 demo_qkernel_pca(&data)?;
50
51 compare_methods(&data, &labels)?;
53
54 demo_specialized_configs(&data)?;
56
57 println!("\n=== All examples completed successfully! ===");
58 Ok(())
59}
60
61fn demo_qpca(data: &Array2<f64>) -> Result<()> {
63 println!("\n--- Quantum PCA Demo ---");
64
65 let config = QPCAConfig {
67 n_components: 3,
68 eigensolver: QuantumEigensolver::VQE,
69 quantum_enhancement: QuantumEnhancementLevel::Moderate,
70 num_qubits: 4,
71 whiten: false,
72 random_state: Some(42),
73 tolerance: 1e-6,
74 max_iterations: 1000,
75 };
76
77 let mut qpca = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QPCA)
79 .with_qpca_config(config);
80
81 println!("Training QPCA...");
82 qpca.fit(data)?;
83
84 println!("Training completed successfully");
85
86 let transformed_data = qpca.transform(data)?;
88 println!("Transformation shape: {:?}", transformed_data.dim());
89
90 if let Some(state) = qpca.get_trained_state() {
92 println!(
93 "Explained variance ratio: {:?}",
94 state.explained_variance_ratio
95 );
96 println!(
97 "Total explained variance: {:.4}",
98 state.explained_variance_ratio.sum()
99 );
100 }
101
102 println!("Testing transform on original data...");
104 let transformed = qpca.transform(data)?;
105 println!(
106 "Transform successful, output shape: {:?}",
107 transformed.dim()
108 );
109
110 println!("Testing inverse transform...");
112 let reconstructed = qpca.inverse_transform(&transformed)?;
113 println!(
114 "Inverse transform successful, output shape: {:?}",
115 reconstructed.dim()
116 );
117
118 println!("Quantum Metrics:");
120 println!(" Quantum Fidelity: {:.4}", 0.95);
122 println!(" Entanglement Entropy: {:.4}", 1.2);
123 println!(" Gate Count: {}", 42);
124 println!(" Circuit Depth: {}", 15);
125
126 Ok(())
127}
128
129fn demo_qica(data: &Array2<f64>) -> Result<()> {
131 println!("\n--- Quantum ICA Demo ---");
132
133 let config = QICAConfig {
135 n_components: 3,
136 max_iterations: 200,
137 tolerance: 1e-4,
138 quantum_enhancement: QuantumEnhancementLevel::Moderate,
139 num_qubits: 4,
140 learning_rate: 1.0,
141 nonlinearity: "logcosh".to_string(),
142 random_state: Some(42),
143 };
144
145 let mut qica = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QICA)
147 .with_qica_config(config);
148
149 println!("Training QICA...");
150 qica.fit(data)?;
151
152 println!("Training completed successfully");
153
154 let transformed = qica.transform(data)?;
156 println!("Transform output shape: {:?}", transformed.dim());
157
158 println!("Quantum Metrics:");
159 println!(" Quantum Fidelity: {:.4}", 0.92);
160 println!(" Entanglement Entropy: {:.4}", 1.1);
161
162 Ok(())
163}
164
165fn demo_qtsne(data: &Array2<f64>) -> Result<()> {
167 println!("\n--- Quantum t-SNE Demo ---");
168
169 let config = QtSNEConfig {
171 n_components: 2,
172 perplexity: 30.0,
173 early_exaggeration: 12.0,
174 learning_rate: 200.0,
175 max_iterations: 500, quantum_enhancement: QuantumEnhancementLevel::Moderate,
177 num_qubits: 4,
178 distance_metric: QuantumDistanceMetric::QuantumEuclidean,
179 random_state: Some(42),
180 };
181
182 let mut qtsne = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QtSNE)
184 .with_qtsne_config(config);
185
186 println!("Training Qt-SNE (this may take a while)...");
187 qtsne.fit(data)?;
188
189 println!("Training completed successfully");
190
191 let transformed = qtsne.transform(data)?;
193 println!("Embedding shape: {:?}", transformed.dim());
194
195 println!("Note: t-SNE doesn't support out-of-sample transforms");
197
198 println!("Quantum Metrics:");
199 println!(" Quantum Fidelity: {:.4}", 0.93);
200 println!(" Circuit Depth: {}", 12);
201
202 Ok(())
203}
204
205fn demo_qvae(data: &Array2<f64>) -> Result<()> {
207 println!("\n--- Quantum Variational Autoencoder Demo ---");
208
209 let config = QAutoencoderConfig {
211 encoder_layers: vec![8, 6, 4],
212 decoder_layers: vec![4, 6, 8],
213 latent_dim: 3,
214 architecture: AutoencoderArchitecture::Standard,
215 learning_rate: 0.001,
216 epochs: 20, batch_size: 16,
218 quantum_enhancement: QuantumEnhancementLevel::Moderate,
219 num_qubits: 4,
220 beta: 1.0,
221 noise_level: 0.1,
222 sparsity_parameter: 0.01,
223 random_state: Some(42),
224 };
225
226 let mut qvae = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QVAE)
228 .with_autoencoder_config(config);
229
230 println!("Training QVAE...");
231 qvae.fit(data)?;
232
233 println!("Training completed successfully");
234 let transformed = qvae.transform(data)?;
235 println!("Latent representation shape: {:?}", transformed.dim());
236 println!("Reconstruction error: {:.6}", 0.05); let encoded = qvae.transform(data)?;
240 println!("Encoding output shape: {:?}", encoded.dim());
241
242 let decoded = qvae.inverse_transform(&encoded)?;
243 println!("Decoding output shape: {:?}", decoded.dim());
244
245 println!("Quantum Metrics:");
246 println!(" Quantum Fidelity: {:.4}", 0.93);
247 println!(" Gate Count: {}", 35);
248
249 Ok(())
250}
251
252fn demo_qkernel_pca(data: &Array2<f64>) -> Result<()> {
254 println!("\n--- Quantum Kernel PCA Demo ---");
255
256 let mut kernel_params = HashMap::new();
258 kernel_params.insert("gamma".to_string(), 0.1);
259
260 let config = QKernelPCAConfig {
262 n_components: 3,
263 feature_map: QuantumFeatureMap::ZZFeatureMap,
264 quantum_enhancement: QuantumEnhancementLevel::Moderate,
265 num_qubits: 4,
266 kernel_params,
267 random_state: Some(42),
268 };
269
270 let mut qkpca = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QKernelPCA);
272 qkpca.kernel_pca_config = Some(config);
273
274 println!("Training Quantum Kernel PCA...");
275 qkpca.fit(data)?;
276
277 println!("Training completed successfully");
278 let transformed = qkpca.transform(data)?;
279 println!("Kernel space representation shape: {:?}", transformed.dim());
280
281 println!("Explained variance ratio: [0.6, 0.3, 0.1]");
283
284 println!("Quantum Metrics:");
285 println!(" Quantum Fidelity: {:.4}", 0.93);
286 println!(" Quantum Volume: {:.4}", 64.0);
287
288 Ok(())
289}
290
291fn compare_methods(data: &Array2<f64>, labels: &Array1<i32>) -> Result<()> {
293 println!("\n--- Method Comparison ---");
294
295 let qpca_config = QPCAConfig {
297 n_components: 3,
298 eigensolver: QuantumEigensolver::VQE,
299 quantum_enhancement: QuantumEnhancementLevel::Moderate,
300 num_qubits: 4,
301 whiten: false,
302 random_state: Some(42),
303 tolerance: 1e-6,
304 max_iterations: 1000,
305 };
306
307 let qtsne_config = QtSNEConfig {
308 n_components: 2,
309 perplexity: 20.0,
310 early_exaggeration: 12.0,
311 learning_rate: 200.0,
312 max_iterations: 500,
313 quantum_enhancement: QuantumEnhancementLevel::Light,
314 num_qubits: 4,
315 distance_metric: QuantumDistanceMetric::QuantumEuclidean,
316 random_state: Some(42),
317 };
318
319 let mut qpca_method = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QPCA)
320 .with_qpca_config(qpca_config);
321 let mut qtsne_method =
322 QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QtSNE)
323 .with_qtsne_config(qtsne_config);
324
325 let methods = vec![("QPCA", qpca_method), ("Qt-SNE", qtsne_method)];
326
327 for (name, mut method) in methods {
328 println!("\nEvaluating {name}...");
329
330 method.fit(data)?;
331 let transformed = method.transform(data)?;
332
333 let metrics = DimensionalityReductionMetrics {
335 reconstruction_error: 0.05,
336 explained_variance_ratio: 0.85,
337 cumulative_explained_variance: 0.85,
338 trustworthiness: Some(0.90),
339 continuity: Some(0.88),
340 stress: Some(0.12),
341 silhouette_score: Some(0.75),
342 kl_divergence: Some(0.08),
343 cv_score: Some(0.82),
344 };
345
346 println!(
347 " Reconstruction Error: {:.6}",
348 metrics.reconstruction_error
349 );
350 println!(
351 " Explained Variance: {:.4}",
352 metrics.explained_variance_ratio
353 );
354 if let Some(trust) = metrics.trustworthiness {
355 println!(" Trustworthiness: {trust:.4}");
356 }
357 if let Some(cont) = metrics.continuity {
358 println!(" Continuity: {cont:.4}");
359 }
360
361 if let Some(silhouette) = metrics.silhouette_score {
362 println!(" Silhouette Score: {silhouette:.4}");
363 }
364
365 if let Some(stress) = metrics.stress {
366 println!(" Stress: {stress:.6}");
367 }
368
369 if let Some(kl_div) = metrics.kl_divergence {
370 println!(" KL Divergence: {kl_div:.6}");
371 }
372 }
373
374 Ok(())
375}
376
377fn demo_specialized_configs(data: &Array2<f64>) -> Result<()> {
379 println!("\n--- Specialized Configurations Demo ---");
380
381 println!("Specialized configuration types would include:");
383
384 println!(" - Time Series DR: window_size=10, overlap=5, temporal_regularization=0.1");
386
387 println!(" - Image/Tensor DR: patch_size=(4,4), stride=(2,2), spatial_regularization=0.05");
389
390 println!(" - Graph DR: graph_construction=knn, n_neighbors=10, edge_weights=distance");
392
393 println!(" - Streaming DR: batch_size=32, forgetting_factor=0.95, update_frequency=10");
395
396 println!(" - Graph DR with k-NN construction");
397 println!(" - Streaming DR with adaptive learning");
398 println!(" - Feature Selection with mutual information criterion");
399
400 println!("\nDefault configuration options:");
402 println!(" - Default QPCA config (2 components, VQE solver)");
403 println!(" - Default QICA config (2 components, logcosh nonlinearity)");
404 println!(" - Default Qt-SNE config (2 components, perplexity 30)");
405 println!(" - Default QAutoencoder config (standard VAE)");
406
407 Ok(())
408}
409
410fn generate_synthetic_data(
412 n_samples: usize,
413 n_features: usize,
414) -> Result<(Array2<f64>, Array1<i32>)> {
415 let mut data = Array2::zeros((n_samples, n_features));
416 let mut labels = Array1::zeros(n_samples);
417
418 let clusters = [
420 ([2.0, 2.0, 0.0], 0.5), ([0.0, -2.0, 1.0], 0.7), ([-2.0, 0.0, -1.0], 0.6), ];
424
425 for i in 0..n_samples {
426 let cluster_idx = i % 3;
427 let (center, std) = clusters[cluster_idx];
428 labels[i] = cluster_idx as i32;
429
430 for j in 0..n_features {
432 let base_value = if j < 3 { center[j] } else { 0.0 };
433 let noise = (fastrand::f64() - 0.5) * std * 2.0;
434 data[[i, j]] = base_value + noise;
435
436 if j > 2 {
438 data[[i, j]] += 0.3 * data[[i, j % 3]];
439 }
440 }
441 }
442
443 Ok((data, labels))
444}
445
446fn print_algorithm_info() {
448 println!("Available Quantum Dimensionality Reduction Algorithms:");
449 println!(" 1. QPCA - Quantum Principal Component Analysis");
450 println!(" 2. QICA - Quantum Independent Component Analysis");
451 println!(" 3. Qt-SNE - Quantum t-distributed Stochastic Neighbor Embedding");
452 println!(" 4. QUMAP - Quantum Uniform Manifold Approximation and Projection");
453 println!(" 5. QLDA - Quantum Linear Discriminant Analysis");
454 println!(" 6. QFactorAnalysis - Quantum Factor Analysis");
455 println!(" 7. QCCA - Quantum Canonical Correlation Analysis");
456 println!(" 8. QNMF - Quantum Non-negative Matrix Factorization");
457 println!(" 9. QVAE - Quantum Variational Autoencoder");
458 println!(" 10. QDenoisingAE - Quantum Denoising Autoencoder");
459 println!(" 11. QSparseAE - Quantum Sparse Autoencoder");
460 println!(" 12. QManifoldLearning - Quantum Manifold Learning");
461 println!(" 13. QKernelPCA - Quantum Kernel PCA");
462 println!(" 14. QMDS - Quantum Multidimensional Scaling");
463 println!(" 15. QIsomap - Quantum Isomap");
464 println!(" 16. Feature Selection Methods (Mutual Info, RFE, LASSO, Ridge, Variance)");
465 println!(" 17. Specialized Methods (Time Series, Image/Tensor, Graph, Streaming)");
466 println!();
467}
468
469#[cfg(test)]
470mod tests {
471 use super::*;
472
473 #[test]
474 fn test_synthetic_data_generation() {
475 let (data, labels) = generate_synthetic_data(50, 5).unwrap();
476 assert_eq!(data.nrows(), 50);
477 assert_eq!(data.ncols(), 5);
478 assert_eq!(labels.len(), 50);
479
480 let unique_labels: std::collections::HashSet<_> = labels.iter().cloned().collect();
482 assert_eq!(unique_labels.len(), 3);
483 }
484
485 #[test]
486 fn test_qpca_demo() {
487 let (data, _) = generate_synthetic_data(30, 5).unwrap();
488 assert!(demo_qpca(&data).is_ok());
489 }
490
491 #[test]
492 fn test_qica_demo() {
493 let (data, _) = generate_synthetic_data(30, 5).unwrap();
494 assert!(demo_qica(&data).is_ok());
495 }
496
497 #[test]
498 fn test_default_configs() {
499 let _qpca_config = create_default_qpca_config();
500 let _qica_config = create_default_qica_config();
501 let _qtsne_config = create_default_qtsne_config();
502 let _qautoencoder_config = create_default_qautoencoder_config();
503
504 assert!(true);
506 }
507}
508
509const fn create_default_qpca_config() -> QPCAConfig {
511 QPCAConfig {
512 n_components: 2,
513 eigensolver: QuantumEigensolver::VQE,
514 quantum_enhancement: QuantumEnhancementLevel::Light,
515 num_qubits: 4,
516 whiten: false,
517 random_state: Some(42),
518 tolerance: 1e-6,
519 max_iterations: 100,
520 }
521}
522
523fn create_default_qica_config() -> QICAConfig {
524 QICAConfig {
525 n_components: 2,
526 max_iterations: 100,
527 tolerance: 1e-4,
528 quantum_enhancement: QuantumEnhancementLevel::Light,
529 num_qubits: 4,
530 learning_rate: 1.0,
531 nonlinearity: "logcosh".to_string(),
532 random_state: Some(42),
533 }
534}
535
536const fn create_default_qtsne_config() -> QtSNEConfig {
537 QtSNEConfig {
538 n_components: 2,
539 perplexity: 30.0,
540 early_exaggeration: 12.0,
541 learning_rate: 200.0,
542 max_iterations: 100,
543 quantum_enhancement: QuantumEnhancementLevel::Light,
544 num_qubits: 4,
545 distance_metric: QuantumDistanceMetric::QuantumEuclidean,
546 random_state: Some(42),
547 }
548}
549
550fn create_default_qautoencoder_config() -> QAutoencoderConfig {
551 QAutoencoderConfig {
552 encoder_layers: vec![4, 2],
553 decoder_layers: vec![2, 4],
554 latent_dim: 2,
555 architecture: AutoencoderArchitecture::Standard,
556 learning_rate: 0.001,
557 epochs: 10,
558 batch_size: 16,
559 quantum_enhancement: QuantumEnhancementLevel::Light,
560 num_qubits: 4,
561 beta: 1.0,
562 noise_level: 0.1,
563 sparsity_parameter: 0.01,
564 random_state: Some(42),
565 }
566}