【机器学习基础算法:从零实现到精通】第1章 数学与计算基础

AI学习指南:从零到精通的完整路线图 Python因其简洁的语法、强大的库支持和广泛的社区资源,成为AI领域的首选编程语言。订阅AI领域的顶级会议(如NeurIPS、ICML、CVPR)和期刊,阅读最新的研究论文。概率论是处理不确定性的数学工具,帮助你理解数据的分布和模型的预测能力。线性代数是深度学习的基础,它帮助你理解数据的结构和神经网络的运算。导数、偏导数和梯度是深度学习中优化模型的关键概念。通过参与GitHub上的项目,你可以学习到先进的架构设计、代码规范和开发流程。数学是AI的核心,它帮助你理解算法背后的原理,而不仅仅是调用库和函数。 阅读详情

目录

机器学习基础算法:从零实现到精通

第1章 数学与计算基础

1.1 线性代数与张量运算

1.1.1 向量空间与矩阵分解

1.1.1.1 特征值分解(EVD)的数值稳定性分析与手动实现

1.1.1.2 奇异值分解(SVD)在降维中的算法实现(Full/Compact/Truncated SVD)

1.1.1.3 Cholesky分解与正定矩阵的高效求解

1.1.2 张量运算与自动微分基础

1.1.2.1 张量索引、广播机制与内存布局(Strided/Contiguous)

1.1.2.2 计算图构建:从反向传播到自动微分(AutoDiff)

1.1.2.3 链式法则的矩阵形式与梯度检查(Gradient Checking)实现

1.2 概率论与统计推断

1.2.1 概率分布与指数族

1.2.1.1 高斯分布的多元形式与马氏距离的几何解释

1.2.1.2 指数族分布的自然参数与充分统计量(Bernoulli/Gaussian/Poisson)

1.2.1.3 共轭先验与后验分布的解析推导(Beta-Binomial/Dirichlet-Multinomial)

1.2.2 信息论与KL散度

1.2.2.1 熵、联合熵、条件熵与互信息的计算实现

1.2.2.2 KL散度与JS散度的非对称性分析及数值稳定性处理

1.2.2.3 最大熵原理与指数族分布的等价性证明

1.3 凸优化与数值计算

1.3.1 凸集、凸函数与最优性条件

1.3.1.1 凸性判定:Hessian矩阵半正定性检验实现

1.3.1.2 强凸性与L-光滑性的收敛率影响分析

1.3.1.3 KKT条件与约束优化的对偶性推导

1.3.2 一阶与二阶优化算法

1.3.2.1 梯度下降:Batch/Mini-batch/Stochastic的方差分析

1.3.2.2 动量法(Momentum/Nesterov)的等价形式与收敛加速证明

1.3.2.3 自适应学习率方法:AdaGrad/RMSprop/Adam的偏差修正实现

1.3.3 约束优化与投影法

1.3.3.1 拉格朗日乘子法与等式约束的Newton法实现

1.3.3.2 不等式约束的障碍法(Barrier Method)与内点法

1.3.3.3 近端梯度下降(Proximal Gradient)与L1正则化的软阈值算子

完整源码


============================================================
开始执行数学基础算法验证测试套件
============================================================

[1.1] 矩阵分解数值稳定性测试
  幂迭代EVD重构误差: 1.33e-15
  Cholesky分解 ||A-LL^T||: 4.44e-16
  Compact SVD重构误差: 1.17e-15

机器学习基础算法:从零实现到精通

第1章 数学与计算基础

1.1 线性代数与张量运算
1.1.1 向量空间与矩阵分解
1.1.1.1 特征值分解(EVD)的数值稳定性分析与手动实现
1.1.1.2 奇异值分解(SVD)在降维中的算法实现(Full/Compact/Truncated SVD)
1.1.1.3 Cholesky分解与正定矩阵的高效求解
1.1.2 张量运算与自动微分基础
1.1.2.1 张量索引、广播机制与内存布局(Strided/Contiguous)
1.1.2.2 计算图构建:从反向传播到自动微分(AutoDiff)
1.1.2.3 链式法则的矩阵形式与梯度检查(Gradient Checking)实现
1.2 概率论与统计推断
1.2.1 概率分布与指数族
1.2.1.1 高斯分布的多元形式与马氏距离的几何解释
1.2.1.2 指数族分布的自然参数与充分统计量(Bernoulli/Gaussian/Poisson)
1.2.1.3 共轭先验与后验分布的解析推导(Beta-Binomial/Dirichlet-Multinomial)
1.2.2 信息论与KL散度
1.2.2.1 熵、联合熵、条件熵与互信息的计算实现
1.2.2.2 KL散度与JS散度的非对称性分析及数值稳定性处理
1.2.2.3 最大熵原理与指数族分布的等价性证明
1.3 凸优化与数值计算
1.3.1 凸集、凸函数与最优性条件
1.3.1.1 凸性判定:Hessian矩阵半正定性检验实现
1.3.1.2 强凸性与L-光滑性的收敛率影响分析
1.3.1.3 KKT条件与约束优化的对偶性推导
1.3.2 一阶与二阶优化算法
1.3.2.1 梯度下降:Batch/Mini-batch/Stochastic的方差分析
1.3.2.2 动量法(Momentum/Nesterov)的等价形式与收敛加速证明
1.3.2.3 自适应学习率方法:AdaGrad/RMSprop/Adam的偏差修正实现
1.3.3 约束优化与投影法
1.3.3.1 拉格朗日乘子法与等式约束的Newton法实现
1.3.3.2 不等式约束的障碍法(Barrier Method)与内点法
1.3.3.3 近端梯度下降(Proximal Gradient)与L1正则化的软阈值算子

完整源码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
机器学习基础算法:数学与计算基础 - 完整实现脚本
Machine Learning Fundamentals: Mathematical and Computational Foundations

本脚本涵盖:
1. 矩阵分解算法(EVD/SVD/Cholesky)的数值稳定实现与复杂度分析
2. 张量运算系统与自动微分引擎的从零构建
3. 概率分布体系(指数族、共轭先验)的统计推断实现
4. 信息论度量(熵、KL散度)的计算与可视化
5. 凸优化算法库(一阶/二阶/约束优化)的完整实现

依赖要求:numpy>=1.21, scipy>=1.7, matplotlib>=3.4, torch>=1.9(仅用于梯度验证)
使用方法:直接运行脚本将执行所有章节的示例与可视化
"""

import numpy as np
import matplotlib.pyplot as plt
from typing import Tuple, Optional, Callable, List, Dict, Union
from dataclasses import dataclass
from abc import ABC, abstractmethod
import warnings
from collections import defaultdict
import time

# 设置随机种子与绘图样式
np.random.seed(42)
plt.style.use('seaborn-v0_8-whitegrid')
plt.rcParams['figure.figsize'] = (10, 6)
plt.rcParams['font.size'] = 10

# =============================================================================
# 1.1 线性代数与张量运算
# =============================================================================

class MatrixDecomposition:
    """
    矩阵分解算法库:实现数值稳定的EVD、SVD与Cholesky分解
    包含Full/Compact/Truncated SVD的内存优化实现
    """
    
    @staticmethod
    def power_iteration_evd(A: np.ndarray, max_iter: int = 1000, tol: float = 1e-10) -> Tuple[np.ndarray, np.ndarray]:
        """
        基于幂迭代的特征值分解(数值稳定实现)
        
        算法原理:通过迭代计算主导特征向量,结合收缩技术(Deflation)依次提取
        剩余特征对。采用Gram-Schmidt正交化确保数值稳定性,处理重特征值情况。
        
        复杂度:O(k·n³) 其中k为迭代次数,n为矩阵维度。适用于中小规模稠密矩阵。
        
        数值稳定性措施:
        1. 迭代向量L2归一化防止溢出
        2. 随机初始化避免初始向量与特征向量正交
        3. 收敛判定基于Rayleigh商残差
        
        参数:
            A: 对称方阵 (n, n)
            max_iter: 最大迭代次数
            tol: 收敛容差
            
        返回:
            eigenvalues: 升序排列的特征值 (n,)
            eigenvectors: 对应特征向量矩阵 (n, n)
        """
        n = A.shape[0]
        if A.shape[0] != A.shape[1]:
            raise ValueError("矩阵必须为方阵")
        
        # 检查对称性(考虑数值误差)
        if not np.allclose(A, A.T, atol=1e-8):
            raise ValueError("当前实现仅支持对称矩阵")
        
        eigenvalues = np.zeros(n)
        eigenvectors = np.zeros((n, n))
        A_remaining = A.copy().astype(float)
        
        for i in range(n):
            # 随机初始化并归一化
            v = np.random.randn(n)
            v = v / np.linalg.norm(v)
            
            # 幂迭代提取第i个特征向量
            for iteration in range(max_iter):
                # 矩阵向量乘法
                v_new = A_remaining @ v
                
                # 归一化
                norm = np.linalg.norm(v_new)
                if norm < 1e-12:
                    break
                v_new = v_new / norm
                
                # Rayleigh商计算特征值
                rayleigh_quotient = (v_new.T @ A_remaining @ v_new)
                
                # 收敛检查
                if np.linalg.norm(v_new - v) < tol or np.linalg.norm(v_new + v) < tol:
                    v = v_new
                    eigenvalues[i] = rayleigh_quotient
                    break
                
                v = v_new
            
            # 存储并收缩(Deflation)
            eigenvectors[:, i] = v
            A_remaining = A_remaining - eigenvalues[i] * np.outer(v, v)
            
            # 强制对称性保持数值稳定
            A_remaining = (A_remaining + A_remaining.T) / 2
        
        # 按特征值绝对值升序排序
        idx = np.argsort(np.abs(eigenvalues))
        return eigenvalues[idx], eigenvectors[:, idx]
    
    @staticmethod
    def qr_algorithm_evd(A: np.ndarray, max_iter: int = 100, tol: float = 1e-10) -> Tuple[np.ndarray, np.ndarray]:
        """
        QR算法实现特征值分解(带位移优化)
        
        相比幂迭代,QR算法通过正交相似变换将矩阵收敛为上三角形式,
        同时获得所有特征值。采用Wilkinson位移加速收敛。
        
        数值稳定性:Householder反射确保正交性,Wilkinson位移处理病态矩阵。
        """
        n = A.shape[0]
        A_k = A.copy().astype(float)
        Q_total = np.eye(n)
        
        for _ in range(max_iter):
            # Wilkinson位移:选择最接近对角元的特征值
            if n > 1:
                d = (A_k[-2, -2] - A_k[-1, -1]) / 2
                if d >= 0:
                    shift = A_k[-1, -1] - A_k[-1, -2]**2 / (d + np.sqrt(d**2 + A_k[-1, -2]**2))
                else:
                    shift = A_k[-1, -1] - A_k[-1, -2]**2 / (d - np.sqrt(d**2 + A_k[-1, -2]**2))
            else:
                shift = 0
            
            # QR分解(基于Householder反射)
            Q, R = MatrixDecomposition.householder_qr(A_k - shift * np.eye(n))
            
            # 反向乘法并恢复位移
            A_k = R @ Q + shift * np.eye(n)
            Q_total = Q_total @ Q
            
            # 检查次对角线收敛
            off_diag_norm = np.sqrt(np.sum(A_k**2) - np.sum(np.diag(A_k)**2))
            if off_diag_norm < tol:
                break
        
        eigenvalues = np.diag(A_k)
        return eigenvalues, Q_total
    
    @staticmethod
    def householder_qr(A: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
        """
        Householder QR分解(数值稳定实现)
        
        通过反射变换将矩阵逐步化为上三角形式,保持正交性。
        避免显式计算Householder矩阵,直接应用反射向量优化内存。
        """
        m, n = A.shape
        R = A.copy().astype(float)
        Q = np.eye(m)
        
        for k in range(min(m, n)):
            # 提取列向量
            x = R[k:, k]
            norm_x = np.linalg.norm(x)
            
            if norm_x < 1e-12:
                continue
            
            # 构造反射向量(避免抵消)
            sign = 1 if x[0] >= 0 else -1
            v = x.copy()
            v[0] += sign * norm_x
            v = v / np.linalg.norm(v)
            
            # 应用反射(避免矩阵乘法,直接向量操作)
            R[k:, k:] -= 2.0 * np.outer(v, v @ R[k:, k:])
            
            # 累积Q
            Q_k = np.eye(m)
            Q_k[k:, k:] -= 2.0 * np.outer(v, v)
            Q = Q @ Q_k
        
        return Q, R
    
    @staticmethod
    def svd_full(A: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
        """
        完全SVD分解实现
        
        基于A^T A与AA^T的特征值分解,处理数值稳定性问题:
        1. 对较小维度进行EVD以减少计算量
        2. 符号一致性校正确保U @ Σ @ V^T = A
        3. 处理零奇异值的数值阈值
        """
        m, n = A.shape
        if m >= n:
            # 计算右奇异向量(A^T A的特征向量)
            ATA = A.T @ A
            S, V = MatrixDecomposition.qr_algorithm_evd(ATA)
            # 数值稳定:处理负特征值(舍入误差)
            S = np.maximum(S, 0)
            sigma = np.sqrt(S)
            
            # 计算左奇异向量 U = A V / sigma
            U = A @ V
            # 处理零奇异值
            for i in range(len(sigma)):
                if sigma[i] > 1e-12:
                    U[:, i] /= sigma[i]
                else:
                    U[:, i] = np.zeros(m)
            
            # Gram-Schmidt补全U(当m>n时)
            if m > n:
                U = MatrixDecomposition.gram_schmidt_completion(U, m)
        else:
            # 对瘦矩阵使用AA^T
            AAT = A @ A.T
            S, U = MatrixDecomposition.qr_algorithm_evd(AAT)
            S = np.maximum(S, 0)
            sigma = np.sqrt(S)
            
            V = A.T @ U
            for i in range(len(sigma)):
                if sigma[i] > 1e-12:
                    V[:, i] /= sigma[i]
                else:
                    V[:, i] = np.zeros(n)
            
            if n > m:
                V = MatrixDecomposition.gram_schmidt_completion(V, n)
        
        # 确保降序排列
        idx = np.argsort(sigma)[::-1]
        return U[:, idx], sigma[idx], V[:, idx]
    
    @staticmethod
    def svd_compact(A: np.ndarray, rank: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
        """
        紧凑SVD(Compact SVD):仅计算非零奇异值对应的奇异向量
        
        内存优化:当rank << min(m,n)时,显著降低存储需求。
        适用于低秩矩阵近似与降维场景。
        """
        m, n = A.shape
        r = min(m, n) if rank is None else min(rank, m, n)
        
        # 使用幂迭代计算前r个奇异值/向量
        U = np.zeros((m, r))
        Sigma = np.zeros(r)
        V = np.zeros((n, r))
        A_temp = A.copy().astype(float)
        
        for i in range(r):
            # 通过A^T A的幂迭代计算右奇异向量
            v = np.random.randn(n)
            v = v / np.linalg.norm(v)
            
            for _ in range(100):
                v_new = A_temp.T @ (A_temp @ v)
                norm = np.linalg.norm(v_new)
                if norm < 1e-12:
                    break
                v_new = v_new / norm
                
                if np.linalg.norm(v_new - v) < 1e-10:
                    break
                v = v_new
            
            # 计算奇异值与左奇异向量
            Av = A_temp @ v
            sigma = np.linalg.norm(Av)
            
            if sigma < 1e-12:
                break
            
            u = Av / sigma
            
            U[:, i] = u
            Sigma[i] = sigma
            V[:, i] = v
            
            # 收缩:减去当前秩-1成分
            A_temp = A_temp - sigma * np.outer(u, v)
        
        return U, Sigma, V
    
    @staticmethod
    def svd_truncated(A: np.ndarray, k: int) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
        """
        截断SVD(Truncated SVD):计算前k个最大奇异值
        
        采用随机SVD算法(Randomized SVD)加速大规模矩阵的低秩近似,
        通过随机投影降维后执行标准SVD,复杂度从O(mn²)降至O(mnk)。
        """
        m, n = A.shape
        # 随机投影矩阵
        Omega = np.random.randn(n, k)
        Y = A @ Omega  # 采样列空间
        
        # QR分解获得正交基
        Q, _ = np.linalg.qr(Y)
        
        # 小矩阵SVD
        B = Q.T @ A
        U_tilde, S, Vt = np.linalg.svd(B, full_matrices=False)
        
        # 重构左奇异向量
        U = Q @ U_tilde
        
        return U[:, :k], S[:k], Vt[:k, :].T
    
    @staticmethod
    def gram_schmidt_completion(Q_partial: np.ndarray, dim: int) -> np.ndarray:
        """
        Gram-Schmidt正交化补全矩阵列(处理数值稳定性)
        
        对不满秩的Q矩阵补充标准正交基,确保Q^T Q = I。
        使用修正Gram-Schmidt过程减少舍入误差累积。
        """
        m, n = Q_partial.shape
        Q_full = np.zeros((dim, dim))
        Q_full[:, :n] = Q_partial
        
        for i in range(n, dim):
            # 随机向量
            q = np.random.randn(dim)
            q = q / np.linalg.norm(q)
            
            # 正交化(修正Gram-Schmidt)
            for j in range(i):
                q = q - np.dot(Q_full[:, j], q) * Q_full[:, j]
                q = q / (np.linalg.norm(q) + 1e-12)
            
            Q_full[:, i] = q
        
        return Q_full
    
    @staticmethod
    def cholesky_decomposition(A: np.ndarray, method: str = 'outer_product') -> np.ndarray:
        """
        Cholesky分解:A = LL^T,针对对称正定矩阵的高效求解
        
        实现两种算法:
        1. 外积形式(Outer-product):缓存友好,适合行优先存储
        2. 内积形式(Inner-product):数值稳定性更好
        
        包含对角线元素平方根检查确保正定性。
        """
        n = A.shape[0]
        if not np.allclose(A, A.T):
            raise ValueError("矩阵必须对称")
        
        L = np.zeros((n, n))
        
        if method == 'outer_product':
            # 外积形式:逐列计算
            for j in range(n):
                # 对角线元素
                diag = A[j, j] - np.sum(L[j, :j]**2)
                if diag <= 0:
                    raise ValueError(f"矩阵非正定:第{j}个顺序主子式非正")
                L[j, j] = np.sqrt(diag)
                
                # 非对角线元素
                for i in range(j+1, n):
                    L[i, j] = (A[i, j] - np.sum(L[i, :j] * L[j, :j])) / L[j, j]
        
        elif method == 'inner_product':
            # 内积形式:逐元素计算,数值更稳定
            for i in range(n):
                for j in range(i+1):
                    sum_val = np.sum(L[i, :j] * L[j, :j])
                    if i == j:
                        diag = A[i, i] - sum_val
                        if diag <= 0:
                            raise ValueError("矩阵非正定")
                        L[i, j] = np.sqrt(diag)
                    else:
                        L[i, j] = (A[i, j] - sum_val) / L[j, j]
        
        return L


class TensorEngine:
    """
    张量运算引擎:实现张量索引、广播机制与自动微分
    
    构建计算图追踪运算历史,支持反向传播计算梯度。
    内存布局优化包含Strided视图与Contiguous数组转换。
    """
    
    def __init__(self, data: np.ndarray, requires_grad: bool = False):
        self.data = np.array(data, dtype=np.float64)
        self.requires_grad = requires_grad
        self.grad = None
        self._grad_fn = None
        self._prev = []
        self._op = ''
        
        if requires_grad:
            self.grad = np.zeros_like(self.data)
    
    def __repr__(self):
        return f"Tensor(shape={self.data.shape}, requires_grad={self.requires_grad})"
    
    @staticmethod
    def broadcast_shapes(shape1: Tuple, shape2: Tuple) -> Tuple:
        """
        广播机制实现:计算两个形状广播后的结果形状
        
        从后向前逐维度比较,维度为1或相等时兼容,否则报错。
        返回结果形状与每个输入需要扩展的维度信息。
        """
        len1, len2 = len(shape1), len(shape2)
        max_len = max(len1, len2)
        
        # 补齐维度
        s1 = (1,) * (max_len - len1) + shape1
        s2 = (1,) * (max_len - len2) + shape2
        
        result_shape = []
        for dim1, dim2 in zip(s1, s2):
            if dim1 == dim2 or dim1 == 1 or dim2 == 1:
                result_shape.append(max(dim1, dim2))
            else:
                raise ValueError(f"形状不匹配:{shape1} vs {shape2}")
        
        return tuple(result_shape)
    
    @staticmethod
    def strided_indexing(arr: np.ndarray, strides: Tuple[int, ...], shape: Tuple[int, ...]) -> np.ndarray:
        """
        基于步长的张量索引(Strided Indexing):零拷贝视图操作
        
        通过修改步长实现切片、转置、扩展等操作,避免内存复制。
        关键概念:stride[i]表示沿第i维移动一个元素的内存偏移量(字节)。
        """
        # 使用as_strided创建视图(需谨慎处理内存安全)
        from numpy.lib.stride_tricks import as_strided
        return as_strided(arr, shape=shape, strides=strides)
    
    def __add__(self, other):
        other = other if isinstance(other, TensorEngine) else TensorEngine(other)
        
        # 广播处理
        out_shape = self.broadcast_shapes(self.data.shape, other.data.shape)
        out_data = np.broadcast_to(self.data, out_shape) + np.broadcast_to(other.data, out_shape)
        
        out = TensorEngine(out_data, requires_grad=(self.requires_grad or other.requires_grad))
        
        def _backward(grad_output):
            if self.requires_grad:
                # 梯度反向广播(Sum over broadcasted dimensions)
                grad_self = self._unbroadcast(grad_output, self.data.shape)
                self.grad = self.grad + grad_self if self.grad is not None else grad_self
            
            if other.requires_grad:
                grad_other = self._unbroadcast(grad_output, other.data.shape)
                other.grad = other.grad + grad_other if other.grad is not None else grad_other
        
        out._grad_fn = _backward
        out._prev = [self, other]
        out._op = 'add'
        return out
    
    def __matmul__(self, other):
        other = other if isinstance(other, TensorEngine) else TensorEngine(other)
        out_data = self.data @ other.data
        out = TensorEngine(out_data, requires_grad=(self.requires_grad or other.requires_grad))
        
        def _backward(grad_output):
            # 矩阵乘法梯度:dL/dA = dL/dC @ B^T, dL/dB = A^T @ dL/dC
            if self.requires_grad:
                self.grad += grad_output @ other.data.T
            if other.requires_grad:
                other.grad += self.data.T @ grad_output
        
        out._grad_fn = _backward
        out._prev = [self, other]
        out._op = 'matmul'
        return out
    
    def _unbroadcast(self, grad: np.ndarray, shape: Tuple) -> np.ndarray:
        """
        梯度反向广播:将梯度从广播后形状还原为原始形状
        
        对扩展的维度求和,对缺失的维度添加轴后求和。
        """
        ndims_added = grad.ndim - len(shape)
        for _ in range(ndims_added):
            grad = grad.sum(axis=0)
        
        for i, dim in enumerate(shape):
            if dim == 1:
                grad = grad.sum(axis=i, keepdims=True)
        return grad
    
    def backward(self, grad_output: Optional[np.ndarray] = None):
        """
        反向传播:基于计算图的拓扑排序自动计算梯度
        
        采用后序遍历确保子节点先于父节点计算,处理非标量输出时
        初始化全1梯度。支持多输出情况的梯度累加。
        """
        if grad_output is None:
            if self.data.shape != ():
                grad_output = np.ones_like(self.data)
            else:
                grad_output = np.array(1.0)
        
        # 拓扑排序构建计算图
        topo = []
        visited = set()
        
        def build_topo(v):
            if v not in visited:
                visited.add(v)
                for child in v._prev:
                    build_topo(child)
                topo.append(v)
        
        build_topo(self)
        
        # 反向传播
        self.grad = grad_output
        for node in reversed(topo):
            if node._grad_fn is not None:
                node._grad_fn(node.grad)
    
    @staticmethod
    def gradient_check(func: Callable, inputs: List[np.ndarray], eps: float = 1e-5) -> bool:
        """
        梯度检查(Gradient Checking):数值梯度与解析梯度对比
        
        基于有限差分法计算数值梯度:f'(x) ≈ (f(x+h) - f(x-h)) / 2h
        相对误差容忍度通常设为1e-7以确保反向传播正确性。
        """
        # 转换为Tensor并计算解析梯度
        tensors = [TensorEngine(x, requires_grad=True) for x in inputs]
        output = func(*tensors)
        output.backward()
        analytical_grads = [t.grad for t in tensors]
        
        # 数值梯度计算
        numerical_grads = []
        for i, x in enumerate(inputs):
            grad = np.zeros_like(x)
            it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
            
            while not it.finished:
                idx = it.multi_index
                old_val = x[idx]
                
                x[idx] = old_val + eps
                f_plus = func(*[TensorEngine(x if j==i else inputs[j]) for j in range(len(inputs))]).data
                
                x[idx] = old_val - eps
                f_minus = func(*[TensorEngine(x if j==i else inputs[j]) for j in range(len(inputs))]).data
                
                grad[idx] = (f_plus - f_minus) / (2 * eps)
                x[idx] = old_val
                it.iternext()
            
            numerical_grads.append(grad)
        
        # 比较相对误差
        for ag, ng in zip(analytical_grads, numerical_grads):
            diff = np.abs(ag - ng)
            denom = np.abs(ag) + np.abs(ng) + 1e-8
            relative_error = np.max(diff / denom)
            
            if relative_error > 1e-5:
                print(f"梯度检查失败,相对误差: {relative_error}")
                return False
        
        print("梯度检查通过")
        return True


# =============================================================================
# 1.2 概率论与统计推断
# =============================================================================

class ExponentialFamily:
    """
    指数族分布实现:包含高斯、伯努利、泊松分布的自然参数化
    
    统一框架:p(x|η) = h(x) exp(η^T T(x) - A(η))
    其中η为自然参数,T(x)为充分统计量,A(η)为对数配分函数。
    """
    
    @staticmethod
    def multivariate_gaussian(x: np.ndarray, mu: np.ndarray, Sigma: np.ndarray) -> np.ndarray:
        """
        多元高斯分布概率密度函数
        
        数值稳定实现采用Cholesky分解避免直接求逆:
        p(x) = (2π)^{-d/2} |Σ|^{-1/2} exp(-0.5 (x-μ)^T Σ^{-1} (x-μ))
        
        马氏距离的几何解释:Σ^{-1}定义了Mahalanobis度量空间中的椭球等值面,
        其特征值决定椭球轴长,特征向量决定轴向。
        """
        d = len(mu)
        
        # Cholesky分解求解精度矩阵
        try:
            L = np.linalg.cholesky(Sigma)
            # 利用三角矩阵求解线性系统(避免显式求逆)
            diff = x - mu
            # 解 Ly = diff
            y = np.linalg.solve_triangular(L, diff, lower=True)
            # 解 L^T z = y,得到 Σ^{-1} (x-μ)
            mahalanobis_sq = np.sum(y**2, axis=-1)
            
            # 对数行列式:2 * sum(log(diag(L)))
            log_det = 2 * np.sum(np.log(np.diag(L)))
            
            log_pdf = -0.5 * d * np.log(2 * np.pi) - 0.5 * log_det - 0.5 * mahalanobis_sq
            return np.exp(log_pdf)
        
        except np.linalg.LinAlgError:
            # 退化情况使用特征值分解
            eigenvalues, eigenvectors = np.linalg.eigh(Sigma)
            # 处理小特征值
            eigenvalues = np.maximum(eigenvalues, 1e-10)
            precision = eigenvectors @ np.diag(1/eigenvalues) @ eigenvectors.T
            
            diff = x - mu
            mahalanobis_sq = np.einsum('...i,ij,...j->...', diff, precision, diff)
            det = np.prod(eigenvalues)
            
            return (2*np.pi)**(-d/2) * det**(-0.5) * np.exp(-0.5 * mahalanobis_sq)
    
    @staticmethod
    def bernoulli_natural_parameter(p: float) -> float:
        """
        伯努利分布的自然参数:η = log(p/(1-p)) (logit函数)
        
        充分统计量:T(x) = x
        对数配分函数:A(η) = log(1 + exp(η))
        """
        return np.log(p / (1 - p + 1e-12))
    
    @staticmethod
    def bernoulli_from_natural(eta: float) -> float:
        """从自然参数恢复均值参数:sigmoid函数"""
        return 1 / (1 + np.exp(-eta))
    
    @staticmethod
    def poisson_natural_parameter(lambda_: float) -> float:
        """
        泊松分布的自然参数:η = log(λ)
        
        充分统计量:T(x) = x
        对数配分函数:A(η) = exp(η)
        """
        return np.log(lambda_ + 1e-12)
    
    @staticmethod
    def conjugate_prior_analysis(dist_type: str, data: np.ndarray, prior_params: Dict) -> Dict:
        """
        共轭先验与后验分布解析推导实现
        
        Beta-Binomial: 二项分布的Beta先验,后验为Beta(α+ successes, β+ failures)
        Dirichlet-Multinomial: 多项分布的Dirichlet先验,后验计数累加
        
        返回后验参数与预测分布。
        """
        if dist_type == 'beta_binomial':
            # Beta(α, β) 先验
            alpha_prior = prior_params['alpha']
            beta_prior = prior_params['beta']
            
            # 观测数据:successes次成功,failures次失败
            successes = np.sum(data)
            n = len(data)
            failures = n - successes
            
            # 后验更新
            alpha_post = alpha_prior + successes
            beta_post = beta_prior + failures
            
            # 后验均值(收缩估计)
            posterior_mean = alpha_post / (alpha_post + beta_post)
            
            return {
                'posterior_alpha': alpha_post,
                'posterior_beta': beta_post,
                'posterior_mean': posterior_mean,
                'posterior_variance': (alpha_post * beta_post) / 
                                     ((alpha_post + beta_post)**2 * (alpha_post + beta_post + 1))
            }
        
        elif dist_type == 'dirichlet_multinomial':
            # Dirichlet(α) 先验
            alpha_prior = np.array(prior_params['alpha'])
            
            # 观测计数
            counts = np.bincount(data, minlength=len(alpha_prior))
            
            # 后验更新:Dirichlet(α + counts)
            alpha_post = alpha_prior + counts
            
            return {
                'posterior_alpha': alpha_post,
                'posterior_mean': alpha_post / np.sum(alpha_post),
                'posterior_mode': (alpha_post - 1) / (np.sum(alpha_post) - len(alpha_post))
            }


class InformationTheory:
    """
    信息论度量计算:熵、互信息、KL散度与JS散度
    
    处理数值稳定性:对概率为零的情况添加平滑(Laplace平滑或微小常数)。
    """
    
    @staticmethod
    def entropy(p: np.ndarray, base: float = np.e) -> float:
        """
        香农熵:H(X) = -Σ p(x) log p(x)
        
        数值稳定:clip概率避免log(0),使用log1p处理小概率。
        """
        p = np.array(p)
        # 归一化与平滑
        p = p / np.sum(p)
        p = np.clip(p, 1e-12, 1.0)
        
        log_p = np.log(p) / np.log(base)
        return -np.sum(p * log_p)
    
    @staticmethod
    def joint_entropy(p_xy: np.ndarray) -> float:
        """
        联合熵:H(X,Y) = -ΣΣ p(x,y) log p(x,y)
        """
        p_xy = p_xy / np.sum(p_xy)
        p_xy = np.clip(p_xy, 1e-12, 1.0)
        return -np.sum(p_xy * np.log(p_xy))
    
    @staticmethod
    def conditional_entropy(p_xy: np.ndarray) -> float:
        """
        条件熵:H(Y|X) = H(X,Y) - H(X)
        """
        # 边缘分布 p(x)
        p_x = np.sum(p_xy, axis=1)
        return InformationTheory.joint_entropy(p_xy) - InformationTheory.entropy(p_x)
    
    @staticmethod
    def mutual_information(p_xy: np.ndarray) -> float:
        """
        互信息:I(X;Y) = H(X) + H(Y) - H(X,Y)
        
        等价于KL散度:I(X;Y) = D_KL(p(x,y) || p(x)p(y))
        """
        p_x = np.sum(p_xy, axis=1, keepdims=True)
        p_y = np.sum(p_xy, axis=0, keepdims=True)
        p_xy_indep = p_x * p_y  # 独立假设下的联合分布
        
        # 避免除零
        p_xy_safe = np.clip(p_xy / np.sum(p_xy), 1e-12, 1.0)
        p_ind_safe = np.clip(p_xy_indep, 1e-12, 1.0)
        
        return np.sum(p_xy_safe * np.log(p_xy_safe / p_ind_safe))
    
    @staticmethod
    def kl_divergence(p: np.ndarray, q: np.ndarray, method: str = 'standard') -> float:
        """
        KL散度:D_KL(P||Q) = Σ p(x) log(p(x)/q(x))
        
        非对称性:D_KL(P||Q) ≠ D_KL(Q||P)
        
        数值稳定性处理:
        1. 零概率处理:当p=0时贡献为0;当p>0且q=0时返回inf
        2. log-sum-exp技巧用于softmax参数化
        """
        p = np.array(p) / np.sum(p)
        q = np.array(q) / np.sum(q)
        
        if method == 'zero_inclusive':
            # 对两个分布进行平滑
            p = (p + 1e-10) / (1 + len(p) * 1e-10)
            q = (q + 1e-10) / (1 + len(q) * 1e-10)
        
        # 仅对p>0的项计算
        mask = p > 1e-12
        ratio = np.log(p[mask]) - np.log(q[mask] + 1e-12)
        
        # 检查q=0的情况(无限散度)
        if np.any(q[mask] < 1e-12):
            return np.inf
        
        return np.sum(p[mask] * ratio)
    
    @staticmethod
    def js_divergence(p: np.ndarray, q: np.ndarray) -> float:
        """
        JS散度(Jensen-Shannon):对称化且平滑版本的KL散度
        
        JS(P||Q) = 0.5*D_KL(P||M) + 0.5*D_KL(Q||M),其中M=0.5*(P+Q)
        
        总是有界:[0, log(2)],适用于概率分布相似度度量。
        """
        p = np.array(p) / np.sum(p)
        q = np.array(q) / np.sum(q)
        m = 0.5 * (p + q)
        
        return 0.5 * InformationTheory.kl_divergence(p, m) + \
               0.5 * InformationTheory.kl_divergence(q, m)


# =============================================================================
# 1.3 凸优化与数值计算
# =============================================================================

class ConvexOptimization:
    """
    凸优化算法库:实现一阶、二阶及约束优化方法
    
    包含收敛性分析、步长选择与数值稳定性处理。
    """
    
    @staticmethod
    def check_convexity(func: Callable, x: np.ndarray, eps: float = 1e-5) -> Tuple[bool, np.ndarray]:
        """
        凸性判定:基于Hessian矩阵半正定性检验
        
        对于二次可微函数,f为凸函数当且仅当∇²f(x) ⪰ 0对所有x成立。
        采用特征值检验:所有特征值非负则为凸。
        """
        # 数值微分计算Hessian
        n = len(x)
        hessian = np.zeros((n, n))
        f_x = func(x)
        
        for i in range(n):
            x_plus = x.copy()
            x_plus[i] += eps
            grad_plus = ConvexOptimization._numerical_gradient(func, x_plus)
            
            x_minus = x.copy()
            x_minus[i] -= eps
            grad_minus = ConvexOptimization._numerical_gradient(func, x_minus)
            
            hessian[:, i] = (grad_plus - grad_minus) / (2 * eps)
        
        # 对称化减少数值误差
        hessian = (hessian + hessian.T) / 2
        
        # 特征值检验(容忍数值误差)
        eigenvalues = np.linalg.eigvalsh(hessian)
        is_convex = np.all(eigenvalues >= -1e-8)
        
        return is_convex, hessian
    
    @staticmethod
    def _numerical_gradient(func: Callable, x: np.ndarray, eps: float = 1e-5) -> np.ndarray:
        """中心差分计算梯度"""
        grad = np.zeros_like(x)
        for i in range(len(x)):
            x_plus = x.copy()
            x_plus[i] += eps
            x_minus = x.copy()
            x_minus[i] -= eps
            grad[i] = (func(x_plus) - func(x_minus)) / (2 * eps)
        return grad
    
    @staticmethod
    def gradient_descent(func: Callable, x0: np.ndarray, method: str = 'batch',
                        lr: float = 0.1, max_iter: int = 1000, tol: float = 1e-6,
                        X: Optional[np.ndarray] = None, y: Optional[np.ndarray] = None) -> Dict:
        """
        梯度下降变体:Batch/Mini-batch/Stochastic
        
        方差分析:
        - Batch:使用全数据集,梯度方差低但计算昂贵
        - Mini-batch:折中方案,方差与批量大小成反比 O(1/b)
        - SGD:单样本更新,高方差但逃离鞍点能力强
        
        收敛率:
        - 凸函数:O(1/√T) for SGD, O(1/T) for GD
        - 强凸函数:O(1/T) for SGD, O(γ^T) for GD
        """
        x = x0.copy()
        trajectory = [x.copy()]
        losses = []
        
        n_samples = len(X) if X is not None else 1000
        
        for t in range(max_iter):
            if method == 'batch':
                # 全批量梯度
                grad = ConvexOptimization._numerical_gradient(
                    lambda xi: func(xi, X, y) if X is not None else func(xi), x)
            
            elif method == 'sgd':
                # 随机单样本
                idx = np.random.randint(n_samples)
                xi = X[idx:idx+1] if X is not None else None
                yi = y[idx:idx+1] if y is not None else None
                grad = ConvexOptimization._numerical_gradient(
                    lambda xv: func(xv, xi, yi), x)
            
            elif method.startswith('mini_batch'):
                # 小批量
                batch_size = int(method.split('_')[-1]) if '_' in method else 32
                indices = np.random.choice(n_samples, min(batch_size, n_samples), replace=False)
                xi = X[indices] if X is not None else None
                yi = y[indices] if y is not None else None
                grad = ConvexOptimization._numerical_gradient(
                    lambda xv: func(xv, xi, yi), x)
            
            # 梯度更新
            x_new = x - lr * grad
            trajectory.append(x_new.copy())
            
            loss = func(x, X, y) if X is not None else func(x)
            losses.append(loss)
            
            if np.linalg.norm(x_new - x) < tol:
                break
            
            x = x_new
        
        return {
            'x_opt': x,
            'trajectory': np.array(trajectory),
            'losses': np.array(losses),
            'iterations': len(losses)
        }
    
    @staticmethod
    def momentum_optimizer(func: Callable, x0: np.ndarray, lr: float = 0.01,
                          momentum: float = 0.9, nesterov: bool = False,
                          max_iter: int = 1000) -> Dict:
        """
        动量法与Nesterov加速梯度(NAG)
        
        标准动量:v_t = γ v_{t-1} + η ∇f(x_{t-1})
                 x_t = x_{t-1} - v_t
        
        Nesterov:先沿动量方向 lookahead,再计算梯度
                 v_t = γ v_{t-1} + η ∇f(x_{t-1} - γ v_{t-1})
                 x_t = x_{t-1} - v_t
        
        收敛加速:对凸函数,Nesterov达到最优收敛率 O(1/T²),
        而标准GD为 O(1/T)。
        """
        x = x0.copy()
        v = np.zeros_like(x)
        trajectory = [x.copy()]
        
        for t in range(max_iter):
            if nesterov:
                # Nesterov: 在 lookahead 点计算梯度
                lookahead_x = x - momentum * v
                grad = ConvexOptimization._numerical_gradient(func, lookahead_x)
            else:
                grad = ConvexOptimization._numerical_gradient(func, x)
            
            # 速度更新
            v = momentum * v + lr * grad
            x = x - v
            
            trajectory.append(x.copy())
            
            if np.linalg.norm(grad) < 1e-6:
                break
        
        return {
            'x_opt': x,
            'trajectory': np.array(trajectory),
            'final_grad_norm': np.linalg.norm(grad)
        }
    
    @staticmethod
    def adam_optimizer(func: Callable, x0: np.ndarray, lr: float = 0.001,
                      beta1: float = 0.9, beta2: float = 0.999,
                      eps: float = 1e-8, max_iter: int = 1000) -> Dict:
        """
        Adam优化器:自适应矩估计
        
        算法步骤:
        m_t = β₁ m_{t-1} + (1-β₁) g_t       (一阶矩估计)
        v_t = β₂ v_{t-1} + (1-β₂) g_t²      (二阶矩估计)
        m̂_t = m_t / (1-β₁^t)                (偏差修正)
        v̂_t = v_t / (1-β₂^t)
        x_t = x_{t-1} - η m̂_t / (√v̂_t + ε)
        
        偏差修正重要性:初始时刻m,v偏向0,需除以(1-β^t)校正。
        """
        x = x0.copy()
        m = np.zeros_like(x)
        v = np.zeros_like(x)
        trajectory = [x.copy()]
        
        for t in range(1, max_iter + 1):
            grad = ConvexOptimization._numerical_gradient(func, x)
            
            # 矩估计更新
            m = beta1 * m + (1 - beta1) * grad
            v = beta2 * v + (1 - beta2) * (grad ** 2)
            
            # 偏差修正(关键步骤)
            m_hat = m / (1 - beta1 ** t)
            v_hat = v / (1 - beta2 ** t)
            
            # 参数更新(学习率自适应调整)
            x = x - lr * m_hat / (np.sqrt(v_hat) + eps)
            trajectory.append(x.copy())
            
            if np.linalg.norm(grad) < 1e-6:
                break
        
        return {
            'x_opt': x,
            'trajectory': np.array(trajectory),
            'iterations': t
        }
    
    @staticmethod
    def newton_method(func: Callable, x0: np.ndarray, max_iter: int = 100,
                     tol: float = 1e-6) -> Dict:
        """
        等式约束Newton法(无约束优化版本)
        
        更新规则:x_{t+1} = x_t - [∇²f(x)]^{-1} ∇f(x)
        
        局部收敛速度:二次收敛(误差平方递减)。
        计算复杂度:O(n³) per step due to Hessian inversion。
        
        采用Cholesky分解求解线性系统提升数值稳定性。
        """
        x = x0.copy()
        trajectory = [x.copy()]
        
        for t in range(max_iter):
            grad = ConvexOptimization._numerical_gradient(func, x)
            
            # 数值Hessian(实际应用应提供解析Hessian)
            _, hessian = ConvexOptimization.check_convexity(func, x)
            
            try:
                # Cholesky求解 H d = -g
                L = np.linalg.cholesky(hessian)
                y = np.linalg.solve_triangular(L, -grad, lower=True)
                delta = np.linalg.solve_triangular(L.T, y, lower=False)
            except np.linalg.LinAlgError:
                # Hessian非正定,使用Levenberg-Marquardt修正
                print("Hessian非正定,添加正则化")
                hessian += np.eye(len(x)) * 0.1
                delta = np.linalg.solve(hessian, -grad)
            
            x = x + delta
            trajectory.append(x.copy())
            
            if np.linalg.norm(grad) < tol:
                break
        
        return {
            'x_opt': x,
            'trajectory': np.array(trajectory),
            'iterations': t
        }
    
    @staticmethod
    def barrier_method(func: Callable, x0: np.ndarray, 
                      inequality_constraints: List[Callable],
                      t: float = 1.0, mu: float = 10.0, max_iter: int = 50) -> Dict:
        """
        障碍法(Barrier Method)处理不等式约束优化
        
        min f(x) s.t. c_i(x) ≤ 0
        
        对数障碍函数:φ(x) = -Σ log(-c_i(x))
        中心路径:x*(t) = argmin t f(x) + φ(x)
        
        算法:逐步增大t,使解逼近原问题最优解。
        收敛速度:O(√m)次外迭代,m为约束数量。
        """
        x = x0.copy()
        m = len(inequality_constraints)
        
        for outer_iter in range(max_iter):
            # 定义障碍函数
            def barrier_func(x):
                f_val = func(x)
                barrier = 0
                for c in inequality_constraints:
                    c_val = c(x)
                    if c_val >= 0:
                        return np.inf
                    barrier -= np.log(-c_val)
                return t * f_val + barrier
            
            # 内层优化(使用Newton法)
            result = ConvexOptimization.newton_method(barrier_func, x, max_iter=100)
            x = result['x_opt']
            
            # 检查收敛
            if m / t < 1e-6:
                break
            
            t *= mu  # 增加惩罚系数
        
        return {
            'x_opt': x,
            'outer_iterations': outer_iter,
            'final_t': t
        }
    
    @staticmethod
    def proximal_gradient(func: Callable, x0: np.ndarray, 
                         regularization: str = 'l1', lambda_reg: float = 0.1,
                         lr: float = 0.1, max_iter: int = 1000) -> Dict:
        """
        近端梯度下降(Proximal Gradient Descent)处理非光滑正则化
        
        适用于 min f(x) + λ r(x),其中f光滑,r非光滑(如L1范数)。
        
        软阈值算子(Soft-thresholding)是L1正则的近端映射:
        prox_{λ||·||_1}(x) = sign(x) max(|x| - λ, 0)
        
        迭代步骤:
        1. 梯度步:y = x - η ∇f(x)
        2. 近端步:x = prox_{ηλ r}(y)
        """
        x = x0.copy()
        
        def soft_threshold(x_vec, threshold):
            """L1近端算子"""
            return np.sign(x_vec) * np.maximum(np.abs(x_vec) - threshold, 0)
        
        for t in range(max_iter):
            # 梯度步
            grad = ConvexOptimization._numerical_gradient(func, x)
            y = x - lr * grad
            
            # 近端步
            if regularization == 'l1':
                x_new = soft_threshold(y, lr * lambda_reg)
            elif regularization == 'l2':
                x_new = y / (1 + 2 * lr * lambda_reg)  # 缩放算子
            else:
                x_new = y
            
            if np.linalg.norm(x_new - x) < 1e-6:
                break
            
            x = x_new
        
        return {
            'x_opt': x,
            'sparsity': np.sum(np.abs(x) < 1e-6) / len(x)  # 稀疏度统计
        }


# =============================================================================
# 可视化与验证部分
# =============================================================================

def visualize_matrix_decomposition():
    """矩阵分解可视化与精度验证"""
    fig, axes = plt.subplots(2, 3, figsize=(15, 10))
    
    # 生成测试矩阵
    np.random.seed(42)
    A = np.random.randn(5, 5)
    A = A.T @ A  # 对称正定
    
    # EVD验证
    eigvals, eigvecs = MatrixDecomposition.qr_algorithm_evd(A)
    axes[0, 0].bar(range(len(eigvals)), sorted(eigvals, reverse=True))
    axes[0, 0].set_title('特征值分布(QR算法)')
    axes[0, 0].set_xlabel('索引')
    axes[0, 0].set_ylabel('特征值')
    
    # 重构误差
    reconstruction = eigvecs @ np.diag(eigvals) @ eigvecs.T
    evd_error = np.linalg.norm(A - reconstruction)
    axes[0, 1].semilogy([evd_error], 'o', markersize=10)
    axes[0, 1].set_title(f'EVD重构误差: {evd_error:.2e}')
    axes[0, 1].set_ylabel('Frobenius范数误差')
    axes[0, 1].grid(True)
    
    # SVD比较
    U, S, V = MatrixDecomposition.svd_compact(A)
    axes[0, 2].plot(S, 'o-', label='手动实现')
    U_np, S_np, Vh_np = np.linalg.svd(A)
    axes[0, 2].plot(S_np, 's--', label='NumPy', alpha=0.7)
    axes[0, 2].set_title('奇异值对比')
    axes[0, 2].legend()
    axes[0, 2].set_yscale('log')
    
    # Cholesky验证
    L = MatrixDecomposition.cholesky_decomposition(A, method='outer_product')
    cholesky_error = np.linalg.norm(A - L @ L.T)
    axes[1, 0].imshow(L, cmap='viridis')
    axes[1, 0].set_title(f'Cholesky因子 L\n误差: {cholesky_error:.2e}')
    plt.colorbar(axes[1, 0].images[0], ax=axes[1, 0])
    
    # 正定性可视化(椭圆等值线)
    mu = np.array([0, 0])
    Sigma = np.array([[2, 1], [1, 2]])
    x, y = np.mgrid[-3:3:.01, -3:3:.01]
    pos = np.dstack((x, y))
    
    # 计算马氏距离
    Sigma_inv = np.linalg.inv(Sigma)
    diff = pos - mu
    mahal = np.einsum('...i,ij,...j->...', diff, Sigma_inv, diff)
    
    axes[1, 1].contour(x, y, mahal, levels=[1, 2, 3], colors='blue', alpha=0.5)
    axes[1, 1].set_title('马氏距离等值线(椭圆)')
    axes[1, 1].set_aspect('equal')
    
    # 特征向量方向
    eigvals_2d, eigvecs_2d = np.linalg.eigh(Sigma)
    for i in range(2):
        vec = eigvecs_2d[:, i] * np.sqrt(eigvals_2d[i])
        axes[1, 1].arrow(0, 0, vec[0], vec[1], 
                        head_width=0.2, color='red', 
                        label=f'λ={eigvals_2d[i]:.1f}' if i == 0 else "")
    axes[1, 1].legend()
    
    # 幂迭代收敛性
    A_test = np.diag([10, 5, 2, 1, 0.5])
    v = np.random.randn(5)
    v = v / np.linalg.norm(v)
    errors = []
    for _ in range(20):
        v_new = A_test @ v
        v_new = v_new / np.linalg.norm(v_new)
        errors.append(np.linalg.norm(v_new - v))
        v = v_new
    
    axes[1, 2].semilogy(errors, 'o-')
    axes[1, 2].set_title('幂迭代收敛速度')
    axes[1, 2].set_xlabel('迭代次数')
    axes[1, 2].set_ylabel('误差(对数尺度)')
    axes[1, 2].grid(True)
    
    plt.tight_layout()
    plt.savefig('matrix_decomposition.png', dpi=150, bbox_inches='tight')
    plt.show()
    
    print("矩阵分解验证完成。重构误差量级验证数值稳定性。")


def visualize_autodiff():
    """自动微分与梯度检查可视化"""
    fig, axes = plt.subplots(1, 3, figsize=(15, 5))
    
    # 测试函数:Rosenbrock函数(优化测试标准函数)
    def rosenbrock(x, y):
        return (1 - x)**2 + 100 * (y - x**2)**2
    
    # 计算梯度场
    x = np.linspace(-2, 2, 50)
    y = np.linspace(-1, 3, 50)
    X, Y = np.meshgrid(x, y)
    Z = rosenbrock(X, Y)
    
    # 等高线
    axes[0].contour(X, Y, Z, levels=np.logspace(0, 3, 10), cmap='viridis')
    axes[0].set_title('Rosenbrock函数等高线')
    axes[0].set_xlabel('x')
    axes[0].set_ylabel('y')
    
    # 自动微分轨迹
    x_init = np.array([-1.5, 2.0])
    
    # 使用TensorEngine优化
    lr = 0.001
    x_curr = TensorEngine(x_init, requires_grad=True)
    trajectory = [x_curr.data.copy()]
    
    for _ in range(1000):
        # 前向传播
        f = (1 - x_curr.data[0])**2 + 100 * (x_curr.data[1] - x_curr.data[0]**2)**2
        # 手动反向传播(简化版)
        grad = np.array([
            -2*(1 - x_curr.data[0]) - 400*x_curr.data[0]*(x_curr.data[1] - x_curr.data[0]**2),
            200*(x_curr.data[1] - x_curr.data[0]**2)
        ])
        x_curr.data = x_curr.data - lr * grad
        trajectory.append(x_curr.data.copy())
        
        if np.linalg.norm(grad) < 1e-6:
            break
    
    traj = np.array(trajectory)
    axes[0].plot(traj[:, 0], traj[:, 1], 'r.-', alpha=0.5, label='梯度下降轨迹')
    axes[0].plot(1, 1, 'r*', markersize=15, label='全局最小值')
    axes[0].legend()
    
    # 梯度检查验证
    test_x = np.array([2.0])
    test_y = np.array([3.0])
    
    def test_func(x, y):
        return x**3 + y**2 + x*y
    
    # 数值梯度 vs 解析梯度
    eps_vals = np.logspace(-1, -10, 20)
    errors = []
    
    for eps in eps_vals:
        # 数值梯度
        f_plus = test_func(test_x + eps, test_y)
        f_minus = test_func(test_x - eps, test_y)
        num_grad = (f_plus - f_minus) / (2 * eps)
        
        # 解析梯度:3x^2 + y
        ana_grad = 3*test_x**2 + test_y
        
        errors.append(np.abs(num_grad - ana_grad))
    
    axes[1].loglog(eps_vals, errors, 'o-')
    axes[1].set_xlabel('扰动大小 ε')
    axes[1].set_ylabel('梯度估计绝对误差')
    axes[1].set_title('有限差分精度与截断误差权衡')
    axes[1].grid(True)
    axes[1].axvline(x=np.sqrt(np.finfo(float).eps), color='r', linestyle='--', 
                   label='机器精度平方根')
    axes[1].legend()
    
    # 计算图可视化(简化)
    axes[2].text(0.5, 0.8, '输入 x, y', ha='center', fontsize=12, 
                bbox=dict(boxstyle='round', facecolor='lightblue'))
    axes[2].arrow(0.5, 0.75, 0, -0.1, head_width=0.05, head_length=0.02, fc='black')
    axes[2].text(0.5, 0.6, '乘法/幂运算\n(前向传播)', ha='center', fontsize=10,
                bbox=dict(boxstyle='round', facecolor='lightgreen'))
    axes[2].arrow(0.5, 0.55, 0, -0.1, head_width=0.05, head_length=0.02, fc='black')
    axes[2].text(0.5, 0.4, '输出 f', ha='center', fontsize=12,
                bbox=dict(boxstyle='round', facecolor='lightyellow'))
    axes[2].arrow(0.5, 0.35, 0, -0.1, head_width=0.05, head_length=0.02, fc='red')
    axes[2].text(0.5, 0.2, '梯度 ∂f/∂x\n(反向传播)', ha='center', fontsize=10,
                bbox=dict(boxstyle='round', facecolor='lightcoral'))
    axes[2].set_xlim(0, 1)
    axes[2].set_ylim(0, 1)
    axes[2].axis('off')
    axes[2].set_title('计算图结构示意图')
    
    plt.tight_layout()
    plt.savefig('autodiff_visualization.png', dpi=150)
    plt.show()


def visualize_probability_distributions():
    """概率分布与信息论度量可视化"""
    fig, axes = plt.subplots(2, 3, figsize=(15, 10))
    
    # Beta-Binomial共轭先验演示
    alpha_prior, beta_prior = 2, 2
    trials = np.arange(0, 20)
    
    # 模拟观测数据(真实参数p=0.7)
    true_p = 0.7
    np.random.seed(42)
    observations = (np.random.rand(20) < true_p).astype(int)
    
    posterior_means = []
    credible_intervals = []
    
    for n in range(1, len(observations)+1):
        data = observations[:n]
        result = ExponentialFamily.conjugate_prior_analysis(
            'beta_binomial', data, {'alpha': alpha_prior, 'beta': beta_prior}
        )
        posterior_means.append(result['posterior_mean'])
        
        # 95% 可信区间(Beta分布分位数)
        from scipy.stats import beta
        ci_low = beta.ppf(0.025, result['posterior_alpha'], result['posterior_beta'])
        ci_high = beta.ppf(0.975, result['posterior_alpha'], result['posterior_beta'])
        credible_intervals.append((ci_low, ci_high))
    
    credible_intervals = np.array(credible_intervals)
    
    axes[0, 0].plot(trials[1:], posterior_means, 'b-', label='后验均值')
    axes[0, 0].axhline(y=true_p, color='r', linestyle='--', label=f'真实值 {true_p}')
    axes[0, 0].fill_between(trials[1:], credible_intervals[:, 0], credible_intervals[:, 1], 
                           alpha=0.3, label='95% 可信区间')
    axes[0, 0].set_xlabel('观测样本数')
    axes[0, 0].set_ylabel('成功概率估计')
    axes[0, 0].set_title('Beta-Binomial共轭推断')
    axes[0, 0].legend()
    axes[0, 0].grid(True)
    
    # 多元高斯等高线
    mu = np.array([0, 0])
    Sigma = np.array([[1, 0.8], [0.8, 1]])
    
    x = np.linspace(-3, 3, 100)
    y = np.linspace(-3, 3, 100)
    X, Y = np.meshgrid(x, y)
    pos = np.dstack((X, Y))
    
    Z = ExponentialFamily.multivariate_gaussian(pos, mu, Sigma)
    
    axes[0, 1].contourf(X, Y, Z, levels=20, cmap='viridis')
    axes[0, 1].set_title('多元高斯分布密度(ρ=0.8)')
    axes[0, 1].set_aspect('equal')
    
    # 绘制主成分方向
    eigvals, eigvecs = np.linalg.eigh(Sigma)
    for i in range(2):
        axes[0, 1].arrow(mu[0], mu[1], 
                        np.sqrt(eigvals[i])*eigvecs[0, i], 
                        np.sqrt(eigvals[i])*eigvecs[1, i],
                        head_width=0.2, color='red')
    
    # 熵与KL散度可视化
    # 两个高斯分布的KL散度
    mu1, sigma1 = 0, 1
    mu2, sigma2 = 1, 2
    
    x_range = np.linspace(-5, 7, 1000)
    p = (1/np.sqrt(2*np.pi*sigma1**2)) * np.exp(-0.5*((x_range-mu1)/sigma1)**2)
    q = (1/np.sqrt(2*np.pi*sigma2**2)) * np.exp(-0.5*((x_range-mu2)/sigma2)**2)
    
    axes[0, 2].fill_between(x_range, p, alpha=0.5, label=f'P~N({mu1},{sigma1}²)')
    axes[0, 2].fill_between(x_range, q, alpha=0.5, label=f'Q~N({mu2},{sigma2}²)')
    axes[0, 2].set_title('KL散度计算示例')
    axes[0, 2].legend()
    
    kl_pq = InformationTheory.kl_divergence(p, q)
    kl_qp = InformationTheory.kl_divergence(q, p)
    js = InformationTheory.js_divergence(p, q)
    
    axes[0, 2].text(0.02, 0.95, f'D_KL(P||Q)={kl_pq:.3f}\nD_KL(Q||P)={kl_qp:.3f}\nJS={js:.3f}',
                   transform=axes[0, 2].transAxes, verticalalignment='top',
                   bbox=dict(boxstyle='round', facecolor='white', alpha=0.8))
    
    # 指数族自然参数空间
    etas = np.linspace(-3, 3, 100)
    # 伯努利对数配分函数 A(η) = log(1 + exp(η))
    A_eta = np.log(1 + np.exp(etas))
    # 均值参数 μ = exp(η)/(1+exp(η))
    mu_params = np.exp(etas) / (1 + np.exp(etas))
    
    ax_twin = axes[1, 0].twinx()
    line1 = axes[1, 0].plot(etas, A_eta, 'b-', label='A(η) - 对数配分函数')
    line2 = ax_twin.plot(etas, mu_params, 'r--', label='μ(η) - 均值参数')
    axes[1, 0].set_xlabel('自然参数 η')
    axes[1, 0].set_ylabel('A(η)', color='b')
    ax_twin.set_ylabel('μ', color='r')
    axes[1, 0].set_title('指数族:自然参数与均值参数关系')
    lines = line1 + line2
    labs = [l.get_label() for l in lines]
    axes[1, 0].legend(lines, labs, loc='center right')
    
    # 互信息热力图(离散分布)
    # 构造相关变量
    p_xy = np.array([[0.3, 0.1], [0.1, 0.5]])
    mi = InformationTheory.mutual_information(p_xy)
    
    im = axes[1, 1].imshow(p_xy, cmap='Blues', aspect='auto')
    axes[1, 1].set_xticks([0, 1])
    axes[1, 1].set_yticks([0, 1])
    axes[1, 1].set_xlabel('Y')
    axes[1, 1].set_ylabel('X')
    axes[1, 1].set_title(f'联合分布热力图\n互信息 I(X;Y)={mi:.3f} bits')
    
    # 添加数值标注
    for i in range(2):
        for j in range(2):
            text = axes[1, 1].text(j, i, f'{p_xy[i, j]:.2f}',
                                  ha="center", va="center", color="black", fontsize=12)
    
    plt.colorbar(im, ax=axes[1, 1])
    
    # 泊松分布序列
    lambda_val = 3
    k_vals = np.arange(0, 15)
    poisson_pmf = np.exp(-lambda_val) * (lambda_val**k_vals) / np.array([np.math.factorial(k) for k in k_vals])
    
    axes[1, 2].bar(k_vals, poisson_pmf, alpha=0.7, color='green')
    axes[1, 2].set_xlabel('k(事件发生次数)')
    axes[1, 2].set_ylabel('P(X=k)')
    axes[1, 2].set_title(f'泊松分布 Poisson(λ={lambda_val})')
    axes[1, 2].grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('probability_distributions.png', dpi=150)
    plt.show()


def visualize_optimization():
    """优化算法可视化与收敛性对比"""
    fig = plt.figure(figsize=(16, 12))
    
    # 测试函数:二次型(凸)与Rosenbrock(非凸)
    def quadratic(x, A=None, b=None):
        if A is None:
            A = np.array([[3, 0.5], [0.5, 1]])
            b = np.array([1, 2])
        return 0.5 * x.T @ A @ x - b.T @ x
    
    # 精确解
    A_quad = np.array([[3, 0.5], [0.5, 1]])
    b_quad = np.array([1, 2])
    x_opt_exact = np.linalg.solve(A_quad, b_quad)
    
    x0 = np.array([-2.0, 3.0])
    
    # 1. 梯度下降变体比较
    ax1 = fig.add_subplot(2, 3, 1)
    
    methods = [('batch', '全批量'), ('mini_batch_10', '小批量(10)'), ('sgd', '随机')]
    colors = ['blue', 'green', 'red']
    
    for (method, label), color in zip(methods, colors):
        result = ConvexOptimization.gradient_descent(
            lambda x, X=None, y=None: quadratic(x), 
            x0, method=method, lr=0.1, max_iter=50
        )
        losses = result['losses']
        ax1.semilogy(losses, 'o-', color=color, label=label, markersize=4)
    
    ax1.set_xlabel('迭代次数')
    ax1.set_ylabel('损失值(对数尺度)')
    ax1.set_title('梯度下降:方差与收敛速度')
    ax1.legend()
    ax1.grid(True)
    
    # 2. 动量法轨迹对比
    ax2 = fig.add_subplot(2, 3, 2)
    
    # 绘制等高线
    x1 = np.linspace(-3, 3, 100)
    x2 = np.linspace(-2, 4, 100)
    X1, X2 = np.meshgrid(x1, x2)
    Z = np.zeros_like(X1)
    for i in range(len(x1)):
        for j in range(len(x2)):
            Z[j, i] = quadratic(np.array([X1[j, i], X2[j, i]]))
    
    ax2.contour(X1, X2, Z, levels=20, alpha=0.5, cmap='viridis')
    
    # 标准动量
    result_mom = ConvexOptimization.momentum_optimizer(
        lambda x: quadratic(x), x0, lr=0.1, momentum=0.9, nesterov=False
    )
    traj_mom = result_mom['trajectory']
    ax2.plot(traj_mom[:, 0], traj_mom[:, 1], 'b.-', label='Momentum', alpha=0.7)
    
    # Nesterov
    result_nest = ConvexOptimization.momentum_optimizer(
        lambda x: quadratic(x), x0, lr=0.1, momentum=0.9, nesterov=True
    )
    traj_nest = result_nest['trajectory']
    ax2.plot(traj_nest[:, 0], traj_nest[:, 1], 'r.-', label='Nesterov AG', alpha=0.7)
    
    ax2.plot(x_opt_exact[0], x_opt_exact[1], 'r*', markersize=15, label='最优解')
    ax2.set_title('动量法轨迹对比')
    ax2.legend()
    ax2.set_aspect('equal')
    
    # 3. 自适应学习率方法对比
    ax3 = fig.add_subplot(2, 3, 3)
    
    # AdaGrad
    def adagrad_opt(func, x0, lr=0.1, max_iter=100):
        x = x0.copy()
        grad_sq_sum = np.zeros_like(x)
        eps = 1e-8
        losses = []
        
        for _ in range(max_iter):
            grad = ConvexOptimization._numerical_gradient(func, x)
            grad_sq_sum += grad ** 2
            adapted_lr = lr / (np.sqrt(grad_sq_sum) + eps)
            x = x - adapted_lr * grad
            losses.append(func(x))
        
        return losses
    
    losses_adagrad = adagrad_opt(lambda x: quadratic(x), x0)
    
    # RMSprop
    def rmsprop_opt(func, x0, lr=0.1, beta=0.9, max_iter=100):
        x = x0.copy()
        grad_sq_avg = np.zeros_like(x)
        eps = 1e-8
        losses = []
        
        for _ in range(max_iter):
            grad = ConvexOptimization._numerical_gradient(func, x)
            grad_sq_avg = beta * grad_sq_avg + (1 - beta) * (grad ** 2)
            adapted_lr = lr / (np.sqrt(grad_sq_avg) + eps)
            x = x - adapted_lr * grad
            losses.append(func(x))
        
        return losses
    
    losses_rmsprop = rmsprop_opt(lambda x: quadratic(x), x0)
    
    # Adam
    result_adam = ConvexOptimization.adam_optimizer(
        lambda x: quadratic(x), x0, lr=0.1, max_iter=100
    )
    
    ax3.semilogy(losses_adagrad, label='AdaGrad', alpha=0.8)
    ax3.semilogy(losses_rmsprop, label='RMSprop', alpha=0.8)
    ax3.semilogy(result_adam['losses'], label='Adam', alpha=0.8)
    ax3.set_xlabel('迭代次数')
    ax3.set_ylabel('损失值')
    ax3.set_title('自适应学习率方法收敛性')
    ax3.legend()
    ax3.grid(True)
    
    # 4. 条件数对收敛影响
    ax4 = fig.add_subplot(2, 3, 4)
    
    condition_numbers = [1, 5, 20, 100]
    for cond in condition_numbers:
        # 构造指定条件数的矩阵
        diag = np.diag([1, cond])
        Q, _ = np.linalg.qr(np.random.randn(2, 2))
        A_cond = Q.T @ diag @ Q
        
        result_cond = ConvexOptimization.gradient_descent(
            lambda x: 0.5 * x.T @ A_cond @ x, 
            x0, method='batch', lr=0.01, max_iter=100
        )
        ax4.semilogy(result_cond['losses'], label=f'κ={cond}')
    
    ax4.set_xlabel('迭代次数')
    ax4.set_ylabel('损失值(对数尺度)')
    ax4.set_title('条件数与收敛速度关系')
    ax4.legend()
    ax4.grid(True)
    
    # 5. 近端梯度法(L1正则化)稀疏性
    ax5 = fig.add_subplot(2, 3, 5)
    
    # 高维LASSO问题
    np.random.seed(42)
    n, d = 50, 100
    X_design = np.random.randn(n, d)
    true_w = np.zeros(d)
    true_w[:5] = np.random.randn(5)  # 稀疏真实解
    y_design = X_design @ true_w + 0.1 * np.random.randn(n)
    
    def lasso_obj(w, lam=0.1):
        residual = X_design @ w - y_design
        return 0.5 * np.sum(residual**2) + lam * np.sum(np.abs(w))
    
    w0 = np.random.randn(d) * 0.1
    result_prox = ConvexOptimization.proximal_gradient(
        lambda w: 0.5 * np.sum((X_design @ w - y_design)**2),
        w0, regularization='l1', lambda_reg=0.1, lr=0.01, max_iter=500
    )
    
    w_opt = result_prox['x_opt']
    ax5.stem(range(d), true_w, linefmt='b-', markerfmt='bo', basefmt=' ', label='真实值')
    ax5.stem(range(d), w_opt, linefmt='r-', markerfmt='rx', basefmt=' ', label='估计值')
    ax5.set_xlabel('特征索引')
    ax5.set_ylabel('权重值')
    ax5.set_title(f'LASSO稀疏解恢复\n稀疏度: {result_prox["sparsity"]:.2%}')
    ax5.legend()
    
    # 6. 约束优化(障碍法路径)
    ax6 = fig.add_subplot(2, 3, 6)
    
    # 简单约束优化:min x^2 s.t. x >= 1
    def constrained_obj(x):
        return x[0]**2 + x[1]**2
    
    def constraint(x):
        return 1 - x[0]  # x >= 1 即 1-x <= 0
    
    # 障碍法路径追踪
    t_values = [1, 5, 20, 100, 500]
    path = []
    
    for t in t_values:
        def barrier(x):
            if constraint(x) >= 0:
                return 1e10
            return t * constrained_obj(x) - np.log(-constraint(x))
        
        result_barrier = ConvexOptimization.newton_method(barrier, np.array([2.0, 1.0]))
        path.append(result_barrier['x_opt'])
    
    path = np.array(path)
    
    # 绘制可行域
    x_range = np.linspace(0, 3, 100)
    y_range = np.linspace(-2, 2, 100)
    X_grid, Y_grid = np.meshgrid(x_range, y_range)
    Z_grid = X_grid**2 + Y_grid**2
    
    ax6.contour(X_grid, Y_grid, Z_grid, levels=10, alpha=0.5)
    ax6.axvline(x=1, color='red', linestyle='--', label='约束边界 x=1')
    ax6.plot(path[:, 0], path[:, 1], 'go-', markersize=8, label='中心路径')
    ax6.plot(1, 0, 'r*', markersize=15, label='最优解')
    ax6.set_xlim(0, 3)
    ax6.set_ylim(-2, 2)
    ax6.set_title('障碍法中心路径追踪')
    ax6.legend()
    ax6.set_aspect('equal')
    
    plt.tight_layout()
    plt.savefig('optimization_methods.png', dpi=150)
    plt.show()
    
    print("优化算法可视化完成。包含收敛速度、轨迹及稀疏性分析。")


def run_comprehensive_tests():
    """
    执行全章节的数值实验与正确性验证
    """
    print("=" * 60)
    print("开始执行数学基础算法验证测试套件")
    print("=" * 60)
    
    # 1. 矩阵分解精度测试
    print("\n[1.1] 矩阵分解数值稳定性测试")
    test_mat = np.array([[4, 2], [2, 3]], dtype=float)
    
    # EVD
    eigvals, eigvecs = MatrixDecomposition.power_iteration_evd(test_mat)
    recon = eigvecs @ np.diag(eigvals) @ eigvecs.T
    print(f"  幂迭代EVD重构误差: {np.linalg.norm(test_mat - recon):.2e}")
    
    # Cholesky
    L = MatrixDecomposition.cholesky_decomposition(test_mat)
    print(f"  Cholesky分解 ||A-LL^T||: {np.linalg.norm(test_mat - L@L.T):.2e}")
    
    # SVD
    U, S, V = MatrixDecomposition.svd_compact(test_mat)
    recon_svd = U @ np.diag(S) @ V.T
    print(f"  Compact SVD重构误差: {np.linalg.norm(test_mat - recon_svd):.2e}")
    
    # 2. 自动微分验证
    print("\n[1.1.2] 自动微分梯度检查")
    x_test = np.array([2.0])
    y_test = np.array([3.0])
    
    def simple_func(x, y):
        return x**2 * y + y**3
    
    result = TensorEngine.gradient_check(simple_func, [x_test, y_test])
    
    # 3. 概率推断验证
    print("\n[1.2] 概率推断正确性验证")
    # 高斯PDF积分验证
    x_samples = np.random.randn(10000, 2)
    mu_test = np.array([0, 0])
    Sigma_test = np.eye(2)
    pdf_vals = ExponentialFamily.multivariate_gaussian(x_samples, mu_test, Sigma_test)
    # Monte Carlo估计积分(应接近1)
    volume = 4  # 采样范围 [-2,2]^2
    mc_integral = np.mean(pdf_vals) * volume
    print(f"  多元高斯PDF蒙特卡洛积分估计: {mc_integral:.4f}(理论值1.0)")
    
    # 4. 优化算法收敛性验证
    print("\n[1.3] 优化算法收敛性验证")
    # 严格凸二次函数
    A_opt = np.array([[2, 0], [0, 4]])
    b_opt = np.array([2, 8])
    x_true = np.linalg.solve(A_opt, b_opt)
    
    def quad_func(x):
        return 0.5 * x.T @ A_opt @ x - b_opt.T @ x
    
    result_gd = ConvexOptimization.gradient_descent(quad_func, np.zeros(2), method='batch', lr=0.1)
    error_final = np.linalg.norm(result_gd['x_opt'] - x_true)
    print(f"  梯度下降最终解误差: {error_final:.2e}")
    
    result_newton = ConvexOptimization.newton_method(quad_func, np.zeros(2))
    error_newton = np.linalg.norm(result_newton['x_opt'] - x_true)
    print(f"  Newton法最终解误差: {error_newton:.2e}(二次收敛)")
    
    print("\n" + "=" * 60)
    print("所有测试完成。生成可视化图表...")
    print("=" * 60)


if __name__ == "__main__":
    # 执行数值验证
    run_comprehensive_tests()
    
    # 生成可视化
    print("\n生成矩阵分解可视化...")
    visualize_matrix_decomposition()
    
    print("生成自动微分可视化...")
    visualize_autodiff()
    
    print("生成概率分布可视化...")
    visualize_probability_distributions()
    
    print("生成优化算法可视化...")
    visualize_optimization()
    
    print("\n全部章节实现与可视化完成。")

本实现涵盖了您指定的全部数学基础内容,并严格遵循学术论文的叙述规范。每个算法模块均包含:

数学基础部分采用综述式描述,系统阐述特征值分解的数值稳定性问题,特别是幂迭代中的正交化修正与QR算法中的位移策略。对于SVD,详细区分了Full、Compact与Truncated三种形式的计算复杂度与内存布局差异。张量运算部分构建了完整的自动微分引擎,实现了基于计算图的反向传播,并通过梯度检查确保数值正确性。

概率统计模块实现了指数族分布的统一框架,涵盖自然参数与充分统计量的对偶关系。共轭先验部分实现了Beta-Binomial与Dirichlet-Multinomial的解析后验更新,展示了贝叶斯推断中的参数收缩效应。信息论部分严格处理了KL散度的非对称性与数值稳定性,实现了平滑处理与零概率保护。

优化算法库从凸性判定出发,实现了完整的一阶方法体系(Batch/Mini-batch/SGD的方差分析、动量法的等价形式证明、Adam的偏差修正)。二阶方法采用Cholesky分解求解Newton系统,处理非正定Hessian的正则化策略。约束优化实现了障碍法的中心路径追踪与近端梯度法的软阈值算子。

代码设计注重工程实践,包含内存布局优化(Strided索引)、数值稳定性处理(截断误差控制、特征值裁剪)与计算效率优化(向量化操作、缓存友好算法)。可视化部分不仅展示算法行为,更通过收敛曲线、误差分析与轨迹追踪验证理论性质。

【AI】用iOS的ML(机器学习)创建自己的AI App 在机器学习中,一切都始于模型,这是进行预测或识别的系统。教计算机学习涉及使用训练数据的机器学习算法进行学习。从训练中生成的输出通常称为机器学习模型。有不同类型的机器学习模型来解决同一个问题(例如对象识别),但使用不同的算法。是其中一些机器学习算法。 阅读详情

相关推荐

入行机器学习,需要具备什么样的数学水平?

在过去的几个月里,我一直和一些人交流,他们已经开始切入数据科学领域并积极使用机器学习(ML)技术来探索统计规律、或构建完善的数据驱动产品。然而,我发现很多情况下统计分析结果不尽人意的原因是是缺乏必要的数学直觉和知识框架。   最近兴起了许多易于使用的机器学习和深度学习的安装包,如scikit-learn,weka,tensorflow,r-caret等。机器学习理论是横跨统计、概率、计算机科学和算...

1199

Interview之AI:人工智能领域岗位求职面试—人工智能算法工程师知识框架及课程大纲(AI基础之数学基础/数据结构与算法/编程学习基础、ML算法简介、DL算法简介)来理解技术交互流程

​ Interview之AI:人工智能领域岗位求职面试—人工智能算法工程师知识框架及课程大纲(AI基础之数学基础/数据结构与算法/编程学习基础、ML算法简介、DL算法简介)来理解技术交互流程 目录 剖析自己 一、AI基础 二、ML算法简介 三、DL算法简介 剖析自己 1、个人能力角度 确定自己应具备的能力:以结果为导向的思维,看职位要求让做什么,自己会会什么,还差哪些? 职位条件 目前能力 还差的能力 ML算法工程师 熟悉python/R、S

头部AI社区如有邀博主AI主题演讲请私信—心比天高,仗剑走天涯,保持热爱,奔赴向梦想!低调,专注,谦虚,自律,反思,成长,还算比较正能量的博主,公益免费传播…内心特别想在AI界做出一些可以推进历史进程影响力的技术(兴趣使然,有点小情怀,也有点使命感呀 1万+

机器学习里面数学知识,到底对数学水平要求多高?

过去几个月里,有不少人联系我,向我表达他们对数据科学、对利用机器学习技术探索统计规律性,开发数据驱动的产品的热情。但是,我发现他们中有些人实际上缺少为了获取有用结果的必要的数学直觉和框架。这是我写这篇文章的主要原因。 最近,许多好用的机器和深度学习软件变得十分易得,例如 scikit-learn,Weka,Tensorflow,等等。机器学习理论是与统计学、概率论、计算机科学、算法等方面交叉的领...

qq_38459404的博客 1207

从入门到精通,计算机er如何快速掌握机器学习(ML)?

写在前面 机器学习是一门涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科的多领域交叉学科,在当下各个领域运用十分广泛。不仅是业内人士,许多业外人士为了丰富自己的知识涉猎领域,提升自身竞争力,也或多或少的开始尝试接触机器学习。 需要进行大量手工调整才能解决的问题,机器学习算法通常可以简化代码、提高性能; 问题复杂,传统方法难以解决,最好的机器学习方法可以找到解决方案; 复杂世界有波动,机器学习算法可以适应新数据;洞察问题和大量数据…… 那么,对于计算机小白来说,如何

Baoyan_cs的博客 2823

图解AI数学基础:从入门到精通系列教程(要点速查清单·完结)

本系列教程展开讲解AI所需的数学基础知识,力求以最直观最易懂的方式给帮助大家掌握AI依赖的数学知识最小子集。本教程内容覆盖线性代数与矩阵论,概率与统计,信息论,微积分与最优化几个核心的知识板块。......

ShowMeAI研究中心 1万+

图解机器学习算法 | 从入门到精通系列教程(机器学习通关指南·完结)

本篇内容是ShowMeAI组织的「图解机器学习算法」系列教程入口,本教程尽量以生动可视化的方式,帮助大家理解机器学习的核心知识和重要的系列模型,并配以相关的代码实现帮助大家了解应用方法。(对机器学习实战感兴趣的同学,可以关注ShowMeAI的另外一个系列[机器学习应用实践])......

ShowMeAI研究中心 1万+

【粉丝福利社】MATLAB数学建模从入门到精通

在当今数据驱动的时代,数学建模已成为解决复杂问题的重要工具。无论是在工程、科学研究,还是在经济和社会科学领域,数学建模都能够通过抽象和简化现实世界的问题,帮助我们更好地理解和预测各种现象。而MATLAB作为一种强大的计算和可视化工具,为数学建模提供了得天独厚的支持。本书《MATLAB数学建模从入门到精通》旨在为读者提供一个全面、系统的学习平台,帮助大家掌握数学建模的基本理论和实际应用。无论你是刚刚接触数学建模的学生,还是希望提升建模能力的专业人士,本书都将为你提供明确的指导和丰富的案例分析。

愚公智库 13万+

Material Studio 2024安装避坑指南:从证书配置到权限设置的完整解决方案

本文详细解析了Material Studio 2024的安装流程,从环境准备到权限优化的完整解决方案。针对证书配置、系统权限和计算服务等常见问题,提供了12个关键风险点的避坑指南,帮助科研工作者高效完成安装,提升材料模拟工作的效率。

moon9的博客 775

25章数学要素完整指南:从加减乘除到机器学习的终极学习路径

你是否曾经因为数学基础薄弱而畏惧机器学习?是否觉得从基础数学到人工智能之间缺少一座桥梁?《数学要素》这本书正是为你量身打造的学习地图,它用25个精心设计的章节,构建了一条从最基础的加减乘除直达机器学习核心的完整学习路径。 ## 📚 数学学习者的困惑与突破 许多人在学习机器学习时都会遇到相同的困境:复杂的算法背后是更复杂的数学原理,而数学基础不牢固直接导致理解困难。传统的数学教材要么过于理论化

gitblog_00341的博客 696

海康工业相机LabVIEW二次开发实战——参数配置优化与图像高效存储

本文详细介绍了海康工业相机在LabVIEW平台上的二次开发实战,重点解析了相机参数配置的优化方法与图像高效存储策略。通过剖析曝光、增益、触发模式等核心参数的设置逻辑,并结合生产者-消费者设计模式,指导开发者构建稳定、高效的图像采集与异步存储流程,有效提升工业视觉项目的开发效率与系统稳定性。

weixin_29306317的博客 222

MAX96712在车载摄像头系统中的带宽分配与传输能力计算解析

在计算摄像头带宽与传输接口的关系时,需要考虑视频流的像素分辨率、帧率、颜色深度等因素。以 MAX96712 这种 GMSL2 产品为例,它支持每个链路在正向方向以 3Gbps 或 6Gbps 的固定速率工作。

weixin_43199439的博客 3331

MATLAB科学计算从入门到精通

MATLAB(Matrix Laboratory)是一种强大的科学计算软件,广泛用于工程、物理、数学、计算生物学和其他领域的数据分析、模拟和可视化。本文将带您从入门到精通,通过具体案例演示如何使用MATLAB进行科学计算。

努力是为了站在万人之中,成为别人的光 8265

Git救援:如何从误操作中恢复未提交的更改

摘要:本文探讨了误操作git reset --hard导致未提交更改丢失后的恢复方法。首先分析git reflog的局限性,随后介绍利用IDE本地历史记录(如IntelliJ IDEA和VS Code)进行文件恢复的具体步骤。最后建议使用文件系统恢复工具(如Linux的extundelete或Windows的Recuva)作为备选方案。文章强调定期提交的重要性,同时提供了意外发生时可行的恢复策略,帮助开发者尽可能挽回丢失的工作内容。(149字)

2501_90323865的博客 131

关于ML工程师的一些想法 2026.1.3

AI项目的岗位分为管理层、数据层、算法层、工程层、支持层。其中ML工程师是算法层和工程层之间的桥梁它负责利用机器学习算法,通过系统的、工程的手段,完成一个可稳定运行的、可迭代的产品;将前沿的算法理论应用到实际产品上,是理论到实践的连接点;注意不要将ML工程师和MLOps工程师弄混ML工程师的职责相当于设计产品而MLOps工程师则是设计产品的产业链比如ML工程师的工作对象是:一个具体的、能解决特定问题的机器学习模型或智能功能MLOps工程师:支撑所有ML模型从诞生到退役的。

2501_93949951的博客 961

Android性能分析深度指南:Perfetto工具全面解析

本文深入探讨Android性能优化工具Perfetto的应用与实践。作为Google推出的新一代追踪系统,Perfetto整合了CPU调度、内存分配、电池状态等多维度分析功能,通过高性能数据处理和可视化界面帮助开发者定位性能瓶颈。文章系统介绍了Perfetto的架构原理、配置方法和核心功能,包括CPU性能分析、内存泄漏检测等关键技术。通过电商应用卡顿优化的实战案例,展示了如何利用数学建模(如帧时间公式$T_{\text{render}}\leq16.67\text{ms}$)指导性能调优。

郑伟强dev的专栏 144

044.树莓派4B部署YOLO:从系统烧录到模型运行

《树莓派4B部署YOLOv8实战笔记》摘要:本文详细记录了在ARM架构树莓派4B上部署YOLOv8的全流程。关键点包括:必须使用64位系统并手动编译OpenCV(禁用FFMPEG、开启NEON优化);模型需在x86转换为TFLite格式(分辨率不超过320×320);推理代码使用tflite_runtime替代TensorFlow以减少内存占用;针对USB摄像头卡顿、内存泄漏等典型问题给出了解决方案。

2603_95664987的博客 169

机器学习入门教学:从零基础到精通,一文搞定!

(一)定义 机器学习是一种让计算机通过数据自动学习并做出预测或决策的技术。它不需要明确的编程指令,而是通过算法从大量数据中发现模式和规律,从而实现自我优化和改进。简单来说,机器学习就是让计算机“学会”如何解决问题,而不是告诉它“怎么做”。 (二)与人工智能的关系 人工智能是一个广泛的概念,它涵盖了让计算机模拟人类智能的各种技术,包括机器学习、深度学习、自然语言处理、计算机视觉等。机器学习是人工智能的基础和核心,为AI提供了学习和适应的能力。可以说,没有机器学习,人工智能就无法实现其强大的

saluteSIWU的博客 2260

MATLAB 图像滤波:高通、低通、带通和方向滤波器

在 MATLAB 中,我们可以使用不同类型的滤波器对图像进行处理,包括高通滤波器、低通滤波器、带通滤波器和方向滤波器。通过以上代码示例,我们介绍了 MATLAB 中使用高通滤波器、低通滤波器、带通滤波器和方向滤波器对图像进行滤波的方法。高斯滤波器可以实现带通滤波效果,通过调整滤波器的方差参数可以控制带通滤波器的频率范围。这里的平均滤波器是一种常见的低通滤波器,通过对图像周围的像素进行平均来实现平滑效果。Sobel 滤波器是一种常用的方向滤波器,用于检测图像中的水平和垂直边缘。函数将高通滤波器应用于图像。

CyberSparkZ的博客 1396

机器学习教程(非常详细)从零基础入门到精通,看完这一篇就够了

从广义上来说,机器学习是一种能够赋予机器学习的能力以此让它完成直接编程无法完成的功能的方法。但从实践的意义上来说,机器学习是一种通过利用数据,训练出模型,然后使用模型预测的一种方法。

Python84310366的博客 3万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【机器学习】窥数据之序,悟算法之道:机器学习的初心与远方

机器学习是人工智能的重要分支,它通过数据驱动的方法,让计算机能够自主学习规律并完成任务。本文从定义入手,详细解析了机器学习的三大类型(监督学习、无监督学习、强化学习),并结合推荐系统、图像处理和金融风控等实际案例,展示了其广泛的应用场景。针对学习机器学习的基础需求,本文梳理了线性代数、概率论和编程的入门路径,并以房价预测的实战项目为例,完整讲解了机器学习项目的核心流程。适合人群:零基础到初学者,帮你轻松搭建学习框架!

半截诗的博客~ 4443

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

机器学习必备数学与编程指南:从入门到精通

机器学习入门指南(150字摘要) 掌握机器学习需要扎实的数学基础(线性代数、概率统计、微积分、优化理论)和编程技能(Python、NumPy、Pandas、Scikit-learn)。学习路径建议分阶段:1个月打基础,2-3个月深入算法,后续专研深度学习。关键建议:用编程实践数学概念,项目驱动学习(Kaggle、开源项目),善用社区资源(StackOverflow、GitHub)。推荐《Hands-On Machine Learning》等书籍,并坚持每日编码和技术总结。

hxsyyds49的博客 518

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

100天机器学习编码挑战:从入门到精通的学习之旅

100-Days-Of-ML-Code项目为机器学习初学者提供了一个结构化的学习路径。通过100天的持续努力,你可以从机器学习的新手成长为具备实战能力的学习者。无论你是计算机科学学生、数据分析师,还是对人工智能感兴趣的专业人士,这个项目都能帮助你系统地学习机器学习知识,为你的职业发展打开新的可能性。现在,是时候开始你的机器学习之旅了。记住,每个专家都曾是初学者,持续学习和实践是成功的关键。让我们一起在这100天的旅程中探索机器学习的奇妙世界吧!

2401_87189860的博客 1075

【机器学习入门】16.[第2章 数学基础] 向量微积分与雅可比-黑塞:优化算法的数学地基

摘要: 本文深入解析优化算法的数学核心——雅可比矩阵与黑塞矩阵,揭示牛顿法相比梯度下降的智能优势。通过多变量函数陷阱、神经网络梯度传播、峡谷震荡问题等案例,阐释一阶导数的局限性与二阶导数矩阵的关键作用。牛顿法利用黑塞矩阵逆自适应调整步长与方向,解决梯度下降的震荡问题。实战中,带L2正则的线性回归黑塞矩阵显式推导证明牛顿法的解析解能力。优化算法的强弱本质在于微积分矩阵运算,掌握这些数学工具能显著提升算法调试与模型优化效率。(150字) 关键词: 梯度下降,牛顿法,雅可比矩阵,黑塞矩阵,优化算法,二阶导数,神经

1037

机器学习从入门到精通:核心知识与学习资源全解析

从实践角度看,它构建了 “数据训练 - 模型生成 - 预测应用” 的完整闭环:利用历史数据训练模型,使其具备归纳规律的能力,进而对新输入数据产生预测输出,完成从经验到决策的转化。当与计算机视觉、自然语言处理等领域融合时,机器学习衍生出丰富的应用场景,涵盖图像分类、语音识别、推荐系统等,成为解决复杂实际问题的核心技术手段。机器学习是理论与践深度融合的领域,通过构建系统化知识框架、熟练运用工具库、参与真实项目实战,初学者可逐步掌握从数据处理到模型部署的全流程能力,为人工智能领域的深入探索奠定坚实基础。

sdfakl的博客 1732

Python机器学习:一文讲透机器学习中的验证集法

验证集法又被称为“留出法”,基本思路是将样本数据集划分为两个互斥的集合:训练集和测试集。其中训练集占比一般为2/3~4/5,常用70%;测试集占比一般为1/5~1/3,常用30%。训练集用来构建机器学习模型;测试集也被称为“验证集”“保留集”,用来进行样本外预测,并计算测试集误差,估计模型预测能力。

m0_72274883的博客 1632
上一篇: 【认知雷达贝叶斯非参数学习:依赖狄利克雷过程驱动的感知-行动循环深化】第一章 感知-行动循环与认知动态系统基础
下一篇: 【机器学习基础算法:从零实现到精通】第2章 监督学习:线性模型与基函数方法
VectorShift
博客等级 码龄1年 1839粉丝 1109原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VectorShift

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值