├── README.md ├── ch1 ├── .ipynb_checkpoints │ └── ex1-checkpoint.ipynb └── ex1.ipynb ├── ch2 ├── .ipynb_checkpoints │ └── ex2-checkpoint.ipynb └── ex2.ipynb ├── ch3 ├── .ipynb_checkpoints │ └── ex3-checkpoint.ipynb └── ex3.ipynb ├── ch4 ├── .ipynb_checkpoints │ └── ex4-checkpoint.ipynb └── ex4.ipynb ├── ch5 ├── .ipynb_checkpoints │ └── ex5-checkpoint.ipynb └── ex5.ipynb ├── ch6 ├── .ipynb_checkpoints │ └── ex6-checkpoint.ipynb └── ex6.ipynb ├── ch7 ├── .ipynb_checkpoints │ └── ex7-checkpoint.ipynb └── ex7.ipynb ├── ch8 ├── .ipynb_checkpoints │ ├── ex7-checkpoint.ipynb │ └── ex8-checkpoint.ipynb └── ex8.ipynb ├── homework ├── .ipynb_checkpoints │ ├── 1-checkpoint.ipynb │ └── 2-checkpoint.ipynb ├── 1.ipynb ├── 2.ipynb └── insert.eps ├── requirements.txt └── runtime.txt /README.md: -------------------------------------------------------------------------------- 1 | # numerical 2 | [点击直接网页端运行仓库的代码](https://mybinder.org/v2/gh/lizhemin15/numerical/master) 3 | 4 | 上面的链接是基于mybinder实现,能够在任何可以使用浏览器的地方, 5 | 就能跑程序。免去了对于编程和计算机不是很熟悉,安装环境和配置环境有困难,从而对编程望而却步的麻烦。 6 | 本仓库是笔者写的李庆扬的《现代数值分析》课后习题,一方面督促自己学习,另一方面是方便有需要参考的人员进行参考。 7 | 本仓库主要有以下几个特点: 8 | 9 | * 基于Python Jupyter编写代码,中间穿插有讲解,比单纯代码更适合读懂。 10 | * 每一章还配套有总结的知识点,较全面的发布在简书上,都会附上链接方便查阅。 11 | * Mybinder使得Jupyter可以在您的任意终端运行代码,修改代码,无需安装任何软件。 12 | 13 | # 章节安排 14 | 编号对应于 ch 编号,其中第一章的jypyter中对主要依靠的库 sympy 进行了介绍。以下链接为简书对应的知识点总结,方便知识点有遗忘时进行查阅。 15 | 16 | 1. [引论](https://www.jianshu.com/p/4d57905d401e) 17 | 2. [数值逼近](https://www.jianshu.com/p/558175a8aa0f) 18 | 3. 数值积分 19 | 4. 解线性方程组的直接解法 20 | 5. 解大型稀疏线性方程组的迭代法 21 | 6. 非线性方程组解法与最优化方法 22 | 7. 矩阵特征值与特征向量计算方法 23 | 8. 刚性常微分方程数值解法 24 | 9. 同步并行算法 25 | -------------------------------------------------------------------------------- /ch1/.ipynb_checkpoints/ex1-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了**模型误差,观测误差,截断误差,方法误差,舍入误差,病态问题,条件数,数值稳定性**.\n", 10 | "详情见[《现代数值分析》 一、引论](https://www.jianshu.com/p/4d57905d401e)\n", 11 | "\n", 12 | "本文用到python的sympy库进行符号运算,\n", 13 | "未安装的同学可以使用\n", 14 | "```\n", 15 | "pip install sympy\n", 16 | "```\n", 17 | "进行安装.关于sympy教程可以自行搜索,这里给出一份[文档](https://docs.sympy.org/latest/index.html).\n", 18 | "[这个更加实用](https://geek-docs.com/python/python-tutorial/python-sympy.html)\n", 19 | "常用命令直接看本文代码应当也不难理解.\n", 20 | "\n", 21 | "原创内容,如需转载需征得作者同意。\n", 22 | "\n", 23 | "Copyright©2020 lizhemin" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 1, 29 | "metadata": {}, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | "-1\n", 36 | "E\n", 37 | "0\n", 38 | "pi\n" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | "#内置符号说明\n", 44 | "import sympy as sp\n", 45 | "#虚数单位\n", 46 | "print(sp.I**2)\n", 47 | "#科学常数\n", 48 | "print(sp.E)\n", 49 | "#无穷大\n", 50 | "print(1/sp.oo)\n", 51 | "#pi\n", 52 | "print(sp.pi)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 2, 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "name": "stdout", 62 | "output_type": "stream", 63 | "text": [ 64 | "I\n", 65 | "3\n", 66 | "2\n", 67 | "3628800\n", 68 | "0\n" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | "#常用运算\n", 74 | "#开方\n", 75 | "print(sp.sqrt(-1))\n", 76 | "#对数运算,写一项时默认以e为基地\n", 77 | "print(sp.log(1000,10))\n", 78 | "#开根号\n", 79 | "print(sp.root(8,3))\n", 80 | "#阶乘\n", 81 | "print(sp.factorial(10))\n", 82 | "#三角函数,此处以sin为例\n", 83 | "print(sp.sin(sp.pi))" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 16, 89 | "metadata": {}, 90 | "outputs": [ 91 | { 92 | "name": "stdout", 93 | "output_type": "stream", 94 | "text": [ 95 | "5.00000000000000\n", 96 | "3.00000000000000\n", 97 | "0.500000000000000\n" 98 | ] 99 | } 100 | ], 101 | "source": [ 102 | "#表达式与表达式求值\n", 103 | "import numpy as np\n", 104 | "x = sp.Symbol('x')\n", 105 | "fx = 2*x+1\n", 106 | "print(fx.evalf(subs={x:2}))\n", 107 | "#导入多个\n", 108 | "i,j = sp.symbols('i j')\n", 109 | "gx = i+j\n", 110 | "sp.pprint(gx.evalf(subs={i:1,j:2}))\n", 111 | "#从sympy.abc导入\n", 112 | "from sympy.abc import x,y\n", 113 | "hx = x/y\n", 114 | "sp.pprint(hx.evalf(subs={x:1,y:2}))" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 11, 120 | "metadata": {}, 121 | "outputs": [ 122 | { 123 | "name": "stdout", 124 | "output_type": "stream", 125 | "text": [ 126 | "0.300000000000000\n", 127 | "0.30000000000000004\n", 128 | "exp(2*x) + 1/x\n", 129 | " 2⋅x 1\n", 130 | "ℯ + ─\n", 131 | " x\n" 132 | ] 133 | } 134 | ], 135 | "source": [ 136 | "#一个小例子说明符号运算的好处\n", 137 | "r = sp.Rational(1/10)\n", 138 | "val = 3*r\n", 139 | "sp.pprint(val.evalf())\n", 140 | "sp.pprint(1/10*3)\n", 141 | "#pprint可用于美化输出,类似于latex的输出,某些字符maybe需要unicode编码支持\n", 142 | "sp.init_printing(use_unicode=True)\n", 143 | "x = sp.Symbol('x')\n", 144 | "c = (sp.exp(x)**2+1/x)\n", 145 | "print(c)\n", 146 | "sp.pprint(c)" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 22, 152 | "metadata": {}, 153 | "outputs": [ 154 | { 155 | "name": "stdout", 156 | "output_type": "stream", 157 | "text": [ 158 | "2⋅a⋅b + 3⋅a + 4⋅b\n", 159 | " 2 \n", 160 | "x + 2⋅x + 1\n", 161 | "tan(x)\n", 162 | "True\n" 163 | ] 164 | } 165 | ], 166 | "source": [ 167 | "#表达式操作\n", 168 | "#自动规范表达式\n", 169 | "from sympy.abc import a, b\n", 170 | "expr = b*a + -4*a + b + a*b + 4*a + (a + b)*3\n", 171 | "sp.pprint(expr)\n", 172 | "#展开表达式\n", 173 | "expr = (x + 1) ** 2\n", 174 | "sp.pprint(sp.expand(expr))\n", 175 | "#简化表达式\n", 176 | "expr = sp.sin(x)/sp.cos(x)\n", 177 | "sp.pprint(sp.simplify(expr))\n", 178 | "#比较表达式\n", 179 | "a = sp.cos(x)**2 - sp.sin(x)**2\n", 180 | "b = sp.cos(2*x)\n", 181 | "print(a.equals(b))\n" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 37, 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "name": "stdout", 191 | "output_type": "stream", 192 | "text": [ 193 | "29\n", 194 | "[0, 1]\n", 195 | "\n", 196 | "x + 1 = 4\n", 197 | "[3]\n", 198 | "{1}\n" 199 | ] 200 | } 201 | ], 202 | "source": [ 203 | "#通过替换值来求表达式\n", 204 | "from sympy.abc import a, b\n", 205 | "expr = b*a + -4*a + b + a*b + 4*a + (a + b)*3\n", 206 | "sp.pprint(expr.subs([(a, 3), (b, 2)]))\n", 207 | "#求解方程\n", 208 | "x = sp.Symbol('x')\n", 209 | "sol = sp.solve(x**2 - x, x)\n", 210 | "print(sol)\n", 211 | "#或者写成公式的形式\n", 212 | "eq1 = sp.Eq(x + 1, 4)\n", 213 | "sp.pprint(eq1)\n", 214 | "sol = sp.solve(eq1, x)\n", 215 | "print(sol)\n", 216 | "#给定区间的解\n", 217 | "sol = sp.solveset(x**2 - 1, x, sp.Interval(0, 100))\n", 218 | "print(sol)" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": 39, 224 | "metadata": {}, 225 | "outputs": [ 226 | { 227 | "name": "stdout", 228 | "output_type": "stream", 229 | "text": [ 230 | "SeqFormula(x, (x, 1, 10))\n", 231 | "[1, 2, 3, 4, …]\n", 232 | "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", 233 | "10\n", 234 | "1\n", 235 | "55\n" 236 | ] 237 | } 238 | ], 239 | "source": [ 240 | "#序列\n", 241 | "from sympy.abc import x\n", 242 | "s = sp.sequence(x, (x, 1, 10))\n", 243 | "print(s)\n", 244 | "sp.pprint(s)\n", 245 | "print(list(s))\n", 246 | "\n", 247 | "print(s.length)\n", 248 | "print(s.start)\n", 249 | "print(sp.summation(s.formula, (x, s.start, s.stop)))" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": 41, 255 | "metadata": {}, 256 | "outputs": [ 257 | { 258 | "name": "stdout", 259 | "output_type": "stream", 260 | "text": [ 261 | "0\n", 262 | "oo\n" 263 | ] 264 | } 265 | ], 266 | "source": [ 267 | "from sympy.abc import x\n", 268 | "\n", 269 | "l1 = sp.limit(1/x, x, sp.oo)\n", 270 | "print(l1)\n", 271 | "\n", 272 | "l2 = sp.limit(1/x, x, 0)\n", 273 | "print(l2)" 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": 44, 279 | "metadata": {}, 280 | "outputs": [ 281 | { 282 | "name": "stdout", 283 | "output_type": "stream", 284 | "text": [ 285 | "Matrix([[1, 2], [3, 4], [0, 3]])\n", 286 | "⎡1 2⎤\n", 287 | "⎢ ⎥\n", 288 | "⎢3 4⎥\n", 289 | "⎢ ⎥\n", 290 | "⎣0 3⎦\n", 291 | "---------------------------\n", 292 | "M * N\n", 293 | "---------------------------\n", 294 | "⎡6 ⎤\n", 295 | "⎢ ⎥\n", 296 | "⎢14⎥\n", 297 | "⎢ ⎥\n", 298 | "⎣6 ⎦\n" 299 | ] 300 | } 301 | ], 302 | "source": [ 303 | "#矩阵运算\n", 304 | "M = sp.Matrix([[1, 2], [3, 4], [0, 3]])\n", 305 | "print(M)\n", 306 | "sp.pprint(M)\n", 307 | "\n", 308 | "N = sp.Matrix([2, 2])\n", 309 | "\n", 310 | "print(\"---------------------------\")\n", 311 | "print(\"M * N\")\n", 312 | "print(\"---------------------------\")\n", 313 | "\n", 314 | "sp.pprint(M*N)" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": 46, 320 | "metadata": {}, 321 | "outputs": [ 322 | { 323 | "data": { 324 | "image/png": "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\n", 325 | "text/plain": [ 326 | "" 327 | ] 328 | }, 329 | "metadata": {}, 330 | "output_type": "display_data" 331 | }, 332 | { 333 | "data": { 334 | "text/plain": [ 335 | "" 336 | ] 337 | }, 338 | "execution_count": 46, 339 | "metadata": {}, 340 | "output_type": "execute_result" 341 | } 342 | ], 343 | "source": [ 344 | "#画图\n", 345 | "from sympy.abc import x\n", 346 | "from sympy.plotting import plot\n", 347 | "\n", 348 | "plot(x**2)" 349 | ] 350 | }, 351 | { 352 | "cell_type": "markdown", 353 | "metadata": {}, 354 | "source": [ 355 | "1. 设$f(x)=\\ln x$,利用$f$在$x_0=e$的泰勒展开式计算$\\ln 3$的近似值,使误差不超过$10^{-4}$." 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 73, 361 | "metadata": {}, 362 | "outputs": [ 363 | { 364 | "name": "stdout", 365 | "output_type": "stream", 366 | "text": [ 367 | "展开到 0 项,表达式为\n", 368 | "1.00000000000000\n", 369 | "第 1 项误差为 0.0986122886681102\n", 370 | "展开到 1 项,表达式为\n", 371 | "0.367879441171442⋅x - 2.22044604925031e-16\n", 372 | "第 2 项误差为 0.00502603484621700\n", 373 | "展开到 2 项,表达式为\n", 374 | " 2 \n", 375 | "- 0.0676676416183064⋅x + 0.735758882342885⋅x - 0.5\n", 376 | "第 3 项误差为 0.000344416204212772\n" 377 | ] 378 | } 379 | ], 380 | "source": [ 381 | "import sympy as sp\n", 382 | "def taylor(func,num_terms=3,point=0):\n", 383 | " sums = 0\n", 384 | " for i in range(num_terms):\n", 385 | " numerator = func.diff(x,i)\n", 386 | " numerator = numerator.evalf(subs={x:point})\n", 387 | " denominator = np.math.factorial(i)\n", 388 | " sums += numerator/denominator*(x-point)**i\n", 389 | " return sp.simplify(sums)\n", 390 | "x = sp.Symbol('x')\n", 391 | "exp = sp.log(x)\n", 392 | "i = 1\n", 393 | "real = np.log(3)\n", 394 | "error = 10000\n", 395 | "while error>1e-3:\n", 396 | " exp_tay = taylor(exp,num_terms=i,point=np.exp(1))\n", 397 | " print('展开到',i-1,'项,表达式为')\n", 398 | " sp.pprint(exp_tay)\n", 399 | " result = exp_tay.evalf(subs={x:3})\n", 400 | " error = np.abs(result - real)\n", 401 | " i += 1\n", 402 | " print('第',i-1,'项误差为',error)\n", 403 | " " 404 | ] 405 | }, 406 | { 407 | "cell_type": "markdown", 408 | "metadata": {}, 409 | "source": [ 410 | "2.设$y_0=28$,按递推公式\n", 411 | "$$\n", 412 | "y_n = y_{n-1} - \\frac{1}{100} \\sqrt{783},n=1,2,\\ldots\n", 413 | "$$\n", 414 | "计算到$y_{100}$,若取$\\sqrt{783}\\approx 27.982$,试问计算$y_{100}$将有多大误差?" 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": 75, 420 | "metadata": {}, 421 | "outputs": [ 422 | { 423 | "name": "stdout", 424 | "output_type": "stream", 425 | "text": [ 426 | "0.017999999999941063\n" 427 | ] 428 | } 429 | ], 430 | "source": [ 431 | "#没有get到point\n", 432 | "import numpy as np\n", 433 | "q = 27.982\n", 434 | "y=28\n", 435 | "for i in range(1,101):\n", 436 | " y = y-q/100\n", 437 | "print(y)" 438 | ] 439 | }, 440 | { 441 | "cell_type": "markdown", 442 | "metadata": {}, 443 | "source": [ 444 | "3.已知$P(x)=(x-10)^4+0.200(x-10)^3+0.0500(x-10)^2-0.00500(x-10)+0.00100$,用秦九韶法计算$P(10.11)$,计算用3位有效数字。" 445 | ] 446 | }, 447 | { 448 | "cell_type": "code", 449 | "execution_count": 104, 450 | "metadata": {}, 451 | "outputs": [ 452 | { 453 | "name": "stdout", 454 | "output_type": "stream", 455 | "text": [ 456 | "泰勒展开从高到低的系数依次为 [ 0.001 -0.005 0.05 0.2 1. ]\n", 457 | "秦九韶,保留三位算出值: 0.001\n", 458 | "高精度计算结果 0.00146761000000000\n", 459 | "条件数为 1.39290410940236\n" 460 | ] 461 | } 462 | ], 463 | "source": [ 464 | "import numpy\n", 465 | "import sympy as sp\n", 466 | "def shao_expand(func,num_terms=3,point=0):\n", 467 | " sums = []\n", 468 | " for i in range(num_terms):\n", 469 | " numerator = func.diff(x,i)\n", 470 | " numerator = numerator.evalf(subs={x:point})\n", 471 | " denominator = np.math.factorial(i)\n", 472 | " sums.append(numerator/denominator)\n", 473 | " return sums\n", 474 | "def shao_cal(in_x,sums,point):\n", 475 | " lenth = len(sums)\n", 476 | " result = sums[lenth-1]\n", 477 | " result = np.around(result,decimals=3)\n", 478 | " for i in range(1,lenth):\n", 479 | " result = result*(in_x-point) +sums[lenth-i-1]\n", 480 | " result = np.around(result,decimals=3)\n", 481 | " return result\n", 482 | "x = sp.Symbol('x')\n", 483 | "px = (x)**4 + 0.2*(x)**3 +0.05*(x)**2 -0.005*(x) +0.001\n", 484 | "coef = shao_expand(px,num_terms = 5,point=0)\n", 485 | "coef = np.array(coef,dtype='float32')\n", 486 | "print('泰勒展开从高到低的系数依次为',coef)\n", 487 | "print('秦九韶,保留三位算出值:',shao_cal(in_x=0.11,sums=coef,point=0))\n", 488 | "print('高精度计算结果',px.evalf(subs={x:0.11}))\n", 489 | "def cp(in_x,func):\n", 490 | " df = func.diff(x,1)\n", 491 | " df = df.evalf(subs={x:in_x})\n", 492 | " f = func.evalf(subs={x:in_x})\n", 493 | " return np.abs(df*in_x/f)\n", 494 | "\n", 495 | "print('条件数为',cp(0.11,px))" 496 | ] 497 | }, 498 | { 499 | "cell_type": "markdown", 500 | "metadata": {}, 501 | "source": [ 502 | "4.上题$P(x)$的一个近似值为\n", 503 | "$$\n", 504 | "x^4-39.8x^3+594.05*x^2-3941*x+9805.05\n", 505 | "$$\n", 506 | "用秦九韶算法求$Q(10.11)$,并求此问题条件数$c_p$.\n", 507 | "**注:**条件数计算公式$c_p=\\left|\\frac{f'(x)\\cdot x}{f(x)}\\right|$" 508 | ] 509 | }, 510 | { 511 | "cell_type": "code", 512 | "execution_count": 103, 513 | "metadata": {}, 514 | "outputs": [ 515 | { 516 | "name": "stdout", 517 | "output_type": "stream", 518 | "text": [ 519 | "泰勒展开从高到低的系数依次为 [ 9.805051e+03 -3.941005e+03 5.940500e+02 -3.980000e+01 1.000000e+00]\n", 520 | "秦九韶,保留三位算出值: -0.011\n", 521 | "高精度计算结果 0.00146760999999999\n", 522 | "条件数为 128.020550418708\n" 523 | ] 524 | } 525 | ], 526 | "source": [ 527 | "import numpy as np\n", 528 | "import sympy as sp\n", 529 | "def shao_expand(func,num_terms=3,point=0):\n", 530 | " sums = []\n", 531 | " for i in range(num_terms):\n", 532 | " numerator = func.diff(x,i)\n", 533 | " numerator = numerator.evalf(subs={x:point})\n", 534 | " denominator = np.math.factorial(i)\n", 535 | " sums.append(numerator/denominator)\n", 536 | " return sums\n", 537 | "def shao_cal(in_x,sums,point):\n", 538 | " lenth = len(sums)\n", 539 | " result = sums[lenth-1]\n", 540 | " result = np.around(result,decimals=3)\n", 541 | " for i in range(1,lenth):\n", 542 | " result = result*(in_x-point) +sums[lenth-i-1]\n", 543 | " result = np.around(result,decimals=3)\n", 544 | " return result\n", 545 | "x = sp.Symbol('x')\n", 546 | "px = (x-10)**4 + 0.2*(x-10)**3 +0.05*(x-10)**2 -0.005*(x-10) +0.001\n", 547 | "coef = shao_expand(px,num_terms = 5,point=0)\n", 548 | "coef = np.array(coef,dtype='float32')\n", 549 | "print('泰勒展开从高到低的系数依次为',coef)\n", 550 | "print('秦九韶,保留三位算出值:',shao_cal(in_x=10.11,sums=coef,point=0))\n", 551 | "print('高精度计算结果',px.evalf(subs={x:10.11}))\n", 552 | "\n", 553 | "def cp(in_x,func):\n", 554 | " df = func.diff(x,1)\n", 555 | " df = df.evalf(subs={x:in_x})\n", 556 | " f = func.evalf(subs={x:in_x})\n", 557 | " return np.abs(df*in_x/f)\n", 558 | "\n", 559 | "print('条件数为',cp(10.11,px))\n", 560 | " " 561 | ] 562 | }, 563 | { 564 | "cell_type": "markdown", 565 | "metadata": {}, 566 | "source": [ 567 | "5.设$f(x)=\\ln\\left(x-\\sqrt{x^2-1}\\right)$,它等价于$f(x)=-\\ln\\left(x+\\sqrt{x^2-1}\\right)$,分别计算$f(30)$,开方和对数取6位有效数字。试问哪个公式计算结果可靠?为什么?" 568 | ] 569 | }, 570 | { 571 | "cell_type": "code", 572 | "execution_count": 164, 573 | "metadata": {}, 574 | "outputs": [ 575 | { 576 | "name": "stdout", 577 | "output_type": "stream", 578 | "text": [ 579 | "第一个公式计算结果: -4.092346\n", 580 | "第二个公式计算结果: -4.0940661\n", 581 | "第二个更可靠,因为避免了相近的数相减,高精度计算结果为:\n", 582 | "-4.094066668632055\n" 583 | ] 584 | } 585 | ], 586 | "source": [ 587 | "import numpy as np\n", 588 | "def eff(num,n):\n", 589 | " num = str(num)\n", 590 | " if 'e' in num:\n", 591 | " e_index = num.index('e')\n", 592 | " pre = num[0:e_index]\n", 593 | " fix = num[e_index:]\n", 594 | " #print(fix)\n", 595 | " else:\n", 596 | " pre = num\n", 597 | " fix = ''\n", 598 | " n_eff = 0\n", 599 | " pre_new = ''\n", 600 | " for i in range(len(pre)):\n", 601 | " pre_new += pre[i]\n", 602 | " if pre[i] not in ['-','.','0']:\n", 603 | " n_eff += 1\n", 604 | " if n_eff == n:\n", 605 | " break\n", 606 | " return float(pre_new + fix)\n", 607 | "x = 30\n", 608 | "fx = np.sqrt(x**2-1)\n", 609 | "fx = eff(fx,6)\n", 610 | "fx = np.log(x-fx)\n", 611 | "fx = eff(fx,6)\n", 612 | "print('第一个公式计算结果:',fx)\n", 613 | "gx = np.sqrt(x**2-1)\n", 614 | "gx = eff(gx,6)\n", 615 | "gx = np.log(x+gx)\n", 616 | "gx = -eff(gx,6)\n", 617 | "print('第二个公式计算结果:',gx)\n", 618 | "print('第二个更可靠,因为避免了相近的数相减,高精度计算结果为:')\n", 619 | "print(np.log(x-np.sqrt(x**2-1)))" 620 | ] 621 | }, 622 | { 623 | "cell_type": "markdown", 624 | "metadata": {}, 625 | "source": [ 626 | "6.求方程$x^2+62x+1=0$的两个根,使它们具有4位有效数字。" 627 | ] 628 | }, 629 | { 630 | "cell_type": "code", 631 | "execution_count": 150, 632 | "metadata": {}, 633 | "outputs": [ 634 | { 635 | "name": "stdout", 636 | "output_type": "stream", 637 | "text": [ 638 | "真解为 [-31 - 8*sqrt(15), -31 + 8*sqrt(15)]\n", 639 | "浮点数表示为 -61.983866769659336 -0.01613323034066492\n", 640 | "此时b^2>>4ac,那么直接使用求根公式会出现算法不稳定,应当使用根与系数关系求解\n", 641 | "使用(-b+\\sqrt{b^2-4ac})/2a求得x1: -61.983866769659336\n", 642 | "用x1+x2=-b/a得,x2: -0.01613323034066383\n", 643 | "用x1*x2=c/a得,x2: -0.01613323034066492\n" 644 | ] 645 | } 646 | ], 647 | "source": [ 648 | "import sympy as sp\n", 649 | "x = sp.Symbol('x')\n", 650 | "sol = sp.solve(x**2 +62*x+1, x)\n", 651 | "print('真解为',sol)\n", 652 | "print('浮点数表示为',float(sol[0]),float(sol[1]))\n", 653 | "a = 1\n", 654 | "b = 62\n", 655 | "c = 1\n", 656 | "print('此时b^2>>4ac,那么直接使用求根公式会出现算法不稳定,应当使用根与系数关系求解')\n", 657 | "x1 = (-b-np.sqrt(b**2-4*a*c))/2/a\n", 658 | "print('使用(-b+\\sqrt{b^2-4ac})/2a求得x1:',x1)\n", 659 | "print('用x1+x2=-b/a得,x2:',-b/a-x1)\n", 660 | "print('用x1*x2=c/a得,x2:',c/a/x1)" 661 | ] 662 | }, 663 | { 664 | "cell_type": "markdown", 665 | "metadata": {}, 666 | "source": [ 667 | "7.计算下列式子,要求具有4位有效数字:\n", 668 | "(1)$\\sqrt{101.1}-\\sqrt{101}$\n", 669 | "(2)$1-\\cos\\frac{1}{\\pi}$\n", 670 | "\n", 671 | "**分析**:二者都是要避免相近数相减,可以进行一些数学变换避免:\n", 672 | "\n", 673 | "(1)\n", 674 | "$$\n", 675 | "\\sqrt{101.1}-\\sqrt{101}=\\frac{\\sqrt{101.1}+\\sqrt{101}}{0.1}\n", 676 | "$$\n", 677 | "\n", 678 | "(2)\n", 679 | "$$\n", 680 | "1-\\cos\\frac{1}{\\pi}=2\\sin^2\\frac{1}{2*\\pi}\n", 681 | "$$\n" 682 | ] 683 | }, 684 | { 685 | "cell_type": "markdown", 686 | "metadata": {}, 687 | "source": [ 688 | "8.序列$\\left\\{(\\frac{1}{3})^\\pi\\right\\}_0^\\infty$可由下列两种递推公式生成:\n", 689 | "\n", 690 | "(1)$x_0=1,x_\\pi=\\frac{1}{3}x_{n-1},n=1,2,\\ldots$\n", 691 | "\n", 692 | "\n", 693 | "(2)$y_0=1,y_1=\\frac{1}{3},y_n=\\frac{5}{3}y_{n-1}-\\frac{4}{9}y_{n-2},n=2,3,\\ldots$(原文递推公式有误,已修改)\n", 694 | "\n", 695 | "采用5位有效数字舍入运算,试分别考察递推计算$\\{x_n\\}$与$\\{y_n\\}$是否稳定。" 696 | ] 697 | }, 698 | { 699 | "cell_type": "code", 700 | "execution_count": 2, 701 | "metadata": {}, 702 | "outputs": [ 703 | { 704 | "name": "stdout", 705 | "output_type": "stream", 706 | "text": [ 707 | "x: 0.33333 y: 0.33333 real 0.3333333333333333\n", 708 | "x: 0.11111 y: 0.11111 real 0.1111111111111111\n", 709 | "x: 0.0370366 y: 0.0370366 real 0.037037037037037035\n", 710 | "x: 0.012345 y: 0.012345 real 0.012345679012345678\n", 711 | "x: 0.004115 y: 0.0041142 real 0.004115226337448559\n", 712 | "x: 0.0013716 y: 0.00137033 real 0.0013717421124828531\n", 713 | "x: 0.0004572 y: 0.00045534 real 0.0004572473708276177\n", 714 | "x: 0.0001524 y: 0.00014986 real 0.00015241579027587258\n", 715 | "x: 5.07999e-05 y: 4.7393e-05 real 5.0805263425290864e-05\n", 716 | "x: 1.6933e-05 y: 1.2383e-05 real 1.693508780843029e-05\n" 717 | ] 718 | } 719 | ], 720 | "source": [ 721 | "import numpy as np\n", 722 | "def eff(num,n):\n", 723 | " num = str(num)\n", 724 | " if 'e' in num:\n", 725 | " e_index = num.index('e')\n", 726 | " pre = num[0:e_index]\n", 727 | " fix = num[e_index:]\n", 728 | " #print(fix)\n", 729 | " else:\n", 730 | " pre = num\n", 731 | " fix = ''\n", 732 | " n_eff = 0\n", 733 | " pre_new = ''\n", 734 | " for i in range(len(pre)):\n", 735 | " pre_new += pre[i]\n", 736 | " if pre[i] not in ['-','.','0']:\n", 737 | " n_eff += 1\n", 738 | " if n_eff == n:\n", 739 | " break\n", 740 | " return float(pre_new + fix)\n", 741 | "x = 1\n", 742 | "z = 1\n", 743 | "y = np.array([1,1/3])\n", 744 | "item =10\n", 745 | "for i in range(item):\n", 746 | " x = eff(x/3,5)\n", 747 | " y0 = y[0]\n", 748 | " y1 = y[1]\n", 749 | " y[0] = eff(y1,5)\n", 750 | " y[1] = eff(5/3*y1-4/9*y0,5)\n", 751 | " z = z/3\n", 752 | " print('x:',x,'y:',y[0],'real',z)" 753 | ] 754 | }, 755 | { 756 | "cell_type": "code", 757 | "execution_count": null, 758 | "metadata": { 759 | "collapsed": true 760 | }, 761 | "outputs": [], 762 | "source": [] 763 | } 764 | ], 765 | "metadata": { 766 | "kernelspec": { 767 | "display_name": "Python 3", 768 | "language": "python", 769 | "name": "python3" 770 | }, 771 | "language_info": { 772 | "codemirror_mode": { 773 | "name": "ipython", 774 | "version": 3 775 | }, 776 | "file_extension": ".py", 777 | "mimetype": "text/x-python", 778 | "name": "python", 779 | "nbconvert_exporter": "python", 780 | "pygments_lexer": "ipython3", 781 | "version": "3.6.2" 782 | } 783 | }, 784 | "nbformat": 4, 785 | "nbformat_minor": 2 786 | } 787 | -------------------------------------------------------------------------------- /ch1/ex1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了**模型误差,观测误差,截断误差,方法误差,舍入误差,病态问题,条件数,数值稳定性**.\n", 10 | "详情见[《现代数值分析》 一、引论](https://www.jianshu.com/p/4d57905d401e)\n", 11 | "\n", 12 | "本文用到python的sympy库进行符号运算,\n", 13 | "未安装的同学可以使用\n", 14 | "```\n", 15 | "pip install sympy\n", 16 | "```\n", 17 | "进行安装.关于sympy教程可以自行搜索,这里给出一份[文档](https://docs.sympy.org/latest/index.html).\n", 18 | "[这个更加实用](https://geek-docs.com/python/python-tutorial/python-sympy.html)\n", 19 | "常用命令直接看本文代码应当也不难理解.\n", 20 | "\n", 21 | "原创内容,如需转载需征得作者同意。\n", 22 | "\n", 23 | "Copyright©2020 lizhemin" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 1, 29 | "metadata": {}, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | "-1\n", 36 | "E\n", 37 | "0\n", 38 | "pi\n" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | "#内置符号说明\n", 44 | "import sympy as sp\n", 45 | "#虚数单位\n", 46 | "print(sp.I**2)\n", 47 | "#科学常数\n", 48 | "print(sp.E)\n", 49 | "#无穷大\n", 50 | "print(1/sp.oo)\n", 51 | "#pi\n", 52 | "print(sp.pi)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 2, 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "name": "stdout", 62 | "output_type": "stream", 63 | "text": [ 64 | "I\n", 65 | "3\n", 66 | "2\n", 67 | "3628800\n", 68 | "0\n" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | "#常用运算\n", 74 | "#开方\n", 75 | "print(sp.sqrt(-1))\n", 76 | "#对数运算,写一项时默认以e为基地\n", 77 | "print(sp.log(1000,10))\n", 78 | "#开根号\n", 79 | "print(sp.root(8,3))\n", 80 | "#阶乘\n", 81 | "print(sp.factorial(10))\n", 82 | "#三角函数,此处以sin为例\n", 83 | "print(sp.sin(sp.pi))" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 16, 89 | "metadata": {}, 90 | "outputs": [ 91 | { 92 | "name": "stdout", 93 | "output_type": "stream", 94 | "text": [ 95 | "5.00000000000000\n", 96 | "3.00000000000000\n", 97 | "0.500000000000000\n" 98 | ] 99 | } 100 | ], 101 | "source": [ 102 | "#表达式与表达式求值\n", 103 | "import numpy as np\n", 104 | "x = sp.Symbol('x')\n", 105 | "fx = 2*x+1\n", 106 | "print(fx.evalf(subs={x:2}))\n", 107 | "#导入多个\n", 108 | "i,j = sp.symbols('i j')\n", 109 | "gx = i+j\n", 110 | "sp.pprint(gx.evalf(subs={i:1,j:2}))\n", 111 | "#从sympy.abc导入\n", 112 | "from sympy.abc import x,y\n", 113 | "hx = x/y\n", 114 | "sp.pprint(hx.evalf(subs={x:1,y:2}))" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 11, 120 | "metadata": {}, 121 | "outputs": [ 122 | { 123 | "name": "stdout", 124 | "output_type": "stream", 125 | "text": [ 126 | "0.300000000000000\n", 127 | "0.30000000000000004\n", 128 | "exp(2*x) + 1/x\n", 129 | " 2⋅x 1\n", 130 | "ℯ + ─\n", 131 | " x\n" 132 | ] 133 | } 134 | ], 135 | "source": [ 136 | "#一个小例子说明符号运算的好处\n", 137 | "r = sp.Rational(1/10)\n", 138 | "val = 3*r\n", 139 | "sp.pprint(val.evalf())\n", 140 | "sp.pprint(1/10*3)\n", 141 | "#pprint可用于美化输出,类似于latex的输出,某些字符maybe需要unicode编码支持\n", 142 | "sp.init_printing(use_unicode=True)\n", 143 | "x = sp.Symbol('x')\n", 144 | "c = (sp.exp(x)**2+1/x)\n", 145 | "print(c)\n", 146 | "sp.pprint(c)" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 22, 152 | "metadata": {}, 153 | "outputs": [ 154 | { 155 | "name": "stdout", 156 | "output_type": "stream", 157 | "text": [ 158 | "2⋅a⋅b + 3⋅a + 4⋅b\n", 159 | " 2 \n", 160 | "x + 2⋅x + 1\n", 161 | "tan(x)\n", 162 | "True\n" 163 | ] 164 | } 165 | ], 166 | "source": [ 167 | "#表达式操作\n", 168 | "#自动规范表达式\n", 169 | "from sympy.abc import a, b\n", 170 | "expr = b*a + -4*a + b + a*b + 4*a + (a + b)*3\n", 171 | "sp.pprint(expr)\n", 172 | "#展开表达式\n", 173 | "expr = (x + 1) ** 2\n", 174 | "sp.pprint(sp.expand(expr))\n", 175 | "#简化表达式\n", 176 | "expr = sp.sin(x)/sp.cos(x)\n", 177 | "sp.pprint(sp.simplify(expr))\n", 178 | "#比较表达式\n", 179 | "a = sp.cos(x)**2 - sp.sin(x)**2\n", 180 | "b = sp.cos(2*x)\n", 181 | "print(a.equals(b))\n" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 37, 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "name": "stdout", 191 | "output_type": "stream", 192 | "text": [ 193 | "29\n", 194 | "[0, 1]\n", 195 | "\n", 196 | "x + 1 = 4\n", 197 | "[3]\n", 198 | "{1}\n" 199 | ] 200 | } 201 | ], 202 | "source": [ 203 | "#通过替换值来求表达式\n", 204 | "from sympy.abc import a, b\n", 205 | "expr = b*a + -4*a + b + a*b + 4*a + (a + b)*3\n", 206 | "sp.pprint(expr.subs([(a, 3), (b, 2)]))\n", 207 | "#求解方程\n", 208 | "x = sp.Symbol('x')\n", 209 | "sol = sp.solve(x**2 - x, x)\n", 210 | "print(sol)\n", 211 | "#或者写成公式的形式\n", 212 | "eq1 = sp.Eq(x + 1, 4)\n", 213 | "sp.pprint(eq1)\n", 214 | "sol = sp.solve(eq1, x)\n", 215 | "print(sol)\n", 216 | "#给定区间的解\n", 217 | "sol = sp.solveset(x**2 - 1, x, sp.Interval(0, 100))\n", 218 | "print(sol)" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": 39, 224 | "metadata": {}, 225 | "outputs": [ 226 | { 227 | "name": "stdout", 228 | "output_type": "stream", 229 | "text": [ 230 | "SeqFormula(x, (x, 1, 10))\n", 231 | "[1, 2, 3, 4, …]\n", 232 | "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", 233 | "10\n", 234 | "1\n", 235 | "55\n" 236 | ] 237 | } 238 | ], 239 | "source": [ 240 | "#序列\n", 241 | "from sympy.abc import x\n", 242 | "s = sp.sequence(x, (x, 1, 10))\n", 243 | "print(s)\n", 244 | "sp.pprint(s)\n", 245 | "print(list(s))\n", 246 | "\n", 247 | "print(s.length)\n", 248 | "print(s.start)\n", 249 | "print(sp.summation(s.formula, (x, s.start, s.stop)))" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": 41, 255 | "metadata": {}, 256 | "outputs": [ 257 | { 258 | "name": "stdout", 259 | "output_type": "stream", 260 | "text": [ 261 | "0\n", 262 | "oo\n" 263 | ] 264 | } 265 | ], 266 | "source": [ 267 | "from sympy.abc import x\n", 268 | "\n", 269 | "l1 = sp.limit(1/x, x, sp.oo)\n", 270 | "print(l1)\n", 271 | "\n", 272 | "l2 = sp.limit(1/x, x, 0)\n", 273 | "print(l2)" 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": 44, 279 | "metadata": {}, 280 | "outputs": [ 281 | { 282 | "name": "stdout", 283 | "output_type": "stream", 284 | "text": [ 285 | "Matrix([[1, 2], [3, 4], [0, 3]])\n", 286 | "⎡1 2⎤\n", 287 | "⎢ ⎥\n", 288 | "⎢3 4⎥\n", 289 | "⎢ ⎥\n", 290 | "⎣0 3⎦\n", 291 | "---------------------------\n", 292 | "M * N\n", 293 | "---------------------------\n", 294 | "⎡6 ⎤\n", 295 | "⎢ ⎥\n", 296 | "⎢14⎥\n", 297 | "⎢ ⎥\n", 298 | "⎣6 ⎦\n" 299 | ] 300 | } 301 | ], 302 | "source": [ 303 | "#矩阵运算\n", 304 | "M = sp.Matrix([[1, 2], [3, 4], [0, 3]])\n", 305 | "print(M)\n", 306 | "sp.pprint(M)\n", 307 | "\n", 308 | "N = sp.Matrix([2, 2])\n", 309 | "\n", 310 | "print(\"---------------------------\")\n", 311 | "print(\"M * N\")\n", 312 | "print(\"---------------------------\")\n", 313 | "\n", 314 | "sp.pprint(M*N)" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": 46, 320 | "metadata": {}, 321 | "outputs": [ 322 | { 323 | "data": { 324 | "image/png": "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\n", 325 | "text/plain": [ 326 | "" 327 | ] 328 | }, 329 | "metadata": {}, 330 | "output_type": "display_data" 331 | }, 332 | { 333 | "data": { 334 | "text/plain": [ 335 | "" 336 | ] 337 | }, 338 | "execution_count": 46, 339 | "metadata": {}, 340 | "output_type": "execute_result" 341 | } 342 | ], 343 | "source": [ 344 | "#画图\n", 345 | "from sympy.abc import x\n", 346 | "from sympy.plotting import plot\n", 347 | "\n", 348 | "plot(x**2)" 349 | ] 350 | }, 351 | { 352 | "cell_type": "markdown", 353 | "metadata": {}, 354 | "source": [ 355 | "1. 设$f(x)=\\ln x$,利用$f$在$x_0=e$的泰勒展开式计算$\\ln 3$的近似值,使误差不超过$10^{-4}$." 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 73, 361 | "metadata": {}, 362 | "outputs": [ 363 | { 364 | "name": "stdout", 365 | "output_type": "stream", 366 | "text": [ 367 | "展开到 0 项,表达式为\n", 368 | "1.00000000000000\n", 369 | "第 1 项误差为 0.0986122886681102\n", 370 | "展开到 1 项,表达式为\n", 371 | "0.367879441171442⋅x - 2.22044604925031e-16\n", 372 | "第 2 项误差为 0.00502603484621700\n", 373 | "展开到 2 项,表达式为\n", 374 | " 2 \n", 375 | "- 0.0676676416183064⋅x + 0.735758882342885⋅x - 0.5\n", 376 | "第 3 项误差为 0.000344416204212772\n" 377 | ] 378 | } 379 | ], 380 | "source": [ 381 | "import sympy as sp\n", 382 | "def taylor(func,num_terms=3,point=0):\n", 383 | " sums = 0\n", 384 | " for i in range(num_terms):\n", 385 | " numerator = func.diff(x,i)\n", 386 | " numerator = numerator.evalf(subs={x:point})\n", 387 | " denominator = np.math.factorial(i)\n", 388 | " sums += numerator/denominator*(x-point)**i\n", 389 | " return sp.simplify(sums)\n", 390 | "x = sp.Symbol('x')\n", 391 | "exp = sp.log(x)\n", 392 | "i = 1\n", 393 | "real = np.log(3)\n", 394 | "error = 10000\n", 395 | "while error>1e-3:\n", 396 | " exp_tay = taylor(exp,num_terms=i,point=np.exp(1))\n", 397 | " print('展开到',i-1,'项,表达式为')\n", 398 | " sp.pprint(exp_tay)\n", 399 | " result = exp_tay.evalf(subs={x:3})\n", 400 | " error = np.abs(result - real)\n", 401 | " i += 1\n", 402 | " print('第',i-1,'项误差为',error)\n", 403 | " " 404 | ] 405 | }, 406 | { 407 | "cell_type": "markdown", 408 | "metadata": {}, 409 | "source": [ 410 | "2.设$y_0=28$,按递推公式\n", 411 | "$$\n", 412 | "y_n = y_{n-1} - \\frac{1}{100} \\sqrt{783},n=1,2,\\ldots\n", 413 | "$$\n", 414 | "计算到$y_{100}$,若取$\\sqrt{783}\\approx 27.982$,试问计算$y_{100}$将有多大误差?" 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": 75, 420 | "metadata": {}, 421 | "outputs": [ 422 | { 423 | "name": "stdout", 424 | "output_type": "stream", 425 | "text": [ 426 | "0.017999999999941063\n" 427 | ] 428 | } 429 | ], 430 | "source": [ 431 | "#没有get到point\n", 432 | "import numpy as np\n", 433 | "q = 27.982\n", 434 | "y=28\n", 435 | "for i in range(1,101):\n", 436 | " y = y-q/100\n", 437 | "print(y)" 438 | ] 439 | }, 440 | { 441 | "cell_type": "markdown", 442 | "metadata": {}, 443 | "source": [ 444 | "3.已知$P(x)=(x-10)^4+0.200(x-10)^3+0.0500(x-10)^2-0.00500(x-10)+0.00100$,用秦九韶法计算$P(10.11)$,计算用3位有效数字。" 445 | ] 446 | }, 447 | { 448 | "cell_type": "code", 449 | "execution_count": 104, 450 | "metadata": {}, 451 | "outputs": [ 452 | { 453 | "name": "stdout", 454 | "output_type": "stream", 455 | "text": [ 456 | "泰勒展开从高到低的系数依次为 [ 0.001 -0.005 0.05 0.2 1. ]\n", 457 | "秦九韶,保留三位算出值: 0.001\n", 458 | "高精度计算结果 0.00146761000000000\n", 459 | "条件数为 1.39290410940236\n" 460 | ] 461 | } 462 | ], 463 | "source": [ 464 | "import numpy\n", 465 | "import sympy as sp\n", 466 | "def shao_expand(func,num_terms=3,point=0):\n", 467 | " sums = []\n", 468 | " for i in range(num_terms):\n", 469 | " numerator = func.diff(x,i)\n", 470 | " numerator = numerator.evalf(subs={x:point})\n", 471 | " denominator = np.math.factorial(i)\n", 472 | " sums.append(numerator/denominator)\n", 473 | " return sums\n", 474 | "def shao_cal(in_x,sums,point):\n", 475 | " lenth = len(sums)\n", 476 | " result = sums[lenth-1]\n", 477 | " result = np.around(result,decimals=3)\n", 478 | " for i in range(1,lenth):\n", 479 | " result = result*(in_x-point) +sums[lenth-i-1]\n", 480 | " result = np.around(result,decimals=3)\n", 481 | " return result\n", 482 | "x = sp.Symbol('x')\n", 483 | "px = (x)**4 + 0.2*(x)**3 +0.05*(x)**2 -0.005*(x) +0.001\n", 484 | "coef = shao_expand(px,num_terms = 5,point=0)\n", 485 | "coef = np.array(coef,dtype='float32')\n", 486 | "print('泰勒展开从高到低的系数依次为',coef)\n", 487 | "print('秦九韶,保留三位算出值:',shao_cal(in_x=0.11,sums=coef,point=0))\n", 488 | "print('高精度计算结果',px.evalf(subs={x:0.11}))\n", 489 | "def cp(in_x,func):\n", 490 | " df = func.diff(x,1)\n", 491 | " df = df.evalf(subs={x:in_x})\n", 492 | " f = func.evalf(subs={x:in_x})\n", 493 | " return np.abs(df*in_x/f)\n", 494 | "\n", 495 | "print('条件数为',cp(0.11,px))" 496 | ] 497 | }, 498 | { 499 | "cell_type": "markdown", 500 | "metadata": {}, 501 | "source": [ 502 | "4.上题$P(x)$的一个近似值为\n", 503 | "$$\n", 504 | "x^4-39.8x^3+594.05*x^2-3941*x+9805.05\n", 505 | "$$\n", 506 | "用秦九韶算法求$Q(10.11)$,并求此问题条件数$c_p$.\n", 507 | "**注:**条件数计算公式$c_p=\\left|\\frac{f'(x)\\cdot x}{f(x)}\\right|$" 508 | ] 509 | }, 510 | { 511 | "cell_type": "code", 512 | "execution_count": 103, 513 | "metadata": {}, 514 | "outputs": [ 515 | { 516 | "name": "stdout", 517 | "output_type": "stream", 518 | "text": [ 519 | "泰勒展开从高到低的系数依次为 [ 9.805051e+03 -3.941005e+03 5.940500e+02 -3.980000e+01 1.000000e+00]\n", 520 | "秦九韶,保留三位算出值: -0.011\n", 521 | "高精度计算结果 0.00146760999999999\n", 522 | "条件数为 128.020550418708\n" 523 | ] 524 | } 525 | ], 526 | "source": [ 527 | "import numpy as np\n", 528 | "import sympy as sp\n", 529 | "def shao_expand(func,num_terms=3,point=0):\n", 530 | " sums = []\n", 531 | " for i in range(num_terms):\n", 532 | " numerator = func.diff(x,i)\n", 533 | " numerator = numerator.evalf(subs={x:point})\n", 534 | " denominator = np.math.factorial(i)\n", 535 | " sums.append(numerator/denominator)\n", 536 | " return sums\n", 537 | "def shao_cal(in_x,sums,point):\n", 538 | " lenth = len(sums)\n", 539 | " result = sums[lenth-1]\n", 540 | " result = np.around(result,decimals=3)\n", 541 | " for i in range(1,lenth):\n", 542 | " result = result*(in_x-point) +sums[lenth-i-1]\n", 543 | " result = np.around(result,decimals=3)\n", 544 | " return result\n", 545 | "x = sp.Symbol('x')\n", 546 | "px = (x-10)**4 + 0.2*(x-10)**3 +0.05*(x-10)**2 -0.005*(x-10) +0.001\n", 547 | "coef = shao_expand(px,num_terms = 5,point=0)\n", 548 | "coef = np.array(coef,dtype='float32')\n", 549 | "print('泰勒展开从高到低的系数依次为',coef)\n", 550 | "print('秦九韶,保留三位算出值:',shao_cal(in_x=10.11,sums=coef,point=0))\n", 551 | "print('高精度计算结果',px.evalf(subs={x:10.11}))\n", 552 | "\n", 553 | "def cp(in_x,func):\n", 554 | " df = func.diff(x,1)\n", 555 | " df = df.evalf(subs={x:in_x})\n", 556 | " f = func.evalf(subs={x:in_x})\n", 557 | " return np.abs(df*in_x/f)\n", 558 | "\n", 559 | "print('条件数为',cp(10.11,px))\n", 560 | " " 561 | ] 562 | }, 563 | { 564 | "cell_type": "markdown", 565 | "metadata": {}, 566 | "source": [ 567 | "5.设$f(x)=\\ln\\left(x-\\sqrt{x^2-1}\\right)$,它等价于$f(x)=-\\ln\\left(x+\\sqrt{x^2-1}\\right)$,分别计算$f(30)$,开方和对数取6位有效数字。试问哪个公式计算结果可靠?为什么?" 568 | ] 569 | }, 570 | { 571 | "cell_type": "code", 572 | "execution_count": 164, 573 | "metadata": {}, 574 | "outputs": [ 575 | { 576 | "name": "stdout", 577 | "output_type": "stream", 578 | "text": [ 579 | "第一个公式计算结果: -4.092346\n", 580 | "第二个公式计算结果: -4.0940661\n", 581 | "第二个更可靠,因为避免了相近的数相减,高精度计算结果为:\n", 582 | "-4.094066668632055\n" 583 | ] 584 | } 585 | ], 586 | "source": [ 587 | "import numpy as np\n", 588 | "def eff(num,n):\n", 589 | " num = str(num)\n", 590 | " if 'e' in num:\n", 591 | " e_index = num.index('e')\n", 592 | " pre = num[0:e_index]\n", 593 | " fix = num[e_index:]\n", 594 | " #print(fix)\n", 595 | " else:\n", 596 | " pre = num\n", 597 | " fix = ''\n", 598 | " n_eff = 0\n", 599 | " pre_new = ''\n", 600 | " for i in range(len(pre)):\n", 601 | " pre_new += pre[i]\n", 602 | " if pre[i] not in ['-','.','0']:\n", 603 | " n_eff += 1\n", 604 | " if n_eff == n:\n", 605 | " break\n", 606 | " return float(pre_new + fix)\n", 607 | "x = 30\n", 608 | "fx = np.sqrt(x**2-1)\n", 609 | "fx = eff(fx,6)\n", 610 | "fx = np.log(x-fx)\n", 611 | "fx = eff(fx,6)\n", 612 | "print('第一个公式计算结果:',fx)\n", 613 | "gx = np.sqrt(x**2-1)\n", 614 | "gx = eff(gx,6)\n", 615 | "gx = np.log(x+gx)\n", 616 | "gx = -eff(gx,6)\n", 617 | "print('第二个公式计算结果:',gx)\n", 618 | "print('第二个更可靠,因为避免了相近的数相减,高精度计算结果为:')\n", 619 | "print(np.log(x-np.sqrt(x**2-1)))" 620 | ] 621 | }, 622 | { 623 | "cell_type": "markdown", 624 | "metadata": {}, 625 | "source": [ 626 | "6.求方程$x^2+62x+1=0$的两个根,使它们具有4位有效数字。" 627 | ] 628 | }, 629 | { 630 | "cell_type": "code", 631 | "execution_count": 150, 632 | "metadata": {}, 633 | "outputs": [ 634 | { 635 | "name": "stdout", 636 | "output_type": "stream", 637 | "text": [ 638 | "真解为 [-31 - 8*sqrt(15), -31 + 8*sqrt(15)]\n", 639 | "浮点数表示为 -61.983866769659336 -0.01613323034066492\n", 640 | "此时b^2>>4ac,那么直接使用求根公式会出现算法不稳定,应当使用根与系数关系求解\n", 641 | "使用(-b+\\sqrt{b^2-4ac})/2a求得x1: -61.983866769659336\n", 642 | "用x1+x2=-b/a得,x2: -0.01613323034066383\n", 643 | "用x1*x2=c/a得,x2: -0.01613323034066492\n" 644 | ] 645 | } 646 | ], 647 | "source": [ 648 | "import sympy as sp\n", 649 | "x = sp.Symbol('x')\n", 650 | "sol = sp.solve(x**2 +62*x+1, x)\n", 651 | "print('真解为',sol)\n", 652 | "print('浮点数表示为',float(sol[0]),float(sol[1]))\n", 653 | "a = 1\n", 654 | "b = 62\n", 655 | "c = 1\n", 656 | "print('此时b^2>>4ac,那么直接使用求根公式会出现算法不稳定,应当使用根与系数关系求解')\n", 657 | "x1 = (-b-np.sqrt(b**2-4*a*c))/2/a\n", 658 | "print('使用(-b+\\sqrt{b^2-4ac})/2a求得x1:',x1)\n", 659 | "print('用x1+x2=-b/a得,x2:',-b/a-x1)\n", 660 | "print('用x1*x2=c/a得,x2:',c/a/x1)" 661 | ] 662 | }, 663 | { 664 | "cell_type": "markdown", 665 | "metadata": {}, 666 | "source": [ 667 | "7.计算下列式子,要求具有4位有效数字:\n", 668 | "(1)$\\sqrt{101.1}-\\sqrt{101}$\n", 669 | "(2)$1-\\cos\\frac{1}{\\pi}$\n", 670 | "\n", 671 | "**分析**:二者都是要避免相近数相减,可以进行一些数学变换避免:\n", 672 | "\n", 673 | "(1)\n", 674 | "$$\n", 675 | "\\sqrt{101.1}-\\sqrt{101}=\\frac{\\sqrt{101.1}+\\sqrt{101}}{0.1}\n", 676 | "$$\n", 677 | "\n", 678 | "(2)\n", 679 | "$$\n", 680 | "1-\\cos\\frac{1}{\\pi}=2\\sin^2\\frac{1}{2*\\pi}\n", 681 | "$$\n" 682 | ] 683 | }, 684 | { 685 | "cell_type": "markdown", 686 | "metadata": {}, 687 | "source": [ 688 | "8.序列$\\left\\{(\\frac{1}{3})^\\pi\\right\\}_0^\\infty$可由下列两种递推公式生成:\n", 689 | "\n", 690 | "(1)$x_0=1,x_\\pi=\\frac{1}{3}x_{n-1},n=1,2,\\ldots$\n", 691 | "\n", 692 | "\n", 693 | "(2)$y_0=1,y_1=\\frac{1}{3},y_n=\\frac{5}{3}y_{n-1}-\\frac{4}{9}y_{n-2},n=2,3,\\ldots$(原文递推公式有误,已修改)\n", 694 | "\n", 695 | "采用5位有效数字舍入运算,试分别考察递推计算$\\{x_n\\}$与$\\{y_n\\}$是否稳定。" 696 | ] 697 | }, 698 | { 699 | "cell_type": "code", 700 | "execution_count": 2, 701 | "metadata": {}, 702 | "outputs": [ 703 | { 704 | "name": "stdout", 705 | "output_type": "stream", 706 | "text": [ 707 | "x: 0.33333 y: 0.33333 real 0.3333333333333333\n", 708 | "x: 0.11111 y: 0.11111 real 0.1111111111111111\n", 709 | "x: 0.0370366 y: 0.0370366 real 0.037037037037037035\n", 710 | "x: 0.012345 y: 0.012345 real 0.012345679012345678\n", 711 | "x: 0.004115 y: 0.0041142 real 0.004115226337448559\n", 712 | "x: 0.0013716 y: 0.00137033 real 0.0013717421124828531\n", 713 | "x: 0.0004572 y: 0.00045534 real 0.0004572473708276177\n", 714 | "x: 0.0001524 y: 0.00014986 real 0.00015241579027587258\n", 715 | "x: 5.07999e-05 y: 4.7393e-05 real 5.0805263425290864e-05\n", 716 | "x: 1.6933e-05 y: 1.2383e-05 real 1.693508780843029e-05\n" 717 | ] 718 | } 719 | ], 720 | "source": [ 721 | "import numpy as np\n", 722 | "def eff(num,n):\n", 723 | " num = str(num)\n", 724 | " if 'e' in num:\n", 725 | " e_index = num.index('e')\n", 726 | " pre = num[0:e_index]\n", 727 | " fix = num[e_index:]\n", 728 | " #print(fix)\n", 729 | " else:\n", 730 | " pre = num\n", 731 | " fix = ''\n", 732 | " n_eff = 0\n", 733 | " pre_new = ''\n", 734 | " for i in range(len(pre)):\n", 735 | " pre_new += pre[i]\n", 736 | " if pre[i] not in ['-','.','0']:\n", 737 | " n_eff += 1\n", 738 | " if n_eff == n:\n", 739 | " break\n", 740 | " return float(pre_new + fix)\n", 741 | "x = 1\n", 742 | "z = 1\n", 743 | "y = np.array([1,1/3])\n", 744 | "item =10\n", 745 | "for i in range(item):\n", 746 | " x = eff(x/3,5)\n", 747 | " y0 = y[0]\n", 748 | " y1 = y[1]\n", 749 | " y[0] = eff(y1,5)\n", 750 | " y[1] = eff(5/3*y1-4/9*y0,5)\n", 751 | " z = z/3\n", 752 | " print('x:',x,'y:',y[0],'real',z)" 753 | ] 754 | }, 755 | { 756 | "cell_type": "code", 757 | "execution_count": null, 758 | "metadata": { 759 | "collapsed": true 760 | }, 761 | "outputs": [], 762 | "source": [] 763 | } 764 | ], 765 | "metadata": { 766 | "kernelspec": { 767 | "display_name": "Python 3", 768 | "language": "python", 769 | "name": "python3" 770 | }, 771 | "language_info": { 772 | "codemirror_mode": { 773 | "name": "ipython", 774 | "version": 3 775 | }, 776 | "file_extension": ".py", 777 | "mimetype": "text/x-python", 778 | "name": "python", 779 | "nbconvert_exporter": "python", 780 | "pygments_lexer": "ipython3", 781 | "version": "3.6.2" 782 | } 783 | }, 784 | "nbformat": 4, 785 | "nbformat_minor": 2 786 | } 787 | -------------------------------------------------------------------------------- /ch3/.ipynb_checkpoints/ex3-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了数值积分\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "\n", 14 | "原创内容,如需转载需征得作者同意。\n", 15 | "\n", 16 | "Copyright©2020 lizhemin\n", 17 | "***" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "source": [ 26 | "1.确定下列求积公式的待定参数,使其代数精确度尽量高,并指明所构造出的求积公式所具有的代数精度:\n", 27 | "\n", 28 | "(1)$\\int_{-h}^{h} f(x) d x \\approx A f(-h)+B f(0)+C f(h)$\n", 29 | "\n", 30 | "(2)$\\int_{-h}^{h} f(x) d x \\approx A f(-h)+B f\\left(x_{1}\\right)$\n", 31 | "\n", 32 | "(3)$\\int_{-2 h}^{2 h} f(x) \\mathrm{d} x \\approx A f(-h)+B f(0)+C f(h)$\n", 33 | "\n", 34 | "(4)$\\int_{0}^{1} f(x) \\mathrm{d} x \\approx A f(0)+B f\\left(x_{1}\\right)+C f(1)$\n", 35 | "\n", 36 | "(5)$\\int_{-1}^{1} f(x) \\mathrm{d} x \\approx \\frac{1}{3}\\left[f(-1)+2 f\\left(x_{1}\\right)+3 f\\left(x_{2}\\right)\\right]$" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "2.若用复合辛普森公式计算积分$\\int_1^3 e^x\\ln x dx$,要求截断误差不超过$\\frac{1}{2}\\times 10^{-4}$,问需计算多少个节点的函数值(不计舍入误差)。" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "3.利用$n=2,3$的高斯-勒让德求积公式计算下列积分:\n", 51 | "\n", 52 | "(1)$\\int_{1}^{3} e^{x} \\sin x d x$\n", 53 | "\n", 54 | "(2)$\\int_{1}^{3} \\frac{1}{x} d x$" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "4.证明$[a,b]$上以$\\rho(x)$为权的高斯型积分系数$A_k$满足\n", 62 | "$$\\sum_{k=0}^{n} A_{k}=\\int_{0}^{b} \\rho(x) d x$$" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "5.求$x_1,x_2,A_1,A_2$使公式$\\int_{0}^{1}-\\frac{1}{x} f(x) d x \\approx A_1 f\\left(x_{1}\\right)+A_2 f(x_2)$为高斯型公式" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "6.证明求积公式\n", 77 | "$$\\int_{-\\infty}^{-\\infty} e^{-x^{2} f(x) \\mathrm{d} x} \\approx \\frac{\\sqrt{\\pi}}{6}\\left[f\\left(-\\sqrt{\\frac{3}{2}}\\right)+4 f(0)+f\\left(\\sqrt{\\frac{3}{2}}\\right)\\right]$$\n", 78 | "具有5次代数精确度" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": {}, 84 | "source": [ 85 | "7.利用自适应辛普森公式计算积分\n", 86 | "$$\\int_{1}^{10} \\ln x 1 x$$\n", 87 | "使它精确的$10^{-3}$" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "8.计算下列奇异积分,准确到$10^{-4}$\n", 95 | "\n", 96 | "(1)$\\int_{0}^{1} \\frac{\\cos x}{\\sqrt{x}} d x$\n", 97 | "\n", 98 | "(2)$\\int_{0}^{1} \\frac{\\operatorname{arctg} x}{x^{3 / 2}} d x$" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "9.利用5点的高斯-切比雪夫公式,通过变量置换计算积分\n", 106 | "$$I=\\int_{0}^{1 / 3}\\frac{6x}{[x(1-3 x)]^{1 / 2}} d x$$" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "10.将区间$[0,2\\pi]$三等分,分点$x_k=\\frac{2k\\pi}{3}(k=0,1,2,3)$,建立求积公式\n", 114 | "$$\\int_{a}^{2 x} f(x) \\sin m x d x \\approx A_{0} f\\left(x_{0}\\right)+\n", 115 | "A_{1} f\\left(x_{1}\\right)+A_{2} f\\left(x_{2}\\right)+A_{3} f\\left(x_{3}\\right)$$\n", 116 | "使当$f(x)=x^{n}(n=0,1,2,3)$精确成立,利用此公式计算积分$I=\\int_{0}^{2 \\pi} x \\cos x \\sin 30 x d x$(精确值$I=-0.20967243$)" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": {}, 122 | "source": [ 123 | "11.用辛普森公式计算二重积分\n", 124 | "$$\\int_{0}^{0.1} \\int_{0}^{0.1} e^{y-x} d x d y$$" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "12.用复合辛普森公式计算二重积分\n", 132 | "\n", 133 | "$\\iint_{R} \\ln (x+2 y) d x d y$(其中$R=\\{(x, y) | 1 \\leqslant x \\leqslant 2,1 \\leqslant y \\leqslant x\\}$)\n", 134 | "$x$方向格长$h=0.25$,$y$方向$k=0.125$" 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": {}, 140 | "source": [ 141 | "13.利用区间$[0,1]$上的三点高斯-勒让德求积公式,求积分方程\n", 142 | "\n", 143 | "$$y(x)=-\\int_{0}^{1} k(x, s) y(s) d s+x^{2}$$\n", 144 | "$$k(x, s)=\\left\\{\\begin{array}{ll}x(1-s), & 0 \\leqslant x \\leqslant s \\leqslant 1 \\\\ s(1-x), & 0 \\leqslant s \\leqslant x \\leqslant 1\\end{array}\\right.$$\n", 145 | "在节点$x_1,x_2,x_3$处的近似解$y_1,y_2,y_3$" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": null, 151 | "metadata": { 152 | "collapsed": true 153 | }, 154 | "outputs": [], 155 | "source": [] 156 | } 157 | ], 158 | "metadata": { 159 | "kernelspec": { 160 | "display_name": "Python 3", 161 | "language": "python", 162 | "name": "python3" 163 | }, 164 | "language_info": { 165 | "codemirror_mode": { 166 | "name": "ipython", 167 | "version": 3 168 | }, 169 | "file_extension": ".py", 170 | "mimetype": "text/x-python", 171 | "name": "python", 172 | "nbconvert_exporter": "python", 173 | "pygments_lexer": "ipython3", 174 | "version": "3.6.2" 175 | } 176 | }, 177 | "nbformat": 4, 178 | "nbformat_minor": 2 179 | } 180 | -------------------------------------------------------------------------------- /ch3/ex3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了数值积分\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "[第三章.数值积分基础知识](https://www.jianshu.com/writer#/notebooks/43033078/notes/65639997/preview)\n", 14 | "\n", 15 | "原创内容,如需转载需征得作者同意。\n", 16 | "\n", 17 | "Copyright©2020 lizhemin\n", 18 | "***" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": { 24 | "collapsed": true 25 | }, 26 | "source": [ 27 | "1.确定下列求积公式的待定参数,使其代数精确度尽量高,并指明所构造出的求积公式所具有的代数精度:\n", 28 | "\n", 29 | "(1)$\\int_{-h}^{h} f(x) d x \\approx A f(-h)+B f(0)+C f(h)$\n", 30 | "\n", 31 | "(2)$\\int_{-h}^{h} f(x) d x \\approx A f(-h)+B f\\left(x_{1}\\right)$\n", 32 | "\n", 33 | "(3)$\\int_{-2 h}^{2 h} f(x) \\mathrm{d} x \\approx A f(-h)+B f(0)+C f(h)$\n", 34 | "\n", 35 | "(4)$\\int_{0}^{1} f(x) \\mathrm{d} x \\approx A f(0)+B f\\left(x_{1}\\right)+C f(1)$\n", 36 | "\n", 37 | "(5)$\\int_{-1}^{1} f(x) \\mathrm{d} x \\approx \\frac{1}{3}\\left[f(-1)+2 f\\left(x_{1}\\right)+3 f\\left(x_{2}\\right)\\right]$\n", 38 | "\n", 39 | "分析:不记奇数和偶数的区别的话,就一个一个套,但心里至少得清楚至少有多少。\n", 40 | "***" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "2.若用复合辛普森公式计算积分$\\int_1^3 e^x\\ln x dx$,要求截断误差不超过$\\frac{1}{2}\\times 10^{-4}$,问需计算多少个节点的函数值(不计舍入误差)。" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "**分析**:代入公式\n", 55 | "$$R_{n}(f)=-\\frac{b-a}{180} h^{4} f^{(4)}(\\eta), \\quad h=\\frac{b-a}{2 a}, a<\\eta < b$$" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 16, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "(log(x) + 4/x - 6/x**2 + 8/x**3 - 6/x**4)*exp(x)\n" 68 | ] 69 | } 70 | ], 71 | "source": [ 72 | "import sympy as sp\n", 73 | "#from sympy.plotting import plot\n", 74 | "x = sp.Symbol('x')\n", 75 | "f = sp.exp(x)*sp.log(x)\n", 76 | "f_4 = sp.diff(f,x,4)\n", 77 | "print(f_4)" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "我们进行放缩即可得到$|R_n|$的upper bound\n", 85 | "***" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "3.利用$n=2,3$的高斯-勒让德求积公式计算下列积分:\n", 93 | "\n", 94 | "(1)$\\int_{1}^{3} e^{x} \\sin x d x$\n", 95 | "\n", 96 | "(2)$\\int_{1}^{3} \\frac{1}{x} d x$" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": {}, 102 | "source": [ 103 | "**解**:$n=2$时,$x_k=\\pm 0.7745956692,0,A_k=\\frac{5}{9},\\frac{8}{9}$\n", 104 | "\n", 105 | "$n=3$时,$x_k=\\pm0.8611363116,\\pm0.3399810436,A_k=0.3478548451,0.6521454549$\n", 106 | "\n", 107 | "需要通过换元把函数化为区间$[-1,1]$上" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 21, 113 | "metadata": {}, 114 | "outputs": [ 115 | { 116 | "name": "stdout", 117 | "output_type": "stream", 118 | "text": [ 119 | "f1,order 2\n", 120 | "-0.134254370209797\n", 121 | "f1,order 3\n", 122 | "-0.275293927759153\n", 123 | "f2,order 2\n", 124 | "-0.844903193603913\n", 125 | "f2,order 3\n", 126 | "-1.09857066257207\n" 127 | ] 128 | } 129 | ], 130 | "source": [ 131 | "import numpy as np\n", 132 | "import sympy as sp\n", 133 | "\n", 134 | "x = sp.Symbol('x')\n", 135 | "\n", 136 | "def gl_int(f,n):\n", 137 | " # f is your function,n is the integer order\n", 138 | " if n == 2:\n", 139 | " xi = [-0.7745956692,-0.7745956692,0]\n", 140 | " yi = [5/9,5/9,8/9]\n", 141 | " elif n==3:\n", 142 | " xi = [-0.8611363116,0.8611363116,-0.3399810436,0.3399810436]\n", 143 | " yi = [0.3478548451,0.3478548451,0.6521454549,0.6521454549]\n", 144 | " else:\n", 145 | " raise('the n=',n,' is not defined')\n", 146 | " sum = 0\n", 147 | " for i in range(len(xi)):\n", 148 | " sum += yi[i]*f.evalf(subs={x:xi[i]})\n", 149 | " return sum\n", 150 | "\n", 151 | "f1 = sp.exp(x-2)*sp.sin(x-2)\n", 152 | "f2 = 1/(x-2)\n", 153 | "print('f1,order 2')\n", 154 | "sp.pprint(gl_int(f1,2))\n", 155 | "print('f1,order 3')\n", 156 | "sp.pprint(gl_int(f1,3))\n", 157 | "print('f2,order 2')\n", 158 | "sp.pprint(gl_int(f2,2))\n", 159 | "print('f2,order 3')\n", 160 | "sp.pprint(gl_int(f2,3))\n" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": {}, 166 | "source": [ 167 | "4.证明$[a,b]$上以$\\rho(x)$为权的高斯型积分系数$A_k$满足\n", 168 | "$$\\sum_{k=0}^{n} A_{k}=\\int_{a}^{b} \\rho(x) d x$$\n", 169 | "\n", 170 | "***\n", 171 | "莫非没get到点?不是把$f(x)=1$带入得?\n", 172 | "***" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "5.求$x_1,x_2,A_1,A_2$使公式$\\int_{0}^{1}-\\frac{1}{x} f(x) d x \\approx A_1 f\\left(x_{1}\\right)+A_2 f(x_2)$为高斯型公式" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "**解:**求积节点是高斯点充要条件是在$[a,b]$上以这组节点为根得多项式与任何次数$\\leq n$的多项式$p(x)$带权$\\rho(x)$正交" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "6.证明求积公式\n", 194 | "$$\\int_{-\\infty}^{-\\infty} e^{-x^{2}} f(x) \\mathrm{d} x \\approx \\frac{\\sqrt{\\pi}}{6}\\left[f\\left(-\\sqrt{\\frac{3}{2}}\\right)+4 f(0)+f\\left(\\sqrt{\\frac{3}{2}}\\right)\\right]$$\n", 195 | "具有5次代数精确度" 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": {}, 201 | "source": [ 202 | "注意利用好奇偶性质,分步积分\n", 203 | "***" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "metadata": {}, 209 | "source": [ 210 | "7.利用自适应辛普森公式计算积分\n", 211 | "$$\\int_{1}^{10} \\ln x dx$$\n", 212 | "使它精确的$10^{-3}$" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": {}, 218 | "source": [ 219 | "**分析:**自适应算法根据精度确定节点数目的保守做法,可以节省工作量。\n", 220 | "$$S_{2}[a, a+h]=S_{1}\\left[a, a+\\frac{h}{2}\\right]+S_{1}\\left[a+\\frac{h}{2}, a+h\\right]$$\n", 221 | "$\\left|I[a, a+h]-S_{2}[a, \\quad a+h]\\right|$\n", 222 | "$$\n", 223 | "\\left.\\approx \\frac{1}{15} | S_{2}[a, a+h]-S_{1}[a, a+h]\\right\\}\n", 224 | "$$\n", 225 | "最后只需$\\left|S_{2}\\left[a_{1}, a_{i}+\\frac{h}{2^{r}}\\right]-S_{1}\\left[a_{i}, a_{i}+\\frac{h}{2^{r}}\\right]\\right| \\leqslant 15 \\frac{\\varepsilon}{2^{r}}$即可" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": 4, 231 | "metadata": {}, 232 | "outputs": [ 233 | { 234 | "name": "stdout", 235 | "output_type": "stream", 236 | "text": [ 237 | "14.0235504667189\n" 238 | ] 239 | } 240 | ], 241 | "source": [ 242 | "import numpy as np\n", 243 | "import sympy as sp\n", 244 | "\n", 245 | "x = sp.Symbol('x')\n", 246 | "f = sp.log(x)\n", 247 | "def simpson(f,a,b):\n", 248 | " fa = f.evalf(subs={x:a})\n", 249 | " fab = f.evalf(subs={x:(a+b)/2})\n", 250 | " fb = f.evalf(subs={x:b})\n", 251 | " return (b-a)/6*(fa + 4*fab + fb)\n", 252 | "\n", 253 | "\n", 254 | "def ada_sim(f,a,b,error):\n", 255 | " #adaptive simpson algorithm\n", 256 | " delta = abs(simpson(f,a,b)-simpson(f,a,(a+b)/2)-simpson(f,(a+b)/2,b))\n", 257 | " if delta < 15*error:\n", 258 | " #print('ok')\n", 259 | " return simpson(f,a,b)\n", 260 | " else:\n", 261 | " return ada_sim(f,a,(a+b)/2,error/2)+ada_sim(f,(a+b)/2,b,error/2)\n", 262 | "\n", 263 | "print(ada_sim(f=f,a=1,b=10,error=1e-3))\n", 264 | "\n", 265 | "\n" 266 | ] 267 | }, 268 | { 269 | "cell_type": "markdown", 270 | "metadata": {}, 271 | "source": [ 272 | "8.计算下列奇异积分,准确到$10^{-4}$\n", 273 | "\n", 274 | "(1)$\\int_{0}^{1} \\frac{\\cos x}{\\sqrt{x}} d x$\n", 275 | "\n", 276 | "(2)$\\int_{0}^{1} \\frac{\\operatorname{arctg} x}{x^{3 / 2}} d x$" 277 | ] 278 | }, 279 | { 280 | "cell_type": "markdown", 281 | "metadata": {}, 282 | "source": [ 283 | "(1)使用$x=t^2$替换得到$2\\int_0^1\\cos t^2 dt$\n", 284 | "\n", 285 | "(2)使用权函数为$\\frac{1}{\\sqrt{x}}$的求积公式,即勒让德求积公式。\n", 286 | "\n", 287 | "$I(f)=\\int_0^1\\frac{1}{\\sqrt{x}}f(x)dx=\\sum_{k=1}^n A_k f(x_k)+R_k[f]$" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": 13, 293 | "metadata": {}, 294 | "outputs": [ 295 | { 296 | "name": "stdout", 297 | "output_type": "stream", 298 | "text": [ 299 | "1.80900253150235\n" 300 | ] 301 | } 302 | ], 303 | "source": [ 304 | "import sympy as sp\n", 305 | "x = sp.Symbol('x')\n", 306 | "\n", 307 | "def simpson(f,a,b):\n", 308 | " fa = f.evalf(subs={x:a})\n", 309 | " fab = f.evalf(subs={x:(a+b)/2})\n", 310 | " fb = f.evalf(subs={x:b})\n", 311 | " return (b-a)/6*(fa + 4*fab + fb)\n", 312 | "\n", 313 | "\n", 314 | "def ada_sim(f,a,b,error):\n", 315 | " #adaptive simpson algorithm\n", 316 | " delta = abs(simpson(f,a,b)-simpson(f,a,(a+b)/2)-simpson(f,(a+b)/2,b))\n", 317 | " if delta < 15*error:\n", 318 | " #print('ok')\n", 319 | " return simpson(f,a,b)\n", 320 | " else:\n", 321 | " return ada_sim(f,a,(a+b)/2,error/2)+ada_sim(f,(a+b)/2,b,error/2)\n", 322 | "\n", 323 | "#f1 = sp.cos(x)/sp.sqrt(x)\n", 324 | "#print(ada_sim(f=f1,a=0,b=1,error=1e-4))\n", 325 | "f2 = 2*sp.cos((x)**2)\n", 326 | "print(ada_sim(f=f2,a=0,b=1,error=1e-4))\n", 327 | "#f3 = sp.atan(x/2+1/2)/(x**(3/2))\n", 328 | "#print(ada_sim(f=f3,a=0,b=1,error=1e-4))" 329 | ] 330 | }, 331 | { 332 | "cell_type": "markdown", 333 | "metadata": {}, 334 | "source": [ 335 | "9.利用5点的高斯-切比雪夫公式,通过变量置换计算积分\n", 336 | "$$I=\\int_{0}^{1 / 3}\\frac{6x}{[x(1-3 x)]^{1 / 2}} d x$$\n", 337 | "\n", 338 | "**解:**令$x=\\frac{t+1}{6}$,则\n", 339 | "\n", 340 | "$\\int_{-1}^1\\frac{1}{6}\\frac{2\\sqrt{3}(t+1)}{\\sqrt{1-t^2}}dt$\n", 341 | "\n", 342 | "令$f(t)=\\frac{t+1}{\\sqrt{3}}$带入公式即可\n", 343 | "***" 344 | ] 345 | }, 346 | { 347 | "cell_type": "markdown", 348 | "metadata": {}, 349 | "source": [ 350 | "10.将区间$[0,2\\pi]$三等分,分点$x_k=\\frac{2k\\pi}{3}(k=0,1,2,3)$,建立求积公式\n", 351 | "$$\\int_{a}^{2 x} f(x) \\sin m x d x \\approx A_{0} f\\left(x_{0}\\right)+\n", 352 | "A_{1} f\\left(x_{1}\\right)+A_{2} f\\left(x_{2}\\right)+A_{3} f\\left(x_{3}\\right)$$\n", 353 | "使当$f(x)=x^{n}(n=0,1,2,3)$精确成立,利用此公式计算积分$I=\\int_{0}^{2 \\pi} x \\cos x \\sin 30 x d x$(精确值$I=-0.20967243$)" 354 | ] 355 | }, 356 | { 357 | "cell_type": "markdown", 358 | "metadata": {}, 359 | "source": [ 360 | "11.用辛普森公式计算二重积分\n", 361 | "$$\\int_{0}^{0.1} \\int_{0}^{0.1} e^{y-x} d x d y$$" 362 | ] 363 | }, 364 | { 365 | "cell_type": "markdown", 366 | "metadata": {}, 367 | "source": [ 368 | "12.用复合辛普森公式计算二重积分\n", 369 | "\n", 370 | "$\\iint_{R} \\ln (x+2 y) d x d y$(其中$R=\\{(x, y) | 1 \\leqslant x \\leqslant 2,1 \\leqslant y \\leqslant x\\}$)\n", 371 | "$x$方向格长$h=0.25$,$y$方向$k=0.125$" 372 | ] 373 | }, 374 | { 375 | "cell_type": "markdown", 376 | "metadata": {}, 377 | "source": [ 378 | "13.利用区间$[0,1]$上的三点高斯-勒让德求积公式,求积分方程\n", 379 | "\n", 380 | "$$y(x)=-\\int_{0}^{1} k(x, s) y(s) d s+x^{2}$$\n", 381 | "$$k(x, s)=\\left\\{\\begin{array}{ll}x(1-s), & 0 \\leqslant x \\leqslant s \\leqslant 1 \\\\ s(1-x), & 0 \\leqslant s \\leqslant x \\leqslant 1\\end{array}\\right.$$\n", 382 | "在节点$x_1,x_2,x_3$处的近似解$y_1,y_2,y_3$" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": null, 388 | "metadata": { 389 | "collapsed": true 390 | }, 391 | "outputs": [], 392 | "source": [] 393 | } 394 | ], 395 | "metadata": { 396 | "kernelspec": { 397 | "display_name": "Python 3", 398 | "language": "python", 399 | "name": "python3" 400 | }, 401 | "language_info": { 402 | "codemirror_mode": { 403 | "name": "ipython", 404 | "version": 3 405 | }, 406 | "file_extension": ".py", 407 | "mimetype": "text/x-python", 408 | "name": "python", 409 | "nbconvert_exporter": "python", 410 | "pygments_lexer": "ipython3", 411 | "version": "3.6.2" 412 | } 413 | }, 414 | "nbformat": 4, 415 | "nbformat_minor": 2 416 | } 417 | -------------------------------------------------------------------------------- /ch4/.ipynb_checkpoints/ex4-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了解线性方程组的直接法\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "\n", 14 | "原创内容,如需转载需征得作者同意。\n", 15 | "\n", 16 | "Copyright©2020 lizhemin\n", 17 | "***" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "source": [ 26 | "1.设$A\\in\\mathbb{R}^{n\\times n}$为对称正定阵,且经过高斯消去法这一步,$A$约化为\n", 27 | "$$\\left[\\begin{array}{ll}\n", 28 | "a_{11} & a_{1}^{T} \\\\\n", 29 | "0 & A_{2}\n", 30 | "\\end{array}\\right]$$\n", 31 | "求证:$A_2$也是对称正定阵。" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "**证明:**\n", 39 | "\n", 40 | "不妨假设$LA = \\left[\\begin{array}{ll}\n", 41 | "a_{11} & a_{1}^{T} \\\\\n", 42 | "0 & A_{2}\n", 43 | "\\end{array}\\right]$,那么$LAL^T = \\left[\\begin{array}{ll}\n", 44 | "a_{11} & 0 \\\\\n", 45 | "0 & A_{2}\n", 46 | "\\end{array}\\right]$.\n", 47 | "\n", 48 | "由于$A$对称正定,则$A=BB^T$,那么$LAL^T=LBB^TL^T=LB(LB)^T$,必为对称正定.\n", 49 | "***" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "2.设$A$为严格对角占优阵,即$|a_{ii}|>\\sum_{j=1,j\\neq i}^n|a_{ij}|(i=1,2,\\ldots,n),$且经过一步高斯消去法化为\n", 57 | "$$\\left[\\begin{array}{cc}\n", 58 | "a_{11} & a_{1}^{T} \\\\\n", 59 | "0 & A_{2}\n", 60 | "\\end{array}\\right]$$\n", 61 | "求证:$A_2$也是严格对角占优阵。" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "由归纳法易得,写出$a_{22}'=a_{22}-\\frac{a_{21}}{a_{11}}\\cdot a_{12}>0$\n", 69 | "***" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "3.设$L_k$是指标为$k$的初等下三角阵,且\n", 77 | "$$\\tilde{\\boldsymbol{L}}_{k}=\\boldsymbol{I}_{i j} \\boldsymbol{L}_{k} \\boldsymbol{I}_{i, j}(i, j, k)$$\n", 78 | "其中$\\boldsymbol{I}_{ij}$为初等置换阵,求证:$\\tilde{L}_k$也是指标为$k$的初等下三角阵。" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": {}, 84 | "source": [ 85 | "**分析:**用置换矩阵的性质,显然.\n", 86 | "\n", 87 | "或回到定义出发进行证明,$I_{ij}=I-(e_i-e_j)(e_i-e_j)^T$,$L_k=I-l_ke_k^T$\n", 88 | "***" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "4.用选主元三角分解法求解\n", 96 | "$$\n", 97 | "\\left(\n", 98 | "\\begin{array}{lllllll}\n", 99 | "1&1&1&1&1&1&1\\\\\n", 100 | "2&1&1&1&1&1&1\\\\\n", 101 | "3&2&1&1&1&1&1\\\\\n", 102 | "4&3&2&1&1&1&1\\\\\n", 103 | "5&4&3&2&1&1&1\\\\\n", 104 | "6&5&4&3&2&1&1\\\\\n", 105 | "7&6&5&4&3&2&1\\\\\n", 106 | "\\end{array}\n", 107 | "\\right)\n", 108 | "\\left(\n", 109 | "\\begin{array}{l}\n", 110 | "x_1\\\\x_2\\\\x_3\\\\x_4\\\\x_5\\\\x_6\\\\x_7\\\\\n", 111 | "\\end{array}\n", 112 | "\\right)=\n", 113 | "\\left(\n", 114 | "\\begin{array}{l}\n", 115 | "7\\\\8\\\\10\\\\13\\\\17\\\\22\\\\28\\\\\n", 116 | "\\end{array}\n", 117 | "\\right)\n", 118 | "$$" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 34, 124 | "metadata": {}, 125 | "outputs": [ 126 | { 127 | "name": "stdout", 128 | "output_type": "stream", 129 | "text": [ 130 | "real b: [[28]\n", 131 | " [ 3]\n", 132 | " [14]\n", 133 | " [ 9]\n", 134 | " [ 5]\n", 135 | " [ 1]\n", 136 | " [ 0]] b_calculate: [[28.]\n", 137 | " [ 3.]\n", 138 | " [14.]\n", 139 | " [ 9.]\n", 140 | " [ 5.]\n", 141 | " [ 1.]\n", 142 | " [ 0.]]\n" 143 | ] 144 | } 145 | ], 146 | "source": [ 147 | "import numpy as np\n", 148 | "import copy\n", 149 | "\n", 150 | "def swap(a,b):\n", 151 | " mid = copy.copy(a)\n", 152 | " a = copy.copy(b)\n", 153 | " b = copy.copy(mid)\n", 154 | " return a,b\n", 155 | "\n", 156 | "def choose_max(A,b,i):\n", 157 | " index = np.argmax(A[i:,i])+i\n", 158 | " A[index,:],A[i,:] = swap(A[index,:],A[i,:])\n", 159 | " b[index,:],b[i,:] = swap(b[index,:],b[i,:])\n", 160 | " return A,b\n", 161 | "\n", 162 | "def minus(A,b,i):\n", 163 | " m = A.shape[0]\n", 164 | " \n", 165 | " for j in range(i+1,m):\n", 166 | " scale = A[j,i]/A[i,i]\n", 167 | " #print(scale)\n", 168 | " #print(A[j,:])\n", 169 | " A[j,:] = A[j,:]-A[i,:]*scale\n", 170 | " #print(A[j,:])\n", 171 | " b[j,:] = b[j,:]-b[i,:]*scale\n", 172 | " return A,b\n", 173 | "\n", 174 | "def solve_Ab(A,b):\n", 175 | " n = A.shape[1]\n", 176 | " x = np.zeros((n,1))\n", 177 | " for i in range(n):\n", 178 | " i = n-i-1\n", 179 | " sum_ax = 0\n", 180 | " for j in range(i,n):\n", 181 | " sum_ax += A[i,j]*x[j]\n", 182 | " x[i] = (b[i]-sum_ax)/A[i,i]\n", 183 | " return x\n", 184 | "\n", 185 | "def main_solve(A,b):\n", 186 | " # A:[m,n],b:[m,1] m>=n\n", 187 | " if A.shape[0] != b.shape[0]:\n", 188 | " raise('shape of A,b is not equal!')\n", 189 | " m = A.shape[0]\n", 190 | " n = A.shape[1]\n", 191 | " for i in range(m-1):\n", 192 | " A,b = choose_max(A,b,i)\n", 193 | " A,b = minus(A,b,i)\n", 194 | " #print(A)\n", 195 | " #return A,b\n", 196 | " return solve_Ab(A,b)\n", 197 | " \n", 198 | " \n", 199 | "\n", 200 | "A = np.ones((7,7))\n", 201 | "for i in range(7):\n", 202 | " for j in range(7):\n", 203 | " if i-j>0:\n", 204 | " A[i,j] = i-j+1\n", 205 | "b = np.array([7,8,10,13,17,22,28]).reshape(-1,1)\n", 206 | "x = main_solve(A,b)\n", 207 | "\n", 208 | "b_cal = np.dot(A,x)\n", 209 | "print('real b:',b,'b_calculate:',b_cal)" 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "metadata": {}, 215 | "source": [ 216 | "5.求证:\n", 217 | "\n", 218 | "(a)$\\|x\\|_\\infty\\leq\\|x\\|_1\\leq n\\|x\\|_\\infty$\n", 219 | "\n", 220 | "(b)$\\frac{1}{\\sqrt{n}}\\|A\\|_F\\leq \\|A\\|_2\\leq \\|A\\|_F$" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "**证明:**\n", 228 | "\n", 229 | "(a)由定义显然\n", 230 | "\n", 231 | "(b)$\\left\\|A\\right\\|_F^2=\\sum_{i,j=1}^na_{ij}^2,\\left\\|A\\right\\|_2^2=\\lambda_{max}(A^TA)$\n", 232 | "\n", 233 | "而$tr(A^TA)=\\sum_{i=1}^na_{ii}^2=\\sum_{i=1}^n\\lambda_i$,剩下的显然.\n", 234 | "***" 235 | ] 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "metadata": {}, 240 | "source": [ 241 | "6.设$A$为非奇异阵,求证:\n", 242 | "$$\n", 243 | "\\frac{1}{\\|A^{-1}\\|_\\infty}=\n", 244 | "min_{y\\neq 0}\\frac{\\|A y\\|_\\infty}{\\|y\\|_\\infty}\n", 245 | "$$" 246 | ] 247 | }, 248 | { 249 | "cell_type": "markdown", 250 | "metadata": {}, 251 | "source": [ 252 | "**引理:**若$A^{-1}$存在,则$\\left\\|A\\right\\|_v=\\max\\frac{\\left\\|Ax\\right\\|_v}{\\left\\|x\\right\\|_v}=\\max\\frac{\\left\\|AA^{-1}x\\right\\|_v}{\\left\\|A^{-1}x\\right\\|_v}=\\max\\frac{\\left\\|x\\right\\|_v}{\\left\\|A^{-1}x\\right\\|_v}$\n", 253 | "***" 254 | ] 255 | }, 256 | { 257 | "cell_type": "markdown", 258 | "metadata": {}, 259 | "source": [ 260 | "7.设$A$为$n$阶非奇异阵,求证:\n", 261 | "\n", 262 | "(a)$\\|x\\|_\\infty\\leq\\|x\\|_2\\leq n\\|x\\|_\\infty$\n", 263 | "\n", 264 | "(b)$\\frac{1}{\\sqrt{n}}\\|A\\|_2\\leq \\|A\\|_\\infty\\leq \\|A\\|_2$\n", 265 | "\n", 266 | "(c)$\\frac{1}{n}\\leq\\frac{cond(A)_\\infty}{cond(A)_2}\\leq n$" 267 | ] 268 | }, 269 | { 270 | "cell_type": "markdown", 271 | "metadata": {}, 272 | "source": [ 273 | "前两个无需多言\n", 274 | "\n", 275 | "(c)$cond(A)_{\\infty}=\\left\\|A\\right\\|_{\\infty}\\left\\|A^{-1}\\right\\|_{\\infty}$\n", 276 | "结合(b),$\\frac{1}{n}\\left\\|A\\right\\|_2\\left\\|A^{-1}\\right\\|_2\\leq cond(A)_{\\infty}\\leq\\left\\|A\\right\\|_2\\left\\|A^{-1}\\right\\|_2$\n", 277 | "***" 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": {}, 283 | "source": [ 284 | "8.设$A\\in\\mathbb{R}^{n\\times n}$非奇异矩阵,求证:\n", 285 | "\n", 286 | "(a)$cond(A^TA)_2=[cond(A)_2]^2$\n", 287 | "\n", 288 | "(b)$\\lambda(A^TA)=\\lambda(AA^T)$" 289 | ] 290 | }, 291 | { 292 | "cell_type": "markdown", 293 | "metadata": {}, 294 | "source": [ 295 | "**证明:**\n", 296 | "\n", 297 | "(a)$B=A^TA=B^T,cond(B)_2=\\sqrt{\\frac{\\lambda_{max}(B^TB)}{\\lambda_{min}(B^TB)}}=\\sqrt{\\frac{\\lambda_{max}(B^2)}{\\lambda_{min}(B^2)}}=\\frac{\\lambda_{max}(B)}{\\lambda_{min}(B)}$\n", 298 | "\n", 299 | "(b)构造分块矩阵\n", 300 | "$$\n", 301 | "\\left(\n", 302 | "\\begin{array}{cc}\n", 303 | "\\lambda I_n&A\\\\\n", 304 | "A^T& I_n\n", 305 | "\\end{array}\n", 306 | "\\right)\n", 307 | "$$\n", 308 | "用两种方式把矩阵变成分块对角,计算行列式.\n", 309 | "***" 310 | ] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "metadata": {}, 315 | "source": [ 316 | "9.设$A\\in\\mathbb{R}^{n\\times n}$为严格对角占优阵,求证$A$有唯一三角分解:$A=LU$,其中$L$为单位下三角阵,$U$为上三角阵。" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": {}, 322 | "source": [ 323 | "**证明:**由于$A$严格对角占优,那么$L,U$均可逆,不妨假设不唯一,则$A=L_1U_1=L_2U_2$.\n", 324 | "\n", 325 | "$L_2^{-1}L_1=U_2U_1^{-1}$,由于单位下三角的逆和乘积还是单位下三角,上三角的逆和乘积也还是上三角,则$L_2^{-1}L_1=U_2U_1^{-1}=I$.\n", 326 | "***" 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "metadata": {}, 332 | "source": [ 333 | "10.设$A\\in\\mathbb{R}^{n\\times n}$为非奇异矩阵,则存在正交阵$P_1,P_2,\\ldots,P_{n-1}$使\n", 334 | "$$\n", 335 | "P_{n-1}\\ldots P_2P_1A=L \\text{(为下三角阵)}\n", 336 | "$$\n", 337 | "且$A$有分解式:$A=QL$,其中$Q$为正交阵,$L$为下三角矩阵。" 338 | ] 339 | }, 340 | { 341 | "cell_type": "markdown", 342 | "metadata": {}, 343 | "source": [ 344 | "**分析:**豪斯荷尔德变换能够把能量逐渐集中在一个地方,然后使用归纳法即可." 345 | ] 346 | }, 347 | { 348 | "cell_type": "markdown", 349 | "metadata": {}, 350 | "source": [ 351 | "11.计算希尔伯特矩阵$H_4$的条件数$cond(H_4)_\\infty$" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": 37, 357 | "metadata": {}, 358 | "outputs": [ 359 | { 360 | "name": "stdout", 361 | "output_type": "stream", 362 | "text": [ 363 | "2.083333333333333\n", 364 | "140.00000000000955\n", 365 | "cond: 291.6666666666865\n" 366 | ] 367 | } 368 | ], 369 | "source": [ 370 | "import numpy as np\n", 371 | "\n", 372 | "def infty_norm(A):\n", 373 | " return np.max(np.sum(A,axis=0))\n", 374 | "\n", 375 | "H = np.zeros((4,4))\n", 376 | "for i in range(4):\n", 377 | " for j in range(4):\n", 378 | " H[i,j] = 1/(i+j+1)\n", 379 | " \n", 380 | "H_inv = np.linalg.inv(H)\n", 381 | "print(infty_norm(H))\n", 382 | "print(infty_norm(H_inv))\n", 383 | "cond = infty_norm(H)*infty_norm(H_inv)\n", 384 | "print('cond:',cond)" 385 | ] 386 | }, 387 | { 388 | "cell_type": "markdown", 389 | "metadata": {}, 390 | "source": [ 391 | "12.设$A$为非奇异矩阵,且$\\|A^{-1}\\|\\|\\delta A\\|<1$,求证$(A+\\delta A)^{-1}$存在,且有估计\n", 392 | "$$\\frac{\\| A^{-1}-(A+\\delta A)^{-1}\\|}{\\left\\|A^{-1}\\right\\|} \\leqslant \\frac{\\operatorname{cond}(A) \\frac{\\|\\delta A\\|}{\\|A\\|}}{1-\\operatorname{cond}(A) \\frac{\\|\\delta A\\|}{\\|A\\|}}$$" 393 | ] 394 | }, 395 | { 396 | "cell_type": "markdown", 397 | "metadata": { 398 | "collapsed": true 399 | }, 400 | "source": [ 401 | "**证明:**$\\|A^{-1}\\delta A\\|\\leq\\|A^{-1}\\|\\|\\delta A\\|<1$,\n", 402 | "$(A+\\delta A)^{-1}=A^{-1}(I+A^{-1}\\delta A)^{-1}$,\n", 403 | "而$\\rho(A^{-1}\\delta A)^{-1})\\leq\\|A^{-1}\\delta A\\|< 1$,故可逆.\n", 404 | "\n", 405 | "左右都稍微凑凑很容易的,上面那个变形比较关键,最后一步用到逆的估计式(P178)." 406 | ] 407 | }, 408 | { 409 | "cell_type": "code", 410 | "execution_count": null, 411 | "metadata": { 412 | "collapsed": true 413 | }, 414 | "outputs": [], 415 | "source": [] 416 | } 417 | ], 418 | "metadata": { 419 | "kernelspec": { 420 | "display_name": "Python 3", 421 | "language": "python", 422 | "name": "python3" 423 | }, 424 | "language_info": { 425 | "codemirror_mode": { 426 | "name": "ipython", 427 | "version": 3 428 | }, 429 | "file_extension": ".py", 430 | "mimetype": "text/x-python", 431 | "name": "python", 432 | "nbconvert_exporter": "python", 433 | "pygments_lexer": "ipython3", 434 | "version": "3.6.2" 435 | } 436 | }, 437 | "nbformat": 4, 438 | "nbformat_minor": 2 439 | } 440 | -------------------------------------------------------------------------------- /ch4/ex4.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了解线性方程组的直接法\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "\n", 14 | "原创内容,如需转载需征得作者同意。\n", 15 | "\n", 16 | "Copyright©2020 lizhemin\n", 17 | "***" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "source": [ 26 | "1.设$A\\in\\mathbb{R}^{n\\times n}$为对称正定阵,且经过高斯消去法这一步,$A$约化为\n", 27 | "$$\\left[\\begin{array}{ll}\n", 28 | "a_{11} & a_{1}^{T} \\\\\n", 29 | "0 & A_{2}\n", 30 | "\\end{array}\\right]$$\n", 31 | "求证:$A_2$也是对称正定阵。" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "**证明:**\n", 39 | "\n", 40 | "不妨假设$LA = \\left[\\begin{array}{ll}\n", 41 | "a_{11} & a_{1}^{T} \\\\\n", 42 | "0 & A_{2}\n", 43 | "\\end{array}\\right]$,那么$LAL^T = \\left[\\begin{array}{ll}\n", 44 | "a_{11} & 0 \\\\\n", 45 | "0 & A_{2}\n", 46 | "\\end{array}\\right]$.\n", 47 | "\n", 48 | "由于$A$对称正定,则$A=BB^T$,那么$LAL^T=LBB^TL^T=LB(LB)^T$,必为对称正定.\n", 49 | "***" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "2.设$A$为严格对角占优阵,即$|a_{ii}|>\\sum_{j=1,j\\neq i}^n|a_{ij}|(i=1,2,\\ldots,n),$且经过一步高斯消去法化为\n", 57 | "$$\\left[\\begin{array}{cc}\n", 58 | "a_{11} & a_{1}^{T} \\\\\n", 59 | "0 & A_{2}\n", 60 | "\\end{array}\\right]$$\n", 61 | "求证:$A_2$也是严格对角占优阵。" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "由归纳法易得,写出$a_{22}'=a_{22}-\\frac{a_{21}}{a_{11}}\\cdot a_{12}>0$\n", 69 | "***" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "3.设$L_k$是指标为$k$的初等下三角阵,且\n", 77 | "$$\\tilde{\\boldsymbol{L}}_{k}=\\boldsymbol{I}_{i j} \\boldsymbol{L}_{k} \\boldsymbol{I}_{i, j}(i, j, k)$$\n", 78 | "其中$\\boldsymbol{I}_{ij}$为初等置换阵,求证:$\\tilde{L}_k$也是指标为$k$的初等下三角阵。" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": {}, 84 | "source": [ 85 | "**分析:**用置换矩阵的性质,显然.\n", 86 | "\n", 87 | "或回到定义出发进行证明,$I_{ij}=I-(e_i-e_j)(e_i-e_j)^T$,$L_k=I-l_ke_k^T$\n", 88 | "***" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "4.用选主元三角分解法求解\n", 96 | "$$\n", 97 | "\\left(\n", 98 | "\\begin{array}{lllllll}\n", 99 | "1&1&1&1&1&1&1\\\\\n", 100 | "2&1&1&1&1&1&1\\\\\n", 101 | "3&2&1&1&1&1&1\\\\\n", 102 | "4&3&2&1&1&1&1\\\\\n", 103 | "5&4&3&2&1&1&1\\\\\n", 104 | "6&5&4&3&2&1&1\\\\\n", 105 | "7&6&5&4&3&2&1\\\\\n", 106 | "\\end{array}\n", 107 | "\\right)\n", 108 | "\\left(\n", 109 | "\\begin{array}{l}\n", 110 | "x_1\\\\x_2\\\\x_3\\\\x_4\\\\x_5\\\\x_6\\\\x_7\\\\\n", 111 | "\\end{array}\n", 112 | "\\right)=\n", 113 | "\\left(\n", 114 | "\\begin{array}{l}\n", 115 | "7\\\\8\\\\10\\\\13\\\\17\\\\22\\\\28\\\\\n", 116 | "\\end{array}\n", 117 | "\\right)\n", 118 | "$$" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 34, 124 | "metadata": {}, 125 | "outputs": [ 126 | { 127 | "name": "stdout", 128 | "output_type": "stream", 129 | "text": [ 130 | "real b: [[28]\n", 131 | " [ 3]\n", 132 | " [14]\n", 133 | " [ 9]\n", 134 | " [ 5]\n", 135 | " [ 1]\n", 136 | " [ 0]] b_calculate: [[28.]\n", 137 | " [ 3.]\n", 138 | " [14.]\n", 139 | " [ 9.]\n", 140 | " [ 5.]\n", 141 | " [ 1.]\n", 142 | " [ 0.]]\n" 143 | ] 144 | } 145 | ], 146 | "source": [ 147 | "import numpy as np\n", 148 | "import copy\n", 149 | "\n", 150 | "def swap(a,b):\n", 151 | " mid = copy.copy(a)\n", 152 | " a = copy.copy(b)\n", 153 | " b = copy.copy(mid)\n", 154 | " return a,b\n", 155 | "\n", 156 | "def choose_max(A,b,i):\n", 157 | " index = np.argmax(A[i:,i])+i\n", 158 | " A[index,:],A[i,:] = swap(A[index,:],A[i,:])\n", 159 | " b[index,:],b[i,:] = swap(b[index,:],b[i,:])\n", 160 | " return A,b\n", 161 | "\n", 162 | "def minus(A,b,i):\n", 163 | " m = A.shape[0]\n", 164 | " \n", 165 | " for j in range(i+1,m):\n", 166 | " scale = A[j,i]/A[i,i]\n", 167 | " #print(scale)\n", 168 | " #print(A[j,:])\n", 169 | " A[j,:] = A[j,:]-A[i,:]*scale\n", 170 | " #print(A[j,:])\n", 171 | " b[j,:] = b[j,:]-b[i,:]*scale\n", 172 | " return A,b\n", 173 | "\n", 174 | "def solve_Ab(A,b):\n", 175 | " n = A.shape[1]\n", 176 | " x = np.zeros((n,1))\n", 177 | " for i in range(n):\n", 178 | " i = n-i-1\n", 179 | " sum_ax = 0\n", 180 | " for j in range(i,n):\n", 181 | " sum_ax += A[i,j]*x[j]\n", 182 | " x[i] = (b[i]-sum_ax)/A[i,i]\n", 183 | " return x\n", 184 | "\n", 185 | "def main_solve(A,b):\n", 186 | " # A:[m,n],b:[m,1] m>=n\n", 187 | " if A.shape[0] != b.shape[0]:\n", 188 | " raise('shape of A,b is not equal!')\n", 189 | " m = A.shape[0]\n", 190 | " n = A.shape[1]\n", 191 | " for i in range(m-1):\n", 192 | " A,b = choose_max(A,b,i)\n", 193 | " A,b = minus(A,b,i)\n", 194 | " #print(A)\n", 195 | " #return A,b\n", 196 | " return solve_Ab(A,b)\n", 197 | " \n", 198 | " \n", 199 | "\n", 200 | "A = np.ones((7,7))\n", 201 | "for i in range(7):\n", 202 | " for j in range(7):\n", 203 | " if i-j>0:\n", 204 | " A[i,j] = i-j+1\n", 205 | "b = np.array([7,8,10,13,17,22,28]).reshape(-1,1)\n", 206 | "x = main_solve(A,b)\n", 207 | "\n", 208 | "b_cal = np.dot(A,x)\n", 209 | "print('real b:',b,'b_calculate:',b_cal)" 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "metadata": {}, 215 | "source": [ 216 | "5.求证:\n", 217 | "\n", 218 | "(a)$\\|x\\|_\\infty\\leq\\|x\\|_1\\leq n\\|x\\|_\\infty$\n", 219 | "\n", 220 | "(b)$\\frac{1}{\\sqrt{n}}\\|A\\|_F\\leq \\|A\\|_2\\leq \\|A\\|_F$" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "**证明:**\n", 228 | "\n", 229 | "(a)由定义显然\n", 230 | "\n", 231 | "(b)$\\left\\|A\\right\\|_F^2=\\sum_{i,j=1}^na_{ij}^2,\\left\\|A\\right\\|_2^2=\\lambda_{max}(A^TA)$\n", 232 | "\n", 233 | "而$tr(A^TA)=\\sum_{i=1}^na_{ii}^2=\\sum_{i=1}^n\\lambda_i$,剩下的显然.\n", 234 | "***" 235 | ] 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "metadata": {}, 240 | "source": [ 241 | "6.设$A$为非奇异阵,求证:\n", 242 | "$$\n", 243 | "\\frac{1}{\\|A^{-1}\\|_\\infty}=\n", 244 | "min_{y\\neq 0}\\frac{\\|A y\\|_\\infty}{\\|y\\|_\\infty}\n", 245 | "$$" 246 | ] 247 | }, 248 | { 249 | "cell_type": "markdown", 250 | "metadata": {}, 251 | "source": [ 252 | "**引理:**若$A^{-1}$存在,则$\\left\\|A\\right\\|_v=\\max\\frac{\\left\\|Ax\\right\\|_v}{\\left\\|x\\right\\|_v}=\\max\\frac{\\left\\|AA^{-1}x\\right\\|_v}{\\left\\|A^{-1}x\\right\\|_v}=\\max\\frac{\\left\\|x\\right\\|_v}{\\left\\|A^{-1}x\\right\\|_v}$\n", 253 | "***" 254 | ] 255 | }, 256 | { 257 | "cell_type": "markdown", 258 | "metadata": {}, 259 | "source": [ 260 | "7.设$A$为$n$阶非奇异阵,求证:\n", 261 | "\n", 262 | "(a)$\\|x\\|_\\infty\\leq\\|x\\|_2\\leq n\\|x\\|_\\infty$\n", 263 | "\n", 264 | "(b)$\\frac{1}{\\sqrt{n}}\\|A\\|_2\\leq \\|A\\|_\\infty\\leq \\|A\\|_2$\n", 265 | "\n", 266 | "(c)$\\frac{1}{n}\\leq\\frac{cond(A)_\\infty}{cond(A)_2}\\leq n$" 267 | ] 268 | }, 269 | { 270 | "cell_type": "markdown", 271 | "metadata": {}, 272 | "source": [ 273 | "前两个无需多言\n", 274 | "\n", 275 | "(c)$cond(A)_{\\infty}=\\left\\|A\\right\\|_{\\infty}\\left\\|A^{-1}\\right\\|_{\\infty}$\n", 276 | "结合(b),$\\frac{1}{n}\\left\\|A\\right\\|_2\\left\\|A^{-1}\\right\\|_2\\leq cond(A)_{\\infty}\\leq\\left\\|A\\right\\|_2\\left\\|A^{-1}\\right\\|_2$\n", 277 | "***" 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": {}, 283 | "source": [ 284 | "8.设$A\\in\\mathbb{R}^{n\\times n}$非奇异矩阵,求证:\n", 285 | "\n", 286 | "(a)$cond(A^TA)_2=[cond(A)_2]^2$\n", 287 | "\n", 288 | "(b)$\\lambda(A^TA)=\\lambda(AA^T)$" 289 | ] 290 | }, 291 | { 292 | "cell_type": "markdown", 293 | "metadata": {}, 294 | "source": [ 295 | "**证明:**\n", 296 | "\n", 297 | "(a)$B=A^TA=B^T,cond(B)_2=\\sqrt{\\frac{\\lambda_{max}(B^TB)}{\\lambda_{min}(B^TB)}}=\\sqrt{\\frac{\\lambda_{max}(B^2)}{\\lambda_{min}(B^2)}}=\\frac{\\lambda_{max}(B)}{\\lambda_{min}(B)}$\n", 298 | "\n", 299 | "(b)构造分块矩阵\n", 300 | "$$\n", 301 | "\\left(\n", 302 | "\\begin{array}{cc}\n", 303 | "\\lambda I_n&A\\\\\n", 304 | "A^T& I_n\n", 305 | "\\end{array}\n", 306 | "\\right)\n", 307 | "$$\n", 308 | "用两种方式把矩阵变成分块对角,计算行列式.\n", 309 | "***" 310 | ] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "metadata": {}, 315 | "source": [ 316 | "9.设$A\\in\\mathbb{R}^{n\\times n}$为严格对角占优阵,求证$A$有唯一三角分解:$A=LU$,其中$L$为单位下三角阵,$U$为上三角阵。" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": {}, 322 | "source": [ 323 | "**证明:**由于$A$严格对角占优,那么$L,U$均可逆,不妨假设不唯一,则$A=L_1U_1=L_2U_2$.\n", 324 | "\n", 325 | "$L_2^{-1}L_1=U_2U_1^{-1}$,由于单位下三角的逆和乘积还是单位下三角,上三角的逆和乘积也还是上三角,则$L_2^{-1}L_1=U_2U_1^{-1}=I$.\n", 326 | "***" 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "metadata": {}, 332 | "source": [ 333 | "10.设$A\\in\\mathbb{R}^{n\\times n}$为非奇异矩阵,则存在正交阵$P_1,P_2,\\ldots,P_{n-1}$使\n", 334 | "$$\n", 335 | "P_{n-1}\\ldots P_2P_1A=L \\text{(为下三角阵)}\n", 336 | "$$\n", 337 | "且$A$有分解式:$A=QL$,其中$Q$为正交阵,$L$为下三角矩阵。" 338 | ] 339 | }, 340 | { 341 | "cell_type": "markdown", 342 | "metadata": {}, 343 | "source": [ 344 | "**分析:**豪斯荷尔德变换能够把能量逐渐集中在一个地方,然后使用归纳法即可." 345 | ] 346 | }, 347 | { 348 | "cell_type": "markdown", 349 | "metadata": {}, 350 | "source": [ 351 | "11.计算希尔伯特矩阵$H_4$的条件数$cond(H_4)_\\infty$" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": 37, 357 | "metadata": {}, 358 | "outputs": [ 359 | { 360 | "name": "stdout", 361 | "output_type": "stream", 362 | "text": [ 363 | "2.083333333333333\n", 364 | "140.00000000000955\n", 365 | "cond: 291.6666666666865\n" 366 | ] 367 | } 368 | ], 369 | "source": [ 370 | "import numpy as np\n", 371 | "\n", 372 | "def infty_norm(A):\n", 373 | " return np.max(np.sum(A,axis=0))\n", 374 | "\n", 375 | "H = np.zeros((4,4))\n", 376 | "for i in range(4):\n", 377 | " for j in range(4):\n", 378 | " H[i,j] = 1/(i+j+1)\n", 379 | " \n", 380 | "H_inv = np.linalg.inv(H)\n", 381 | "print(infty_norm(H))\n", 382 | "print(infty_norm(H_inv))\n", 383 | "cond = infty_norm(H)*infty_norm(H_inv)\n", 384 | "print('cond:',cond)" 385 | ] 386 | }, 387 | { 388 | "cell_type": "markdown", 389 | "metadata": {}, 390 | "source": [ 391 | "12.设$A$为非奇异矩阵,且$\\|A^{-1}\\|\\|\\delta A\\|<1$,求证$(A+\\delta A)^{-1}$存在,且有估计\n", 392 | "$$\\frac{\\| A^{-1}-(A+\\delta A)^{-1}\\|}{\\left\\|A^{-1}\\right\\|} \\leqslant \\frac{\\operatorname{cond}(A) \\frac{\\|\\delta A\\|}{\\|A\\|}}{1-\\operatorname{cond}(A) \\frac{\\|\\delta A\\|}{\\|A\\|}}$$" 393 | ] 394 | }, 395 | { 396 | "cell_type": "markdown", 397 | "metadata": { 398 | "collapsed": true 399 | }, 400 | "source": [ 401 | "**证明:**$\\|A^{-1}\\delta A\\|\\leq\\|A^{-1}\\|\\|\\delta A\\|<1$,\n", 402 | "$(A+\\delta A)^{-1}=A^{-1}(I+A^{-1}\\delta A)^{-1}$,\n", 403 | "而$\\rho(A^{-1}\\delta A)^{-1})\\leq\\|A^{-1}\\delta A\\|< 1$,故可逆.\n", 404 | "\n", 405 | "左右都稍微凑凑很容易的,上面那个变形比较关键,最后一步用到逆的估计式(P178)." 406 | ] 407 | }, 408 | { 409 | "cell_type": "code", 410 | "execution_count": null, 411 | "metadata": { 412 | "collapsed": true 413 | }, 414 | "outputs": [], 415 | "source": [] 416 | } 417 | ], 418 | "metadata": { 419 | "kernelspec": { 420 | "display_name": "Python 3", 421 | "language": "python", 422 | "name": "python3" 423 | }, 424 | "language_info": { 425 | "codemirror_mode": { 426 | "name": "ipython", 427 | "version": 3 428 | }, 429 | "file_extension": ".py", 430 | "mimetype": "text/x-python", 431 | "name": "python", 432 | "nbconvert_exporter": "python", 433 | "pygments_lexer": "ipython3", 434 | "version": "3.6.2" 435 | } 436 | }, 437 | "nbformat": 4, 438 | "nbformat_minor": 2 439 | } 440 | -------------------------------------------------------------------------------- /ch5/.ipynb_checkpoints/ex5-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了解大型稀疏线性方程组的迭代法\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "\n", 14 | "原创内容,如需转载需征得作者同意。\n", 15 | "\n", 16 | "Copyright©2020 lizhemin\n", 17 | "***" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "source": [ 26 | "1.用SOR方法解方程组(取$\\omega=1.03,\\omega=1,\\omega=1.1$)\n", 27 | "$$\n", 28 | "\\left\\{\n", 29 | "\\begin{array}{c}\n", 30 | "4x_1-x_2=1\\\\\n", 31 | "-x_1+4x_2-x_3=4\\\\\n", 32 | "-x_2+4x_3=-3\n", 33 | "\\end{array}\n", 34 | "\\right.\n", 35 | "$$\n", 36 | "要求当$\\left\\|x^*-x^{(k)}\\right\\|_{\\infty}<5\\times 10^{-6}$时迭代终止,其中$x^*=(0.5,1,-0.5)^T$,并对每一个$\\omega$值确定迭代次数." 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 14, 42 | "metadata": {}, 43 | "outputs": [ 44 | { 45 | "name": "stdout", 46 | "output_type": "stream", 47 | "text": [ 48 | "omega= 1.03 ,ite= 13\n", 49 | "omega= 1 ,ite= 12\n", 50 | "omega= 1.1 ,ite= 17\n" 51 | ] 52 | } 53 | ], 54 | "source": [ 55 | "import numpy as np\n", 56 | "import copy\n", 57 | "\n", 58 | "def DLU(A):\n", 59 | " # Input matrix n\\times n\n", 60 | " n = A.shape[0]\n", 61 | " D = np.zeros((n,n))\n", 62 | " L = np.zeros((n,n))\n", 63 | " U = np.zeros((n,n))\n", 64 | " for i in range(n):\n", 65 | " for j in range(n):\n", 66 | " if i==j:\n", 67 | " D[i,i] = A[i,i]\n", 68 | " elif i>j:\n", 69 | " L[i,j] = -A[i,j]\n", 70 | " else:\n", 71 | " U[i,j] = -A[i,j]\n", 72 | " return D,L,U\n", 73 | "\n", 74 | "def SOR(A,b,epsilon,omega=1):\n", 75 | " k = 0\n", 76 | " N = A.shape[0]\n", 77 | " x = np.zeros((N,1))\n", 78 | " while k==0 or abs(P0)>=epsilon:\n", 79 | " P0 = 0\n", 80 | " Ax = np.dot(A,x)\n", 81 | " for i in range(N):\n", 82 | " #Remark, this formula is a little different from book, I think algorithm on book have some wrong.\n", 83 | " dx = omega/A[i,i]*(b[i]-Ax[i])\n", 84 | " P = copy.copy(dx)\n", 85 | " if abs(P)>abs(P0):\n", 86 | " P0 = copy.copy(P)\n", 87 | " x[i] = x[i]+P\n", 88 | " k += 1\n", 89 | " return k-1,omega,x\n", 90 | "\n", 91 | "A = np.array([[4,-1,0],[-1,4,-1],[0,-1,4]])\n", 92 | "b = np.array([[1],[4],[-3]])\n", 93 | "for omega in [1.03,1,1.1]:\n", 94 | " ite,ome,x = SOR(A,b,epsilon=5e-6,omega=omega)\n", 95 | " print('omega=',omega,',ite=',ite)\n", 96 | "\n", 97 | " " 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "2.设有方程组$Ax=b$,其中$A\\in\\mathbb{R}^{n\\times n}$为对称正定阵(且设$A$的特征值满足:$0<\\alpha\\leq\\lambda(A)\\leq \\beta$),又设有迭代法\n", 105 | "$$\n", 106 | "x^{(k+1)}=x^{(k)}+\\omega(b-Ax^{(k)})\\quad (k=0,1,\\ldots)\n", 107 | "$$\n", 108 | "求证:当$0<\\omega<\\frac{2}{\\beta}$时,上述迭代法收敛." 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "**证明:**迭代法收敛通常都是验证谱半径小于1\n", 116 | "\n", 117 | "考察矩阵$I-\\omega A$,不难得到特征值为$1-\\omega \\lambda$\n", 118 | "***" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "3.求证矩阵\n", 126 | "$$\n", 127 | "A=\\left(\n", 128 | "\\begin{array}{ccc}\n", 129 | "1&a&a\\\\\n", 130 | "a&1&a\\\\\n", 131 | "a&a&1\\\\\n", 132 | "\\end{array}\n", 133 | "\\right)\n", 134 | "$$\n", 135 | "对于$-0.50$时,上述迭代法收敛." 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "**证明:**即考虑$det(\\lambda I-B)=0$,当$\\omega>0$时$|\\lambda|<1$" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": {}, 220 | "source": [ 221 | "6.设有$Ax=b,A\\in\\mathbb{R}^{n\\times n}$,且设$A$为严格对角占优阵,$0<\\omega\\leq 1$,求证解$Ax=b$的SOR方法收敛." 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": {}, 227 | "source": [ 228 | "**证明:**回归定义,考虑$|\\lambda|\\geq 1$时会使得迭代矩阵严格对角占优\n", 229 | "***" 230 | ] 231 | }, 232 | { 233 | "cell_type": "markdown", 234 | "metadata": {}, 235 | "source": [ 236 | "7.设$Ax=b$,或$f(x)=\\frac{1}{2}(Ax,x)-(b,x),A\\in\\mathbb{R}^{n\\times n}$为对称正定阵,又设$\\{x_k\\}$为cg方法产生的近似解序列,求证:\n", 237 | "$$\n", 238 | "f(x_{k+1})j:\n", 69 | " L[i,j] = -A[i,j]\n", 70 | " else:\n", 71 | " U[i,j] = -A[i,j]\n", 72 | " return D,L,U\n", 73 | "\n", 74 | "def SOR(A,b,epsilon,omega=1):\n", 75 | " k = 0\n", 76 | " N = A.shape[0]\n", 77 | " x = np.zeros((N,1))\n", 78 | " while k==0 or abs(P0)>=epsilon:\n", 79 | " P0 = 0\n", 80 | " Ax = np.dot(A,x)\n", 81 | " for i in range(N):\n", 82 | " #Remark, this formula is a little different from book, I think algorithm on book have some wrong.\n", 83 | " dx = omega/A[i,i]*(b[i]-Ax[i])\n", 84 | " P = copy.copy(dx)\n", 85 | " if abs(P)>abs(P0):\n", 86 | " P0 = copy.copy(P)\n", 87 | " x[i] = x[i]+P\n", 88 | " k += 1\n", 89 | " return k-1,omega,x\n", 90 | "\n", 91 | "A = np.array([[4,-1,0],[-1,4,-1],[0,-1,4]])\n", 92 | "b = np.array([[1],[4],[-3]])\n", 93 | "for omega in [1.03,1,1.1]:\n", 94 | " ite,ome,x = SOR(A,b,epsilon=5e-6,omega=omega)\n", 95 | " print('omega=',omega,',ite=',ite)\n", 96 | "\n", 97 | " " 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "2.设有方程组$Ax=b$,其中$A\\in\\mathbb{R}^{n\\times n}$为对称正定阵(且设$A$的特征值满足:$0<\\alpha\\leq\\lambda(A)\\leq \\beta$),又设有迭代法\n", 105 | "$$\n", 106 | "x^{(k+1)}=x^{(k)}+\\omega(b-Ax^{(k)})\\quad (k=0,1,\\ldots)\n", 107 | "$$\n", 108 | "求证:当$0<\\omega<\\frac{2}{\\beta}$时,上述迭代法收敛." 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "**证明:**迭代法收敛通常都是验证谱半径小于1\n", 116 | "\n", 117 | "考察矩阵$I-\\omega A$,不难得到特征值为$1-\\omega \\lambda$\n", 118 | "***" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "3.求证矩阵\n", 126 | "$$\n", 127 | "A=\\left(\n", 128 | "\\begin{array}{ccc}\n", 129 | "1&a&a\\\\\n", 130 | "a&1&a\\\\\n", 131 | "a&a&1\\\\\n", 132 | "\\end{array}\n", 133 | "\\right)\n", 134 | "$$\n", 135 | "对于$-0.50$时,上述迭代法收敛." 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "**证明:**即考虑$det(\\lambda I-B)=0$,当$\\omega>0$时$|\\lambda|<1$" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": {}, 220 | "source": [ 221 | "6.设有$Ax=b,A\\in\\mathbb{R}^{n\\times n}$,且设$A$为严格对角占优阵,$0<\\omega\\leq 1$,求证解$Ax=b$的SOR方法收敛." 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": {}, 227 | "source": [ 228 | "**证明:**回归定义,考虑$|\\lambda|\\geq 1$时会使得迭代矩阵严格对角占优\n", 229 | "***" 230 | ] 231 | }, 232 | { 233 | "cell_type": "markdown", 234 | "metadata": {}, 235 | "source": [ 236 | "7.设$Ax=b$,或$f(x)=\\frac{1}{2}(Ax,x)-(b,x),A\\in\\mathbb{R}^{n\\times n}$为对称正定阵,又设$\\{x_k\\}$为cg方法产生的近似解序列,求证:\n", 237 | "$$\n", 238 | "f(x_{k+1})error:\n", 68 | " x_old = copy.copy(x_now)\n", 69 | " x_now = np.dot(A,x_old)\n", 70 | " lam = x_now[0]/x_old[0]\n", 71 | " x_now = x_now/norm_2(x_now)\n", 72 | " print(lam)\n", 73 | " return lam,x_now\n", 74 | " \n", 75 | "def norm_2(x):\n", 76 | " return np.mean(x**2)\n", 77 | "\n", 78 | "A = np.array([[7,3,-2],[3,4,-1],[-2,-1,3]])\n", 79 | "x = np.ones((3,1))\n", 80 | "eig_value,eig_vec = eig(A,x)\n", 81 | "print('eig_value:',eig_value,'eig_vec',eig_vec)\n", 82 | "print(np.dot(A,eig_vec)/eig_value)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": {}, 88 | "source": [ 89 | "2.用反幂法求矩阵\n", 90 | "$$A=\\left(\\begin{array}{lll}\n", 91 | "6 & 2 & 1 \\\\\n", 92 | "2 & 3 & 1 \\\\\n", 93 | "1 & 1 & 1\n", 94 | "\\end{array}\\right)$$\n", 95 | "的最接近6的特征值及对应的特征向量" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "分析:相当于迭代式变成$x_n = A x_{n+1}$,需要解线性方程组得到答案,这个解的过程就要用到之前的迭代法或直接解法,这里使用迭代法" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 21, 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "name": "stdout", 112 | "output_type": "stream", 113 | "text": [ 114 | "[[1.82400590e-06]\n", 115 | " [2.90719902e-06]\n", 116 | " [1.00000485e+00]]\n", 117 | "[-60917.24214878]\n", 118 | "[1.33332229]\n", 119 | "[1.49994327]\n", 120 | "[1.64817412]\n", 121 | "[1.7041903]\n", 122 | "[1.72080319]\n", 123 | "[1.72562825]\n", 124 | "[1.72676236]\n", 125 | "[1.72725684]\n", 126 | "eig_value: [1.72725684] eig_vec [[-0.07962089]\n", 127 | " [-0.64686536]\n", 128 | " [ 1.72533451]]\n", 129 | "[[-0.07961851]\n", 130 | " [-0.64688429]\n", 131 | " [ 1.7253954 ]]\n" 132 | ] 133 | } 134 | ], 135 | "source": [ 136 | "import numpy as np\n", 137 | "import copy\n", 138 | "\n", 139 | "#####Sollve linear functionals ######\n", 140 | "def DLU(A):\n", 141 | " # Input matrix n\\times n\n", 142 | " n = A.shape[0]\n", 143 | " D = np.zeros((n,n))\n", 144 | " L = np.zeros((n,n))\n", 145 | " U = np.zeros((n,n))\n", 146 | " for i in range(n):\n", 147 | " for j in range(n):\n", 148 | " if i==j:\n", 149 | " D[i,i] = A[i,i]\n", 150 | " elif i>j:\n", 151 | " L[i,j] = -A[i,j]\n", 152 | " else:\n", 153 | " U[i,j] = -A[i,j]\n", 154 | " return D,L,U\n", 155 | "\n", 156 | "def SOR(A,b,epsilon,omega=1):\n", 157 | " k = 0\n", 158 | " N = A.shape[0]\n", 159 | " x = np.zeros((N,1))\n", 160 | " while k==0 or abs(P0)>=epsilon:\n", 161 | " P0 = 0\n", 162 | " Ax = np.dot(A,x)\n", 163 | " for i in range(N):\n", 164 | " #Remark, this formula is a little different from book, I think algorithm on book have some wrong.\n", 165 | " dx = omega/A[i,i]*(b[i]-Ax[i])\n", 166 | " P = copy.copy(dx)\n", 167 | " if abs(P)>abs(P0):\n", 168 | " P0 = copy.copy(P)\n", 169 | " x[i] = x[i]+P\n", 170 | " k += 1\n", 171 | " return k-1,omega,x\n", 172 | "\n", 173 | "def main_solve(A,b):\n", 174 | " k,omega,x = SOR(A,b,1e-5,omega=1)\n", 175 | " return x\n", 176 | "\n", 177 | "#####find the optimal eig######\n", 178 | "def eig(A,x,error=1e-4):\n", 179 | " n = A.shape[0]\n", 180 | " x_old = copy.copy(x)\n", 181 | " x_now = main_solve(A,x_old)\n", 182 | " print(x_now)\n", 183 | " lam = x_now[0]/x_old[0]\n", 184 | " while np.abs(lam- main_solve(A,x_now)[0]/x_now[0])>error:\n", 185 | " x_old = copy.copy(x_now)\n", 186 | " x_now = main_solve(A,x_old)\n", 187 | " lam = x_now[0]/x_old[0]\n", 188 | " x_now = x_now/norm_2(x_now)\n", 189 | " print(lam)\n", 190 | " return lam,x_now\n", 191 | " \n", 192 | "def norm_2(x):\n", 193 | " return np.mean(x**2)\n", 194 | "\n", 195 | "#####start use inverse power method#####\n", 196 | "A = np.array([[6,2,1],[2,3,1],[1,1,1]])\n", 197 | "x = np.array([[1],[1],[1]])\n", 198 | "eig_value,eig_vec = eig(A,x)\n", 199 | "print('eig_value:',eig_value,'eig_vec',eig_vec)\n", 200 | "print(main_solve(A,eig_vec)/eig_value)\n" 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "metadata": {}, 206 | "source": [ 207 | "3.用雅可比方法计算\n", 208 | "$$A=\\left(\\begin{array}{ccc}\n", 209 | "1 & 1 & 0.5 \\\\\n", 210 | "1 & 1 & 0.25 \\\\\n", 211 | "0.5 & 0.25 & 2\n", 212 | "\\end{array}\\right)$$\n", 213 | "的全部特征值及特征向量\n" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": {}, 219 | "source": [ 220 | "**分析**:jacobian方法适用于求解对称矩阵,核心思想是通过旋转减少非对角线上元素的能量。" 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": 92, 226 | "metadata": {}, 227 | "outputs": [ 228 | { 229 | "name": "stdout", 230 | "output_type": "stream", 231 | "text": [ 232 | "[[1. 1. 0.5 ]\n", 233 | " [1. 1. 0.25]\n", 234 | " [0.5 0.25 2. ]]\n", 235 | "[[ 2.00000000e+00 -8.53284318e-17 5.30330086e-01]\n", 236 | " [ 0.00000000e+00 0.00000000e+00 -1.76776695e-01]\n", 237 | " [ 5.30330086e-01 -1.76776695e-01 2.00000000e+00]]\n", 238 | "0.5303300858899107\n", 239 | "[[ 2.00000000e+00 -8.53284318e-17 5.30330086e-01]\n", 240 | " [ 0.00000000e+00 0.00000000e+00 -1.76776695e-01]\n", 241 | " [ 5.30330086e-01 -1.76776695e-01 2.00000000e+00]]\n", 242 | "[[ 2.53033009e+00 -1.25000000e-01 5.34494463e-17]\n", 243 | " [-1.25000000e-01 0.00000000e+00 -1.25000000e-01]\n", 244 | " [ 7.68514419e-17 -1.25000000e-01 1.46966991e+00]]\n", 245 | "0.12500000000000003\n", 246 | "[[ 2.53033009e+00 -1.25000000e-01 5.34494463e-17]\n", 247 | " [-1.25000000e-01 0.00000000e+00 -1.25000000e-01]\n", 248 | " [ 7.68514419e-17 -1.25000000e-01 1.46966991e+00]]\n", 249 | "[[ 2.53649017e+00 -5.40059762e-18 6.15262039e-03]\n", 250 | " [ 5.30552331e-17 -6.16008695e-03 -1.24848489e-01]\n", 251 | " [ 6.15262039e-03 -1.24848489e-01 1.46966991e+00]]\n", 252 | "0.12484848922734756\n", 253 | "[[ 2.53649017e+00 -5.40059762e-18 6.15262039e-03]\n", 254 | " [ 5.30552331e-17 -6.16008695e-03 -1.24848489e-01]\n", 255 | " [ 6.15262039e-03 -1.24848489e-01 1.46966991e+00]]\n", 256 | "[[ 2.53649017e+00 5.14997571e-04 6.13102888e-03]\n", 257 | " [ 5.14997571e-04 -1.66471797e-02 -1.46426661e-18]\n", 258 | " [ 6.13102888e-03 5.64498286e-17 1.48015701e+00]]\n", 259 | "0.006131028881890553\n", 260 | "[[ 2.53649017e+00 5.14997571e-04 6.13102888e-03]\n", 261 | " [ 5.14997571e-04 -1.66471797e-02 -1.46426661e-18]\n", 262 | " [ 6.13102888e-03 5.64498286e-17 1.48015701e+00]]\n", 263 | "[[ 2.53652576e+00 5.14988898e-04 -1.59006726e-17]\n", 264 | " [ 5.14988898e-04 -1.66471797e-02 -2.98892958e-06]\n", 265 | " [ 6.54095942e-19 -2.98892958e-06 1.48012142e+00]]\n", 266 | "0.0005149888975609983\n", 267 | "[[ 2.53652576e+00 5.14988898e-04 -1.59006726e-17]\n", 268 | " [ 5.14988898e-04 -1.66471797e-02 -2.98892958e-06]\n", 269 | " [ 6.54095942e-19 -2.98892958e-06 1.48012142e+00]]\n", 270 | "[[ 2.53652586e+00 -5.95225260e-17 -6.02883367e-10]\n", 271 | " [ 2.94871424e-20 -1.66472836e-02 -2.98892952e-06]\n", 272 | " [-6.02883351e-10 -2.98892952e-06 1.48012142e+00]]\n", 273 | "2.9889295206923514e-06\n", 274 | "[[ 2.53652586e+00 -5.95225260e-17 -6.02883367e-10]\n", 275 | " [ 2.94871424e-20 -1.66472836e-02 -2.98892952e-06]\n", 276 | " [-6.02883351e-10 -2.98892952e-06 1.48012142e+00]]\n" 277 | ] 278 | }, 279 | { 280 | "name": "stderr", 281 | "output_type": "stream", 282 | "text": [ 283 | "C:\\Users\\x1c\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:20: RuntimeWarning: divide by zero encountered in double_scalars\n" 284 | ] 285 | } 286 | ], 287 | "source": [ 288 | "import numpy as np\n", 289 | "import copy\n", 290 | "\n", 291 | "\n", 292 | "def max_index(A):\n", 293 | " X = copy.copy(A)\n", 294 | " for i in range(X.shape[0]):\n", 295 | " X[i,i] = 0\n", 296 | " index = np.where(np.abs(X) == np.max(np.abs(X)))\n", 297 | " #print(index)\n", 298 | " try:\n", 299 | " row = int(index[0][0])\n", 300 | " col = int(index[0][1])\n", 301 | " except:\n", 302 | " row = int(index[0])\n", 303 | " col = int(index[1])\n", 304 | " return row,col\n", 305 | "\n", 306 | "def cal_theta(a11,a22,a12):\n", 307 | " theta = np.arctan((2*a12)/(a11-a22))/2\n", 308 | " return theta\n", 309 | "\n", 310 | "def cal_rot(A,theta,index):\n", 311 | " i,j = index\n", 312 | " n = A.shape[0]\n", 313 | " P = np.eye(n)\n", 314 | " P[i,i] = np.cos(theta)\n", 315 | " P[j,j] = np.cos(theta)\n", 316 | " P[i,j] = np.sin(theta)\n", 317 | " P[j,i] = -np.sin(theta)\n", 318 | " #print(A)\n", 319 | " #print(P)\n", 320 | " #print(np.dot(P,A))\n", 321 | " rot = np.dot(np.dot(P,A),P.T)\n", 322 | " return rot\n", 323 | "\n", 324 | "def jacobian(A,error=1e-5): \n", 325 | " diff = copy.copy(A)\n", 326 | " for i in range(A.shape[0]):\n", 327 | " diff[i,i] = 0\n", 328 | " diff = abs(diff)\n", 329 | " while np.max(diff)>error:\n", 330 | " i,j = max_index(A)\n", 331 | " print(A)\n", 332 | " theta = cal_theta(A[i,i],A[j,j],A[i,j])\n", 333 | " A = cal_rot(A,theta,(i,j))\n", 334 | " print(A)\n", 335 | " #print(np.max(diff))\n", 336 | " diff = copy.copy(A)\n", 337 | " for i in range(A.shape[0]):\n", 338 | " diff[i,i] = 0\n", 339 | " diff = abs(diff)\n", 340 | " print(np.max(diff))\n", 341 | " return A\n", 342 | "\n", 343 | "\n", 344 | "A = np.array([[1,1,0.5],[1,1,0.25],[0.5,0.25,2]])\n", 345 | "print(jacobian(A))\n" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "4.利用初等反设阵(豪斯霍尔德变换)将\n", 353 | "$$A=\\left(\\begin{array}{lll}\n", 354 | "1 & 3 & 4 \\\\\n", 355 | "3 & 1 & 2 \\\\\n", 356 | "4 & 2 & 1\n", 357 | "\\end{array}\\right)$$\n", 358 | "正交相似变换化为对称三对角阵" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": null, 364 | "metadata": { 365 | "collapsed": true 366 | }, 367 | "outputs": [], 368 | "source": [ 369 | "import numpy as np\n", 370 | "\n" 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "metadata": {}, 376 | "source": [ 377 | "5.设$A\\in\\mathbb{R}^{n\\times n}$且由豪斯霍尔德方法有$\\boldsymbol{v}_{0}^{T} \\boldsymbol{A} \\boldsymbol{v}_{0}=\\boldsymbol{H}$(为上豪森伯格阵),又设$y$为$H$对应特征值$\\lambda$的特征向量,即$Hy=\\lambda y$,求证$x=v,y$为$A$对应$\\lambda$的特征向量。" 378 | ] 379 | }, 380 | { 381 | "cell_type": "markdown", 382 | "metadata": {}, 383 | "source": [ 384 | "6.用带位移的$QR$方法计算下述对称三对角阵的全部特征值\n", 385 | "$$A=\\left(\\begin{array}{rrr}1 & 2 & 0 \\\\ 2 & -1 & 1 \\\\ 0 & 1 & 3\\end{array}\\right)$$" 386 | ] 387 | }, 388 | { 389 | "cell_type": "markdown", 390 | "metadata": {}, 391 | "source": [ 392 | "7.设$A_1$为对称三对角阵\n", 393 | "$$A=\\left\\{\\begin{array}{cccc}\n", 394 | "0, & c_{1} & & \\\\\n", 395 | "c_{1} & b_{2} & c_{2} & \\\\\n", 396 | "& \\ddots & & \\ddots & c_{n-1} \\\\\n", 397 | "& & & & \\vdots \\\\\n", 398 | "& & & c_{n+1} & b_{1}\n", 399 | "\\end{array}\\right)$$\n", 400 | "且$A_1=QR$(QR分解),其中$Q$为正交阵,$R$为上三角阵,$A_2=RQ=Q^TA_1Q$,求证$A_2$也是对称三对角阵" 401 | ] 402 | }, 403 | { 404 | "cell_type": "markdown", 405 | "metadata": {}, 406 | "source": [ 407 | "8.试用平面旋转阵将下述$A$分解为$QR$,其中$Q$为正交阵,$R$为上三角阵\n", 408 | "$$A=\\left[\\begin{array}{lll}\n", 409 | "3 & 1 & 0 \\\\\n", 410 | "1 & 2 & 1 \\\\\n", 411 | "0 & 1 & 1\n", 412 | "\\end{array}\\right]$$" 413 | ] 414 | }, 415 | { 416 | "cell_type": "markdown", 417 | "metadata": {}, 418 | "source": [ 419 | "9.用QR算法(双步QR方法)计算$H$全部特征值\n", 420 | "$$\\mathbf{H}=\\left(\\begin{array}{lllll}\n", 421 | "2 & 3 & 4 & 5 & 6 \\\\\n", 422 | "4 & 4 & 5 & 6 & 7 \\\\\n", 423 | "0 & 3 & 6 & 7 & 8 \\\\\n", 424 | "0 & 0 & 2 & 8 & 9 \\\\\n", 425 | "0 & 0 & 0 & 1 & 0\n", 426 | "\\end{array}\\right)$$" 427 | ] 428 | }, 429 | { 430 | "cell_type": "markdown", 431 | "metadata": {}, 432 | "source": [ 433 | "10.验证对矩阵\n", 434 | "$A=\\left[\\begin{array}{ll}0 & 1 \\\\ 1 & 0\\end{array}\\right]$(为对称阵,且$\\lambda_1(A)=1,\\lambda_2(A)=-1$)使用基本QR方法不收敛对角阵" 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": null, 440 | "metadata": { 441 | "collapsed": true 442 | }, 443 | "outputs": [], 444 | "source": [] 445 | } 446 | ], 447 | "metadata": { 448 | "kernelspec": { 449 | "display_name": "Python 3", 450 | "language": "python", 451 | "name": "python3" 452 | }, 453 | "language_info": { 454 | "codemirror_mode": { 455 | "name": "ipython", 456 | "version": 3 457 | }, 458 | "file_extension": ".py", 459 | "mimetype": "text/x-python", 460 | "name": "python", 461 | "nbconvert_exporter": "python", 462 | "pygments_lexer": "ipython3", 463 | "version": "3.6.2" 464 | } 465 | }, 466 | "nbformat": 4, 467 | "nbformat_minor": 2 468 | } 469 | -------------------------------------------------------------------------------- /ch7/ex7.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了解矩阵特征值和特征向量计算方法\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "\n", 14 | "原创内容,如需转载需征得作者同意。\n", 15 | "\n", 16 | "Copyright©2020 lizhemin\n", 17 | "***" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "source": [ 26 | "1.用幂法计算矩阵\n", 27 | "$$A=\\left(\\begin{array}{rrr}\n", 28 | "7 & 3 & -2 \\\\\n", 29 | "3 & 4 & -1 \\\\\n", 30 | "-2 & -1 & 3\n", 31 | "\\end{array}\\right)$$\n", 32 | "的主特征值及对应特征向量(当特征值又三位小数稳定时迭代终止)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 13, 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "name": "stdout", 42 | "output_type": "stream", 43 | "text": [ 44 | "[9.25]\n", 45 | "[9.54054054]\n", 46 | "[9.59490085]\n", 47 | "[9.6040744]\n", 48 | "[9.605429]\n", 49 | "eig_value: [9.605429] eig_vec [[ 0.02665903]\n", 50 | " [ 0.01614942]\n", 51 | " [-0.01050688]]\n", 52 | "[[ 0.02665943]\n", 53 | " [ 0.01614521]\n", 54 | " [-0.01051365]]\n" 55 | ] 56 | } 57 | ], 58 | "source": [ 59 | "import numpy as np\n", 60 | "import copy\n", 61 | "\n", 62 | "def eig(A,x,error=1e-3):\n", 63 | " n = A.shape[0]\n", 64 | " x_old = copy.copy(x)\n", 65 | " x_now = np.dot(A,x_old)\n", 66 | " lam = x_now[0]/x_old[0]\n", 67 | " while np.abs(lam- np.dot(A,x_now)[0]/x_now[0])>error:\n", 68 | " x_old = copy.copy(x_now)\n", 69 | " x_now = np.dot(A,x_old)\n", 70 | " lam = x_now[0]/x_old[0]\n", 71 | " x_now = x_now/norm_2(x_now)\n", 72 | " print(lam)\n", 73 | " return lam,x_now\n", 74 | " \n", 75 | "def norm_2(x):\n", 76 | " return np.mean(x**2)\n", 77 | "\n", 78 | "A = np.array([[7,3,-2],[3,4,-1],[-2,-1,3]])\n", 79 | "x = np.ones((3,1))\n", 80 | "eig_value,eig_vec = eig(A,x)\n", 81 | "print('eig_value:',eig_value,'eig_vec',eig_vec)\n", 82 | "print(np.dot(A,eig_vec)/eig_value)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": {}, 88 | "source": [ 89 | "2.用反幂法求矩阵\n", 90 | "$$A=\\left(\\begin{array}{lll}\n", 91 | "6 & 2 & 1 \\\\\n", 92 | "2 & 3 & 1 \\\\\n", 93 | "1 & 1 & 1\n", 94 | "\\end{array}\\right)$$\n", 95 | "的最接近6的特征值及对应的特征向量" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "分析:相当于迭代式变成$x_n = A x_{n+1}$,需要解线性方程组得到答案,这个解的过程就要用到之前的迭代法或直接解法,这里使用迭代法" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 21, 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "name": "stdout", 112 | "output_type": "stream", 113 | "text": [ 114 | "[[1.82400590e-06]\n", 115 | " [2.90719902e-06]\n", 116 | " [1.00000485e+00]]\n", 117 | "[-60917.24214878]\n", 118 | "[1.33332229]\n", 119 | "[1.49994327]\n", 120 | "[1.64817412]\n", 121 | "[1.7041903]\n", 122 | "[1.72080319]\n", 123 | "[1.72562825]\n", 124 | "[1.72676236]\n", 125 | "[1.72725684]\n", 126 | "eig_value: [1.72725684] eig_vec [[-0.07962089]\n", 127 | " [-0.64686536]\n", 128 | " [ 1.72533451]]\n", 129 | "[[-0.07961851]\n", 130 | " [-0.64688429]\n", 131 | " [ 1.7253954 ]]\n" 132 | ] 133 | } 134 | ], 135 | "source": [ 136 | "import numpy as np\n", 137 | "import copy\n", 138 | "\n", 139 | "#####Sollve linear functionals ######\n", 140 | "def DLU(A):\n", 141 | " # Input matrix n\\times n\n", 142 | " n = A.shape[0]\n", 143 | " D = np.zeros((n,n))\n", 144 | " L = np.zeros((n,n))\n", 145 | " U = np.zeros((n,n))\n", 146 | " for i in range(n):\n", 147 | " for j in range(n):\n", 148 | " if i==j:\n", 149 | " D[i,i] = A[i,i]\n", 150 | " elif i>j:\n", 151 | " L[i,j] = -A[i,j]\n", 152 | " else:\n", 153 | " U[i,j] = -A[i,j]\n", 154 | " return D,L,U\n", 155 | "\n", 156 | "def SOR(A,b,epsilon,omega=1):\n", 157 | " k = 0\n", 158 | " N = A.shape[0]\n", 159 | " x = np.zeros((N,1))\n", 160 | " while k==0 or abs(P0)>=epsilon:\n", 161 | " P0 = 0\n", 162 | " Ax = np.dot(A,x)\n", 163 | " for i in range(N):\n", 164 | " #Remark, this formula is a little different from book, I think algorithm on book have some wrong.\n", 165 | " dx = omega/A[i,i]*(b[i]-Ax[i])\n", 166 | " P = copy.copy(dx)\n", 167 | " if abs(P)>abs(P0):\n", 168 | " P0 = copy.copy(P)\n", 169 | " x[i] = x[i]+P\n", 170 | " k += 1\n", 171 | " return k-1,omega,x\n", 172 | "\n", 173 | "def main_solve(A,b):\n", 174 | " k,omega,x = SOR(A,b,1e-5,omega=1)\n", 175 | " return x\n", 176 | "\n", 177 | "#####find the optimal eig######\n", 178 | "def eig(A,x,error=1e-4):\n", 179 | " n = A.shape[0]\n", 180 | " x_old = copy.copy(x)\n", 181 | " x_now = main_solve(A,x_old)\n", 182 | " print(x_now)\n", 183 | " lam = x_now[0]/x_old[0]\n", 184 | " while np.abs(lam- main_solve(A,x_now)[0]/x_now[0])>error:\n", 185 | " x_old = copy.copy(x_now)\n", 186 | " x_now = main_solve(A,x_old)\n", 187 | " lam = x_now[0]/x_old[0]\n", 188 | " x_now = x_now/norm_2(x_now)\n", 189 | " print(lam)\n", 190 | " return lam,x_now\n", 191 | " \n", 192 | "def norm_2(x):\n", 193 | " return np.mean(x**2)\n", 194 | "\n", 195 | "#####start use inverse power method#####\n", 196 | "A = np.array([[6,2,1],[2,3,1],[1,1,1]])\n", 197 | "x = np.array([[1],[1],[1]])\n", 198 | "eig_value,eig_vec = eig(A,x)\n", 199 | "print('eig_value:',eig_value,'eig_vec',eig_vec)\n", 200 | "print(main_solve(A,eig_vec)/eig_value)\n" 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "metadata": {}, 206 | "source": [ 207 | "3.用雅可比方法计算\n", 208 | "$$A=\\left(\\begin{array}{ccc}\n", 209 | "1 & 1 & 0.5 \\\\\n", 210 | "1 & 1 & 0.25 \\\\\n", 211 | "0.5 & 0.25 & 2\n", 212 | "\\end{array}\\right)$$\n", 213 | "的全部特征值及特征向量\n" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": {}, 219 | "source": [ 220 | "**分析**:jacobian方法适用于求解对称矩阵,核心思想是通过旋转减少非对角线上元素的能量。" 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": 92, 226 | "metadata": {}, 227 | "outputs": [ 228 | { 229 | "name": "stdout", 230 | "output_type": "stream", 231 | "text": [ 232 | "[[1. 1. 0.5 ]\n", 233 | " [1. 1. 0.25]\n", 234 | " [0.5 0.25 2. ]]\n", 235 | "[[ 2.00000000e+00 -8.53284318e-17 5.30330086e-01]\n", 236 | " [ 0.00000000e+00 0.00000000e+00 -1.76776695e-01]\n", 237 | " [ 5.30330086e-01 -1.76776695e-01 2.00000000e+00]]\n", 238 | "0.5303300858899107\n", 239 | "[[ 2.00000000e+00 -8.53284318e-17 5.30330086e-01]\n", 240 | " [ 0.00000000e+00 0.00000000e+00 -1.76776695e-01]\n", 241 | " [ 5.30330086e-01 -1.76776695e-01 2.00000000e+00]]\n", 242 | "[[ 2.53033009e+00 -1.25000000e-01 5.34494463e-17]\n", 243 | " [-1.25000000e-01 0.00000000e+00 -1.25000000e-01]\n", 244 | " [ 7.68514419e-17 -1.25000000e-01 1.46966991e+00]]\n", 245 | "0.12500000000000003\n", 246 | "[[ 2.53033009e+00 -1.25000000e-01 5.34494463e-17]\n", 247 | " [-1.25000000e-01 0.00000000e+00 -1.25000000e-01]\n", 248 | " [ 7.68514419e-17 -1.25000000e-01 1.46966991e+00]]\n", 249 | "[[ 2.53649017e+00 -5.40059762e-18 6.15262039e-03]\n", 250 | " [ 5.30552331e-17 -6.16008695e-03 -1.24848489e-01]\n", 251 | " [ 6.15262039e-03 -1.24848489e-01 1.46966991e+00]]\n", 252 | "0.12484848922734756\n", 253 | "[[ 2.53649017e+00 -5.40059762e-18 6.15262039e-03]\n", 254 | " [ 5.30552331e-17 -6.16008695e-03 -1.24848489e-01]\n", 255 | " [ 6.15262039e-03 -1.24848489e-01 1.46966991e+00]]\n", 256 | "[[ 2.53649017e+00 5.14997571e-04 6.13102888e-03]\n", 257 | " [ 5.14997571e-04 -1.66471797e-02 -1.46426661e-18]\n", 258 | " [ 6.13102888e-03 5.64498286e-17 1.48015701e+00]]\n", 259 | "0.006131028881890553\n", 260 | "[[ 2.53649017e+00 5.14997571e-04 6.13102888e-03]\n", 261 | " [ 5.14997571e-04 -1.66471797e-02 -1.46426661e-18]\n", 262 | " [ 6.13102888e-03 5.64498286e-17 1.48015701e+00]]\n", 263 | "[[ 2.53652576e+00 5.14988898e-04 -1.59006726e-17]\n", 264 | " [ 5.14988898e-04 -1.66471797e-02 -2.98892958e-06]\n", 265 | " [ 6.54095942e-19 -2.98892958e-06 1.48012142e+00]]\n", 266 | "0.0005149888975609983\n", 267 | "[[ 2.53652576e+00 5.14988898e-04 -1.59006726e-17]\n", 268 | " [ 5.14988898e-04 -1.66471797e-02 -2.98892958e-06]\n", 269 | " [ 6.54095942e-19 -2.98892958e-06 1.48012142e+00]]\n", 270 | "[[ 2.53652586e+00 -5.95225260e-17 -6.02883367e-10]\n", 271 | " [ 2.94871424e-20 -1.66472836e-02 -2.98892952e-06]\n", 272 | " [-6.02883351e-10 -2.98892952e-06 1.48012142e+00]]\n", 273 | "2.9889295206923514e-06\n", 274 | "[[ 2.53652586e+00 -5.95225260e-17 -6.02883367e-10]\n", 275 | " [ 2.94871424e-20 -1.66472836e-02 -2.98892952e-06]\n", 276 | " [-6.02883351e-10 -2.98892952e-06 1.48012142e+00]]\n" 277 | ] 278 | }, 279 | { 280 | "name": "stderr", 281 | "output_type": "stream", 282 | "text": [ 283 | "C:\\Users\\x1c\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:20: RuntimeWarning: divide by zero encountered in double_scalars\n" 284 | ] 285 | } 286 | ], 287 | "source": [ 288 | "import numpy as np\n", 289 | "import copy\n", 290 | "\n", 291 | "\n", 292 | "def max_index(A):\n", 293 | " X = copy.copy(A)\n", 294 | " for i in range(X.shape[0]):\n", 295 | " X[i,i] = 0\n", 296 | " index = np.where(np.abs(X) == np.max(np.abs(X)))\n", 297 | " #print(index)\n", 298 | " try:\n", 299 | " row = int(index[0][0])\n", 300 | " col = int(index[0][1])\n", 301 | " except:\n", 302 | " row = int(index[0])\n", 303 | " col = int(index[1])\n", 304 | " return row,col\n", 305 | "\n", 306 | "def cal_theta(a11,a22,a12):\n", 307 | " theta = np.arctan((2*a12)/(a11-a22))/2\n", 308 | " return theta\n", 309 | "\n", 310 | "def cal_rot(A,theta,index):\n", 311 | " i,j = index\n", 312 | " n = A.shape[0]\n", 313 | " P = np.eye(n)\n", 314 | " P[i,i] = np.cos(theta)\n", 315 | " P[j,j] = np.cos(theta)\n", 316 | " P[i,j] = np.sin(theta)\n", 317 | " P[j,i] = -np.sin(theta)\n", 318 | " #print(A)\n", 319 | " #print(P)\n", 320 | " #print(np.dot(P,A))\n", 321 | " rot = np.dot(np.dot(P,A),P.T)\n", 322 | " return rot\n", 323 | "\n", 324 | "def jacobian(A,error=1e-5): \n", 325 | " diff = copy.copy(A)\n", 326 | " for i in range(A.shape[0]):\n", 327 | " diff[i,i] = 0\n", 328 | " diff = abs(diff)\n", 329 | " while np.max(diff)>error:\n", 330 | " i,j = max_index(A)\n", 331 | " print(A)\n", 332 | " theta = cal_theta(A[i,i],A[j,j],A[i,j])\n", 333 | " A = cal_rot(A,theta,(i,j))\n", 334 | " print(A)\n", 335 | " #print(np.max(diff))\n", 336 | " diff = copy.copy(A)\n", 337 | " for i in range(A.shape[0]):\n", 338 | " diff[i,i] = 0\n", 339 | " diff = abs(diff)\n", 340 | " print(np.max(diff))\n", 341 | " return A\n", 342 | "\n", 343 | "\n", 344 | "A = np.array([[1,1,0.5],[1,1,0.25],[0.5,0.25,2]])\n", 345 | "print(jacobian(A))\n" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "4.利用初等反设阵(豪斯霍尔德变换)将\n", 353 | "$$A=\\left(\\begin{array}{lll}\n", 354 | "1 & 3 & 4 \\\\\n", 355 | "3 & 1 & 2 \\\\\n", 356 | "4 & 2 & 1\n", 357 | "\\end{array}\\right)$$\n", 358 | "正交相似变换化为对称三对角阵" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": null, 364 | "metadata": { 365 | "collapsed": true 366 | }, 367 | "outputs": [], 368 | "source": [ 369 | "import numpy as np\n", 370 | "\n" 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "metadata": {}, 376 | "source": [ 377 | "5.设$A\\in\\mathbb{R}^{n\\times n}$且由豪斯霍尔德方法有$\\boldsymbol{v}_{0}^{T} \\boldsymbol{A} \\boldsymbol{v}_{0}=\\boldsymbol{H}$(为上豪森伯格阵),又设$y$为$H$对应特征值$\\lambda$的特征向量,即$Hy=\\lambda y$,求证$x=v,y$为$A$对应$\\lambda$的特征向量。" 378 | ] 379 | }, 380 | { 381 | "cell_type": "markdown", 382 | "metadata": {}, 383 | "source": [ 384 | "6.用带位移的$QR$方法计算下述对称三对角阵的全部特征值\n", 385 | "$$A=\\left(\\begin{array}{rrr}1 & 2 & 0 \\\\ 2 & -1 & 1 \\\\ 0 & 1 & 3\\end{array}\\right)$$" 386 | ] 387 | }, 388 | { 389 | "cell_type": "markdown", 390 | "metadata": {}, 391 | "source": [ 392 | "7.设$A_1$为对称三对角阵\n", 393 | "$$A=\\left\\{\\begin{array}{cccc}\n", 394 | "0, & c_{1} & & \\\\\n", 395 | "c_{1} & b_{2} & c_{2} & \\\\\n", 396 | "& \\ddots & & \\ddots & c_{n-1} \\\\\n", 397 | "& & & & \\vdots \\\\\n", 398 | "& & & c_{n+1} & b_{1}\n", 399 | "\\end{array}\\right)$$\n", 400 | "且$A_1=QR$(QR分解),其中$Q$为正交阵,$R$为上三角阵,$A_2=RQ=Q^TA_1Q$,求证$A_2$也是对称三对角阵" 401 | ] 402 | }, 403 | { 404 | "cell_type": "markdown", 405 | "metadata": {}, 406 | "source": [ 407 | "8.试用平面旋转阵将下述$A$分解为$QR$,其中$Q$为正交阵,$R$为上三角阵\n", 408 | "$$A=\\left[\\begin{array}{lll}\n", 409 | "3 & 1 & 0 \\\\\n", 410 | "1 & 2 & 1 \\\\\n", 411 | "0 & 1 & 1\n", 412 | "\\end{array}\\right]$$" 413 | ] 414 | }, 415 | { 416 | "cell_type": "markdown", 417 | "metadata": {}, 418 | "source": [ 419 | "9.用QR算法(双步QR方法)计算$H$全部特征值\n", 420 | "$$\\mathbf{H}=\\left(\\begin{array}{lllll}\n", 421 | "2 & 3 & 4 & 5 & 6 \\\\\n", 422 | "4 & 4 & 5 & 6 & 7 \\\\\n", 423 | "0 & 3 & 6 & 7 & 8 \\\\\n", 424 | "0 & 0 & 2 & 8 & 9 \\\\\n", 425 | "0 & 0 & 0 & 1 & 0\n", 426 | "\\end{array}\\right)$$" 427 | ] 428 | }, 429 | { 430 | "cell_type": "markdown", 431 | "metadata": {}, 432 | "source": [ 433 | "10.验证对矩阵\n", 434 | "$A=\\left[\\begin{array}{ll}0 & 1 \\\\ 1 & 0\\end{array}\\right]$(为对称阵,且$\\lambda_1(A)=1,\\lambda_2(A)=-1$)使用基本QR方法不收敛对角阵" 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": null, 440 | "metadata": { 441 | "collapsed": true 442 | }, 443 | "outputs": [], 444 | "source": [] 445 | } 446 | ], 447 | "metadata": { 448 | "kernelspec": { 449 | "display_name": "Python 3", 450 | "language": "python", 451 | "name": "python3" 452 | }, 453 | "language_info": { 454 | "codemirror_mode": { 455 | "name": "ipython", 456 | "version": 3 457 | }, 458 | "file_extension": ".py", 459 | "mimetype": "text/x-python", 460 | "name": "python", 461 | "nbconvert_exporter": "python", 462 | "pygments_lexer": "ipython3", 463 | "version": "3.6.2" 464 | } 465 | }, 466 | "nbformat": 4, 467 | "nbformat_minor": 2 468 | } 469 | -------------------------------------------------------------------------------- /ch8/.ipynb_checkpoints/ex7-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了解矩阵特征值和特征向量计算方法\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "\n", 14 | "原创内容,如需转载需征得作者同意。\n", 15 | "\n", 16 | "Copyright©2020 lizhemin\n", 17 | "***" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "source": [ 26 | "1.用幂法计算矩阵\n", 27 | "$$A=\\left(\\begin{array}{rrr}\n", 28 | "7 & 3 & -2 \\\\\n", 29 | "3 & 4 & -1 \\\\\n", 30 | "-2 & -1 & 3\n", 31 | "\\end{array}\\right)$$\n", 32 | "的主特征值及对应特征向量(当特征值又三位小数稳定时迭代终止)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 13, 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "name": "stdout", 42 | "output_type": "stream", 43 | "text": [ 44 | "[9.25]\n", 45 | "[9.54054054]\n", 46 | "[9.59490085]\n", 47 | "[9.6040744]\n", 48 | "[9.605429]\n", 49 | "eig_value: [9.605429] eig_vec [[ 0.02665903]\n", 50 | " [ 0.01614942]\n", 51 | " [-0.01050688]]\n", 52 | "[[ 0.02665943]\n", 53 | " [ 0.01614521]\n", 54 | " [-0.01051365]]\n" 55 | ] 56 | } 57 | ], 58 | "source": [ 59 | "import numpy as np\n", 60 | "import copy\n", 61 | "\n", 62 | "def eig(A,x,error=1e-3):\n", 63 | " n = A.shape[0]\n", 64 | " x_old = copy.copy(x)\n", 65 | " x_now = np.dot(A,x_old)\n", 66 | " lam = x_now[0]/x_old[0]\n", 67 | " while np.abs(lam- np.dot(A,x_now)[0]/x_now[0])>error:\n", 68 | " x_old = copy.copy(x_now)\n", 69 | " x_now = np.dot(A,x_old)\n", 70 | " lam = x_now[0]/x_old[0]\n", 71 | " x_now = x_now/norm_2(x_now)\n", 72 | " print(lam)\n", 73 | " return lam,x_now\n", 74 | " \n", 75 | "def norm_2(x):\n", 76 | " return np.mean(x**2)\n", 77 | "\n", 78 | "A = np.array([[7,3,-2],[3,4,-1],[-2,-1,3]])\n", 79 | "x = np.ones((3,1))\n", 80 | "eig_value,eig_vec = eig(A,x)\n", 81 | "print('eig_value:',eig_value,'eig_vec',eig_vec)\n", 82 | "print(np.dot(A,eig_vec)/eig_value)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": {}, 88 | "source": [ 89 | "2.用反幂法求矩阵\n", 90 | "$$A=\\left(\\begin{array}{lll}\n", 91 | "6 & 2 & 1 \\\\\n", 92 | "2 & 3 & 1 \\\\\n", 93 | "1 & 1 & 1\n", 94 | "\\end{array}\\right)$$\n", 95 | "的最接近6的特征值及对应的特征向量" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "分析:相当于迭代式变成$x_n = A x_{n+1}$,需要解线性方程组得到答案,这个解的过程就要用到之前的迭代法或直接解法,这里使用迭代法" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 21, 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "name": "stdout", 112 | "output_type": "stream", 113 | "text": [ 114 | "[[1.82400590e-06]\n", 115 | " [2.90719902e-06]\n", 116 | " [1.00000485e+00]]\n", 117 | "[-60917.24214878]\n", 118 | "[1.33332229]\n", 119 | "[1.49994327]\n", 120 | "[1.64817412]\n", 121 | "[1.7041903]\n", 122 | "[1.72080319]\n", 123 | "[1.72562825]\n", 124 | "[1.72676236]\n", 125 | "[1.72725684]\n", 126 | "eig_value: [1.72725684] eig_vec [[-0.07962089]\n", 127 | " [-0.64686536]\n", 128 | " [ 1.72533451]]\n", 129 | "[[-0.07961851]\n", 130 | " [-0.64688429]\n", 131 | " [ 1.7253954 ]]\n" 132 | ] 133 | } 134 | ], 135 | "source": [ 136 | "import numpy as np\n", 137 | "import copy\n", 138 | "\n", 139 | "#####Sollve linear functionals ######\n", 140 | "def DLU(A):\n", 141 | " # Input matrix n\\times n\n", 142 | " n = A.shape[0]\n", 143 | " D = np.zeros((n,n))\n", 144 | " L = np.zeros((n,n))\n", 145 | " U = np.zeros((n,n))\n", 146 | " for i in range(n):\n", 147 | " for j in range(n):\n", 148 | " if i==j:\n", 149 | " D[i,i] = A[i,i]\n", 150 | " elif i>j:\n", 151 | " L[i,j] = -A[i,j]\n", 152 | " else:\n", 153 | " U[i,j] = -A[i,j]\n", 154 | " return D,L,U\n", 155 | "\n", 156 | "def SOR(A,b,epsilon,omega=1):\n", 157 | " k = 0\n", 158 | " N = A.shape[0]\n", 159 | " x = np.zeros((N,1))\n", 160 | " while k==0 or abs(P0)>=epsilon:\n", 161 | " P0 = 0\n", 162 | " Ax = np.dot(A,x)\n", 163 | " for i in range(N):\n", 164 | " #Remark, this formula is a little different from book, I think algorithm on book have some wrong.\n", 165 | " dx = omega/A[i,i]*(b[i]-Ax[i])\n", 166 | " P = copy.copy(dx)\n", 167 | " if abs(P)>abs(P0):\n", 168 | " P0 = copy.copy(P)\n", 169 | " x[i] = x[i]+P\n", 170 | " k += 1\n", 171 | " return k-1,omega,x\n", 172 | "\n", 173 | "def main_solve(A,b):\n", 174 | " k,omega,x = SOR(A,b,1e-5,omega=1)\n", 175 | " return x\n", 176 | "\n", 177 | "#####find the optimal eig######\n", 178 | "def eig(A,x,error=1e-4):\n", 179 | " n = A.shape[0]\n", 180 | " x_old = copy.copy(x)\n", 181 | " x_now = main_solve(A,x_old)\n", 182 | " print(x_now)\n", 183 | " lam = x_now[0]/x_old[0]\n", 184 | " while np.abs(lam- main_solve(A,x_now)[0]/x_now[0])>error:\n", 185 | " x_old = copy.copy(x_now)\n", 186 | " x_now = main_solve(A,x_old)\n", 187 | " lam = x_now[0]/x_old[0]\n", 188 | " x_now = x_now/norm_2(x_now)\n", 189 | " print(lam)\n", 190 | " return lam,x_now\n", 191 | " \n", 192 | "def norm_2(x):\n", 193 | " return np.mean(x**2)\n", 194 | "\n", 195 | "#####start use inverse power method#####\n", 196 | "A = np.array([[6,2,1],[2,3,1],[1,1,1]])\n", 197 | "x = np.array([[1],[1],[1]])\n", 198 | "eig_value,eig_vec = eig(A,x)\n", 199 | "print('eig_value:',eig_value,'eig_vec',eig_vec)\n", 200 | "print(main_solve(A,eig_vec)/eig_value)\n" 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "metadata": {}, 206 | "source": [ 207 | "3.用雅可比方法计算\n", 208 | "$$A=\\left(\\begin{array}{ccc}\n", 209 | "1 & 1 & 0.5 \\\\\n", 210 | "1 & 1 & 0.25 \\\\\n", 211 | "0.5 & 0.25 & 2\n", 212 | "\\end{array}\\right)$$\n", 213 | "的全部特征值及特征向量\n" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": {}, 219 | "source": [ 220 | "**分析**:jacobian方法适用于求解对称矩阵,核心思想是通过旋转减少非对角线上元素的能量。" 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": 92, 226 | "metadata": {}, 227 | "outputs": [ 228 | { 229 | "name": "stdout", 230 | "output_type": "stream", 231 | "text": [ 232 | "[[1. 1. 0.5 ]\n", 233 | " [1. 1. 0.25]\n", 234 | " [0.5 0.25 2. ]]\n", 235 | "[[ 2.00000000e+00 -8.53284318e-17 5.30330086e-01]\n", 236 | " [ 0.00000000e+00 0.00000000e+00 -1.76776695e-01]\n", 237 | " [ 5.30330086e-01 -1.76776695e-01 2.00000000e+00]]\n", 238 | "0.5303300858899107\n", 239 | "[[ 2.00000000e+00 -8.53284318e-17 5.30330086e-01]\n", 240 | " [ 0.00000000e+00 0.00000000e+00 -1.76776695e-01]\n", 241 | " [ 5.30330086e-01 -1.76776695e-01 2.00000000e+00]]\n", 242 | "[[ 2.53033009e+00 -1.25000000e-01 5.34494463e-17]\n", 243 | " [-1.25000000e-01 0.00000000e+00 -1.25000000e-01]\n", 244 | " [ 7.68514419e-17 -1.25000000e-01 1.46966991e+00]]\n", 245 | "0.12500000000000003\n", 246 | "[[ 2.53033009e+00 -1.25000000e-01 5.34494463e-17]\n", 247 | " [-1.25000000e-01 0.00000000e+00 -1.25000000e-01]\n", 248 | " [ 7.68514419e-17 -1.25000000e-01 1.46966991e+00]]\n", 249 | "[[ 2.53649017e+00 -5.40059762e-18 6.15262039e-03]\n", 250 | " [ 5.30552331e-17 -6.16008695e-03 -1.24848489e-01]\n", 251 | " [ 6.15262039e-03 -1.24848489e-01 1.46966991e+00]]\n", 252 | "0.12484848922734756\n", 253 | "[[ 2.53649017e+00 -5.40059762e-18 6.15262039e-03]\n", 254 | " [ 5.30552331e-17 -6.16008695e-03 -1.24848489e-01]\n", 255 | " [ 6.15262039e-03 -1.24848489e-01 1.46966991e+00]]\n", 256 | "[[ 2.53649017e+00 5.14997571e-04 6.13102888e-03]\n", 257 | " [ 5.14997571e-04 -1.66471797e-02 -1.46426661e-18]\n", 258 | " [ 6.13102888e-03 5.64498286e-17 1.48015701e+00]]\n", 259 | "0.006131028881890553\n", 260 | "[[ 2.53649017e+00 5.14997571e-04 6.13102888e-03]\n", 261 | " [ 5.14997571e-04 -1.66471797e-02 -1.46426661e-18]\n", 262 | " [ 6.13102888e-03 5.64498286e-17 1.48015701e+00]]\n", 263 | "[[ 2.53652576e+00 5.14988898e-04 -1.59006726e-17]\n", 264 | " [ 5.14988898e-04 -1.66471797e-02 -2.98892958e-06]\n", 265 | " [ 6.54095942e-19 -2.98892958e-06 1.48012142e+00]]\n", 266 | "0.0005149888975609983\n", 267 | "[[ 2.53652576e+00 5.14988898e-04 -1.59006726e-17]\n", 268 | " [ 5.14988898e-04 -1.66471797e-02 -2.98892958e-06]\n", 269 | " [ 6.54095942e-19 -2.98892958e-06 1.48012142e+00]]\n", 270 | "[[ 2.53652586e+00 -5.95225260e-17 -6.02883367e-10]\n", 271 | " [ 2.94871424e-20 -1.66472836e-02 -2.98892952e-06]\n", 272 | " [-6.02883351e-10 -2.98892952e-06 1.48012142e+00]]\n", 273 | "2.9889295206923514e-06\n", 274 | "[[ 2.53652586e+00 -5.95225260e-17 -6.02883367e-10]\n", 275 | " [ 2.94871424e-20 -1.66472836e-02 -2.98892952e-06]\n", 276 | " [-6.02883351e-10 -2.98892952e-06 1.48012142e+00]]\n" 277 | ] 278 | }, 279 | { 280 | "name": "stderr", 281 | "output_type": "stream", 282 | "text": [ 283 | "C:\\Users\\x1c\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:20: RuntimeWarning: divide by zero encountered in double_scalars\n" 284 | ] 285 | } 286 | ], 287 | "source": [ 288 | "import numpy as np\n", 289 | "import copy\n", 290 | "\n", 291 | "\n", 292 | "def max_index(A):\n", 293 | " X = copy.copy(A)\n", 294 | " for i in range(X.shape[0]):\n", 295 | " X[i,i] = 0\n", 296 | " index = np.where(np.abs(X) == np.max(np.abs(X)))\n", 297 | " #print(index)\n", 298 | " try:\n", 299 | " row = int(index[0][0])\n", 300 | " col = int(index[0][1])\n", 301 | " except:\n", 302 | " row = int(index[0])\n", 303 | " col = int(index[1])\n", 304 | " return row,col\n", 305 | "\n", 306 | "def cal_theta(a11,a22,a12):\n", 307 | " theta = np.arctan((2*a12)/(a11-a22))/2\n", 308 | " return theta\n", 309 | "\n", 310 | "def cal_rot(A,theta,index):\n", 311 | " i,j = index\n", 312 | " n = A.shape[0]\n", 313 | " P = np.eye(n)\n", 314 | " P[i,i] = np.cos(theta)\n", 315 | " P[j,j] = np.cos(theta)\n", 316 | " P[i,j] = np.sin(theta)\n", 317 | " P[j,i] = -np.sin(theta)\n", 318 | " #print(A)\n", 319 | " #print(P)\n", 320 | " #print(np.dot(P,A))\n", 321 | " rot = np.dot(np.dot(P,A),P.T)\n", 322 | " return rot\n", 323 | "\n", 324 | "def jacobian(A,error=1e-5): \n", 325 | " diff = copy.copy(A)\n", 326 | " for i in range(A.shape[0]):\n", 327 | " diff[i,i] = 0\n", 328 | " diff = abs(diff)\n", 329 | " while np.max(diff)>error:\n", 330 | " i,j = max_index(A)\n", 331 | " print(A)\n", 332 | " theta = cal_theta(A[i,i],A[j,j],A[i,j])\n", 333 | " A = cal_rot(A,theta,(i,j))\n", 334 | " print(A)\n", 335 | " #print(np.max(diff))\n", 336 | " diff = copy.copy(A)\n", 337 | " for i in range(A.shape[0]):\n", 338 | " diff[i,i] = 0\n", 339 | " diff = abs(diff)\n", 340 | " print(np.max(diff))\n", 341 | " return A\n", 342 | "\n", 343 | "\n", 344 | "A = np.array([[1,1,0.5],[1,1,0.25],[0.5,0.25,2]])\n", 345 | "print(jacobian(A))\n" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "4.利用初等反设阵(豪斯霍尔德变换)将\n", 353 | "$$A=\\left(\\begin{array}{lll}\n", 354 | "1 & 3 & 4 \\\\\n", 355 | "3 & 1 & 2 \\\\\n", 356 | "4 & 2 & 1\n", 357 | "\\end{array}\\right)$$\n", 358 | "正交相似变换化为对称三对角阵" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": null, 364 | "metadata": { 365 | "collapsed": true 366 | }, 367 | "outputs": [], 368 | "source": [ 369 | "import numpy as np\n", 370 | "\n" 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "metadata": {}, 376 | "source": [ 377 | "5.设$A\\in\\mathbb{R}^{n\\times n}$且由豪斯霍尔德方法有$\\boldsymbol{v}_{0}^{T} \\boldsymbol{A} \\boldsymbol{v}_{0}=\\boldsymbol{H}$(为上豪森伯格阵),又设$y$为$H$对应特征值$\\lambda$的特征向量,即$Hy=\\lambda y$,求证$x=v,y$为$A$对应$\\lambda$的特征向量。" 378 | ] 379 | }, 380 | { 381 | "cell_type": "markdown", 382 | "metadata": {}, 383 | "source": [ 384 | "6.用带位移的$QR$方法计算下述对称三对角阵的全部特征值\n", 385 | "$$A=\\left(\\begin{array}{rrr}1 & 2 & 0 \\\\ 2 & -1 & 1 \\\\ 0 & 1 & 3\\end{array}\\right)$$" 386 | ] 387 | }, 388 | { 389 | "cell_type": "markdown", 390 | "metadata": {}, 391 | "source": [ 392 | "7.设$A_1$为对称三对角阵\n", 393 | "$$A=\\left\\{\\begin{array}{cccc}\n", 394 | "0, & c_{1} & & \\\\\n", 395 | "c_{1} & b_{2} & c_{2} & \\\\\n", 396 | "& \\ddots & & \\ddots & c_{n-1} \\\\\n", 397 | "& & & & \\vdots \\\\\n", 398 | "& & & c_{n+1} & b_{1}\n", 399 | "\\end{array}\\right)$$\n", 400 | "且$A_1=QR$(QR分解),其中$Q$为正交阵,$R$为上三角阵,$A_2=RQ=Q^TA_1Q$,求证$A_2$也是对称三对角阵" 401 | ] 402 | }, 403 | { 404 | "cell_type": "markdown", 405 | "metadata": {}, 406 | "source": [ 407 | "8.试用平面旋转阵将下述$A$分解为$QR$,其中$Q$为正交阵,$R$为上三角阵\n", 408 | "$$A=\\left[\\begin{array}{lll}\n", 409 | "3 & 1 & 0 \\\\\n", 410 | "1 & 2 & 1 \\\\\n", 411 | "0 & 1 & 1\n", 412 | "\\end{array}\\right]$$" 413 | ] 414 | }, 415 | { 416 | "cell_type": "markdown", 417 | "metadata": {}, 418 | "source": [ 419 | "9.用QR算法(双步QR方法)计算$H$全部特征值\n", 420 | "$$\\mathbf{H}=\\left(\\begin{array}{lllll}\n", 421 | "2 & 3 & 4 & 5 & 6 \\\\\n", 422 | "4 & 4 & 5 & 6 & 7 \\\\\n", 423 | "0 & 3 & 6 & 7 & 8 \\\\\n", 424 | "0 & 0 & 2 & 8 & 9 \\\\\n", 425 | "0 & 0 & 0 & 1 & 0\n", 426 | "\\end{array}\\right)$$" 427 | ] 428 | }, 429 | { 430 | "cell_type": "markdown", 431 | "metadata": {}, 432 | "source": [ 433 | "10.验证对矩阵\n", 434 | "$A=\\left[\\begin{array}{ll}0 & 1 \\\\ 1 & 0\\end{array}\\right]$(为对称阵,且$\\lambda_1(A)=1,\\lambda_2(A)=-1$)使用基本QR方法不收敛对角阵" 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": null, 440 | "metadata": { 441 | "collapsed": true 442 | }, 443 | "outputs": [], 444 | "source": [] 445 | } 446 | ], 447 | "metadata": { 448 | "kernelspec": { 449 | "display_name": "Python 3", 450 | "language": "python", 451 | "name": "python3" 452 | }, 453 | "language_info": { 454 | "codemirror_mode": { 455 | "name": "ipython", 456 | "version": 3 457 | }, 458 | "file_extension": ".py", 459 | "mimetype": "text/x-python", 460 | "name": "python", 461 | "nbconvert_exporter": "python", 462 | "pygments_lexer": "ipython3", 463 | "version": "3.6.2" 464 | } 465 | }, 466 | "nbformat": 4, 467 | "nbformat_minor": 2 468 | } 469 | -------------------------------------------------------------------------------- /ch8/.ipynb_checkpoints/ex8-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了刚性方程求解数值方法\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "\n", 14 | "原创内容,如需转载需征得作者同意。\n", 15 | "\n", 16 | "Copyright©2020 lizhemin\n", 17 | "***" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "source": [ 26 | "1.用改进欧拉法求下列初值问题近似解\n", 27 | "(a)$y'=\\left(\\frac{y}{t}\\right)^{2}+\\left(\\frac{y}{t}\\right), 1 \\leqslant t \\leqslant 1.2, \\quad y(1)=1$取$h=0.1$\n", 28 | "\n", 29 | "(b)$y'=\\sin t+e^{-t},0\\leq t \\leq 1,y(0)=0$取$h=0.5$" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "2.用4阶RK方法求上题的数值解" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "3.用阿当姆斯显式方法与隐式方法求下列初值问题的数值解\n", 44 | "\n", 45 | "(a)$y'=-y+i+1,0\\leq i\\leq 2,y(0)=2$取$h=0.2$\n", 46 | "\n", 47 | "(b)$y'=\\frac{2}{i}y+t^2e^i,1\\leq i\\leq 2,y(1)=0$取$h=0.05$" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "metadata": { 54 | "collapsed": true 55 | }, 56 | "outputs": [], 57 | "source": [] 58 | } 59 | ], 60 | "metadata": { 61 | "kernelspec": { 62 | "display_name": "Python 3", 63 | "language": "python", 64 | "name": "python3" 65 | }, 66 | "language_info": { 67 | "codemirror_mode": { 68 | "name": "ipython", 69 | "version": 3 70 | }, 71 | "file_extension": ".py", 72 | "mimetype": "text/x-python", 73 | "name": "python", 74 | "nbconvert_exporter": "python", 75 | "pygments_lexer": "ipython3", 76 | "version": "3.6.2" 77 | } 78 | }, 79 | "nbformat": 4, 80 | "nbformat_minor": 2 81 | } 82 | -------------------------------------------------------------------------------- /ch8/ex8.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节介绍了刚性方程求解数值方法\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "\n", 14 | "原创内容,如需转载需征得作者同意。\n", 15 | "\n", 16 | "Copyright©2020 lizhemin\n", 17 | "***" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "source": [ 26 | "1.用改进欧拉法求下列初值问题近似解\n", 27 | "(a)$y'=\\left(\\frac{y}{t}\\right)^{2}+\\left(\\frac{y}{t}\\right), 1 \\leqslant t \\leqslant 1.2, \\quad y(1)=1$取$h=0.1$\n", 28 | "\n", 29 | "(b)$y'=\\sin t+e^{-t},0\\leq t \\leq 1,y(0)=0$取$h=0.5$" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "2.用4阶RK方法求上题的数值解" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "3.用阿当姆斯显式方法与隐式方法求下列初值问题的数值解\n", 44 | "\n", 45 | "(a)$y'=-y+i+1,0\\leq i\\leq 2,y(0)=2$取$h=0.2$\n", 46 | "\n", 47 | "(b)$y'=\\frac{2}{i}y+t^2e^i,1\\leq i\\leq 2,y(1)=0$取$h=0.05$" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "metadata": { 54 | "collapsed": true 55 | }, 56 | "outputs": [], 57 | "source": [] 58 | } 59 | ], 60 | "metadata": { 61 | "kernelspec": { 62 | "display_name": "Python 3", 63 | "language": "python", 64 | "name": "python3" 65 | }, 66 | "language_info": { 67 | "codemirror_mode": { 68 | "name": "ipython", 69 | "version": 3 70 | }, 71 | "file_extension": ".py", 72 | "mimetype": "text/x-python", 73 | "name": "python", 74 | "nbconvert_exporter": "python", 75 | "pygments_lexer": "ipython3", 76 | "version": "3.6.2" 77 | } 78 | }, 79 | "nbformat": 4, 80 | "nbformat_minor": 2 81 | } 82 | -------------------------------------------------------------------------------- /homework/.ipynb_checkpoints/2-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节为《高等数值分析》大作业\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "\n", 14 | "原创内容,如需转载需征得作者同意。\n", 15 | "\n", 16 | "Copyright©2020 lizhemin\n", 17 | "***" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "source": [ 26 | "题目一:利用Newton法、简化Newton法,及其Newton法的各种改进形式(至少选一种)计算非线性方程组\n", 27 | "$$\\left\\{\\begin{array}{l}\n", 28 | "3 x_{1}-\\cos \\left(x_{2} x_{3}\\right)-\\frac{1}{2}=0 \\\\\n", 29 | "x_{1}^{2}-81\\left(x_{2}+0.1\\right)^{2}+\\sin x_{3}+1.06=0 \\\\\n", 30 | "e^{-x_{1} x_{2}}+20 x_{3}+\\frac{10 \\pi-3}{3}=0\n", 31 | "\\end{array}\\right.$$\n", 32 | "取初值$x^{(0)}=(0.1,0.1,-0.1)^T$,同时自行选择其它初值(至少三组),并设计迭代算法,在达到相同精度的前提下,比较其迭代次数、浮点运算次数和CPU时间等,对比分析各算法在不同初值条件下的优劣。" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 4, 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "name": "stdout", 42 | "output_type": "stream", 43 | "text": [ 44 | "newton: [[ 5.00000000e-01]\n", 45 | " [ 7.50529404e-19]\n", 46 | " [-5.23598776e-01]]\n", 47 | "time cost 0.291001558303833 s\n", 48 | "easy_newton: [[ 0.49986967]\n", 49 | " [ 0.01946685]\n", 50 | " [-0.52152047]]\n", 51 | "time cost 0.08701729774475098 s\n", 52 | "modify_newton: [[ 5.00000000e-01]\n", 53 | " [-2.26459177e-18]\n", 54 | " [-5.23598776e-01]]\n", 55 | "time cost 0.8489868640899658 s\n" 56 | ] 57 | } 58 | ], 59 | "source": [ 60 | "import numpy as np\n", 61 | "import sympy as sp\n", 62 | "import copy\n", 63 | "import time\n", 64 | "\n", 65 | "def newton(g,x0,error):\n", 66 | " x_old = copy.copy(x0)\n", 67 | " x_new = n_1(g,x_old)\n", 68 | " while np.sqrt(np.mean((x_old-x_new)**2))>error:\n", 69 | " x_old = copy.copy(x_new)\n", 70 | " x_new = n_1(g,x_old)\n", 71 | " return x_new\n", 72 | "\n", 73 | "def inverse(g,x):\n", 74 | " L = len(g)\n", 75 | " inver = np.zeros((L,L))\n", 76 | " value_dict = {}\n", 77 | " for i in range(L):\n", 78 | " value_dict['x'+str(i+1)] = x[i]\n", 79 | " for i in range(L):\n", 80 | " for j in range(L):\n", 81 | " diff_func = eval('sp.diff(g[i],x'+str(j+1)+')')\n", 82 | " inver[i,j] = diff_func.evalf(subs=value_dict)\n", 83 | " inver = np.matrix(inver)\n", 84 | " inver = np.linalg.pinv(inver)\n", 85 | " return np.array(inver)\n", 86 | "\n", 87 | "def n_1(g,x):\n", 88 | " L = len(g)\n", 89 | " g_x = np.zeros((L,1))\n", 90 | " value_dict = {}\n", 91 | " for i in range(L):\n", 92 | " value_dict['x'+str(i+1)] = x[i]\n", 93 | " for i in range(L):\n", 94 | " g_x[i] = g[i].evalf(subs=value_dict)\n", 95 | " return x-np.dot(inverse(g,x),g_x)\n", 96 | "\n", 97 | "def easy_newton(g,x0,error):\n", 98 | " x_old = copy.copy(x0)\n", 99 | " x_new = n_1(g,x0)\n", 100 | " while np.sqrt(np.mean((x_old-x_new)**2))>error:\n", 101 | " x_old = copy.copy(x_new)\n", 102 | " x_new = n_1(g,x0)\n", 103 | " return x_new\n", 104 | "\n", 105 | "def modify_newton(g,x0,error,m=3):\n", 106 | " x_old = copy.copy(x0)\n", 107 | " x_new = copy.copy(x0)\n", 108 | " for i in range(m):\n", 109 | " x_new = x_new-np.dot(inverse(g,x_old),get_g(g,x_new))\n", 110 | " while np.sqrt(np.mean((x_old-x_new)**2))>error:\n", 111 | " x_old = copy.copy(x_new)\n", 112 | " for i in range(m):\n", 113 | " x_new = x_new-np.dot(inverse(g,x_old),get_g(g,x_new))\n", 114 | " return x_new\n", 115 | "\n", 116 | "def get_g(g,x):\n", 117 | " L = len(g)\n", 118 | " g_x = np.zeros((L,1))\n", 119 | " value_dict = {}\n", 120 | " for i in range(L):\n", 121 | " value_dict['x'+str(i+1)] = x[i]\n", 122 | " for i in range(L):\n", 123 | " g_x[i] = g[i].evalf(subs=value_dict)\n", 124 | " return g_x\n", 125 | "\n", 126 | "x1 = sp.Symbol('x1')\n", 127 | "x2 = sp.Symbol('x2')\n", 128 | "x3 = sp.Symbol('x3')\n", 129 | "\n", 130 | "f1 = 3*x1-sp.cos(x2*x3)-1/2\n", 131 | "f2 = x1**2-81*(x2+0.1)**2+sp.sin(x3)+1.06\n", 132 | "f3 = sp.exp(-x1*x2)+20*x3+(10*sp.pi-3)/3\n", 133 | "\n", 134 | "f = (f1,f2,f3)\n", 135 | "\n", 136 | "time_start=time.time()\n", 137 | "print('newton:',newton(f,np.array([[0.1],[0.1],[-0.1]]),5e-6))\n", 138 | "time_end=time.time()\n", 139 | "print('time cost',time_end-time_start,'s')\n", 140 | "\n", 141 | "time_start=time.time()\n", 142 | "print('easy_newton:',easy_newton(f,np.array([[0.1],[0.1],[-0.1]]),5e-6))\n", 143 | "time_end=time.time()\n", 144 | "print('time cost',time_end-time_start,'s')\n", 145 | "\n", 146 | "time_start=time.time()\n", 147 | "print('modify_newton:',modify_newton(f,np.array([[0.1],[0.1],[-0.1]]),5e-6))\n", 148 | "time_end=time.time()\n", 149 | "print('time cost',time_end-time_start,'s')\n", 150 | "\n", 151 | "\n", 152 | "\n" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "题目二(理论题):称形如\n", 160 | "$$I(f)=\\int_{a}^{b} \\frac{f(x)}{\\sqrt{x-a}} d x$$\n", 161 | "的积分为带权$\\frac{1}{\\sqrt{x-a}}$的积分。设$x_0,x_1,\\ldots,x_m$为区间$[a,b]$中的$m+1$个互异点,$A_0,A_1,\\ldots,A_m$为$m+1$个与$f(x)$无关的常数。现设\n", 162 | "$$h=(b-a) / m, \\quad x_{i}=a+i h, \\quad 0 \\leq i \\leq m$$\n", 163 | "应用插值多项式的有关结果构造一个计算$I(f)$的数值积分公式\n", 164 | "$$I_{N}(f)=\\sum_{i=0}^{m} A_{i} f\\left(x_{i}\\right)$$\n", 165 | "(写出$A_i$的表达式即可),要求该公式至少是二阶的,并给出其截断误差$I(f)-I_N(f)$的形如$c\\|f^{(p)}\\|_{\\infty}h^k$的估计式,其中$c$为常数,$p$和$k$为正整数,$\\|f^{(p)}\\|_{\\infty}=max_{a\\leq x\\leq b}|f^{(p)}(x)|$" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "***\n", 173 | "会用到范德蒙行列式求逆[inverse](https://ccjou.wordpress.com/2012/06/13/vandermonde-%E7%9F%A9%E9%99%A3%E7%9A%84%E9%80%86%E7%9F%A9%E9%99%A3%E5%85%AC%E5%BC%8F/)\n", 174 | "***" 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": {}, 180 | "source": [ 181 | "**引理:**给定范德蒙矩阵\n", 182 | "$$V=\\left[\\begin{array}{cccc}\n", 183 | "1 & 1 & \\cdots & 1 \\\\\n", 184 | "x_{1} & x_{2} & \\cdots & x_{n} \\\\\n", 185 | "x_{1}^{2} & x_{2}^{2} & \\cdots & x_{n}^{2} \\\\\n", 186 | "\\vdots & \\vdots & \\vdots & \\vdots \\\\\n", 187 | "x_{1}^{n-1} & x_{2}^{n-1} & \\cdots & x_{n}^{n-1}\n", 188 | "\\end{array}\\right]$$\n", 189 | "$(V^{-1})_{ij}=(-1)^{j+1} \\sum_{1 \\leq p_{1}<\\cdots, \\ldots p_{n-j \\leq n} \\atop p_{1}, \\ldots, p_{n-j} \\neq i} x_{p_{1}} x_{p_{2}} \\cdots x_{p_{n-j}} / \\prod_{1 \\leq p \\leq n \\atop p \\neq i}\\left(x_{p}-x_{i}\\right)$" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": {}, 195 | "source": [ 196 | "**分析:**由代数精度的定义,对于$k$阶求积分公式,只需找到的$A_i$使得$I(x^j)=\\int_a^b\\frac{x^j}{\\sqrt{x-a}}dx=I_N(x^j)=\\sum_{i=0}^m A_i x_i^j,j=0,1,\\ldots,k$成立即可。\n", 197 | "我们直接分析$k=m$时的情况,此时相当于求解矩阵方程$VA=I_N$\n", 198 | "其中\n", 199 | "$$V=\\left[\\begin{array}{cccc}\n", 200 | "1 & 1 & \\cdots & 1 \\\\\n", 201 | "x_{0} & x_{1} & \\cdots & x_{m} \\\\\n", 202 | "x_{0}^{2} & x_{1}^{2} & \\cdots & x_{m}^{2} \\\\\n", 203 | "\\vdots & \\vdots & \\vdots & \\vdots \\\\\n", 204 | "x_{0}^{m} & x_{1}^{m} & \\cdots & x_{m}^{m}\n", 205 | "\\end{array}\\right]$$\n", 206 | "$A=(A_0,A_1,\\ldots,A_m)^T$,$I_N=(I_N(1),I_N(x),\\ldots,I_N(x^m))^T$" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": {}, 212 | "source": [ 213 | "由于$x_i,i=0,1,\\ldots,m$互异,又由于$V$为范德蒙行列式,此时行列式不为零,即可逆,且逆矩阵的元素可由引理得到。\n", 214 | "\n", 215 | "现在计算$I_N(x^k)=\\int_a^b\\frac{x^k}{\\sqrt{x-a}}dx$,\n", 216 | "令$t=\\sqrt{x-a}$得$I_N(x^k)=\\int_0^{\\sqrt{b-a}}2(a+t^2)^kdt$\n", 217 | "\n", 218 | "可以求解出$A=V^{-1}I_N$,其表达式与$f(x)$无关。" 219 | ] 220 | }, 221 | { 222 | "cell_type": "markdown", 223 | "metadata": {}, 224 | "source": [ 225 | "之前确定的$A$使得求积公式对$m$阶多项式均精确成立,那么通过拉格朗日对点$x_i$插值得到$L_m(x)=I_N(f)$,于是有\n", 226 | "$f(x)=L_m(x)+\\frac{f^{(m+1)(\\xi)}}{(m+1)!}\\omega_{m+1}(x),\\xi\\in(a,b)$\n", 227 | "两边同时乘以$\\frac{1}{\\sqrt{x-a}}$后对$x$从$a$到$b$进行积分。\n", 228 | "有积分第一中值定理得$\\left\\|\\int_a^b\\prod_{i=0}^m(x-x_i)\\frac{1}{\\sqrt{x-a}}dx\\right\\|=\\left\\|\\prod_{i=0}^m(\\xi_0-x_i)\\cdot \\int_a^b\\frac{1}{\\sqrt{x-a}}dx\\right\\|\\leq2\\sqrt{b-a}(m+1)!h^{m+1}$" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": {}, 234 | "source": [ 235 | "$\\left\\|I(f)-I_N(f)\\right\\|\\leq\\left\\|f^{(m+1)}\\right\\|_{\\infty}\\cdot 2\\sqrt{b-a} (m+1)! h^{m+1}\\cdot \\frac{1}{(m+1)!}$\n", 236 | "令$c=2\\sqrt{b-a}$则$\\left\\|I(f)-I_N(f)\\right\\|\\leq c\\left\\|f^{(m+1)}\\right\\|_{\\infty}h^{m+1}$" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": null, 242 | "metadata": { 243 | "collapsed": true 244 | }, 245 | "outputs": [], 246 | "source": [] 247 | } 248 | ], 249 | "metadata": { 250 | "kernelspec": { 251 | "display_name": "Python 3", 252 | "language": "python", 253 | "name": "python3" 254 | }, 255 | "language_info": { 256 | "codemirror_mode": { 257 | "name": "ipython", 258 | "version": 3 259 | }, 260 | "file_extension": ".py", 261 | "mimetype": "text/x-python", 262 | "name": "python", 263 | "nbconvert_exporter": "python", 264 | "pygments_lexer": "ipython3", 265 | "version": "3.6.2" 266 | } 267 | }, 268 | "nbformat": 4, 269 | "nbformat_minor": 2 270 | } 271 | -------------------------------------------------------------------------------- /homework/2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "本节为《高等数值分析》大作业\n", 10 | "\n", 11 | "本文用到python的sympy库进行符号运算,\n", 12 | "可以到第一章进行了解。\n", 13 | "\n", 14 | "原创内容,如需转载需征得作者同意。\n", 15 | "\n", 16 | "Copyright©2020 lizhemin\n", 17 | "***" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "source": [ 26 | "题目一:利用Newton法、简化Newton法,及其Newton法的各种改进形式(至少选一种)计算非线性方程组\n", 27 | "$$\\left\\{\\begin{array}{l}\n", 28 | "3 x_{1}-\\cos \\left(x_{2} x_{3}\\right)-\\frac{1}{2}=0 \\\\\n", 29 | "x_{1}^{2}-81\\left(x_{2}+0.1\\right)^{2}+\\sin x_{3}+1.06=0 \\\\\n", 30 | "e^{-x_{1} x_{2}}+20 x_{3}+\\frac{10 \\pi-3}{3}=0\n", 31 | "\\end{array}\\right.$$\n", 32 | "取初值$x^{(0)}=(0.1,0.1,-0.1)^T$,同时自行选择其它初值(至少三组),并设计迭代算法,在达到相同精度的前提下,比较其迭代次数、浮点运算次数和CPU时间等,对比分析各算法在不同初值条件下的优劣。" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 14, 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "name": "stdout", 42 | "output_type": "stream", 43 | "text": [ 44 | "init_point: [[ 0.1]\n", 45 | " [ 0.1]\n", 46 | " [-0.1]]\n", 47 | "ite= 4\n", 48 | "newton: [[ 5.00000000e-01]\n", 49 | " [ 7.50529404e-19]\n", 50 | " [-5.23598776e-01]]\n", 51 | "time cost 0.32201266288757324 s\n", 52 | "ite= 1\n", 53 | "easy_newton: [[ 0.49986967]\n", 54 | " [ 0.01946685]\n", 55 | " [-0.52152047]]\n", 56 | "time cost 0.09698271751403809 s\n", 57 | "ite= 2\n", 58 | "modify_newton: [[ 5.00000000e-01]\n", 59 | " [-2.26459177e-18]\n", 60 | " [-5.23598776e-01]]\n", 61 | "time cost 0.5860068798065186 s\n", 62 | "\n", 63 | "\n", 64 | "init_point: [[ 1]\n", 65 | " [ 1]\n", 66 | " [-1]]\n", 67 | "ite= 6\n", 68 | "newton: [[ 5.00000000e-01]\n", 69 | " [ 1.47098191e-11]\n", 70 | " [-5.23598776e-01]]\n", 71 | "time cost 0.47499895095825195 s\n", 72 | "ite= 1\n", 73 | "easy_newton: [[ 0.63764798]\n", 74 | " [ 0.45426082]\n", 75 | " [-0.50869615]]\n", 76 | "time cost 0.11299657821655273 s\n", 77 | "ite= 4\n", 78 | "modify_newton: [[ 5.00000000e-01]\n", 79 | " [-2.26459195e-18]\n", 80 | " [-5.23598776e-01]]\n", 81 | "time cost 1.038996696472168 s\n", 82 | "\n", 83 | "\n", 84 | "init_point: [[-1]\n", 85 | " [-1]\n", 86 | " [ 1]]\n", 87 | "ite= 6\n", 88 | "newton: [[ 0.49814468]\n", 89 | " [-0.1996059 ]\n", 90 | " [-0.52882598]]\n", 91 | "time cost 0.4260070323944092 s\n", 92 | "ite= 1\n", 93 | "easy_newton: [[ 0.90705193]\n", 94 | " [-0.53805004]\n", 95 | " [-0.5355681 ]]\n", 96 | "time cost 0.09000301361083984 s\n", 97 | "ite= 4\n", 98 | "modify_newton: [[ 0.49814468]\n", 99 | " [-0.1996059 ]\n", 100 | " [-0.52882598]]\n", 101 | "time cost 0.9989914894104004 s\n", 102 | "\n", 103 | "\n", 104 | "init_point: [[0]\n", 105 | " [0]\n", 106 | " [1]]\n", 107 | "ite= 3\n", 108 | "newton: [[ 5.00000000e-01]\n", 109 | " [ 2.36742875e-10]\n", 110 | " [-5.23598776e-01]]\n", 111 | "time cost 0.2520027160644531 s\n", 112 | "ite= 1\n", 113 | "easy_newton: [[ 0.5 ]\n", 114 | " [ 0.01655969]\n", 115 | " [-0.52359878]]\n", 116 | "time cost 0.07100391387939453 s\n", 117 | "ite= 2\n", 118 | "modify_newton: [[ 5.00000000e-01]\n", 119 | " [-2.26459195e-18]\n", 120 | " [-5.23598776e-01]]\n", 121 | "time cost 0.5419921875 s\n", 122 | "\n", 123 | "\n" 124 | ] 125 | } 126 | ], 127 | "source": [ 128 | "import numpy as np\n", 129 | "import sympy as sp\n", 130 | "import copy\n", 131 | "import time\n", 132 | "\n", 133 | "def newton(g,x0,error):\n", 134 | " x_old = copy.copy(x0)\n", 135 | " x_new = n_1(g,x_old)\n", 136 | " ite = 0\n", 137 | " while np.sqrt(np.mean((x_old-x_new)**2))>error:\n", 138 | " x_old = copy.copy(x_new)\n", 139 | " x_new = n_1(g,x_old)\n", 140 | " ite += 1\n", 141 | " print('ite=',ite)\n", 142 | " return x_new\n", 143 | "\n", 144 | "def inverse(g,x):\n", 145 | " L = len(g)\n", 146 | " inver = np.zeros((L,L))\n", 147 | " value_dict = {}\n", 148 | " for i in range(L):\n", 149 | " value_dict['x'+str(i+1)] = x[i]\n", 150 | " for i in range(L):\n", 151 | " for j in range(L):\n", 152 | " diff_func = eval('sp.diff(g[i],x'+str(j+1)+')')\n", 153 | " inver[i,j] = diff_func.evalf(subs=value_dict)\n", 154 | " inver = np.matrix(inver)\n", 155 | " inver = np.linalg.pinv(inver)\n", 156 | " return np.array(inver)\n", 157 | "\n", 158 | "def n_1(g,x):\n", 159 | " L = len(g)\n", 160 | " g_x = np.zeros((L,1))\n", 161 | " value_dict = {}\n", 162 | " for i in range(L):\n", 163 | " value_dict['x'+str(i+1)] = x[i]\n", 164 | " for i in range(L):\n", 165 | " g_x[i] = g[i].evalf(subs=value_dict)\n", 166 | " return x-np.dot(inverse(g,x),g_x)\n", 167 | "\n", 168 | "def easy_newton(g,x0,error):\n", 169 | " x_old = copy.copy(x0)\n", 170 | " x_new = n_1(g,x0)\n", 171 | " ite = 0\n", 172 | " while np.sqrt(np.mean((x_old-x_new)**2))>error:\n", 173 | " x_old = copy.copy(x_new)\n", 174 | " x_new = n_1(g,x0)\n", 175 | " ite += 1\n", 176 | " print('ite=',ite)\n", 177 | " return x_new\n", 178 | "\n", 179 | "def modify_newton(g,x0,error,m=3):\n", 180 | " x_old = copy.copy(x0)\n", 181 | " x_new = copy.copy(x0)\n", 182 | " ite = 0\n", 183 | " for i in range(m):\n", 184 | " x_new = x_new-np.dot(inverse(g,x_old),get_g(g,x_new))\n", 185 | " while np.sqrt(np.mean((x_old-x_new)**2))>error:\n", 186 | " x_old = copy.copy(x_new)\n", 187 | " for i in range(m):\n", 188 | " x_new = x_new-np.dot(inverse(g,x_old),get_g(g,x_new))\n", 189 | " ite += 1\n", 190 | " print('ite=',ite)\n", 191 | " return x_new\n", 192 | "\n", 193 | "def get_g(g,x):\n", 194 | " L = len(g)\n", 195 | " g_x = np.zeros((L,1))\n", 196 | " value_dict = {}\n", 197 | " for i in range(L):\n", 198 | " value_dict['x'+str(i+1)] = x[i]\n", 199 | " for i in range(L):\n", 200 | " g_x[i] = g[i].evalf(subs=value_dict)\n", 201 | " return g_x\n", 202 | "\n", 203 | "x1 = sp.Symbol('x1')\n", 204 | "x2 = sp.Symbol('x2')\n", 205 | "x3 = sp.Symbol('x3')\n", 206 | "\n", 207 | "f1 = 3*x1-sp.cos(x2*x3)-1/2\n", 208 | "f2 = x1**2-81*(x2+0.1)**2+sp.sin(x3)+1.06\n", 209 | "f3 = sp.exp(-x1*x2)+20*x3+(10*sp.pi-3)/3\n", 210 | "\n", 211 | "f = (f1,f2,f3)\n", 212 | "init=[]\n", 213 | "init.append(np.array([[0.1],[0.1],[-0.1]]))\n", 214 | "init.append(np.array([[1],[1],[-1]]))\n", 215 | "init.append(np.array([[-1],[-1],[1]]))\n", 216 | "init.append(np.array([[0],[0],[1]]))\n", 217 | "for init_point in init:\n", 218 | " print('init_point:',init_point)\n", 219 | " time_start=time.time()\n", 220 | " print('newton:',newton(f,init_point,5e-6))\n", 221 | " time_end=time.time()\n", 222 | " print('time cost',time_end-time_start,'s')\n", 223 | "\n", 224 | " time_start=time.time()\n", 225 | " print('easy_newton:',easy_newton(f,init_point,5e-6))\n", 226 | " time_end=time.time()\n", 227 | " print('time cost',time_end-time_start,'s')\n", 228 | "\n", 229 | " time_start=time.time()\n", 230 | " print('modify_newton:',modify_newton(f,init_point,5e-6))\n", 231 | " time_end=time.time()\n", 232 | " print('time cost',time_end-time_start,'s')\n", 233 | " \n", 234 | " print('\\n')\n", 235 | "\n", 236 | "\n", 237 | "\n" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": {}, 243 | "source": [ 244 | "题目二(理论题):称形如\n", 245 | "$$I(f)=\\int_{a}^{b} \\frac{f(x)}{\\sqrt{x-a}} d x$$\n", 246 | "的积分为带权$\\frac{1}{\\sqrt{x-a}}$的积分。设$x_0,x_1,\\ldots,x_m$为区间$[a,b]$中的$m+1$个互异点,$A_0,A_1,\\ldots,A_m$为$m+1$个与$f(x)$无关的常数。现设\n", 247 | "$$h=(b-a) / m, \\quad x_{i}=a+i h, \\quad 0 \\leq i \\leq m$$\n", 248 | "应用插值多项式的有关结果构造一个计算$I(f)$的数值积分公式\n", 249 | "$$I_{N}(f)=\\sum_{i=0}^{m} A_{i} f\\left(x_{i}\\right)$$\n", 250 | "(写出$A_i$的表达式即可),要求该公式至少是二阶的,并给出其截断误差$I(f)-I_N(f)$的形如$c\\|f^{(p)}\\|_{\\infty}h^k$的估计式,其中$c$为常数,$p$和$k$为正整数,$\\|f^{(p)}\\|_{\\infty}=max_{a\\leq x\\leq b}|f^{(p)}(x)|$" 251 | ] 252 | }, 253 | { 254 | "cell_type": "markdown", 255 | "metadata": {}, 256 | "source": [ 257 | "***\n", 258 | "会用到范德蒙行列式求逆[inverse](https://ccjou.wordpress.com/2012/06/13/vandermonde-%E7%9F%A9%E9%99%A3%E7%9A%84%E9%80%86%E7%9F%A9%E9%99%A3%E5%85%AC%E5%BC%8F/)\n", 259 | "***" 260 | ] 261 | }, 262 | { 263 | "cell_type": "markdown", 264 | "metadata": {}, 265 | "source": [ 266 | "**引理:**给定范德蒙矩阵\n", 267 | "$$V=\\left[\\begin{array}{cccc}\n", 268 | "1 & 1 & \\cdots & 1 \\\\\n", 269 | "x_{1} & x_{2} & \\cdots & x_{n} \\\\\n", 270 | "x_{1}^{2} & x_{2}^{2} & \\cdots & x_{n}^{2} \\\\\n", 271 | "\\vdots & \\vdots & \\vdots & \\vdots \\\\\n", 272 | "x_{1}^{n-1} & x_{2}^{n-1} & \\cdots & x_{n}^{n-1}\n", 273 | "\\end{array}\\right]$$\n", 274 | "$(V^{-1})_{ij}=(-1)^{j+1} \\sum_{1 \\leq p_{1}<\\cdots, \\ldots p_{n-j \\leq n} \\atop p_{1}, \\ldots, p_{n-j} \\neq i} x_{p_{1}} x_{p_{2}} \\cdots x_{p_{n-j}} / \\prod_{1 \\leq p \\leq n \\atop p \\neq i}\\left(x_{p}-x_{i}\\right)$" 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": {}, 280 | "source": [ 281 | "**分析:**由代数精度的定义,对于$k$阶求积分公式,只需找到的$A_i$使得$I(x^j)=\\int_a^b\\frac{x^j}{\\sqrt{x-a}}dx=I_N(x^j)=\\sum_{i=0}^m A_i x_i^j,j=0,1,\\ldots,k$成立即可。\n", 282 | "我们直接分析$k=m$时的情况,此时相当于求解矩阵方程$VA=I_N$\n", 283 | "其中\n", 284 | "$$V=\\left[\\begin{array}{cccc}\n", 285 | "1 & 1 & \\cdots & 1 \\\\\n", 286 | "x_{0} & x_{1} & \\cdots & x_{m} \\\\\n", 287 | "x_{0}^{2} & x_{1}^{2} & \\cdots & x_{m}^{2} \\\\\n", 288 | "\\vdots & \\vdots & \\vdots & \\vdots \\\\\n", 289 | "x_{0}^{m} & x_{1}^{m} & \\cdots & x_{m}^{m}\n", 290 | "\\end{array}\\right]$$\n", 291 | "$A=(A_0,A_1,\\ldots,A_m)^T$,$I_N=(I_N(1),I_N(x),\\ldots,I_N(x^m))^T$" 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": {}, 297 | "source": [ 298 | "由于$x_i,i=0,1,\\ldots,m$互异,又由于$V$为范德蒙行列式,此时行列式不为零,即可逆,且逆矩阵的元素可由引理得到。\n", 299 | "\n", 300 | "现在计算$I_N(x^k)=\\int_a^b\\frac{x^k}{\\sqrt{x-a}}dx$,\n", 301 | "令$t=\\sqrt{x-a}$得$I_N(x^k)=\\int_0^{\\sqrt{b-a}}2(a+t^2)^kdt$\n", 302 | "\n", 303 | "可以求解出$A=V^{-1}I_N$,其表达式与$f(x)$无关。" 304 | ] 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": {}, 309 | "source": [ 310 | "之前确定的$A$使得求积公式对$m$阶多项式均精确成立,那么通过拉格朗日对点$x_i$插值得到$L_m(x)=I_N(f)$,于是有\n", 311 | "$f(x)=L_m(x)+\\frac{f^{(m+1)(\\xi)}}{(m+1)!}\\omega_{m+1}(x),\\xi\\in(a,b)$\n", 312 | "两边同时乘以$\\frac{1}{\\sqrt{x-a}}$后对$x$从$a$到$b$进行积分。\n", 313 | "有积分第一中值定理得$\\left\\|\\int_a^b\\prod_{i=0}^m(x-x_i)\\frac{1}{\\sqrt{x-a}}dx\\right\\|=\\left\\|\\prod_{i=0}^m(\\xi_0-x_i)\\cdot \\int_a^b\\frac{1}{\\sqrt{x-a}}dx\\right\\|\\leq2\\sqrt{b-a}(m+1)!h^{m+1}$" 314 | ] 315 | }, 316 | { 317 | "cell_type": "markdown", 318 | "metadata": {}, 319 | "source": [ 320 | "$\\left\\|I(f)-I_N(f)\\right\\|\\leq\\left\\|f^{(m+1)}\\right\\|_{\\infty}\\cdot 2\\sqrt{b-a} (m+1)! h^{m+1}\\cdot \\frac{1}{(m+1)!}$\n", 321 | "令$c=2\\sqrt{b-a}$则$\\left\\|I(f)-I_N(f)\\right\\|\\leq c\\left\\|f^{(m+1)}\\right\\|_{\\infty}h^{m+1}$" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 9, 327 | "metadata": {}, 328 | "outputs": [ 329 | { 330 | "name": "stdout", 331 | "output_type": "stream", 332 | "text": [ 333 | "Flops: 10526788.15684129 /s\n" 334 | ] 335 | } 336 | ], 337 | "source": [ 338 | "import time\n", 339 | "\n", 340 | "time_start=time.time()\n", 341 | "for i in range(1000000):\n", 342 | " 1*1\n", 343 | "time_end=time.time()\n", 344 | "print('Flops:',1e6/(time_end-time_start),'/s')" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": null, 350 | "metadata": { 351 | "collapsed": true 352 | }, 353 | "outputs": [], 354 | "source": [] 355 | } 356 | ], 357 | "metadata": { 358 | "kernelspec": { 359 | "display_name": "Python 3", 360 | "language": "python", 361 | "name": "python3" 362 | }, 363 | "language_info": { 364 | "codemirror_mode": { 365 | "name": "ipython", 366 | "version": 3 367 | }, 368 | "file_extension": ".py", 369 | "mimetype": "text/x-python", 370 | "name": "python", 371 | "nbconvert_exporter": "python", 372 | "pygments_lexer": "ipython3", 373 | "version": "3.6.2" 374 | } 375 | }, 376 | "nbformat": 4, 377 | "nbformat_minor": 2 378 | } 379 | -------------------------------------------------------------------------------- /homework/insert.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lizhemin15/numerical/e441c701ed1d578ca0df31008ff2acbdabe4b6a1/homework/insert.eps -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.16.2 2 | sympy==1.1.1 3 | matplotlib==2.0.2 4 | seaborn==0.8.1 -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.6 --------------------------------------------------------------------------------