Householder 变换与 QR 分解

import random
import copy

EPS = 0.00001

class MatrixException( Exception ):
    pass

class Matrix( object ):

    def __init__( self, rows, cols, values_list = None, description = None ):
        self.rows = rows
        self.cols = cols
        self.matrix = [ [ 0 for c in xrange( cols ) ] for r in xrange( rows ) ]
        if values_list:
            for r in xrange( rows ):
                for c in xrange( cols ):
                    try:
                        self.matrix[r][c] = values_list[cols * r + c]
                    except IndexError:
                        self.matrix[r][c] = 0
        if description:
            self.description = description

    def __getitem__( self, index ):
        #以后写
        if isinstance( index, str ):
            pass
        else:
            return self.matrix[index]

    def __repr__( self ):
        for r in xrange( self.rows ):
            print self.matrix[r]
        return ''

    def transpose( self ):
        M = Matrix( self.cols, self.rows )
        for c in xrange( self.cols ):
            for r in xrange( self.rows ):
                M[c][r] = self.matrix[r][c]
        return M

    @property
    def T( self ):
        return self.transpose()

    @staticmethod
    def mul( M, factor ):
        res = Matrix( M.rows, M.cols )
        for r in xrange( M.rows ):
            for c in xrange( M.cols ):
                res[r][c] = M[r][c] * factor
        res = Matrix.format_matrix( res )
        return res

    def __sub__( self, other ):
        try:
            if self.rows != other.rows or self.cols != other.cols:
                raise MatrixException
            M = Matrix( self.rows, self.cols )
            for r in xrange( self.rows ):
                for c in xrange( self.cols ):
                    M[r][c] = self[r][c] - other[r][c]
            M = Matrix.format_matrix( M )
            return M
        except MatrixException:
            print "two matrix must be the same size."

    def __rmul__( self, other ):
        try:
            if not isinstance( other, float ):
                raise TypeError
            return Matrix.mul( self, other )
        except TypeError:
            print "factor must be float."

    def __mul__( self, other ):
        if isinstance( other, float ):
            return Matrix.mul( self, other )
        elif isinstance( other, Matrix ):
            try:
                if self.cols != other.rows:
                    raise MatrixException
                M = Matrix( self.rows, other.cols )
                for r in xrange( self.rows ):
                    for c in xrange( other.cols ):
                        M[r][c] = cross_product( self[r], map( lambda x: x[c], other ) )
                M = Matrix.format_matrix( M )
                return M
            except MatrixException:
                print "self.cols must be equal to other.rows"
        else:
            pass

    @staticmethod
    def format_matrix( M ):
        global EPS
        for r in xrange( M.rows ):
            for c in xrange( M.cols ):
                if abs( M[r][c] ) < EPS:
                    M[r][c] = 0.0
                else:
                    M[r][c] = round( M[r][c], 7 )
        return M

    def random_create( self, min = 1, max = 20 ):
        for r in xrange( self.rows ):
            for c in xrange( self.cols ):
                self[r][c] = random.randint( min, max )

    def get_col( self, col ):
        M = Matrix( self.rows, 1 )
        for r in xrange( self.rows ):
            M[r][0] = self[r][col]
        return M

    def QR( self ):
        R = copy.deepcopy( self )
        Q = IdentityMatrix( self.rows )
        for c in xrange( self.cols ):
            col_matrix = R.get_col( c )
            H = create_householder_matrix_by_cleared_to_zero( col_matrix, c )
            Q = H * Q
            R = H * R
        return Q , R            

class IdentityMatrix( Matrix ):
    def __init__( self, size = 1 ):
        self.matrix = [ [ 1 if c == r else 0 for c in xrange( size ) ] for r in xrange( size ) ]
        self.rows = self.cols = size

    def __sub__( self, other ):
        try:
            if other.rows != other.cols:
                raise TypeError
            self.matrix = [ [ 1 if c == r else 0 for c in xrange( other.rows ) ] for r in xrange( other.rows ) ]
            self.rows = self.cols = other.rows
            return Matrix.__sub__( self, other )
        except TypeError:
            print "matrix.rows must be equal to matrix.cols."

def cross_product( a, b ):
    return reduce( lambda x, y : x + y, map( lambda x: x[0] * x[1], zip( a, b ) ) )

def create_householder_matrix_by_mirror_base( vector, mirror_base ):
    global I
    cut_index = mirror_base.index( 1 )
    sign = -1 if vector[cut_index] < 0 else 1
    sigma = sign * ( cross_product( vector, vector ) ) ** 0.5
    U = vector[:cut_index] + [sigma + vector[cut_index]] + vector[cut_index + 1:]
    U = Matrix( len( U ), 1, U )
    rho = 0.5 * ( U.transpose() * U )[0][0]
    H = I - ( 1.0 / rho ) * ( U * U.transpose() )
    return H

def create_householder_matrix_by_cleared_to_zero( vector, cut_index ):
    if isinstance( vector, Matrix ):
        res = []
        for r in xrange( vector.rows ):
            res.append( vector[r][0] )
        vector = res
    global I
    sign = -1 if vector[cut_index] < 0 else 1
    sigma = sign * ( cross_product( vector[cut_index:],
                                    vector[cut_index:] ) ) ** 0.5
    mirror = vector[:cut_index] + [-sigma] + [0] * ( len( vector ) - cut_index - 1 )
    U = map( lambda x: x[0] - x[1], zip( vector, mirror ) )
    U = Matrix( len( U ), 1, U )
    rho = 0.5 * ( U.transpose() * U )[0][0]
    H = I - ( 1.0 / rho ) * ( U * U.transpose() )
    return H

I = IdentityMatrix()
M1 = Matrix( 5, 5 )
M1.random_create()
Q, R = M1.QR()
print "Q:\n", Q
print "R:\n", R

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-19 16:56:03

Householder 变换与 QR 分解的相关文章

QR分解

从矩阵分解的角度来看,LU和Cholesky分解目标在于将矩阵转化为三角矩阵的乘积,所以在LAPACK种对应的名称是trf(Triangular Factorization).QR分解的目的在于将矩阵转化成正交矩阵和上三角矩阵的乘积,对应的分解公式是A=Q*R.正交矩阵有很多良好的性质,比如矩阵的逆和矩阵的转置相同,任意一个向量和正交矩阵的乘积不改变向量的2范数等等.QR分解可以用于求解线性方程组,线性拟合.更重要的是QR分解是QR算法的基础,可以用于各种特征值问题,所以QR分集的应用非常广泛.

机器学习中的矩阵方法03:QR 分解

1. QR 分解的形式 QR 分解是把矩阵分解成一个正交矩阵与一个上三角矩阵的积.QR 分解经常用来解线性最小二乘法问题.QR 分解也是特定特征值算法即QR算法的基础.用图可以将分解形象地表示成: 其中, Q 是一个标准正交方阵, R 是上三角矩阵. 2. QR 分解的求解 QR 分解的实际计算有很多方法,例如 Givens 旋转.Householder 变换,以及 Gram-Schmidt 正交化等等.每一种方法都有其优点和不足.上一篇博客介绍了 Givens 旋转和 Householder

QR分解与最小二乘(转载自AndyJee)

转载网址:http://www.cnblogs.com/AndyJee/p/3846455.html 主要内容: 1.QR分解定义 2.QR分解求法 3.QR分解与最小二乘 4.Matlab实现 一.QR分解 R分解法是三种将矩阵分解的方式之一.这种方式,把矩阵分解成一个正交矩阵与一个上三角矩阵的积. QR 分解经常用来解线性最小二乘法问题.QR 分解也是特定特征值算法即QR算法的基础. 定义: 实数矩阵 A 的 QR 分解是把 A 分解为Q.R,这里的 Q 是正交矩阵(意味着 QTQ = I)

QR分解与最小二乘

主要内容: 1.QR分解定义 2.QR分解求法 3.QR分解与最小二乘 4.Matlab实现   一.QR分解 R分解法是三种将矩阵分解的方式之一.这种方式,把矩阵分解成一个正交矩阵与一个上三角矩阵的积. QR 分解经常用来解线性最小二乘法问题.QR 分解也是特定特征值算法即QR算法的基础. 定义: 实数矩阵 A 的 QR 分解是把 A 分解为Q.R,这里的 Q 是正交矩阵(意味着 QTQ = I)而 R 是上三角矩阵.类似的,我们可以定义 A 的 QL, RQ 和 LQ 分解. 更一般的说,我

8.QR分解的python实现

import numpy as np import math #直到主对角线上的值变化很小时,结束循环 def is_same(a,b): print(a) print(b) n = len(a) for i in range(n): if(math.fabs(a[i]-b[i]) > 1e-9): return False return True if __name__ == '__main__': a = np.array([0.65,0.28,0.02,0.15,0.67,0.18,0.1

数值分析--矩阵QR分解的三种方法

QR分解法是目前求一般矩阵全部特征值的最有效并广泛应用的方法,一般矩阵先经过正交相似变化成为Hessenberg矩阵,然后再应用QR方法求特征值和特征向量.它是将矩阵分解成一个正规正交矩阵Q与上三角形矩阵R,所以称为QR分解法,与此正规正交矩阵的通用符号Q有关.

矩阵的QR分解(三种方法)

Gram-Schmidt正交化 假设原来的矩阵为[a,b],a,b为线性无关的二维向量,下面我们通过Gram-Schmidt正交化使得矩阵A为标准正交矩阵: 假设正交化后的矩阵为Q=[A,B],我们可以令A=a,那么我们的目的根据AB=I来求B,B可以表示为b向量与b向量在a上的投影的误差向量: $$B=b-Pb=b-\frac{A^Tb}{A^TA}A$$

求解矩阵特征值

特征值的条件数 Weilandt-Hoffman定理:设A与B是两个n阶正规矩阵,它们的特征值分别是li和mj,则存在一个排列p(n),使得 $\sqrt {\sum_i \left | \pi(i)-\lambda_i \right |^2}\leqslant \left \| B-A \right \|_F$ Weilandt-Hoffman定理表明Hermite矩阵和正规矩阵的特征值是良态的,因此在此主要讨论非正规矩阵对扰动的敏感程度的数据标准. 假定n阶方阵A的Jordan分解为Q-1A

矩阵分解---QR正交分解,LU分解

相关概念: 正交矩阵:若一个方阵其行与列皆为正交的单位向量,则该矩阵为正交矩阵,且该矩阵的转置和其逆相等.两个向量正交的意思是两个向量的内积为 0 正定矩阵:如果对于所有的非零实系数向量x ,都有 x'Ax>0,则称矩阵A 是正定的.正定矩阵的行列式必然大于 0, 所有特征值也必然 > 0.相对应的,半正定矩阵的行列式必然 ≥ 0. QR分解 矩阵的正交分解又称为QR分解,是将矩阵分解为一个正交矩阵Q和一个上三角矩阵的乘积的形式. 任意实数方阵A,都能被分解为A=QR.这里的Q为正交单位阵,即