1use scirs2_core::numeric::Float;
8use std::collections::HashMap;
9use std::fmt::Debug;
10
11use crate::advanced_coordinator_modules::types::{
12 DataProfile, InterpolationMethodType, PerformanceMetrics, PerformanceTargets,
13};
14use crate::error::{InterpolateError, InterpolateResult};
15
16#[derive(Debug)]
18pub struct CrossDomainInterpolationKnowledge<F: Float + Debug> {
19 knowledge_base: InterpolationKnowledgeBase<F>,
21 transfer_model: TransferLearningModel<F>,
23 domain_adapter: DomainAdapter<F>,
25}
26
27impl<F: Float + Debug + std::ops::MulAssign + std::default::Default>
28 CrossDomainInterpolationKnowledge<F>
29{
30 pub fn new() -> Self {
32 Self {
33 knowledge_base: InterpolationKnowledgeBase::new(),
34 transfer_model: TransferLearningModel::new(),
35 domain_adapter: DomainAdapter::new(),
36 }
37 }
38
39 pub fn learn_from_experience(
41 &mut self,
42 domain: String,
43 data_profile: &DataProfile<F>,
44 method: InterpolationMethodType,
45 performance: &PerformanceMetrics,
46 ) -> InterpolateResult<()> {
47 self.knowledge_base.add_domain_experience(
49 domain.clone(),
50 data_profile,
51 method,
52 performance,
53 )?;
54
55 self.transfer_model
57 .update_model(&domain, data_profile, performance)?;
58
59 self.domain_adapter.update_mappings(&domain, data_profile)?;
61
62 Ok(())
63 }
64
65 pub fn transfer_knowledge(
67 &self,
68 source_domain: &str,
69 target_domain: &str,
70 target_profile: &DataProfile<F>,
71 ) -> InterpolateResult<TransferKnowledgeResult<F>> {
72 let source_knowledge = self
74 .knowledge_base
75 .get_domain_knowledge(source_domain)
76 .ok_or_else(|| InterpolateError::InvalidInput {
77 message: format!(
78 "No knowledge available for source domain: {}",
79 source_domain
80 ),
81 })?;
82
83 let applicable_patterns = self.knowledge_base.find_applicable_patterns(
85 source_domain,
86 target_domain,
87 target_profile,
88 )?;
89
90 let adapted_knowledge = self.domain_adapter.adapt_knowledge(
92 source_knowledge,
93 target_profile,
94 &applicable_patterns,
95 )?;
96
97 let recommendations = self.transfer_model.generate_recommendations(
99 source_domain,
100 target_domain,
101 &adapted_knowledge,
102 target_profile,
103 )?;
104
105 Ok(TransferKnowledgeResult {
106 adapted_knowledge,
107 recommendations,
108 confidence_score: self.calculate_transfer_confidence(
109 source_domain,
110 target_domain,
111 &applicable_patterns,
112 ),
113 })
114 }
115
116 pub fn get_knowledge_summary(&self) -> KnowledgeSummary {
118 KnowledgeSummary {
119 total_domains: self.knowledge_base.domain_knowledge.len(),
120 total_patterns: self.knowledge_base.cross_domain_patterns.len(),
121 average_confidence: self.knowledge_base.calculate_average_confidence(),
122 most_successful_methods: self.knowledge_base.get_most_successful_methods(),
123 }
124 }
125
126 fn calculate_transfer_confidence(
128 &self,
129 source_domain: &str,
130 target_domain: &str,
131 patterns: &[CrossDomainPattern<F>],
132 ) -> f64 {
133 if patterns.is_empty() {
134 return 0.1; }
136
137 let pattern_strengths: Vec<f64> = patterns
138 .iter()
139 .map(|p| p.transfer_strength.to_f64().unwrap_or(0.0))
140 .collect();
141
142 let avg_strength = pattern_strengths.iter().sum::<f64>() / pattern_strengths.len() as f64;
143
144 let domain_confidence = self
146 .knowledge_base
147 .get_domain_confidence(source_domain)
148 .unwrap_or(0.5);
149
150 (avg_strength * 0.7 + domain_confidence * 0.3).min(1.0)
151 }
152}
153
154impl<F: Float + Debug + std::ops::MulAssign + std::default::Default> Default
155 for CrossDomainInterpolationKnowledge<F>
156{
157 fn default() -> Self {
158 Self::new()
159 }
160}
161
162#[derive(Debug)]
164pub struct InterpolationKnowledgeBase<F: Float> {
165 domain_knowledge: HashMap<String, DomainKnowledge<F>>,
167 cross_domain_patterns: Vec<CrossDomainPattern<F>>,
169 confidence_scores: HashMap<String, f64>,
171}
172
173impl<F: Float + std::default::Default> InterpolationKnowledgeBase<F> {
174 pub fn new() -> Self {
176 Self {
177 domain_knowledge: HashMap::new(),
178 cross_domain_patterns: Vec::new(),
179 confidence_scores: HashMap::new(),
180 }
181 }
182
183 pub fn add_domain_experience(
185 &mut self,
186 domain: String,
187 data_profile: &DataProfile<F>,
188 method: InterpolationMethodType,
189 performance: &PerformanceMetrics,
190 ) -> InterpolateResult<()> {
191 let domain_knowledge = self
192 .domain_knowledge
193 .entry(domain.clone())
194 .or_insert_with(|| DomainKnowledge::new(domain.clone()));
195
196 domain_knowledge.add_experience(data_profile, method, performance)?;
197
198 let current_confidence = self.confidence_scores.get(&domain).unwrap_or(&0.5);
200 let new_confidence = (current_confidence + 0.1).min(1.0);
201 self.confidence_scores.insert(domain, new_confidence);
202
203 self.discover_cross_domain_patterns()?;
205
206 Ok(())
207 }
208
209 pub fn get_domain_knowledge(&self, domain: &str) -> Option<&DomainKnowledge<F>> {
211 self.domain_knowledge.get(domain)
212 }
213
214 pub fn find_applicable_patterns(
216 &self,
217 source_domain: &str,
218 target_domain: &str,
219 target_profile: &DataProfile<F>,
220 ) -> InterpolateResult<Vec<CrossDomainPattern<F>>> {
221 let patterns: Vec<CrossDomainPattern<F>> = self
222 .cross_domain_patterns
223 .iter()
224 .filter(|pattern| {
225 pattern.source_domains.contains(&source_domain.to_string())
226 && (pattern.target_domains.contains(&target_domain.to_string())
227 || pattern.target_domains.is_empty())
228 && self.pattern_matches_profile(pattern, target_profile)
229 })
230 .cloned()
231 .collect();
232
233 Ok(patterns)
234 }
235
236 pub fn get_domain_confidence(&self, domain: &str) -> Option<f64> {
238 self.confidence_scores.get(domain).copied()
239 }
240
241 pub fn calculate_average_confidence(&self) -> f64 {
243 if self.confidence_scores.is_empty() {
244 return 0.0;
245 }
246
247 let sum: f64 = self.confidence_scores.values().sum();
248 sum / self.confidence_scores.len() as f64
249 }
250
251 pub fn get_most_successful_methods(&self) -> Vec<InterpolationMethodType> {
253 let mut method_scores: HashMap<InterpolationMethodType, f64> = HashMap::new();
254
255 for domain_knowledge in self.domain_knowledge.values() {
256 for method in &domain_knowledge.optimal_methods {
257 let score = method_scores.entry(*method).or_insert(0.0);
258 *score += domain_knowledge
259 .performance_profile
260 .accuracy_profile
261 .mean_accuracy
262 .to_f64()
263 .unwrap_or(0.0);
264 }
265 }
266
267 let mut methods: Vec<(InterpolationMethodType, f64)> = method_scores.into_iter().collect();
268 methods.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
269
270 methods
271 .into_iter()
272 .take(5)
273 .map(|(method, _)| method)
274 .collect()
275 }
276
277 fn discover_cross_domain_patterns(&mut self) -> InterpolateResult<()> {
279 let domains: Vec<String> = self.domain_knowledge.keys().cloned().collect();
281
282 for i in 0..domains.len() {
283 for j in (i + 1)..domains.len() {
284 let source_domain = &domains[i];
285 let target_domain = &domains[j];
286
287 if let Some(pattern) =
288 self.analyze_domain_similarity(source_domain, target_domain)?
289 {
290 if !self
292 .cross_domain_patterns
293 .iter()
294 .any(|p| p.pattern_signature == pattern.pattern_signature)
295 {
296 self.cross_domain_patterns.push(pattern);
297 }
298 }
299 }
300 }
301
302 Ok(())
303 }
304
305 fn analyze_domain_similarity(
307 &self,
308 source_domain: &str,
309 target_domain: &str,
310 ) -> InterpolateResult<Option<CrossDomainPattern<F>>> {
311 let source_knowledge = self.domain_knowledge.get(source_domain);
312 let target_knowledge = self.domain_knowledge.get(target_domain);
313
314 if let (Some(source), Some(target)) = (source_knowledge, target_knowledge) {
315 let method_overlap =
317 self.calculate_method_overlap(&source.optimal_methods, &target.optimal_methods);
318
319 if method_overlap > 0.5 {
320 let pattern_signature =
321 format!("method_overlap_{}_{}", source_domain, target_domain);
322 let transfer_strength = F::from(method_overlap).unwrap_or(F::zero());
323
324 return Ok(Some(CrossDomainPattern {
325 source_domains: vec![source_domain.to_string()],
326 target_domains: vec![target_domain.to_string()],
327 pattern_signature,
328 transfer_strength,
329 }));
330 }
331 }
332
333 Ok(None)
334 }
335
336 fn calculate_method_overlap(
338 &self,
339 methods1: &[InterpolationMethodType],
340 methods2: &[InterpolationMethodType],
341 ) -> f64 {
342 if methods1.is_empty() || methods2.is_empty() {
343 return 0.0;
344 }
345
346 let common_methods = methods1
347 .iter()
348 .filter(|method| methods2.contains(method))
349 .count();
350
351 let total_unique = methods1.len() + methods2.len() - common_methods;
352
353 if total_unique == 0 {
354 1.0
355 } else {
356 common_methods as f64 / total_unique as f64
357 }
358 }
359
360 fn pattern_matches_profile(
362 &self,
363 pattern: &CrossDomainPattern<F>,
364 _profile: &DataProfile<F>,
365 ) -> bool {
366 pattern.transfer_strength > F::from(0.3).unwrap_or(F::zero())
368 }
369}
370
371impl<F: Float + std::default::Default> Default for InterpolationKnowledgeBase<F> {
372 fn default() -> Self {
373 Self::new()
374 }
375}
376
377#[derive(Debug, Clone)]
379pub struct DomainKnowledge<F: Float> {
380 pub domain: String,
382 pub optimal_methods: Vec<InterpolationMethodType>,
384 pub optimizations: Vec<DomainOptimization>,
386 pub performance_profile: PerformanceProfile<F>,
388}
389
390impl<F: Float + std::default::Default> DomainKnowledge<F> {
391 pub fn new(domain: String) -> Self {
393 Self {
394 domain,
395 optimal_methods: Vec::new(),
396 optimizations: Vec::new(),
397 performance_profile: PerformanceProfile::default(),
398 }
399 }
400
401 pub fn add_experience(
403 &mut self,
404 _data_profile: &DataProfile<F>,
405 method: InterpolationMethodType,
406 performance: &PerformanceMetrics,
407 ) -> InterpolateResult<()> {
408 if performance.accuracy > 0.8 && !self.optimal_methods.contains(&method) {
410 self.optimal_methods.push(method);
411 }
412
413 self.performance_profile
415 .execution_times
416 .push(F::from(performance.execution_time_ms).unwrap_or(F::zero()));
417 self.performance_profile
418 .memory_patterns
419 .push(performance.memory_usage_bytes);
420
421 let accuracy_f = F::from(performance.accuracy).unwrap_or(F::zero());
423 self.performance_profile
424 .accuracy_profile
425 .accuracy_distribution
426 .push(accuracy_f);
427
428 let accuracies = &self
430 .performance_profile
431 .accuracy_profile
432 .accuracy_distribution;
433 if !accuracies.is_empty() {
434 let sum = accuracies.iter().fold(F::zero(), |acc, &x| acc + x);
435 self.performance_profile.accuracy_profile.mean_accuracy =
436 sum / F::from(accuracies.len()).unwrap_or(F::one());
437 }
438
439 Ok(())
440 }
441}
442
443#[derive(Debug, Clone)]
445pub struct DomainOptimization {
446 pub name: String,
448 pub parameters: HashMap<String, f64>,
450 pub expected_improvement: f64,
452}
453
454#[derive(Debug, Clone, Default)]
456pub struct PerformanceProfile<F: Float> {
457 pub execution_times: Vec<F>,
459 pub memory_patterns: Vec<usize>,
461 pub accuracy_profile: AccuracyProfile<F>,
463}
464
465#[derive(Debug, Clone, Default)]
467pub struct AccuracyProfile<F: Float> {
468 pub mean_accuracy: F,
470 pub accuracy_variance: F,
472 pub accuracy_distribution: Vec<F>,
474}
475
476#[derive(Debug, Clone)]
478pub struct CrossDomainPattern<F: Float> {
479 pub source_domains: Vec<String>,
481 pub target_domains: Vec<String>,
483 pub pattern_signature: String,
485 pub transfer_strength: F,
487}
488
489#[derive(Debug)]
491pub struct TransferLearningModel<F: Float> {
492 source_models: HashMap<String, SourceModel<F>>,
494 transfer_weights: HashMap<String, f64>,
496 adaptation_params: AdaptationParameters<F>,
498}
499
500impl<F: Float> TransferLearningModel<F> {
501 pub fn new() -> Self {
503 Self {
504 source_models: HashMap::new(),
505 transfer_weights: HashMap::new(),
506 adaptation_params: AdaptationParameters::default(),
507 }
508 }
509
510 pub fn update_model(
512 &mut self,
513 domain: &str,
514 data_profile: &DataProfile<F>,
515 performance: &PerformanceMetrics,
516 ) -> InterpolateResult<()> {
517 let model = self
519 .source_models
520 .entry(domain.to_string())
521 .or_insert_with(|| SourceModel::new());
522
523 model.update_with_performance(data_profile, performance)?;
524
525 let weight =
527 performance.accuracy * 0.8 + (1.0 - performance.execution_time_ms / 10000.0) * 0.2;
528 self.transfer_weights
529 .insert(domain.to_string(), weight.clamp(0.0, 1.0));
530
531 Ok(())
532 }
533
534 pub fn generate_recommendations(
536 &self,
537 source_domain: &str,
538 target_domain: &str,
539 adapted_knowledge: &DomainKnowledge<F>,
540 _target_profile: &DataProfile<F>,
541 ) -> InterpolateResult<Vec<TransferRecommendation>> {
542 let mut recommendations = Vec::new();
543
544 for method in &adapted_knowledge.optimal_methods {
546 let confidence = self.transfer_weights.get(source_domain).unwrap_or(&0.5);
547
548 recommendations.push(TransferRecommendation {
549 method: *method,
550 confidence: *confidence,
551 reasoning: format!(
552 "Method {:?} showed good performance in source domain {}",
553 method, source_domain
554 ),
555 estimated_improvement: confidence * 0.2,
556 });
557 }
558
559 recommendations.sort_by(|a, b| {
561 b.confidence
562 .partial_cmp(&a.confidence)
563 .unwrap_or(std::cmp::Ordering::Equal)
564 });
565
566 Ok(recommendations)
567 }
568}
569
570impl<F: Float> Default for TransferLearningModel<F> {
571 fn default() -> Self {
572 Self::new()
573 }
574}
575
576#[derive(Debug, Clone)]
578pub struct SourceModel<F: Float> {
579 pub parameters: Vec<F>,
581 pub accuracy: F,
583 pub complexity: usize,
585}
586
587impl<F: Float> Default for SourceModel<F> {
588 fn default() -> Self {
589 Self::new()
590 }
591}
592
593impl<F: Float> SourceModel<F> {
594 pub fn new() -> Self {
596 Self {
597 parameters: Vec::new(),
598 accuracy: F::zero(),
599 complexity: 0,
600 }
601 }
602
603 pub fn update_with_performance(
605 &mut self,
606 _data_profile: &DataProfile<F>,
607 performance: &PerformanceMetrics,
608 ) -> InterpolateResult<()> {
609 self.accuracy = F::from(performance.accuracy).unwrap_or(F::zero());
610 self.complexity = performance.memory_usage_bytes / 1024; if self.parameters.is_empty() {
614 self.parameters = vec![self.accuracy, F::from(self.complexity).unwrap_or(F::zero())];
615 } else {
616 let alpha = F::from(0.1).unwrap_or(F::zero());
618 self.parameters[0] = self.parameters[0] * (F::one() - alpha) + self.accuracy * alpha;
619 }
620
621 Ok(())
622 }
623}
624
625#[derive(Debug, Clone)]
627pub struct AdaptationParameters<F: Float> {
628 pub learning_rate: F,
630 pub regularization: F,
632 pub confidence_threshold: F,
634}
635
636impl<F: Float> Default for AdaptationParameters<F> {
637 fn default() -> Self {
638 Self {
639 learning_rate: F::from(0.01).unwrap_or(F::zero()),
640 regularization: F::from(0.001).unwrap_or(F::zero()),
641 confidence_threshold: F::from(0.5).unwrap_or(F::zero()),
642 }
643 }
644}
645
646#[derive(Debug)]
648pub struct DomainAdapter<F: Float> {
649 domain_mappings: HashMap<String, DomainMapping<F>>,
651 adaptation_strategies: Vec<AdaptationStrategy<F>>,
653}
654
655impl<F: Float + std::ops::MulAssign> DomainAdapter<F> {
656 pub fn new() -> Self {
658 Self {
659 domain_mappings: HashMap::new(),
660 adaptation_strategies: Vec::new(),
661 }
662 }
663
664 pub fn update_mappings(
666 &mut self,
667 domain: &str,
668 _data_profile: &DataProfile<F>,
669 ) -> InterpolateResult<()> {
670 let mapping_key = format!("general_to_{}", domain);
672 let mapping = DomainMapping {
673 source_domain: "general".to_string(),
674 target_domain: domain.to_string(),
675 mapping_params: vec![F::one()],
676 mapping_accuracy: F::from(0.8).unwrap_or(F::zero()),
677 };
678
679 self.domain_mappings.insert(mapping_key, mapping);
680 Ok(())
681 }
682
683 pub fn adapt_knowledge(
685 &self,
686 source_knowledge: &DomainKnowledge<F>,
687 _target_profile: &DataProfile<F>,
688 patterns: &[CrossDomainPattern<F>],
689 ) -> InterpolateResult<DomainKnowledge<F>> {
690 let mut adapted_knowledge = source_knowledge.clone();
691
692 for pattern in patterns {
694 let strength = pattern.transfer_strength.to_f64().unwrap_or(0.0);
695
696 if strength > 0.5 {
697 } else if strength > 0.3 {
700 adapted_knowledge.optimal_methods.retain(|method| {
702 matches!(
704 method,
705 InterpolationMethodType::Linear
706 | InterpolationMethodType::CubicSpline
707 | InterpolationMethodType::BSpline
708 )
709 });
710 }
711 }
712
713 let adaptation_factor = F::from(0.9).unwrap_or(F::one());
715 adapted_knowledge
716 .performance_profile
717 .accuracy_profile
718 .mean_accuracy *= adaptation_factor;
719
720 Ok(adapted_knowledge)
721 }
722}
723
724impl<F: Float + std::ops::MulAssign> Default for DomainAdapter<F> {
725 fn default() -> Self {
726 Self::new()
727 }
728}
729
730#[derive(Debug, Clone)]
732pub struct DomainMapping<F: Float> {
733 pub source_domain: String,
735 pub target_domain: String,
737 pub mapping_params: Vec<F>,
739 pub mapping_accuracy: F,
741}
742
743#[derive(Debug, Clone)]
745pub struct AdaptationStrategy<F: Float> {
746 pub name: String,
748 pub parameters: HashMap<String, F>,
750 pub success_rate: f64,
752}
753
754#[derive(Debug)]
756pub struct TransferKnowledgeResult<F: Float> {
757 pub adapted_knowledge: DomainKnowledge<F>,
759 pub recommendations: Vec<TransferRecommendation>,
761 pub confidence_score: f64,
763}
764
765#[derive(Debug, Clone)]
767pub struct TransferRecommendation {
768 pub method: InterpolationMethodType,
770 pub confidence: f64,
772 pub reasoning: String,
774 pub estimated_improvement: f64,
776}
777
778#[derive(Debug, Clone)]
780pub struct KnowledgeSummary {
781 pub total_domains: usize,
783 pub total_patterns: usize,
785 pub average_confidence: f64,
787 pub most_successful_methods: Vec<InterpolationMethodType>,
789}