CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyamg

Algebraic Multigrid (AMG) solvers for large sparse linear systems with Python interface

Pending
Overview
Eval results
Files

strength-of-connection.mddocs/

Strength of Connection

Methods for determining the strength of connections between unknowns, fundamental to AMG coarsening strategies. Strength of connection measures identify which matrix entries represent strong coupling that must be preserved during coarsening.

Capabilities

Classical Strength Measures

Traditional strength of connection measures based on matrix entry magnitudes.

def classical_strength_of_connection(A, theta=0.25):
    """
    Classical strength of connection measure.
    
    Determines strong connections based on ratio of off-diagonal
    entries to diagonal entries. Entry A[i,j] is strong if
    |A[i,j]| >= theta * max{|A[i,k]| : k != i}.
    
    Parameters:
    - A: sparse matrix, coefficient matrix
    - theta: float, strength threshold (0 < theta <= 1):
        * 0.25: standard choice, moderate strength
        * 0.5: stricter strength requirement
        * 0.1: weaker strength, more connections
    
    Returns:
    sparse matrix: strength matrix S where S[i,j] != 0
        indicates strong connection from i to j
    
    Notes:
    - Most common strength measure for Classical AMG
    - Works well for M-matrices and diagonally dominant systems
    - May not be suitable for systems matrices or indefinite problems
    """

def symmetric_strength_of_connection(A, theta=0.0):
    """
    Symmetric strength of connection measure.
    
    Creates symmetric strength matrix by taking maximum of
    classical strength in both directions. Suitable for
    symmetric matrices and Smoothed Aggregation AMG.
    
    Parameters:
    - A: sparse matrix, coefficient matrix (preferably symmetric)
    - theta: float, strength threshold (default 0.0)
    
    Returns:
    sparse matrix: symmetric strength matrix where
        S[i,j] = S[j,i] and represents strong coupling
    
    Notes:
    - Default choice for Smoothed Aggregation AMG
    - Preserves symmetry of strength pattern
    - theta=0.0 includes all matrix connections
    """

Usage Examples:

import pyamg
import numpy as np

# Classical strength for Poisson problem
A = pyamg.gallery.poisson((50, 50))
S_classical = pyamg.strength.classical_strength_of_connection(A, theta=0.25)
print(f"Classical SOC: {S_classical.nnz} strong connections")

# Symmetric strength for elasticity
A_elastic = pyamg.gallery.linear_elasticity((30, 30))
S_symmetric = pyamg.strength.symmetric_strength_of_connection(A_elastic)
print(f"Symmetric SOC: {S_symmetric.nnz} strong connections")

# Different strength thresholds
S_weak = pyamg.strength.classical_strength_of_connection(A, theta=0.1)
S_strong = pyamg.strength.classical_strength_of_connection(A, theta=0.5)
print(f"Weak ({S_weak.nnz}) vs Strong ({S_strong.nnz}) connections")

Advanced Strength Measures

Sophisticated measures for challenging problems and special matrix types.

def energy_based_strength_of_connection(A, theta=0.0, **kwargs):
    """
    Energy-based strength of connection measure.
    
    Determines strength based on energy contribution of connections
    rather than algebraic magnitude. More robust for systems with
    complex coupling patterns.
    
    Parameters:
    - A: sparse matrix, coefficient matrix
    - theta: float, energy threshold
    - B: array, near-nullspace vectors (optional)
    - BtBinv: array, inverse of B^T B (optional)
    
    Returns:
    sparse matrix: energy-based strength matrix
    
    Notes:
    - Accounts for near-nullspace in strength computation
    - More expensive than classical measures
    - Better for elasticity and other systems problems
    """

def evolution_strength_of_connection(A, B=None, epsilon=4.0, k=2, proj_type='l2'):
    """
    Evolution-based strength of connection measure.
    
    Uses evolution process to determine strength based on
    how connections affect error evolution. Most sophisticated
    strength measure available.
    
    Parameters:
    - A: sparse matrix, coefficient matrix
    - B: array, near-nullspace vectors (default: constant)
    - epsilon: float, evolution parameter (default 4.0)
    - k: int, number of evolution steps (default 2)
    - proj_type: str, projection type ('l2', 'D_A')
    
    Returns:
    sparse matrix: evolution-based strength matrix
    
    Notes:
    - Most robust strength measure for difficult problems
    - Higher computational cost than other measures
    - Automatically adapts to problem characteristics
    """

def distance_strength_of_connection(A, theta=2.0):
    """
    Distance-based strength of connection measure.
    
    Determines strength based on geometric or algebraic
    distance between degrees of freedom.
    
    Parameters:
    - A: sparse matrix, coefficient matrix
    - theta: float, distance threshold
    
    Returns:
    sparse matrix: distance-based strength matrix
    
    Notes:
    - Useful when geometric information is available
    - Can incorporate coordinate data
    - Less common than algebraic measures
    """

Usage Examples:

# Energy-based strength for elasticity
A = pyamg.gallery.linear_elasticity((25, 25))
B = np.ones((A.shape[0], 3))  # Rigid body modes
S_energy = pyamg.strength.energy_based_strength_of_connection(A, B=B)

# Evolution-based strength (most robust)
S_evolution = pyamg.strength.evolution_strength_of_connection(A, B=B, epsilon=4.0)

# Compare different measures
print(f"Energy SOC: {S_energy.nnz} connections")
print(f"Evolution SOC: {S_evolution.nnz} connections")

Distance and Affinity Measures

Specialized measures for geometric and graph-based strength computation.

def algebraic_distance(A, B=None, distance='unit', **kwargs):
    """
    Compute algebraic distance between degrees of freedom.
    
    Measures algebraic distance based on how connections
    propagate through the matrix graph structure.
    
    Parameters:
    - A: sparse matrix, coefficient matrix
    - B: array, near-nullspace vectors
    - distance: str, distance measure:
        * 'unit': unit distance (default)
        * 'abs': absolute value distance
        * 'min': minimum distance
    - **kwargs: distance-specific parameters
    
    Returns:
    array: distance matrix or distance values
    
    Notes:
    - Fundamental component of many strength measures
    - Used internally by other strength functions
    - Can be used standalone for analysis
    """

def affinity_distance(A, B=None, distance='unit', **kwargs):
    """
    Compute affinity-based distance measure.
    
    Measures strength based on affinity (similarity) of
    connections rather than direct algebraic relationships.
    
    Parameters:
    - A: sparse matrix, coefficient matrix  
    - B: array, near-nullspace vectors
    - distance: str, affinity measure type
    - **kwargs: affinity-specific parameters
    
    Returns:
    sparse matrix: affinity-based strength matrix
    
    Notes:
    - Useful for graph-based problems
    - Can incorporate problem-specific similarity measures
    - Experimental, less established than classical measures
    """

Usage Examples:

# Algebraic distance computation
A = pyamg.gallery.poisson((40, 40))
distances = pyamg.strength.algebraic_distance(A, distance='unit')

# Affinity-based strength
S_affinity = pyamg.strength.affinity_distance(A)

Strength Measure Selection

Problem Type Guidelines

  • M-matrices, Poisson: Classical strength (theta=0.25)
  • Symmetric problems: Symmetric strength (theta=0.0)
  • Elasticity, systems: Energy-based or evolution strength
  • General/difficult: Evolution strength with adaptive parameters
  • Anisotropic: Evolution or energy-based measures

Parameter Tuning

# Conservative (many connections)
S_conservative = pyamg.strength.classical_strength_of_connection(A, theta=0.1)

# Standard (balanced)  
S_standard = pyamg.strength.classical_strength_of_connection(A, theta=0.25)

# Aggressive (fewer connections)
S_aggressive = pyamg.strength.classical_strength_of_connection(A, theta=0.5)

Integration with Solvers

# Use custom strength in solver construction
def custom_strength(A):
    return pyamg.strength.evolution_strength_of_connection(A, epsilon=6.0)

ml = pyamg.ruge_stuben_solver(A, strength=custom_strength)

# Or pass strength parameters directly
ml = pyamg.smoothed_aggregation_solver(A, strength=('evolution', {'epsilon': 4.0}))

Performance Considerations

  • Classical: Fastest, O(nnz) complexity
  • Symmetric: Fast, slight overhead for symmetrization
  • Energy: Moderate cost, requires near-nullspace computation
  • Evolution: Most expensive, O(k * nnz) for k evolution steps
  • Memory: Evolution and energy require additional storage

Analysis and Debugging

# Analyze strength connectivity
A = pyamg.gallery.poisson((30, 30))
S = pyamg.strength.classical_strength_of_connection(A, theta=0.25)

# Connection statistics
print(f"Matrix nnz: {A.nnz}")
print(f"Strong connections: {S.nnz}")
print(f"Strength ratio: {S.nnz / A.nnz:.2f}")

# Visualize strength pattern (for small problems)
import matplotlib.pyplot as plt
plt.spy(S, markersize=1)
plt.title("Strength of Connection Pattern")
plt.show()

Common Issues

  • Too many connections: Increase theta, use stricter measure
  • Too few connections: Decrease theta, use weaker measure
  • Poor coarsening: Try evolution or energy-based measures
  • Slow setup: Use simpler measures like classical or symmetric
  • Indefinite problems: Avoid classical strength, use evolution-based

Install with Tessl CLI

npx tessl i tessl/pypi-pyamg

docs

aggregation-methods.md

gallery.md

high-level-interface.md

index.md

krylov-methods.md

multilevel-solver.md

relaxation-methods.md

solver-constructors.md

strength-of-connection.md

utilities.md

tile.json