{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "##内容索引\n", "1. 矩阵 --- mat函数\n", "2. 线性代数 --- \n", "numpy.linalg中的逆矩阵函数inv函数、行列式det函数、求解线性方程组的solve函数、内积dot函数、特征分解eigvals函数、eig函数、奇异值分解svd函数、广义逆矩阵的pinv函数" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##1. 矩阵\n", "在NumP中,矩阵是ndarray的子类,可以由专用的字符串格式来创建。我们可以使用mat、matrix、以及bmat函数来创建矩阵。" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "###1.1 创建矩阵\n", "mat函数创建矩阵时,若输入已经为matrix或ndarray对象,则不会为它们创建副本。因此,调用mat函数和调用matrix(data, copy=False)等价。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**在创建矩阵的专用字符串中,矩阵的行与行之间用分号隔开,行内的元素之间用空格隔开。**" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Creation from string:\n", "[[1 2 3]\n", " [4 5 6]\n", " [7 8 9]]\n" ] } ], "source": [ "A = np.mat('1 2 3; 4 5 6; 7 8 9')\n", "print \"Creation from string:\\n\", A" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Transpose A :\n", "[[1 4 7]\n", " [2 5 8]\n", " [3 6 9]]\n", "Inverse A :\n", "[[ -4.50359963e+15 9.00719925e+15 -4.50359963e+15]\n", " [ 9.00719925e+15 -1.80143985e+16 9.00719925e+15]\n", " [ -4.50359963e+15 9.00719925e+15 -4.50359963e+15]]\n" ] } ], "source": [ "# 转置\n", "print \"Transpose A :\\n\", A.T\n", "\n", "# 逆矩阵\n", "print \"Inverse A :\\n\", A.I" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Creation from array: \n", "[[0 1 2]\n", " [3 4 5]\n", " [6 7 8]]\n" ] } ], "source": [ "# 通过NumPy数组创建矩阵\n", "print \"Creation from array: \\n\", np.mat(np.arange(9).reshape(3,3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "###1.2 从已有矩阵创建新矩阵\n", "我们可以利用一些已有的较小的矩阵来创建一个新的大矩阵。用bmat函数来实现。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", "[[ 1. 0.]\n", " [ 0. 1.]]\n", "B:\n", "[[ 2. 0.]\n", " [ 0. 2.]]\n", "Compound matrix:\n", "[[ 1. 0. 2. 0.]\n", " [ 0. 1. 0. 2.]]\n", "Compound matrix:\n", "[[ 1. 0. 2. 0.]\n", " [ 0. 1. 0. 2.]\n", " [ 2. 0. 1. 0.]\n", " [ 0. 2. 0. 1.]]\n" ] } ], "source": [ "A = np.eye(2)\n", "print \"A:\\n\", A\n", "\n", "B = 2 * A\n", "print \"B:\\n\", B\n", "\n", "# 使用字符串创建复合矩阵\n", "print \"Compound matrix:\\n\", np.bmat(\"A B\")\n", "print \"Compound matrix:\\n\", np.bmat(\"A B; B A\")" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "##2. 线性代数\n", "线性代数是数学的一个重要分支。numpy.linalg模块包含线性代数的函数。使用这个模块,我们可以计算逆矩阵、求特征值、解线性方程组以及求解行列式。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "###2.1 计算逆矩阵\n", "使用inv函数计算逆矩阵。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", "[[ 0 1 2]\n", " [ 1 0 3]\n", " [ 4 -3 8]]\n", "inverse of A:\n", "[[-4.5 7. -1.5]\n", " [-2. 4. -1. ]\n", " [ 1.5 -2. 0.5]]\n", "check inverse:\n", "[[ 1. 0. 0.]\n", " [ 0. 1. 0.]\n", " [ 0. 0. 1.]]\n" ] } ], "source": [ "A = np.mat(\"0 1 2; 1 0 3; 4 -3 8\")\n", "print \"A:\\n\", A\n", "inverse = np.linalg.inv(A)\n", "print \"inverse of A:\\n\", inverse\n", "\n", "print \"check inverse:\\n\", inverse * A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "###2.2 行列式\n", "行列式是与方阵相关的一个标量值。对于一个n*n的实数矩阵,**行列式描述的是一个线性变换对“有向体积”所造成的影响。行列式的值为正,表示保持了空间的定向(顺时针或逆时针),为负表示颠倒空间的定向。**numpy.linalg模块中的det函数可以计算矩阵的行列式。" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", "[[3 4]\n", " [5 6]]\n", "Determinant:\n", "-2.0\n" ] } ], "source": [ "A = np.mat(\"3 4; 5 6\")\n", "print \"A:\\n\", A\n", "\n", "print \"Determinant:\\n\", np.linalg.det(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "###2.3 求解线性方程组\n", "矩阵可以对向量进行线性变换,这对应于数学中的线性方程组。solve函数可以求解形如Ax = b的线性方程组,其中A是矩阵,b是一维或二维的数组,x是未知变量。" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", "[[ 1 -2 1]\n", " [ 0 2 -8]\n", " [-4 5 9]]\n", "b:\n", "[ 0 8 -9]\n" ] } ], "source": [ "A = np.mat(\"1 -2 1; 0 2 -8; -4 5 9\")\n", "print \"A:\\n\", A\n", "b = np.array([0,8,-9])\n", "print \"b:\\n\", b" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Solution:\n", "[ 29. 16. 3.]\n", "Check:\n", "[[ True True True]]\n", "[[ 0. 8. -9.]]\n" ] } ], "source": [ "x = np.linalg.solve(A, b)\n", "print \"Solution:\\n\", x\n", "\n", "# check\n", "print \"Check:\\n\",b == np.dot(A, x)\n", "print np.dot(A, x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "###2.4 特征值和特征向量\n", "特征值(eigenvalue)即方程Ax = ax的根,是一个标量。其中,A是一个二维矩阵,x是一个一维向量。特征向量(eigenvector)是关于特征值的向量。在numpy.linalg模块中,eigvals函数可以计算矩阵的特征值,而eig函数可以返回一个包含特征值和对应特征向量的元组。" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", "[[ 3 -2]\n", " [ 1 0]]\n", "Eigenvalues:\n", "[ 2. 1.]\n", "Eigenvalues:\n", "[ 2. 1.]\n", "Eigenvectors:\n", "[[ 0.89442719 0.70710678]\n", " [ 0.4472136 0.70710678]]\n" ] } ], "source": [ "A = np.mat(\"3 -2; 1 0\")\n", "print \"A:\\n\", A\n", "\n", "print \"Eigenvalues:\\n\", np.linalg.eigvals(A)\n", "\n", "eigenvalues, eigenvectors = np.linalg.eig(A)\n", "print \"Eigenvalues:\\n\", eigenvalues\n", "print \"Eigenvectors:\\n\", eigenvectors" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Left:\n", "[[ 1.78885438]\n", " [ 0.89442719]]\n", "Right:\n", "[[ 1.78885438]\n", " [ 0.89442719]]\n", "\n", "Left:\n", "[[ 0.70710678]\n", " [ 0.70710678]]\n", "Right:\n", "[[ 0.70710678]\n", " [ 0.70710678]]\n", "\n" ] } ], "source": [ "# check\n", "# 计算 Ax = ax的左右两部分的值\n", "for i in range(len(eigenvalues)):\n", " print \"Left:\\n\", np.dot(A, eigenvectors[:,i])\n", " print \"Right:\\n\", np.dot(eigenvalues[i], eigenvectors[:,i])\n", " print" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "###2.5 奇异值分解\n", "SVD(Singular Value Decomposition,奇异值分解)是一种因子分解运算,将一个矩阵分解为3个矩阵的乘积。奇异值分解是特征值分解的一种推广。\n", "\n", "在numpy.linalg模块中的svd函数可以对矩阵进行奇异值分解。该函数返回3个矩阵——U、Sigma和V,其中U和V是正交矩阵,Sigma包含输入矩阵的奇异值。" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$M=U \\Sigma V^*$" ], "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import Latex\n", "Latex(r\"$M=U \\Sigma V^*$\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*号表示共轭转置" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", "[[ 4 11 14]\n", " [ 8 7 -2]]\n", "U:\n", "[[-0.9486833 -0.31622777]\n", " [-0.31622777 0.9486833 ]]\n", "Sigma:\n", "[ 18.97366596 9.48683298]\n", "V:\n", "[[-0.33333333 -0.66666667 -0.66666667]\n", " [ 0.66666667 0.33333333 -0.66666667]]\n" ] } ], "source": [ "A = np.mat(\"4 11 14;8 7 -2\")\n", "print \"A:\\n\", A\n", "\n", "U, Sigma, V = np.linalg.svd(A, full_matrices=False)\n", "print \"U:\\n\", U\n", "print \"Sigma:\\n\", Sigma\n", "print \"V:\\n\", V" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 18.97366596, 0. ],\n", " [ 0. , 9.48683298]])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Sigma矩阵是奇异值矩阵对角线上的值\n", "np.diag(Sigma)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Product:\n", "[[ 4. 11. 14.]\n", " [ 8. 7. -2.]]\n" ] } ], "source": [ "# check\n", "M = U*np.diag(Sigma)*V\n", "print \"Product:\\n\", M" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "###2.6 广义逆矩阵\n", "广义逆矩阵可以使用numpy.linalg模块中的pinv函数进行求解。inv函数只接受方阵作为输入矩阵,而pinv函数没有这个限制。" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", "[[ 4 11 14]\n", " [ 8 7 -2]]\n" ] } ], "source": [ "A = np.mat(\"4 11 14; 8 7 -2\")\n", "print \"A:\\n\", A" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Pseudo inverse:\n", "[[-0.00555556 0.07222222]\n", " [ 0.02222222 0.04444444]\n", " [ 0.05555556 -0.05555556]]\n" ] } ], "source": [ "pseudoinv = np.linalg.pinv(A)\n", "print \"Pseudo inverse:\\n\", pseudoinv" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Check pseudo inverse:\n", "[[ 1.00000000e+00 0.00000000e+00]\n", " [ 8.32667268e-17 1.00000000e+00]]\n" ] } ], "source": [ "# check\n", "print \"Check pseudo inverse:\\n\", A*pseudoinv" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "得到的结果并非严格意义上的单位矩阵,但是非常近似。" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A:\n", "[[ 0 1 2]\n", " [ 1 0 3]\n", " [ 4 -3 8]]\n", "inverse of A:\n", "[[-4.5 7. -1.5]\n", " [-2. 4. -1. ]\n", " [ 1.5 -2. 0.5]]\n", "check inverse:\n", "[[ 1. 0. 0.]\n", " [ 0. 1. 0.]\n", " [ 0. 0. 1.]]\n", "Pseudo inverse:\n", "[[-4.5 7. -1.5]\n", " [-2. 4. -1. ]\n", " [ 1.5 -2. 0.5]]\n", "Check pseudo inverse:\n", "[[ 1.00000000e+00 -2.66453526e-15 8.88178420e-16]\n", " [ 8.88178420e-16 1.00000000e+00 2.22044605e-16]\n", " [ 0.00000000e+00 3.55271368e-15 1.00000000e+00]]\n" ] } ], "source": [ "A = np.mat(\"0 1 2; 1 0 3; 4 -3 8\")\n", "print \"A:\\n\", A\n", "inverse = np.linalg.inv(A)\n", "print \"inverse of A:\\n\", inverse\n", "print \"check inverse:\\n\", inverse * A\n", "\n", "pseudoinv = np.linalg.pinv(A)\n", "print \"Pseudo inverse:\\n\", pseudoinv\n", "print \"Check pseudo inverse:\\n\", A*pseudoinv" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.5" } }, "nbformat": 4, "nbformat_minor": 0 }