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