You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求改写RNimble的LQ分解函数以实现tensr包lq()功能

矩阵LQ分解的Nimble函数实现

需求说明

  • 目标:实现tensr包中lq()函数的功能,将m×n(m>n)矩形矩阵A分解为:
    • L:m×n下三角矩阵(主对角线以上元素为0)
    • Q:n×n正交矩阵(满足$Q^TQ=I_n$)
  • 现有问题:当前代码对$A^T$做Gram-Schmidt分解时变量逻辑混乱,生成的是n×m正交矩阵和m×m下三角矩阵,不符合需求,需修正。

现有代码

nimQR.Q = nimbleFunction(
  run = function(A = double(2)){
    returnType(double(2))
    A1 = t(A)
    m <- dim(A1)[1]
    n <- dim(A1)[2]
    Q <- matrix(0, m, n)
    R <- matrix(0, n, n)
    for (k in 1:n) {
      Q[1:m, k] <- A1[1:m, k]
      if (k > 1) {
        for (i in 1:(k - 1)) {
          R[i, k] <- t(Q[1:m, i]) %*% Q[1:m, k]
          Q[1:m, k] <- Q[1:m, k] - R[i, k] * Q[1:m, i]
        }
      }
      R[k, k] <- sum(abs(Q[, k])^2)^(1/2)
      Q[1:m, k] <- Q[1:m, k]/R[k, k]
    }
    return(Q)
})

nimQR.R = nimbleFunction(
  run = function(A = double(2)){
    returnType(double(2))
    A1 = t(A)
    m <- dim(A1)[1]
    n <- dim(A1)[2]
    Q <- matrix(0, m, m)
    R <- matrix(0, n, n)
    for (k in 1:n) {
      Q[1:m, k] <- A1[1:m, k]
      if (k > 1) {
        for (i in 1:(k - 1)) {
          R[i, k] <- t(Q[1:m, i]) %*% Q[1:m, k]
          Q[1:m, k] <- Q[1:m, k] - R[i, k] * Q[1:m, i]
        }
      }
      R[k, k] <- sum(abs(Q[1:m, k])^2)^(1/2)
      Q[1:m, k] <- Q[1:m, k]/R[k, k]
    }
    return(t(R))
    
  })

改写后的解决方案

核心思路

LQ分解可通过对$A^T$做QR分解推导:

  1. 对$AT$(n×m矩阵)执行QR分解,得到$AT = Q_{QR} R_{QR}$,其中$Q_{QR}$是n×n正交矩阵,$R_{QR}$是n×m上三角矩阵。
  2. 转置等式得到$A = R_{QR}^T Q_{QR}^T$,此时:
    • $L = R_{QR}^T$:m×n下三角矩阵(因$R_{QR}$是上三角,转置后为下三角)
    • $Q = Q_{QR}^T$:n×n正交矩阵(正交矩阵的转置仍为正交矩阵)

改写后的代码

# 返回LQ分解中的n×n正交矩阵Q
nimLQ.Q = nimbleFunction(
  run = function(A = double(2)){
    returnType(double(2))
    # 获取矩阵A的维度:m行n列(m>n)
    m <- dim(A)[1]
    n <- dim(A)[2]
    # 处理A的转置矩阵A^T(n×m)
    A_t <- t(A)
    # 初始化QR分解所需的矩阵
    Q_qr <- matrix(0, n, n)  # n×n正交矩阵
    R_qr <- matrix(0, n, m)  # n×m上三角矩阵
    
    # 对A^T的前n列执行Gram-Schmidt正交化(对应A的前n行)
    for (k in 1:n) {
      # 初始化当前列
      Q_qr[, k] <- A_t[, k]
      # 减去已正交化列的投影
      if (k > 1) {
        for (i in 1:(k-1)) {
          R_qr[i, k] <- t(Q_qr[, i]) %*% Q_qr[, k]
          Q_qr[, k] <- Q_qr[, k] - R_qr[i, k] * Q_qr[, i]
        }
      }
      # 归一化当前列
      norm_val <- sqrt(sum(Q_qr[, k]^2))
      R_qr[k, k] <- norm_val
      Q_qr[, k] <- Q_qr[, k] / norm_val
    }
    
    # LQ分解的Q是Q_qr的转置
    Q <- t(Q_qr)
    return(Q)
  })

# 返回LQ分解中的m×n下三角矩阵L
nimLQ.L = nimbleFunction(
  run = function(A = double(2)){
    returnType(double(2))
    m <- dim(A)[1]
    n <- dim(A)[2]
    A_t <- t(A)
    Q_qr <- matrix(0, n, n)
    R_qr <- matrix(0, n, m)
    
    for (k in 1:n) {
      Q_qr[, k] <- A_t[, k]
      if (k > 1) {
        for (i in 1:(k-1)) {
          R_qr[i, k] <- t(Q_qr[, i]) %*% Q_qr[, k]
          Q_qr[, k] <- Q_qr[, k] - R_qr[i, k] * Q_qr[, i]
        }
      }
      norm_val <- sqrt(sum(Q_qr[, k]^2))
      R_qr[k, k] <- norm_val
      Q_qr[, k] <- Q_qr[, k] / norm_val
    }
    
    # LQ分解的L是R_qr前n列的转置(对应A的n列)
    L <- t(R_qr[, 1:n])
    return(L)
  })

验证说明

调用函数后可通过以下方式验证正确性:

# 生成测试矩阵
set.seed(123)
A <- matrix(rnorm(10*5), nrow=10, ncol=5)  # m=10, n=5

# 执行LQ分解
L <- nimLQ.L(A)()
Q <- nimLQ.Q(A)()

# 验证A ≈ L %*% Q
all.equal(A, L %*% Q, tolerance=1e-6)

# 验证Q是正交矩阵:Q^T %*% Q ≈ I_n
all.equal(t(Q) %*% Q, diag(5), tolerance=1e-6)

# 验证L是下三角矩阵:主对角线以上元素为0
all.equal(L[upper.tri(L)], rep(0, sum(upper.tri(L))), tolerance=1e-6)

内容的提问来源于stack exchange,提问作者EM823823

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:49:51