"""第 16 章：顺序、循环状态与 LSTM 记忆通路；只用标准库。"""

from math import tanh


def recurrent(sequence, recurrent_weight=0.5):
    state, history = 0.0, []
    for value in sequence:
        state = tanh(value+recurrent_weight*state)
        history.append(state)
    return history


def lstm_fixed_gates(sequence):
    # 为便于观察，三个门固定；完整 LSTM 的门由输入与旧状态学习得到。
    cell, history = 0.0, []
    forget, write, read = 0.8, 0.2, 0.9
    for value in sequence:
        candidate = tanh(value)
        cell = forget*cell + write*candidate
        hidden = read*tanh(cell)
        history.append((cell, hidden))
    return history


def main():
    first, second = [1, 0, -1], [-1, 0, 1]
    print(f"两条序列的均值：{sum(first)/3:.1f}，{sum(second)/3:.1f}")
    for sequence in [first, second]:
        states = recurrent(sequence)
        print(f"序列 {sequence} 的循环状态：" + ", ".join(f"{x:.4f}" for x in states))
    for step, (cell, hidden) in enumerate(lstm_fixed_gates(first), start=1):
        print(f"固定门 LSTM 第 {step} 步：c={cell:.4f}，h={hidden:.4f}")
    print(f"20 次相乘：0.5^20={0.5**20:.8f}，0.99^20={0.99**20:.4f}")


if __name__ == "__main__":
    main()
