Skip to main content

similarity

Use when working with component similarity calculations - comparing MPNs, finding equivalent parts, implementing new similarity calculators, or understanding how component matching works.

Ir a la instalación

Datos de origen

Repositorio
Cantara/lib-electronic-components
Última actividad en el origen
24 de enero de 2026 a las 11:21
Idioma detectado de SKILL.md
inglés
Estrellas
4
Forks
0

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
similarity
description
Use when working with component similarity calculations - comparing MPNs, finding equivalent parts, implementing new similarity calculators, or understanding how component matching works.
# Component Similarity Calculator Skill This skill provides guidance for working with component similarity calculators in the lib-electronic-components library. --- **For metadata-driven similarity architecture**, see `/similarity-metadata`: - SpecImportance levels (CRITICAL, HIGH, MEDIUM, LOW, OPTIONAL) - ToleranceRule types (exactMatch, percentageTolerance, minimumRequired, etc.) - SimilarityProfile contexts (DESIGN_PHASE, REPLACEMENT, COST_OPTIMIZATION, etc.) - Calculator integration patterns and gotchas --- ## Overview Similarity calculators determine how similar two electronic components are based on their MPNs (Manufacturer Part Numbers). They return a value between 0.0 (completely different) and 1.0 (identical or equivalent). ## Core Interfaces ### SimilarityCalculator (Simple) ```java public interface SimilarityCalculator { double calculateSimilarity(String normalizedMpn1, String normalizedMpn2); } ``` Used for generic calculators that don't need component type context. ### ComponentSimilarityCalculator (Type-Aware) ```java public interface ComponentSimilarityCalculator { boolean isApplicable(ComponentType type); double calculateSimilarity(String mpn1, String mpn2, PatternRegistry registry); } ``` Used for component-specific calculators that need to check applicability. ## Standard Similarity Thresholds ```java private static final double HIGH_SIMILARITY = 0.9; // Equivalent/interchangeable private static final double MEDIUM_SIMILARITY = 0.7; // Similar, may work as substitute private static final double LOW_SIMILARITY = 0.3; // Same category but different specs ``` ## Available Calculators | Calculator | Interface | Component Types | Key Features | |------------|-----------|-----------------|--------------| | `ResistorSimilarityCalculator` | Component | RESISTOR, RESISTOR_* | Value, package, tolerance | | `CapacitorSimilarityCalculator` | Component | CAPACITOR, CAPACITOR_* | Value, voltage, dielectric | | `TransistorSimilarityCalculator` | Component | TRANSISTOR, TRANSISTOR_* | NPN/PNP polarity, equivalent groups | | `DiodeSimilarityCalculator` | Component | DIODE, DIODE_* | Signal/rectifier/zener types | | `MosfetSimilarityCalculator` | Component | MOSFET, MOSFET_* | N/P channel, equivalent groups | | `OpAmpSimilarityCalculator` | Component | OPAMP, OPAMP_* | Single/dual/quad, equivalent families | | `VoltageRegulatorSimilarityCalculator` | Component | VOLTAGE_REGULATOR* | Fixed (78xx) vs adjustable (LM317) | | `LogicICSimilarityCalculator` | Component | LOGIC_IC, IC | 74xx/CD4000 series, function groups | | `LEDSimilarityCalculator` | Component | LED, LED_* | Color, bins, families | | `MemorySimilarityCalculator` | Component | MEMORY, MEMORY_* | I2C/SPI EEPROM, Flash equivalents | | `SensorSimilarityCalculator` | Component | SENSOR, TEMPERATURE_SENSOR, ACCELEROMETER | Sensor families, package variants | | `ConnectorSimilarityCalculator` | Component | CONNECTOR, CONNECTOR_* | Pin count, pitch, family | | `MicrocontrollerSimilarityCalculator` | Component | MICROCONTROLLER* | Series, package, manufacturer | | `MCUSimilarityCalculator` | Simple | (generic) | Family, series, features | | `PassiveComponentCalculator` | Simple | (generic) | Value, size code, tolerance | | `LevenshteinCalculator` | Simple | (generic) | String edit distance | | `DefaultSimilarityCalculator` | Simple | (generic) | Prefix, numeric, suffix weights | ## Creating a New Similarity Calculator ### 1. Implement the Interface ```java public class NewComponentSimilarityCalculator implements ComponentSimilarityCalculator { private static final double HIGH_SIMILARITY = 0.9; private static final double MEDIUM_SIMILARITY = 0.7; private static final double LOW_SIMILARITY = 0.3; @Override public boolean isApplicable(ComponentType type) { if (type == null) return false; return type == ComponentType.NEW_COMPONENT || type.name().startsWith("NEW_COMPONENT_"); } @Override public double calculateSimilarity(String mpn1, String mpn2, PatternRegistry registry) { if (mpn1 == null || mpn2 == null) return 0.0; // Check if both are the component type we handle if (!isComponentType(mpn1) || !isComponentType(mpn2)) { return 0.0; } // Compare components // ... return similarity; } } ``` ### 2. Key Design Principles 1. **Return 0.0 for null inputs** - Always check for null MPNs and registry 2. **Return 0.0 for non-matching types** - If the MPN isn't your component type 3. **Use equivalent groups** - Define known equivalent parts (e.g., 2N2222 ≈ PN2222) 4. **Consider package variants** - Same part in different package should be high similarity 5. **Ensure symmetry** - `sim(A,B) == sim(B,A)` 6. **Keep in [0.0, 1.0]** - Never return values outside this range ### 3. Common Patterns #### Equivalent Groups ```java private static final Map<String, Set<String>> EQUIVALENT_GROUPS = new HashMap<>(); static { EQUIVALENT_GROUPS.put("2N2222", Set.of("2N2222", "2N2222A", "PN2222", "PN2222A")); } private boolean areEquivalent(String mpn1, String mpn2) { for (Set<String> group : EQUIVALENT_GROUPS.values()) { if (group.contains(mpn1) && group.contains(mpn2)) { return true; } } return false; } ``` #### Package Code Extraction ```java private String extractBasePart(String mpn) { // Remove common package suffixes return mpn.replaceAll("(?:CT|T|N|P|DG|PW|DR)$", ""); } ``` #### Polarity/Type Checking ```java private boolean areSamePolarity(String mpn1, String mpn2) { boolean isNPN1 = NPN_PATTERNS.stream().anyMatch(mpn1::matches); boolean isNPN2 = NPN_PATTERNS.stream().anyMatch(mpn2::matches); return isNPN1 == isNPN2; } ``` ## Testing ### Test Structure ```java @Nested @DisplayName("isApplicable tests") class IsApplicableTests { /* ... */ } @Nested @DisplayName("Equivalent groups tests") class EquivalentGroupTests { /* ... */ } @Nested @DisplayName("Edge cases and null handling") class EdgeCaseTests { /* ... */ } @Nested @DisplayName("Symmetry and property tests") class PropertyTests { /* ... */ } ``` ### Run Tests ```bash # All similarity calculator tests mvn test -Dtest="*SimilarityCalculatorTest,PassiveComponentCalculatorTest" # Specific calculator mvn test -Dtest=TransistorSimilarityCalculatorTest ``` ## Related Skills - `/similarity-resistor` - Resistor similarity details - `/similarity-transistor` - Transistor equivalent groups and polarity - `/similarity-mosfet` - MOSFET N/P channel comparison - `/similarity-opamp` - Op-amp families and equivalents - `/similarity-memory` - Memory IC equivalents (I2C/SPI EEPROM, Flash) - `/similarity-sensor` - Sensor family comparison - `/similarity-led` - LED bins and color temperature - `/similarity-regulator` - Voltage regulator comparison (78xx, LM317) - `/similarity-logic` - Logic IC function groups (74xx, CD4000) --- ## Metadata-Driven Architecture (January 2026) The similarity system now uses a **metadata-driven architecture** for configurable, type-specific similarity rules. **Conversion Status**: 12 of 17 calculators converted (71% complete) | Calculator | Status | PR | Conversion Date | |-----------|--------|-----|-----------------| | ResistorSimilarityCalculator | ✅ Converted | - | Jan 2026 | | CapacitorSimilarityCalculator | ✅ Converted | - | Jan 2026 | | TransistorSimilarityCalculator | ✅ Converted | - | Jan 2026 | | DiodeSimilarityCalculator | ✅ Converted | - | Jan 2026 | | MosfetSimilarityCalculator | ✅ Converted | - | Jan 2026 | | VoltageRegulatorSimilarityCalculator | ✅ Converted | - | Jan 2026 | | OpAmpSimilarityCalculator | ✅ Converted | #116 | Jan 2026 | | MemorySimilarityCalculator | ✅ Converted | #117 | Jan 2026 | | LEDSimilarityCalculator | ✅ Converted | #118 | Jan 2026 | | ConnectorSimilarityCalculator | ✅ Converted | (pre-existing) | Jan 2026 | | LogicICSimilarityCalculator | ✅ Converted | #119 | Jan 2026 | | SensorSimilarityCalculator | ✅ Converted | #120 | Jan 2026 | | MicrocontrollerSimilarityCalculator | ⏳ Legacy | - | - | | MCUSimilarityCalculator | ⏳ Legacy | - | - | | PassiveComponentCalculator | ⏳ Legacy | - | - | | LevenshteinCalculator | ⏳ Legacy | - | - | | DefaultSimilarityCalculator | ⏳ Legacy | - | - | ### Core Metadata Classes | Class | Purpose | |-------|---------| | `ComponentTypeMetadata` | Defines specs, importance levels, tolerance rules per component type | | `ComponentTypeMetadataRegistry` | Singleton registry mapping ComponentType → metadata | | `SpecImportance` | Enum: CRITICAL (1.0), HIGH (0.7), MEDIUM (0.4), LOW (0.2), OPTIONAL (0.0) | | `ToleranceRule` | Interface for comparing spec values (ExactMatch, Percentage, MinRequired, MaxAllowed, Range) | | `SimilarityProfile` | Context-aware profiles (DESIGN_PHASE, REPLACEMENT, COST_OPTIMIZATION, PERFORMANCE_UPGRADE, EMERGENCY_SOURCING) | ### Retrieving Metadata ```java ComponentTypeMetadataRegistry registry = ComponentTypeMetadataRegistry.getInstance(); // Get metadata for a component type Optional<ComponentTypeMetadata> metadata = registry.getMetadata(ComponentType.RESISTOR); // Query specs if (metadata.isPresent()) { ComponentTypeMetadata meta = metadata.get(); // Check if spec is critical boolean critical = meta.isCritical("resistance"); // true // Get tolerance rule for a spec SpecConfig config = meta.getSpecConfig("resistance"); if (config != null) { ToleranceRule rule = config.getToleranceRule(); SpecImportance importance = config.getImportance(); } // Get all configured specs Set<String> allSpecs = meta.getAllSpecs(); } ``` ### Pre-Registered Types (10) RESISTOR, CAPACITOR, MOSFET, TRANSISTOR, DIODE, OPAMP, MICROCONTROLLER, MEMORY, LED, CONNECTOR Each type has: - Critical specs (must match for similarity) - High/Medium/Low importance specs (contribute to score) - Tolerance rules (how to compare values) - Default similarity profile ### Context-Aware Profiles Adjust importance multipliers based on use case: | Profile | Threshold | CRITICAL | HIGH | MEDIUM | LOW | Use Case | |---------|-----------|----------|------|--------|-----|----------| | DESIGN_PHASE | 0.85 | 1.0 | 0.9 | 0.7 | 0.4 | Exact match for new designs | | REPLACEMENT | 0.75 | 1.0 | 0.7 | 0.4 | 0.2 | **Default**: Direct replacement | | COST_OPTIMIZATION | 0.60 | 1.0 | 0.4 | 0.2 | 0.0 | Maintain critical specs only | | EMERGENCY_SOURCING | 0.50 | 0.8 | 0.4 | 0.2 | 0.0 | Urgent, relaxed requirements | ```java // Check if similarity meets threshold for a profile SimilarityProfile profile = SimilarityProfile.REPLACEMENT; double similarity = 0.78; boolean passes = profile.meetsThreshold(similarity); // true // Get effective weight for a spec double effectiveWeight = profile.getEffectiveWeight(SpecImportance.HIGH); // 0.7 × 0.7 = 0.49 ``` ### Converted Calculator Implementation Pattern Calculators converted to metadata-driven approach follow this pattern: ```java @Override public double calculateSimilarity(String mpn1, String mpn2, PatternRegistry registry) { if (mpn1 == null || mpn2 == null) return 0.0; // Try metadata-driven approach first Optional<ComponentTypeMetadata> metadataOpt = metadataRegistry.getMetadata(ComponentType.OPAMP); if (metadataOpt.isPresent()) { logger.trace("Using metadata-driven similarity calculation"); return calculateMetadataDrivenSimilarity(mpn1, mpn2, metadataOpt.get()); } // Fallback to legacy pattern-based approach logger.trace("No metadata found, using legacy approach"); return calculateLegacySimilarity(mpn1, mpn2); } private double calculateMetadataDrivenSimilarity(String mpn1, String mpn2, ComponentTypeMetadata metadata) { SimilarityProfile profile = metadata.getDefaultProfile(); // Extract specs from MPNs String config1 = extractConfiguration(mpn1); // e.g., "dual", "quad" String config2 = extractConfiguration(mpn2); // ... extract other specs // Short-circuit check for CRITICAL incompatibility if (!config1.isEmpty() && !config2.isEmpty() && !config1.equals(config2)) { return LOW_SIMILARITY; } double totalScore = 0.0; double maxPossibleScore = 0.0; // Compare each spec with weighted scoring ComponentTypeMetadata.SpecConfig configSpec = metadata.getSpecConfig("configuration"); if (configSpec != null && !config1.isEmpty() && !config2.isEmpty()) { ToleranceRule rule = configSpec.getToleranceRule(); SpecValue<String> orig = new SpecValue<>(config1, SpecUnit.NONE); SpecValue<String> cand = new SpecValue<>(config2, SpecUnit.NONE); double specScore = rule.compare(orig, cand); double specWeight = profile.getEffectiveWeight(configSpec.getImportance()); totalScore += specScore * specWeight; maxPossibleScore += specWeight; } // Repeat for other specs (family, package, etc.) // ... double similarity = maxPossibleScore > 0 ? totalScore / maxPossibleScore : 0.0; // Apply boosts for equivalent groups
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub