Mathematical Notation Parser - API Reference¶
Overview¶
The Mathematical Notation Parser provides a standardized system for mathematical notation in DSP algorithms. It supports validation, conversion between formats (LaTeX, Unicode, ASCII), and symbol lookup.
Installation¶
Quick Start¶
from notation_parser import NotationParser
# Create parser instance
parser = NotationParser()
# Validate notation
result = parser.validate_notation("y[n] = x[n] + x[n-1]")
print(f"Valid: {result['valid']}")
# Convert to LaTeX
latex_eq = parser.to_latex("H(ω) = 1 / (1 + jω)")
print(latex_eq) # H(\omega) = 1 / (1 + j\omega)
# Lookup symbol info
fc_info = parser.get_symbol_info("fc")
print(f"{fc_info.description}: {fc_info.range}")
Class: NotationParser¶
Main parser class for mathematical notation operations.
Constructor¶
Parameters:
- schema_path (Optional[Path]): Path to notation schema YAML file. If None, uses default schema.
Example:
parser = NotationParser() # Use default schema
# Or specify custom schema
from pathlib import Path
custom_parser = NotationParser(schema_path=Path("custom_notation.yaml"))
Methods¶
validate_notation(expression: str) -> Dict[str, Union[bool, List[str]]]¶
Validates that an expression uses standard notation.
Parameters:
- expression (str): Mathematical expression to validate
Returns:
- Dict with keys:
- valid (bool): True if notation is valid
- issues (List[str]): List of validation issues found
Example:
result = parser.validate_notation("y[n] = x(t) + z[n]")
print(result)
# {'valid': False, 'issues': ['Mixing discrete [n] and continuous (t) notation']}
Validation Rules:
- Detects mixing of discrete [n] and continuous (t) notation
- Checks for inconsistent parameter naming (e.g., fc vs f_c)
to_latex(expression: str) -> str¶
Converts expression from Unicode to LaTeX format.
Parameters:
- expression (str): Mathematical expression with Unicode symbols
Returns: - str: LaTeX-formatted expression
Example:
unicode_eq = "H(ω) = ω0² / Q"
latex_eq = parser.to_latex(unicode_eq)
print(latex_eq) # H(\omega) = \omega0² / Q
Conversions:
- ω → \omega
- π → \pi
- ∑ → \sum
- ∏ → \prod
- ∫ → \int
- And more (see schema)
to_ascii(expression: str) -> str¶
Converts expression to ASCII-only format.
Parameters:
- expression (str): Mathematical expression with Unicode symbols
Returns: - str: ASCII-only expression
Example:
unicode_eq = "y[n] = ω·x[n] + π"
ascii_eq = parser.to_ascii(unicode_eq)
print(ascii_eq) # y[n] = w*x[n] + pi
Conversions:
- ω → w
- π → pi
- × → *
- · → *
- And more
to_unicode(expression: str, from_format: str = 'ascii') -> str¶
Converts expression to Unicode format.
Parameters:
- expression (str): Mathematical expression
- from_format (str): Source format - 'ascii' or 'latex'
Returns: - str: Unicode-formatted expression
Example:
ascii_eq = "H(omega) = pi * f"
unicode_eq = parser.to_unicode(ascii_eq, from_format='ascii')
print(unicode_eq) # H(ω) = π * f
get_symbol_info(symbol: str) -> Optional[MathSymbol]¶
Retrieves information about a mathematical symbol.
Parameters:
- symbol (str): Symbol to lookup (e.g., "fc", "x[n]", "Q")
Returns:
- MathSymbol object or None if not found
Example:
fc_info = parser.get_symbol_info("fc")
print(f"Symbol: {fc_info.symbol}")
print(f"Description: {fc_info.description}")
print(f"LaTeX: {fc_info.latex}")
print(f"Unit: {fc_info.unit}")
print(f"Range: {fc_info.range}")
list_symbols(category: Optional[str] = None, domain: Optional[str] = None) -> List[MathSymbol]¶
Lists all symbols, optionally filtered.
Parameters:
- category (Optional[str]): Filter by category (not yet implemented)
- domain (Optional[str]): Filter by domain - 'discrete', 'continuous', 'frequency'
Returns:
- List of MathSymbol objects
Example:
# List all discrete time signals
discrete_symbols = parser.list_symbols(domain='discrete')
for sym in discrete_symbols:
print(f"{sym.symbol}: {sym.description}")
# List all symbols
all_symbols = parser.list_symbols()
print(f"Total symbols: {len(all_symbols)}")
format_equation(equation: str, output_format: str = 'latex') -> str¶
Formats equation in specified output format.
Parameters:
- equation (str): Mathematical equation
- output_format (str): Desired format - 'latex', 'ascii', or 'unicode'
Returns: - str: Formatted equation
Example:
eq = "H(ω) = ω0 / Q"
latex = parser.format_equation(eq, output_format='latex')
ascii_eq = parser.format_equation(eq, output_format='ascii')
unicode_eq = parser.format_equation(eq, output_format='unicode')
generate_reference_doc(output_format: str = 'markdown') -> str¶
Generates reference documentation for notation system.
Parameters:
- output_format (str): Format for output - currently only 'markdown' supported
Returns: - str: Formatted documentation
Example:
doc = parser.generate_reference_doc(output_format='markdown')
print(doc)
# Save to file
with open('notation_reference.md', 'w', encoding='utf-8') as f:
f.write(doc)
Class: MathSymbol¶
Dataclass representing a mathematical symbol.
Attributes¶
@dataclass
class MathSymbol:
symbol: str # Symbol representation (e.g., "fc", "x[n]")
description: str # Human-readable description
latex: str # LaTeX representation
domain: Optional[str] # Domain: 'discrete', 'continuous', 'frequency'
type: Optional[str] # Type: 'signal', 'parameter', 'index', etc.
unit: Optional[str] # Physical unit (e.g., "Hz", "s")
range: Optional[List[float]] # Valid range [min, max]
formula: Optional[str] # Formula for derived parameters
Example¶
from notation_parser import MathSymbol
# Create custom symbol
cutoff_freq = MathSymbol(
symbol='fc',
description='Cutoff frequency',
latex='f_c',
domain='discrete',
type='parameter',
unit='Hz',
range=[20, 20000]
)
print(f"{cutoff_freq.symbol}: {cutoff_freq.description}")
print(f"Valid range: {cutoff_freq.range[0]} to {cutoff_freq.range[1]} {cutoff_freq.unit}")
Schema Reference¶
The notation schema is defined in schemas/notation_schema.yaml.
Schema Structure¶
schema_version: "1.0.0"
signals:
discrete_time: [...] # Signals like x[n], y[n], h[n]
continuous_time: [...] # Signals like x(t), y(t)
frequency_domain: [...] # Signals like X(ω), H(jω)
parameters:
filter: [...] # Parameters like fc, Q, G
envelope: [...] # Parameters like A, D, S, R
delay: [...] # Parameters like D, fb, mix
operations:
basic: [...] # Operations like +, -, ×, /
signal: [...] # Operations like ∑, ∏, ∫
functions: [...] # Functions like sin(), exp(), log()
systems:
difference_equation: {...}
transfer_function_discrete: {...}
transfer_function_continuous: {...}
state_space: {...}
diagram_symbols: [...] # Block diagram symbols
validation:
naming_conventions: {...}
consistency: [...]
export_formats:
supported: [...]
conversions: {...}
Adding Custom Symbols¶
To add custom symbols, modify notation_schema.yaml:
parameters:
custom:
- symbol: "my_param"
description: "My custom parameter"
type: "custom"
latex: "\\text{my\\_param}"
unit: "units"
range: [0, 100]
Error Handling¶
The parser uses standard Python exceptions:
# ValueError for unsupported formats
try:
parser.format_equation(eq, output_format='invalid')
except ValueError as e:
print(f"Error: {e}")
# FileNotFoundError for missing schema
try:
parser = NotationParser(schema_path=Path("missing.yaml"))
except FileNotFoundError as e:
print(f"Schema not found: {e}")
Best Practices¶
1. Consistent Notation¶
Always use the same symbol for the same concept:
# GOOD
eq1 = "y[n] = fc·x[n]"
eq2 = "H(z) = 1 / (1 + fc·z⁻¹)"
# BAD - inconsistent
eq1 = "y[n] = fc·x[n]"
eq2 = "H(z) = 1 / (1 + f_c·z⁻¹)" # Different notation for fc!
2. Validate Before Processing¶
# Always validate first
result = parser.validate_notation(equation)
if not result['valid']:
print(f"Validation errors: {result['issues']}")
# Handle errors...
else:
# Process equation...
latex = parser.to_latex(equation)
3. Use Appropriate Domains¶
Don't mix discrete and continuous notation:
# GOOD - discrete
discrete_eq = "y[n] = x[n] + x[n-1]"
# GOOD - continuous
continuous_eq = "y(t) = x(t) + dx/dt"
# BAD - mixed domains
mixed_eq = "y[n] = x(t) + z[n-1]" # Will fail validation!
4. Document Units¶
Always specify units for physical parameters:
fc_info = parser.get_symbol_info("fc")
print(f"Cutoff frequency: {value} {fc_info.unit}") # "Cutoff frequency: 1000 Hz"
Performance¶
- Schema loading: ~10ms (cached after first load)
- Validation: ~1ms per equation
- Format conversion: ~0.5ms per equation
- Symbol lookup: O(1) via dictionary
Version History¶
v1.0.0 (2025-10-10)¶
- Initial release
- Support for LaTeX, Unicode, ASCII formats
- Comprehensive DSP symbol database
- Validation system
- Reference documentation generation