Python phân tách qr mà không có numpy

Vui lòng tìm mã cho bài đăng này trên GitHub. Như mọi khi, tôi hy vọng bạn sẽ sao chép nó và biến nó thành của riêng bạn. Mô-đun chính trong repo chứa tất cả các mô-đun mà chúng tôi sẽ trình bày có tên là LinearAlgebraPurePython. py. Có một tệp python đơn giản có tên BasicToolsPractice. py nhập mô-đun chính đó và minh họa các chức năng của mô-đun. Sẽ thật tuyệt nếu bạn có thể sao chép hoặc tải xuống trước tiên để có ích khi chúng tôi xem qua bài đăng này

Tại sao bài này?

LỜI NHẮC NHỞ. Mục tiêu của chúng tôi là hiểu rõ hơn về nguyên tắc của các công cụ máy học bằng cách khám phá cách tự viết mã cho chúng…

Có nghĩa là, chúng tôi đang tìm cách viết mã các công cụ này mà không cần sử dụng các mô-đun python TUYỆT VỜI có sẵn cho máy học

Những nỗ lực này sẽ cung cấp thông tin chi tiết và sự hiểu biết tốt hơn, nhưng những thông tin chi tiết đó sẽ không đến với chúng tôi sau mỗi bài đăng. Thay vào đó, chúng tôi đang xây dựng một nền tảng hỗ trợ những hiểu biết đó trong tương lai

Để hợp lý hóa một số bài đăng sắp tới, tôi muốn đề cập đến một số chức năng cơ bản sẽ giúp những bài đăng trong tương lai dễ dàng hơn. Rõ ràng, nếu chúng ta tránh sử dụng numpy và scipy, chúng ta sẽ phải tạo các hàm/công cụ tiện lợi của riêng mình. Bài đăng này đề cập đến những công cụ tiện lợi đó.  

Ở một đầu của quang phổ, nếu bạn chưa quen với đại số tuyến tính hoặc python hoặc cả hai, tôi tin rằng bạn sẽ thấy bài đăng này hữu ích, tôi hy vọng, một nhóm tốt các liên kết đã lưu

Mặt khác, nếu bạn có nền tảng về trăn và đại số tuyến tính, thì lý do bạn đọc bài đăng này là để so sánh cách tôi đã làm với cách bạn sẽ làm. Đánh giá có thể cung cấp cho bạn một số ý tưởng mới hoặc có thể xác nhận rằng bạn vẫn thích cách của mình hơn.  

Công cụ

Bạn sẽ tìm thấy tài liệu và nhận xét trong tất cả các chức năng này. Khi có thêm mô tả được đảm bảo, tôi sẽ cung cấp hoặc cung cấp hướng dẫn cho các tài nguyên khác để mô tả chi tiết hơn. Nếu có một phần cụ thể mà bạn không hiểu, tôi rất mong bạn hiểu nó tốt hơn. Cách tốt nhất để làm điều đó là gì?

Đầu tiên là zeros_matrix. Khi chúng ta chỉ cần một ma trận mới, hãy tạo một ma trận và điền vào nó bằng số không

def zeros_matrix[rows, cols]:
    """
    Creates a matrix filled with zeros.
        :param rows: the number of rows the matrix should have
        :param cols: the number of columns the matrix should have

        :return: list of lists that form the matrix
    """
    M = []
    while len[M] < rows:
        M.append[[]]
        while len[M[-1]] < cols:
            M[-1].append[0.0]

    return M

Như bạn đã thấy từ các bài viết trước, cả ma trận và vectơ đều được xử lý bằng Python dưới dạng mảng hai chiều. Do đó, mảng các hàng chứa một mảng các giá trị cột và mỗi giá trị cột được khởi tạo bằng 0. Lưu ý chỉ số -1 cho hàng ma trận trong vòng lặp thứ hai. Đây là một cách đơn giản để tham chiếu phần tử cuối cùng của một mảng và trong trường hợp này, đó là mảng [hàng] cuối cùng được thêm vào mảng

Hàm trợ giúp thứ hai của chúng tôi là id_matrix được sử dụng để tạo ma trận nhận dạng. Và, như một lập trình viên lười xây dựng tốt nên làm, tôi đã tận dụng rất nhiều vào lệnh gọi ban đầu tới zeros_matrix. Tất cả những gì còn lại sau khi chúng ta có ma trận đồng nhất là thay thế các phần tử đường chéo bằng 1

def identity_matrix[n]:
    """
    Creates and returns an identity matrix.
        :param n: the square size of the matrix

        :return: a square identity matrix
    """
    IdM = zeros_matrix[n, n]
    for i in range[n]:
        IdM[i][i] = 1.0

    return IdM

Thứ ba là copy_matrix cũng dựa nhiều vào zeros_matrix. Chúng tôi muốn điều này cho những lúc chúng tôi cần làm việc trên một bản sao và giữ nguyên ma trận gốc. Ở đây, chúng tôi chỉ đơn giản là lấy kích thước của ma trận ban đầu và sử dụng các kích thước đó để tạo ma trận 0 và sau đó sao chép các phần tử của ma trận ban đầu sang phần tử ma trận mới theo phần tử

def copy_matrix[M]:
    """
    Creates and returns a copy of a matrix.
        :param M: The matrix to be copied

        :return: A copy of the given matrix
    """
    # Section 1: Get matrix dimensions
    rows = len[M]
    cols = len[M[0]]

    # Section 2: Create a new matrix of zeros
    MC = zeros_matrix[rows, cols]

    # Section 3: Copy values of M into the copy
    for i in range[rows]:
        for j in range[cols]:
            MC[i][j] = M[i][j]

    return MC

Thứ tư là print_matrix để chúng ta có thể xem liệu chúng ta có nhầm lẫn hay không trong các phép toán đại số tuyến tính của mình. Ở đây, chúng tôi chỉ in ma trận hoặc vectơ, mỗi lần một hàng. “+0” trong phần hiểu danh sách đã được đề cập trong một bài viết trước. Hãy thử hiểu danh sách có và không có “+0” đó và xem điều gì sẽ xảy ra.  

def print_matrix[M, decimals=3]:
    """
    Print a matrix one row at a time
        :param M: The matrix to be printed
    """
    for row in M:
        print[[round[x,decimals]+0 for x in row]]

Trong trường hợp bạn chưa biết các kỹ thuật hiểu danh sách python, chúng rất đáng để học. Có rất nhiều blog và trang web dạy nó. Như mọi khi, tôi khuyên bạn nên tham khảo ít nhất ba nguồn khi chọn bất kỳ kỹ năng mới nào, đặc biệt là khi học một kỹ năng Python mới. Một số ví dụ ngắn gọn sẽ là…

some_new_list = [ for x in list if  else ]
# or
another_list = [s.method[] for s in string_list if ]
# or
one_more_list = [ for x in list]

Mục đích của việc hiển thị one_more_list là để làm rõ rằng bạn thực sự không cần phải có bất kỳ điều kiện nào trong phần hiểu danh sách và phương pháp bạn áp dụng có thể là phương pháp bạn viết

Thứ năm là chuyển vị. Chuyển vị ma trận chỉ đơn giản là hành động di chuyển các phần tử từ một hàng và cột ban đầu nhất định sang một hàng = cột ban đầu và một cột = hàng ban đầu. Nghĩa là, nếu một phần tử đã cho của Mm_{i,j}, it will move to m_{j,i} in the transposed matrix, which is shown as

MT[j][i] = M[i][j]

trong mã. Liên quan đến nguyên tắc này, lưu ý rằng ma trận số 0 được tạo với số cột của ma trận gốc cho số hàng của ma trận được chuyển vị và số hàng của ma trận gốc cho số cột của ma trận được chuyển vị. Thật là một mồm

Lưu ý rằng trong phần 1 bên dưới, trước tiên chúng tôi đảm bảo rằng M là một mảng Python hai chiều. Sau đó, chúng tôi lưu trữ kích thước của M trong phần 2. Tiếp theo, trong phần 3, chúng tôi sử dụng các kích thước đó để tạo ma trận số 0 có kích thước của ma trận được chuyển vị và gọi nó là MT. Cuối cùng, trong phần 4, chúng tôi chuyển các giá trị từ M sang MT theo cách hoán vị như đã mô tả trước đó

def transpose[M]:
    """
    Returns a transpose of a matrix.
        :param M: The matrix to be transposed

        :return: The transpose of the given matrix
    """
    # Section 1: if a 1D array, convert to a 2D array = matrix
    if not isinstance[M[0],list]:
        M = [M]

    # Section 2: Get dimensions
    rows = len[M]
    cols = len[M[0]]

    # Section 3: MT is zeros matrix with transposed dimensions
    MT = zeros_matrix[cols, rows]

    # Section 4: Copy values from M to it's transpose MT
    for i in range[rows]:
        for j in range[cols]:
            MT[j][i] = M[i][j]

    return MT

Thứ sáu và thứ bảy là matrix_addition và matrix_subtraction. Tôi đang giải thích chúng cùng một lúc, bởi vì về cơ bản chúng giống hệt nhau ngoại trừ một dòng mã duy nhất trong đó diễn ra phép cộng hoặc phép trừ từng phần tử. Trong phần 1 của mỗi hàm, bạn thấy chúng ta kiểm tra xem mỗi ma trận có chiều giống nhau không, nếu không thì không cộng được. Phần 2 của mỗi chức năng tạo ma trận số 0 để giữ ma trận kết quả. Đoạn 3 mỗi hàm thực hiện lần lượt từng phần tử của phép toán cộng hoặc trừ.  

def matrix_addition[A, B]:
    """
    Adds two matrices and returns the sum
        :param A: The first matrix
        :param B: The second matrix

        :return: Matrix sum
    """
    # Section 1: Ensure dimensions are valid for matrix addition
    rowsA = len[A]
    colsA = len[A[0]]
    rowsB = len[B]
    colsB = len[B[0]]
    if rowsA != rowsB or colsA != colsB:
        raise ArithmeticError['Matrices are NOT the same size.']

    # Section 2: Create a new matrix for the matrix sum
    C = zeros_matrix[rowsA, colsB]

    # Section 3: Perform element by element sum
    for i in range[rowsA]:
        for j in range[colsB]:
            C[i][j] = A[i][j] + B[i][j]

    return C

def matrix_subtraction[A, B]:
    """
    Subtracts matrix B from matrix A and returns difference
        :param A: The first matrix
        :param B: The second matrix

        :return: Matrix difference
    """
    # Section 1: Ensure dimensions are valid for matrix subtraction
    rowsA = len[A]
    colsA = len[A[0]]
    rowsB = len[B]
    colsB = len[B[0]]
    if rowsA != rowsB or colsA != colsB:
        raise ArithmeticError['Matrices are NOT the same size.']

    # Section 2: Create a new matrix for the matrix difference
    C = zeros_matrix[rowsA, colsB]

    # Section 3: Perform element by element subtraction
    for i in range[rowsA]:
        for j in range[colsB]:
            C[i][j] = A[i][j] - B[i][j]

    return C

Thứ tám là matrix_multiply. Quy tắc đầu tiên trong phép nhân ma trận là nếu bạn muốn nhân ma trận A với ma trận B, the number of columns of A MUST equal the number of rows of B. Thus, if A có kích thước là m hàng và n columns [m\,x\,n for short] B must have n rows and it can have 1 or more columns. Let’s say it has k cột. Như vậy, tích kết quả của hai ma trận sẽ là một ma trận m\,x\,k hoặc ma trận kết quả có số hàng < . Do đó, chúng ta tạo một ma trận 0 để chứa tích kết quả của hai ma trận có kích thước A and the number of columns of B.  Hence, we create a zeros matrix to hold the resulting product of the two matrices that has dimensions of rows_A \, x \, cols_B trong mã. Ngoài ra, NẾU AB có cùng kích thước của n rows and n columns, that is they are square matrices, A \cdot B does NOT equal B \cdot A. Remember that the order of multiplication matters when multiplying matrices. Finally, the result for each new element c_{i,j} trong C, which will be the result of A \cdot B, is found as follows using a 3\,x\,3 matrix as an example:

c_{i,j} = a_{i,0} \cdot b_{0,j} + a_{i,1} \cdot b_{1,j} + a_{i,2} \cdot b_{2,j

Tức là, để có được c_{i,j} , chúng ta sẽ nhân từng phần tử cột trong mỗi hàng i of A times each row element in each column j of B and adding up those products. Phew!

________số 8

Thứ chín là một hàm, multi_matrices, để nhân danh sách các ma trận bằng cách sử dụng matrix_multiply. Lưu ý rằng chúng ta chỉ cần thiết lập sản phẩm đang chạy làm ma trận đầu tiên trong danh sách, sau đó vòng lặp for bắt đầu ở phần tử thứ hai [của danh sách ma trận] để lặp qua các ma trận và tạo sản phẩm đang chạy, matrix_product, nhân với ma trận tiếp theo .  

def multiply_matrices[list]:
    """
    Find the product of a list of matrices from first to last
        :param list: The list of matrices IN ORDER

        :return: The product of the matrices
    """
    # Section 1: Start matrix product using 1st matrix in list
    matrix_product = list[0]

    # Section 2: Loop thru list to create product
    for matrix in list[1:]:
        matrix_product = matrix_multiply[matrix_product, matrix]

    return matrix_product

Thứ mười, và tôi thú nhận là tôi không chắc khi nào là tốt nhất để trình bày cái này, đó là check_matrix_equality. Sẽ có lúc kiểm tra sự bằng nhau giữa hai ma trận là cách tốt nhất để xác minh kết quả của chúng tôi. Tuy nhiên, các phép toán đó sẽ có một số lỗi làm tròn đến mức các ma trận sẽ không hoàn toàn bằng nhau, nhưng về cơ bản chúng sẽ bằng nhau. Do đó, lưu ý rằng có một tol [tham số dung sai], có thể được đặt. Nếu mặc định được sử dụng, hai ma trận dự kiến ​​​​sẽ hoàn toàn bằng nhau. Nếu một dung sai được đặt, giá trị của tol là số vị trí thập phân mà các giá trị phần tử được làm tròn để kiểm tra trạng thái cơ bản bằng nhau

def identity_matrix[n]:
    """
    Creates and returns an identity matrix.
        :param n: the square size of the matrix

        :return: a square identity matrix
    """
    IdM = zeros_matrix[n, n]
    for i in range[n]:
        IdM[i][i] = 1.0

    return IdM
0

Tích vô hướng giữa hai vectơ hoặc ma trận về cơ bản là phép nhân ma trận và phải tuân theo cùng một quy tắc. Điều quan trọng cần lưu ý là quy trình nhân ma trận của chúng tôi có thể được sử dụng để nhân hai vectơ có thể dẫn đến một ma trận giá trị duy nhất. Trong những trường hợp như vậy, kết quả đó không được coi là một vectơ hoặc ma trận, mà là một giá trị đơn lẻ hoặc bộ chia tỷ lệ. Tuy nhiên, sử dụng các thói quen của chúng tôi, nó vẫn sẽ là một mảng với một mảng có giá trị bên trong nó. Để đọc một tài liệu tham khảo khác, hãy kiểm tra TẠI ĐÂY và tôi sẽ lưu liên kết đó dưới dạng dấu trang – đó là một nguồn tài nguyên tuyệt vời

Hàm thứ mười một là hàm unitize_vector. Hãy bước qua các phần của nó. Phần 1 đảm bảo rằng một vectơ được nhập vào có nghĩa là một trong các kích thước phải là 1. Ngoài ra, nó đảm bảo rằng mảng là 2 chiều. Bộ công cụ này muốn tất cả các ma trận và vectơ là 2 chiều để có tính nhất quán. Tiết 2 sử dụng định lý Pitago để tìm độ lớn của vectơ. Phần 3 tạo một bản sao của vectơ ban đầu [hàm copy_matrix hoạt động tốt vì nó vẫn hoạt động trên mảng 2D] và Phần 4 chia từng phần tử theo độ lớn xác định của vectơ để tạo một vectơ đơn vị.  

def identity_matrix[n]:
    """
    Creates and returns an identity matrix.
        :param n: the square size of the matrix

        :return: a square identity matrix
    """
    IdM = zeros_matrix[n, n]
    for i in range[n]:
        IdM[i][i] = 1.0

    return IdM
1

Sử dụng Numpy cho các hoạt động trên

Làm thế nào chúng ta sẽ thực hiện tất cả những hành động này với numpy? . Đoạn mã dưới đây tuân theo cùng một thứ tự các chức năng mà chúng ta vừa trình bày ở trên nhưng chỉ ra cách thực hiện từng chức năng một cách gọn gàng. Mã bên dưới nằm trong tệp NumpyToolsPractice. py trong repo. Sao chép mã bên dưới hoặc lấy mã từ repo, nhưng tôi thực sự khuyến khích bạn chạy mã và chơi với mã đó

def identity_matrix[n]:
    """
    Creates and returns an identity matrix.
        :param n: the square size of the matrix

        :return: a square identity matrix
    """
    IdM = zeros_matrix[n, n]
    for i in range[n]:
        IdM[i][i] = 1.0

    return IdM
2

Đóng cửa

Đó là nó cho bây giờ. Thư viện này tất nhiên sẽ phát triển với mỗi bài đăng mới. Tôi sẽ giới thiệu các chức năng trợ giúp mới nếu và khi chúng cần thiết trong các bài đăng trong tương lai và có các bài đăng riêng cho những bổ sung cần giải thích thêm. Nhưng những chức năng này là những chức năng cơ bản nhất. Một số trong số này cũng hỗ trợ công việc cho bài ma trận nghịch đảo và bài giải hệ phương trình.  

Phân tích QR có giống như phân tích QR không?

Trong đại số tuyến tính, phân tích QR, còn được gọi là phân tích QR hoặc phân tích QU , là phân tích ma trận A thành một .

Quá trình phân tách QR có thể thất bại không?

Phân tích QR luôn tồn tại, ngay cả khi ma trận không có thứ hạng đầy đủ, vì vậy hàm tạo sẽ không bao giờ bị lỗi . Công dụng chính của phép phân tách QR là trong nghiệm bình phương nhỏ nhất của các hệ phương trình tuyến tính đồng thời không bình phương.

Hệ số QR có phải là duy nhất không?

Trong lớp, chúng tôi đã xem xét trường hợp đặc biệt của ma trận hạng đầy đủ, n × n và chỉ ra rằng phân tích QR là duy nhất cho đến một thừa số của ma trận đường chéo với các phần tử ± . .

Phân tách QR có nghĩa là gì?

Phân tách QR là gì? . Trong công thức, A đại diện cho ma trận bắt đầu, Q. đại diện cho một ma trận trực giao, và. R đại diện cho một ma trận tam giác trên. a method used when converting a matrix into the form A = QR. In the formula, A represents the starting matrix, Q. represents an orthogonal matrix, and. R represents an upper triangle matrix.

Chủ Đề