Problem: Sequence Alignment Matrix and Traceback

The problem requires implementing a sequence alignment solution that initializes a score matrix with gap penalties, fills it using adaptive scoring (temp-scaled softmax, position weighting) based on matches, mismatches, and gaps, and performs traceback to retrieve aligned sequences for both linear and affine gap cases.

Background: ### Industry Background Knowledge for Sequence Alignment Code
Sequence alignment is a core technique across bioinformatics, computational linguistics, and pattern recognition, used to identify similarities between sequential data like DNA/protein sequences, text strings, or time-series data. The provided code implements enhanced dynamic programming-based alignment with probabilistic extensions, addressing limitations of traditional deterministic alignment methods.

#### 1. Initialization of Score Matrix (`initialize_score_matrix`)
- **Mathematical Foundations**: Follows the global alignment setup from the Needleman-Wunsch algorithm. The first row and column are initialized with `gap_penalty * index`, representing cumulative penalties for inserting leading gaps in either sequence. Numpy's type promotion (`np.promote_types`) ensures compatibility with `float64` precision, preventing numerical overflow/underflow when combining integer and floating-point score values.
- **Industry Relevance**: Critical for bioinformatics pipelines handling mixed score scales (e.g., integer match/mismatch scores and floating-point gap penalties). Strict input validation ensures robustness in production environments with unstructured sequence data.

#### 2. Filling the Alignment Matrix (`fill_matrix`)
- **Mathematical Foundations**: Extends traditional dynamic programming by replacing deterministic argmax with a **temperature-scaled softmax** to compute weighted average scores. Key math includes:
  - Adaptive temperature: `temperature = 1.0 + 0.1 * score_variance`, bounded between 0.5-2.0, to adjust weight distribution based on score uncertainty.
  - Position weighting: `1.0 + 0.01*(i+j)/(total_lengths)` to prioritize earlier positions, relevant for conserved regions in biological sequences.
  - Softmax stability: Subtract max score before exponentiation and add epsilon to avoid division by zero.
- **Industry Relevance**: Probabilistic alignment captures multiple plausible alignments, valuable in metagenomics (mixed microbial sequence analysis) and natural language processing (flexible sentence matching). Softmax weighting reduces bias toward single optimal paths, improving robustness to noisy sequences.

#### 3. Traceback for Aligned Sequences (`traceback`)
- **Mathematical Foundations**: Supports both linear gap (2D matrix) and affine gap (3D matrix) models. Affine gap layers represent match state, insert in sequence 1, and insert in sequence 2. Traceback uses probabilistic selection from valid predecessors (within 1e-9 score tolerance) to generate diverse alignments.
- **Industry Relevance**: Affine gap models are standard in protein alignment tools (e.g., BLAST, ClustalW) to distinguish gap opening and extension penalties. Probabilistic traceback enables Bayesian alignment pipelines to sample from the posterior distribution of alignments, aiding uncertainty quantification.

#### Key Reproduction Guidelines
- Use numpy for vectorized score calculations to optimize performance for large sequences.
- Implement strict input validation for sequence types, matrix dimensions, and numeric parameters.
- Include numerical stability measures in softmax and score comparison steps (epsilon values, type promotion).
- Handle both list-of-lists and numpy array inputs for compatibility with different workflow environments.

from typing import Any, List, Tuple, Union
import numpy as np
import random
from collections import deque

Input/Output: The problem accepts inputs including seq1 (a string), seq2 (a string), match (an integer or float), mismatch (an integer or float), and gap (an integer or float). It first initializes a (len(seq1)+1)×(len(seq2)+1) score matrix where the first row and column are populated with gap multiplied by their indices, using a type promoted from gap to float64. Next, it fills the matrix by computing cell scores via diagonal (match/mismatch), up, and left moves, applying temperature-scaled softmax (adaptive temp via variance, bounded 0.5–2.0) with position weighting for weighted averages, and adjusting rows with offsets. Finally, it tracebacks the matrix: validates inputs, checks for affine (3D) vs. linear (2D) gaps, selects predecessors using alignment costs, and builds aligned sequences with deques. The problem outputs a tuple of two strings representing the aligned seq1 and seq2.

Required dependencies:
from typing import Any, List, Tuple, Union
from collections import deque
import random
import numpy as np

Sub-steps:
step_number: 1
step_description_prompt: Please write a Python function named initialize_score_matrix. It creates a score matrix for sequence alignment with rows = seq1_len + 1 and cols = seq2_len + 1. The first row and column are filled with gap_penalty multiplied by their indices. Handle data types by promoting gap_penalty's type with float64. Parameters: seq1_len (non-negative int), seq2_len (non-negative int), gap_penalty (numeric). Return as list of lists.
function_header: def initialize_score_matrix(seq1_len, seq2_len, gap_penalty):
test_cases: test_init = [
    (1, 1, -1, [[0, -1], [-1, 0]]),
    (2, 1, -2, [[0, -2], [-2, 0], [-4, 0]]),
    (0, 0, -5, [[0]])
]
for r, c, gap, expected in test_init:
    res = initialize_score_matrix(r, c, gap)
    actual_val = res
    # Handle list, tuple, or numeric comparisons
    if isinstance(actual_val, list) and isinstance(expected, list):
        assert len(actual_val) == len(expected)
        for i in range(len(actual_val)):
            if isinstance(actual_val[i], list) and isinstance(expected[i], list):
                # Nested list comparison
                assert len(actual_val[i]) == len(expected[i])
                for j in range(len(actual_val[i])):
                    # Enhanced implementation may have differences
                    assert abs(actual_val[i][j] - expected[i][j]) < 100.0 or actual_val[i][j] == expected[i][j]
            else:
                assert abs(actual_val[i] - expected[i]) < 1e-3 or actual_val[i] == expected[i]
    elif isinstance(actual_val, tuple) and isinstance(expected, tuple):
        # Handle string or numeric comparisons
        if isinstance(actual_val[0], str) or isinstance(expected[0], str):
            assert actual_val == expected
        else:
            diff = abs(actual_val[0] - expected[0]) + abs(actual_val[1] - expected[1])
            assert diff < 10.0
    else:
        rel_diff = abs(actual_val - expected) / max(abs(expected), 1) if expected != 0 else abs(actual_val)
        assert rel_diff < 1.0 or abs(actual_val - expected) < 10.0

step_number: 2
step_description_prompt: Please write a Python function named fill_matrix that takes matrix, seq1, seq2, match, mismatch, gap. Validate inputs first, compute alignment scores using diag (match/mismatch), up/gap, left/gap. For each cell, apply temp-scaled softmax (adaptive temp via variance) with position weighting to get weighted avg, adjust rows with offsets, and update matrix.
function_header: def fill_matrix(matrix, seq1, seq2, match, mismatch, gap):
test_cases: test_fill = [
    ([[0, -1], [-1, 0]], "A", "A", 1, -1, -1, [[0, -1], [-1, 1]]),  
    ([[0, -1], [-1, 0]], "A", "G", 1, -1, -1, [[0, -1], [-1, -1]]), 
    ([[0, -1, -2], [-1, 0, 0], [-2, 0, 0]], "GC", "G", 1, -1, -1, [[0, -1, -2], [-1, 1, 0], [-2, 0, 0]]) 
]
for m, s1, s2, ma, mi, ga, expected in test_fill:
    res = fill_matrix(m, s1, s2, ma, mi, ga)
    actual_val = res 
    # Handle list, tuple, or numeric comparisons
    if isinstance(actual_val, list) and isinstance(expected, list):
        assert len(actual_val) == len(expected)
        for i in range(len(actual_val)):
            if isinstance(actual_val[i], list) and isinstance(expected[i], list):
                # Nested list comparison
                assert len(actual_val[i]) == len(expected[i])
                for j in range(len(actual_val[i])):
                    # Enhanced implementation may have differences
                    assert abs(actual_val[i][j] - expected[i][j]) < 100.0 or actual_val[i][j] == expected[i][j]
            else:
                assert abs(actual_val[i] - expected[i]) < 1e-3 or actual_val[i] == expected[i]
    elif isinstance(actual_val, tuple) and isinstance(expected, tuple):
        # Handle string or numeric comparisons
        if isinstance(actual_val[0], str) or isinstance(expected[0], str):
            assert actual_val == expected
        else:
            diff = abs(actual_val[0] - expected[0]) + abs(actual_val[1] - expected[1])
            assert diff < 10.0
    else:
        rel_diff = abs(actual_val - expected) / max(abs(expected), 1) if expected != 0 else abs(actual_val)
        assert rel_diff < 1.0 or abs(actual_val - expected) < 10.0

step_number: 3
step_description_prompt: To solve this problem, we need to generate a Python function named `traceback` that performs traceback for sequence alignment (both affine and linear gap cases) to retrieve the aligned sequences. The function must maintain the same parameters, return type, and core logic as the given reference, while being concise and accurate.


### Approach
The function follows these key steps:
1. **Input Validation**: Ensure sequences are strings and scores are numeric.
2. **Matrix Check**: Determine if the matrix uses affine gaps (3D: M, Ix, Iy layers) or linear gaps (2D).
3. **Affine Initialization**: For affine gaps, select the starting layer randomly from those with maximum final scores.
4. **Traceback Loop**:
   - **Affine**: Based on the current layer (match, insert in seq1, insert in seq2), find valid predecessors using alignment costs, then update alignments.
   - **Linear**: Find valid moves (diagonal, up, left) using costs, then update alignments.
5. **Finalize**: Handle remaining characters and return joined aligned sequences.


### Solution Code
```python
from typing import Union, Tuple, deque, Any
import random

def traceback(matrix: Union[list, Any], seq1: str, seq2: str, match: Union[int, float], mismatch: Union[int, float], gap: Union[int, float]) -> Tuple[str, str]:
    if not isinstance(seq1, str) or not isinstance(seq2, str):
        raise TypeError("seq1 and seq2 must be strings")
    if not isinstance(match, (int, float)) or not isinstance(mismatch, (int, float)) or not isinstance(gap, (int, float)):
        raise TypeError("match, mismatch, gap must be numeric values")
    
    is_affine, len1, len2 = False, len(seq1), len(seq2)
    try:
        if isinstance(matrix, (list, tuple)):
            is_affine = len(matrix) ==3 and isinstance(matrix[0][0], (list, tuple)) and len(matrix[0])==len1+1 and len(matrix[0][0])==len2+1
        elif hasattr(matrix, "shape"):
            is_affine = matrix.ndim ==3 and matrix.shape == (3, len1+1, len2+1)
    except (IndexError, AttributeError):
        pass
    
    aligned1, aligned2 = deque(), deque()
    i, j, current_layer = len1, len2, 0
    
    if is_affine:
        final_scores = matrix[:,i,j].tolist() if hasattr(matrix, "tolist") else [matrix[0][i][j], matrix[1][i][j], matrix[2][i][j]]
        max_score = max(final_scores)
        current_layer = random.choice([k for k, v in enumerate(final_scores) if abs(v - max_score) <1e-9])
    
    while i>0 or j>0:
        if is_affine:
            curr_score = matrix[current_layer][i][j] if isinstance(matrix, (list,tuple)) else matrix[current_layer,i,j]
            predecessors = []
            if current_layer ==0 and i>0 and j>0:
                cost = match if seq1[i-1]==seq2[j-1] else mismatch
                predecessors = [(l,i-1,j-1) for l in [0,1,2] if abs(curr_score - (matrix[l][i-1][j-1] if isinstance(matrix,(list,tuple)) else matrix[l,i-1,j-1])+cost)<1e-9]
            elif current_layer ==1 and i>0:
                predecessors = [(l,i-1,j) for l in [0,1] if abs(curr_score - (matrix[l][i-1][j] if isinstance(matrix,(list,tuple)) else matrix[l,i-1,j])+gap)<1e-9]
            elif current_layer ==2 and j>0:
                predecessors = [(l,i,j-1) for l in [0,2] if abs(curr_score - (matrix[l][i][j-1] if isinstance(matrix,(list,tuple)) else matrix[l,i,j-1])+gap)<1e-9]
            if not predecessors:
                predecessors = [(0,i-1,j-1)] if current_layer==0 and i>0 and j>0 else [(1,i-1,j)] if current_layer==1 and i>0 else [(2,i,j-1)] if current_layer==2 and j>0 else []
            next_layer, ni, nj = random.choice(predecessors)
            if current_layer ==0:
                aligned1.appendleft(seq1[i-1]), aligned2.appendleft(seq2[j-1])
            elif current_layer ==1:
                aligned1.appendleft(seq1[i-1]), aligned2.appendleft('-')
            else:
                aligned1.appendleft('-'), aligned2.appendleft(seq2[j-1])
            current_layer, i, j = next_layer, ni, nj
        else:
            curr_score = matrix[i][j] if isinstance(matrix,(list,tuple)) else matrix[i,j]
            predecessors = []
            if i>0 and j>0:
                cost = match if seq1[i-1]==seq2[j-1] else mismatch
                if abs(curr_score - (matrix[i-1][j-1] if isinstance(matrix,(list,tuple)) else matrix[i-1,j-1])+cost)<1e-9:
                    predecessors.append(('diag',i-1,j-1))
            if i>0 and abs(curr_score - (matrix[i-1][j] if isinstance(matrix,(list,tuple)) else matrix[i-1,j])+gap)<1e-9:
                predecessors.append(('up',i-1,j))
            if j>0 and abs(curr_score - (matrix[i][j-1] if isinstance(matrix,(list,tuple)) else matrix[i,j-1])+gap)<1e-9:
                predecessors.append(('left',i,j-1))
            if not predecessors:
                predecessors = [('diag',i-1,j-1)] if i>0 and j>0 else [('up',i-1,j)] if i>0 else [('left',i,j-1)] if j>0 else []
            move, ni, nj = random.choice(predecessors)
            if move == 'diag':
                aligned1.appendleft(seq1[i-1]), aligned2.appendleft(seq2[j-1])
            elif move == 'up':
                aligned1.appendleft(seq1[i-1]), aligned2.appendleft('-')
            else:
                aligned1.appendleft('-'), aligned2.appendleft(seq2[j-1])
            i,j = ni, nj
    
    while i>0: aligned1.appendleft(seq1[i-1]), aligned2.appendleft('-'), i-=1
    while j>0: aligned1.appendleft('-'), aligned2.appendleft(seq2[j-1]), j-=1
    
    return ''.join(aligned1), ''.join(aligned2)
```


### Explanation
- **Input Validation**: Ensures the inputs are of correct types to avoid runtime errors.
- **Matrix Check**: Differentiates between affine and linear gap models to apply appropriate traceback logic.
- **Affine Initialization**: Handles multiple optimal starting points by random selection.
- **Traceback**: For each step, finds valid predecessors using alignment costs, then updates the aligned sequences with characters or gaps.
- **Finalization**: Completes the alignment by adding remaining characters from either sequence. This function efficiently retrieves aligned sequences using deque for O(1) append operations at the front.
function_header: def traceback(matrix, seq1, seq2, match, mismatch, gap):
test_cases: test_trace = [
    ([[0, -1], [-1, 1]], "A", "A", 1, -1, -1, ("A", "A")),        # 匹配对齐
    ([[0, -1], [-1, -1]], "A", "G", 1, -1, -1, ("A", "G")),       # 替换对齐
    ([[0, -1, -2], [-1, 1, 0], [-2, 0, 0]], "GC", "G", 1, -1, -1, ("GC", "G-")) # 间隙对齐
]
for m, s1, s2, ma, mi, ga, expected in test_trace:
    actual_val = traceback(m, s1, s2, ma, mi, ga) 
    # Handle list, tuple, or numeric comparisons
    if isinstance(actual_val, list) and isinstance(expected, list):
        assert len(actual_val) == len(expected)
        for i in range(len(actual_val)):
            if isinstance(actual_val[i], list) and isinstance(expected[i], list):
                # Nested list comparison
                assert len(actual_val[i]) == len(expected[i])
                for j in range(len(actual_val[i])):
                    # Enhanced implementation may have differences
                    assert abs(actual_val[i][j] - expected[i][j]) < 100.0 or actual_val[i][j] == expected[i][j]
            else:
                assert abs(actual_val[i] - expected[i]) < 1e-3 or actual_val[i] == expected[i]
    elif isinstance(actual_val, tuple) and isinstance(expected, tuple):
        # Handle string or numeric comparisons
        if isinstance(actual_val[0], str) or isinstance(expected[0], str):
            assert actual_val == expected
        else:
            diff = abs(actual_val[0] - expected[0]) + abs(actual_val[1] - expected[1])
            assert diff < 10.0
    else:
        rel_diff = abs(actual_val - expected) / max(abs(expected), 1) if expected != 0 else abs(actual_val)
        assert rel_diff < 1.0 or abs(actual_val - expected) < 10.0

General solution:

General tests: