1717 lines
65 KiB
HTML
1717 lines
65 KiB
HTML
\
|
|
<!DOCTYPE html>
|
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<meta name="generator" content="DocOnce: https://github.com/hplgit/doconce/" />
|
|
<meta name="description" content="Data analysis and Machine Learning Lectures: Linear Algebra methods">
|
|
|
|
<title>Data analysis and Machine Learning Lectures: Linear Algebra methods</title>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- reveal.js: http://lab.hakim.se/reveal-js/ -->
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
|
|
|
|
<link rel="stylesheet" href="reveal.js/css/reveal.css">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/beige.css" id="theme">
|
|
<!--
|
|
<link rel="stylesheet" href="reveal.js/css/reveal.css">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/beige.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/beigesmall.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/solarized.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/serif.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/night.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/moon.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/simple.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/sky.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/darkgray.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/default.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/cbc.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/simula.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/black.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/white.css" id="theme">
|
|
<link rel="stylesheet" href="reveal.js/css/theme/league.css" id="theme">
|
|
-->
|
|
|
|
<!-- For syntax highlighting -->
|
|
<link rel="stylesheet" href="reveal.js/lib/css/zenburn.css">
|
|
|
|
<!-- Printing and PDF exports -->
|
|
<script>
|
|
var link = document.createElement( 'link' );
|
|
link.rel = 'stylesheet';
|
|
link.type = 'text/css';
|
|
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
|
|
document.getElementsByTagName( 'head' )[0].appendChild( link );
|
|
</script>
|
|
|
|
<style type="text/css">
|
|
hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
|
|
p.caption { width: 80%; font-size: 60%; font-style: italic; text-align: left; }
|
|
hr.figure { border: 0; width: 80%; border-bottom: 1px solid #aaa}
|
|
.reveal .alert-text-small { font-size: 80%; }
|
|
.reveal .alert-text-large { font-size: 130%; }
|
|
.reveal .alert-text-normal { font-size: 90%; }
|
|
.reveal .alert {
|
|
padding:8px 35px 8px 14px; margin-bottom:18px;
|
|
text-shadow:0 1px 0 rgba(255,255,255,0.5);
|
|
border:5px solid #bababa;
|
|
-webkit-border-radius: 14px; -moz-border-radius: 14px;
|
|
border-radius:14px;
|
|
background-position: 10px 10px;
|
|
background-repeat: no-repeat;
|
|
background-size: 38px;
|
|
padding-left: 30px; /* 55px; if icon */
|
|
}
|
|
.reveal .alert-block {padding-top:14px; padding-bottom:14px}
|
|
.reveal .alert-block > p, .alert-block > ul {margin-bottom:1em}
|
|
/*.reveal .alert li {margin-top: 1em}*/
|
|
.reveal .alert-block p+p {margin-top:5px}
|
|
/*.reveal .alert-notice { background-image: url(http://hplgit.github.io/doconce/bundled/html_images/small_gray_notice.png); }
|
|
.reveal .alert-summary { background-image:url(http://hplgit.github.io/doconce/bundled/html_images/small_gray_summary.png); }
|
|
.reveal .alert-warning { background-image: url(http://hplgit.github.io/doconce/bundled/html_images/small_gray_warning.png); }
|
|
.reveal .alert-question {background-image:url(http://hplgit.github.io/doconce/bundled/html_images/small_gray_question.png); } */
|
|
|
|
</style>
|
|
|
|
|
|
|
|
<!-- Styles for table layout of slides -->
|
|
<style type="text/css">
|
|
td.padding {
|
|
padding-top:20px;
|
|
padding-bottom:20px;
|
|
padding-right:50px;
|
|
padding-left:50px;
|
|
}
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
<div class="reveal">
|
|
|
|
<!-- Any section element inside the <div class="slides"> container
|
|
is displayed as a slide -->
|
|
|
|
<div class="slides">
|
|
|
|
|
|
|
|
|
|
|
|
<script type="text/x-mathjax-config">
|
|
MathJax.Hub.Config({
|
|
TeX: {
|
|
equationNumbers: { autoNumber: "none" },
|
|
extensions: ["AMSmath.js", "AMSsymbols.js", "autobold.js", "color.js"]
|
|
}
|
|
});
|
|
</script>
|
|
<script type="text/javascript" async
|
|
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section>
|
|
<!-- ------------------- main content ---------------------- -->
|
|
|
|
|
|
|
|
<center><h1 style="text-align: center;">Data analysis and Machine Learning Lectures: Linear Algebra methods </h1></center> <!-- document title -->
|
|
|
|
<p>
|
|
<!-- author(s): Morten Hjorth-Jensen -->
|
|
|
|
<center>
|
|
<b>Morten Hjorth-Jensen</b> [1, 2]
|
|
</center>
|
|
|
|
<p> <br>
|
|
<!-- institution(s) -->
|
|
|
|
<center>[1] <b>Department of Physics, University of Oslo</b></center>
|
|
<center>[2] <b>Department of Physics and Astronomy and National Superconducting Cyclotron Laboratory, Michigan State University</b></center>
|
|
<br>
|
|
<p> <br>
|
|
<center><h4>Jan 27, 2018</h4></center> <!-- date -->
|
|
<br>
|
|
<p>
|
|
|
|
<center style="font-size:80%">
|
|
<!-- copyright --> © 1999-2018, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license
|
|
</center>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec0">Important Matrix and vector handling packages </h2>
|
|
|
|
<p>
|
|
The Numerical Recipes codes have been rewritten in Fortran 90/95 and
|
|
C/C++ by us. The original source codes are taken from the widely used
|
|
software package LAPACK, which follows two other popular packages
|
|
developed in the 1970s, namely EISPACK and LINPACK.
|
|
|
|
<ul>
|
|
|
|
<p><li> LINPACK: package for linear equations and least square problems.</li>
|
|
|
|
<p><li> LAPACK:package for solving symmetric, unsymmetric and generalized eigenvalue problems. From LAPACK's website <a href="http://www.netlib.org" target="_blank"><tt>http://www.netlib.org</tt></a> it is possible to download for free all source codes from this library. Both C/C++ and Fortran versions are available.</li>
|
|
|
|
<p><li> BLAS (I, II and III): (Basic Linear Algebra Subprograms) are routines that provide standard building blocks for performing basic vector and matrix operations. Blas I is vector operations, II vector-matrix operations and III matrix-matrix operations. Highly parallelized and efficient codes, all available for download from <a href="http://www.netlib.org" target="_blank"><tt>http://www.netlib.org</tt></a>.</li>
|
|
</ul>
|
|
<p>
|
|
|
|
<b>Add python material on linear algebra and array handling, text on numpy etc</b>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec1">Basic Matrix Features </h2>
|
|
|
|
<p>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b>Matrix properties reminder.</b>
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A} =
|
|
\begin{bmatrix} a_{11} & a_{12} & a_{13} & a_{14} \\
|
|
a_{21} & a_{22} & a_{23} & a_{24} \\
|
|
a_{31} & a_{32} & a_{33} & a_{34} \\
|
|
a_{41} & a_{42} & a_{43} & a_{44}
|
|
\end{bmatrix}\qquad
|
|
\mathbf{I} =
|
|
\begin{bmatrix} 1 & 0 & 0 & 0 \\
|
|
0 & 1 & 0 & 0 \\
|
|
0 & 0 & 1 & 0 \\
|
|
0 & 0 & 0 & 1
|
|
\end{bmatrix}
|
|
$$
|
|
<p> <br>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec2">Basic Matrix Features </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
The inverse of a matrix is defined by
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A}^{-1} \cdot \mathbf{A} = I
|
|
$$
|
|
<p> <br>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec3">Basic Matrix Features </h2>
|
|
|
|
<p>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b>Matrix Properties Reminder.</b>
|
|
<p>
|
|
<table border="1">
|
|
<thead>
|
|
<tr><th align="center"> Relations </th> <th align="center"> Name </th> <th align="center"> matrix elements </th> </tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td align="center"> \( A = A^{T} \) </td> <td align="center"> symmetric </td> <td align="center"> \( a_{ij} = a_{ji} \) </td> </tr>
|
|
<tr><td align="center"> \( A = \left (A^{T} \right )^{-1} \) </td> <td align="center"> real orthogonal </td> <td align="center"> \( \sum_k a_{ik} a_{jk} = \sum_k a_{ki} a_{kj} = \delta_{ij} \) </td> </tr>
|
|
<tr><td align="center"> \( A = A^{ * } \) </td> <td align="center"> real matrix </td> <td align="center"> \( a_{ij} = a_{ij}^{ * } \) </td> </tr>
|
|
<tr><td align="center"> \( A = A^{\dagger} \) </td> <td align="center"> hermitian </td> <td align="center"> \( a_{ij} = a_{ji}^{ * } \) </td> </tr>
|
|
<tr><td align="center"> \( A = \left (A^{\dagger} \right )^{-1} \) </td> <td align="center"> unitary </td> <td align="center"> \( \sum_k a_{ik} a_{jk}^{ * } = \sum_k a_{ki}^{ * } a_{kj} = \delta_{ij} \) </td> </tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec4">Some famous Matrices </h2>
|
|
|
|
<ul>
|
|
|
|
<p><li> Diagonal if \( a_{ij}=0 \) for \( i\ne j \)</li>
|
|
|
|
<p><li> Upper triangular if \( a_{ij}=0 \) for \( i > j \)</li>
|
|
|
|
<p><li> Lower triangular if \( a_{ij}=0 \) for \( i < j \)</li>
|
|
|
|
<p><li> Upper Hessenberg if \( a_{ij}=0 \) for \( i > j+1 \)</li>
|
|
|
|
<p><li> Lower Hessenberg if \( a_{ij}=0 \) for \( i < j+1 \)</li>
|
|
|
|
<p><li> Tridiagonal if \( a_{ij}=0 \) for \( |i -j| > 1 \)</li>
|
|
|
|
<p><li> Lower banded with bandwidth \( p \): \( a_{ij}=0 \) for \( i > j+p \)</li>
|
|
|
|
<p><li> Upper banded with bandwidth \( p \): \( a_{ij}=0 \) for \( i < j+p \)</li>
|
|
|
|
<p><li> Banded, block upper triangular, block lower triangular....</li>
|
|
</ul>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec5">Basic Matrix Features </h2>
|
|
|
|
<p>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b>Some Equivalent Statements.</b>
|
|
<p>
|
|
For an \( N\times N \) matrix \( \mathbf{A} \) the following properties are all equivalent
|
|
|
|
<ul>
|
|
|
|
<p><li> If the inverse of \( \mathbf{A} \) exists, \( \mathbf{A} \) is nonsingular.</li>
|
|
|
|
<p><li> The equation \( \mathbf{Ax}=0 \) implies \( \mathbf{x}=0 \).</li>
|
|
|
|
<p><li> The rows of \( \mathbf{A} \) form a basis of \( R^N \).</li>
|
|
|
|
<p><li> The columns of \( \mathbf{A} \) form a basis of \( R^N \).</li>
|
|
|
|
<p><li> \( \mathbf{A} \) is a product of elementary matrices.</li>
|
|
|
|
<p><li> \( 0 \) is not eigenvalue of \( \mathbf{A} \).</li>
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec6">Matrix Handling in C/C++, Static and Dynamical allocation </h2>
|
|
|
|
<p>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b>Static.</b>
|
|
<p>
|
|
We have an \( N\times N \) matrix A with \( N=100 \)
|
|
In C/C++ this would be defined as
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span> <span style="color: #00688B; font-weight: bold">int</span> N = <span style="color: #B452CD">100</span>;
|
|
<span style="color: #00688B; font-weight: bold">double</span> A[<span style="color: #B452CD">100</span>][<span style="color: #B452CD">100</span>];
|
|
<span style="color: #228B22">// initialize all elements to zero</span>
|
|
<span style="color: #8B008B; font-weight: bold">for</span>(i=<span style="color: #B452CD">0</span> ; i < N ; i++) {
|
|
<span style="color: #8B008B; font-weight: bold">for</span>(j=<span style="color: #B452CD">0</span> ; j < N ; j++) {
|
|
A[i][j] = <span style="color: #B452CD">0.0</span>;
|
|
</pre></div>
|
|
<p>
|
|
Note the way the matrix is organized, row-major order.
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec7">Matrix Handling in C/C++ </h2>
|
|
|
|
<p>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b>Row Major Order, Addition.</b>
|
|
<p>
|
|
We have \( N\times N \) matrices A, B and C and we wish to
|
|
evaluate \( A=B+C \).
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A}= \mathbf{B}\pm\mathbf{C} \Longrightarrow a_{ij} = b_{ij}\pm c_{ij},
|
|
$$
|
|
<p> <br>
|
|
|
|
In C/C++ this would be coded like
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span> <span style="color: #8B008B; font-weight: bold">for</span>(i=<span style="color: #B452CD">0</span> ; i < N ; i++) {
|
|
<span style="color: #8B008B; font-weight: bold">for</span>(j=<span style="color: #B452CD">0</span> ; j < N ; j++) {
|
|
a[i][j] = b[i][j]+c[i][j]
|
|
</pre></div>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec8">Matrix Handling in C/C++ </h2>
|
|
|
|
<p>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b>Row Major Order, Multiplication.</b>
|
|
<p>
|
|
We have \( N\times N \) matrices A, B and C and we wish to
|
|
evaluate \( A=BC \).
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A}=\mathbf{BC} \Longrightarrow a_{ij} = \sum_{k=1}^{n} b_{ik}c_{kj},
|
|
$$
|
|
<p> <br>
|
|
|
|
In C/C++ this would be coded like
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span> <span style="color: #8B008B; font-weight: bold">for</span>(i=<span style="color: #B452CD">0</span> ; i < N ; i++) {
|
|
<span style="color: #8B008B; font-weight: bold">for</span>(j=<span style="color: #B452CD">0</span> ; j < N ; j++) {
|
|
<span style="color: #8B008B; font-weight: bold">for</span>(k=<span style="color: #B452CD">0</span> ; k < N ; k++) {
|
|
a[i][j]+=b[i][k]*c[k][j];
|
|
</pre></div>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec9">Dynamic memory allocation in C/C++ </h2>
|
|
|
|
<p>
|
|
At least three possibilities in this course
|
|
|
|
<ul>
|
|
|
|
<p><li> Do it yourself</li>
|
|
|
|
<p><li> Use the functions provided in the library package lib.cpp</li>
|
|
|
|
<p><li> Use Armadillo <a href="http://arma.sourceforgenet" target="_blank"><tt>http://arma.sourceforgenet</tt></a> (a C++ linear algebra library, discussion both here and at lab).</li>
|
|
</ul>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec10">Matrix Handling in C/C++, Dynamic Allocation </h2>
|
|
|
|
<p>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b>Do it yourself.</b>
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span><span style="color: #00688B; font-weight: bold">int</span> N;
|
|
<span style="color: #00688B; font-weight: bold">double</span> ** A;
|
|
A = <span style="color: #8B008B; font-weight: bold">new</span> <span style="color: #00688B; font-weight: bold">double</span>*[N]
|
|
<span style="color: #8B008B; font-weight: bold">for</span> ( i = <span style="color: #B452CD">0</span>; i < N; i++)
|
|
A[i] = <span style="color: #8B008B; font-weight: bold">new</span> <span style="color: #00688B; font-weight: bold">double</span>[N];
|
|
</pre></div>
|
|
<p>
|
|
Always free space when you don't need an array anymore.
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span><span style="color: #8B008B; font-weight: bold">for</span> ( i = <span style="color: #B452CD">0</span>; i < N; i++)
|
|
<span style="color: #8B008B; font-weight: bold">delete</span>[] A[i];
|
|
<span style="color: #8B008B; font-weight: bold">delete</span>[] A;
|
|
</pre></div>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec11">Armadillo, recommended!! </h2>
|
|
|
|
<ul>
|
|
|
|
<p><li> Armadillo is a C++ linear algebra library (matrix maths) aiming towards a good balance between speed and ease of use. The syntax is deliberately similar to Matlab.</li>
|
|
|
|
<p><li> Integer, floating point and complex numbers are supported, as well as a subset of trigonometric and statistics functions. Various matrix decompositions are provided through optional integration with LAPACK, or one of its high performance drop-in replacements (such as the multi-threaded MKL or ACML libraries).</li>
|
|
|
|
<p><li> A delayed evaluation approach is employed (at compile-time) to combine several operations into one and reduce (or eliminate) the need for temporaries. This is accomplished through recursive templates and template meta-programming.</li>
|
|
|
|
<p><li> Useful for conversion of research code into production environments, or if C++ has been decided as the language of choice, due to speed and/or integration capabilities.</li>
|
|
|
|
<p><li> The library is open-source software, and is distributed under a license that is useful in both open-source and commercial/proprietary contexts.</li>
|
|
</ul>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec12">Armadillo, simple examples </h2>
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span><span style="color: #1e889b">#include</span> <span style="color: #228B22"><iostream></span><span style="color: #1e889b"></span>
|
|
<span style="color: #1e889b">#include</span> <span style="color: #228B22"><armadillo></span><span style="color: #1e889b"></span>
|
|
|
|
<span style="color: #8B008B; font-weight: bold">using</span> <span style="color: #8B008B; font-weight: bold">namespace</span> std;
|
|
<span style="color: #8B008B; font-weight: bold">using</span> <span style="color: #8B008B; font-weight: bold">namespace</span> arma;
|
|
|
|
<span style="color: #00688B; font-weight: bold">int</span> <span style="color: #008b45">main</span>(<span style="color: #00688B; font-weight: bold">int</span> argc, <span style="color: #00688B; font-weight: bold">char</span>** argv)
|
|
{
|
|
mat A = randu<mat>(<span style="color: #B452CD">5</span>,<span style="color: #B452CD">5</span>);
|
|
mat B = randu<mat>(<span style="color: #B452CD">5</span>,<span style="color: #B452CD">5</span>);
|
|
|
|
cout << A*B << endl;
|
|
|
|
<span style="color: #8B008B; font-weight: bold">return</span> <span style="color: #B452CD">0</span>;
|
|
</pre></div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec13">Armadillo, how to compile and install </h2>
|
|
|
|
<p>
|
|
For people using Ubuntu, Debian, Linux Mint, simply go to the synaptic package manager and install
|
|
armadillo from there.
|
|
You may have to install Lapack as well.
|
|
For Mac and Windows users, follow the instructions from the webpage
|
|
<a href="http://arma.sourceforge.net" target="_blank"><tt>http://arma.sourceforge.net</tt></a>.
|
|
To compile, use for example (linux/ubuntu)
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span>c++ -O2 -o program.x program.cpp -larmadillo -llapack -lblas
|
|
</pre></div>
|
|
<p>
|
|
where the <code>-l</code> option indicates the library you wish to link to.
|
|
|
|
<p>
|
|
For OS X users you may have to declare the paths to the include files and the libraries as
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span>c++ -O2 -o program.x program.cpp -L/usr/local/lib -I/usr/local/include -larmadillo -llapack -lblas
|
|
</pre></div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec14">Armadillo, simple examples </h2>
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span><span style="color: #1e889b">#include</span> <span style="color: #228B22"><iostream></span><span style="color: #1e889b"></span>
|
|
<span style="color: #1e889b">#include</span> <span style="color: #228B22">"armadillo"</span><span style="color: #1e889b"></span>
|
|
<span style="color: #8B008B; font-weight: bold">using</span> <span style="color: #8B008B; font-weight: bold">namespace</span> arma;
|
|
<span style="color: #8B008B; font-weight: bold">using</span> <span style="color: #8B008B; font-weight: bold">namespace</span> std;
|
|
|
|
<span style="color: #00688B; font-weight: bold">int</span> <span style="color: #008b45">main</span>(<span style="color: #00688B; font-weight: bold">int</span> argc, <span style="color: #00688B; font-weight: bold">char</span>** argv)
|
|
{
|
|
<span style="color: #228B22">// directly specify the matrix size (elements are uninitialised)</span>
|
|
mat A(<span style="color: #B452CD">2</span>,<span style="color: #B452CD">3</span>);
|
|
<span style="color: #228B22">// .n_rows = number of rows (read only)</span>
|
|
<span style="color: #228B22">// .n_cols = number of columns (read only)</span>
|
|
cout << <span style="color: #CD5555">"A.n_rows = "</span> << A.n_rows << endl;
|
|
cout << <span style="color: #CD5555">"A.n_cols = "</span> << A.n_cols << endl;
|
|
<span style="color: #228B22">// directly access an element (indexing starts at 0)</span>
|
|
A(<span style="color: #B452CD">1</span>,<span style="color: #B452CD">2</span>) = <span style="color: #B452CD">456.0</span>;
|
|
A.print(<span style="color: #CD5555">"A:"</span>);
|
|
<span style="color: #228B22">// scalars are treated as a 1x1 matrix,</span>
|
|
<span style="color: #228B22">// hence the code below will set A to have a size of 1x1</span>
|
|
A = <span style="color: #B452CD">5.0</span>;
|
|
A.print(<span style="color: #CD5555">"A:"</span>);
|
|
<span style="color: #228B22">// if you want a matrix with all elements set to a particular value</span>
|
|
<span style="color: #228B22">// the .fill() member function can be used</span>
|
|
A.set_size(<span style="color: #B452CD">3</span>,<span style="color: #B452CD">3</span>);
|
|
A.fill(<span style="color: #B452CD">5.0</span>); A.print(<span style="color: #CD5555">"A:"</span>);
|
|
</pre></div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec15">Armadillo, simple examples </h2>
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span> mat B;
|
|
|
|
<span style="color: #228B22">// endr indicates "end of row"</span>
|
|
B << <span style="color: #B452CD">0.555950</span> << <span style="color: #B452CD">0.274690</span> << <span style="color: #B452CD">0.540605</span> << <span style="color: #B452CD">0.798938</span> << endr
|
|
<< <span style="color: #B452CD">0.108929</span> << <span style="color: #B452CD">0.830123</span> << <span style="color: #B452CD">0.891726</span> << <span style="color: #B452CD">0.895283</span> << endr
|
|
<< <span style="color: #B452CD">0.948014</span> << <span style="color: #B452CD">0.973234</span> << <span style="color: #B452CD">0.216504</span> << <span style="color: #B452CD">0.883152</span> << endr
|
|
<< <span style="color: #B452CD">0.023787</span> << <span style="color: #B452CD">0.675382</span> << <span style="color: #B452CD">0.231751</span> << <span style="color: #B452CD">0.450332</span> << endr;
|
|
|
|
<span style="color: #228B22">// print to the cout stream</span>
|
|
<span style="color: #228B22">// with an optional string before the contents of the matrix</span>
|
|
B.print(<span style="color: #CD5555">"B:"</span>);
|
|
|
|
<span style="color: #228B22">// the << operator can also be used to print the matrix</span>
|
|
<span style="color: #228B22">// to an arbitrary stream (cout in this case)</span>
|
|
cout << <span style="color: #CD5555">"B:"</span> << endl << B << endl;
|
|
<span style="color: #228B22">// save to disk</span>
|
|
B.save(<span style="color: #CD5555">"B.txt"</span>, raw_ascii);
|
|
<span style="color: #228B22">// load from disk</span>
|
|
mat C;
|
|
C.load(<span style="color: #CD5555">"B.txt"</span>);
|
|
C += <span style="color: #B452CD">2.0</span> * B;
|
|
C.print(<span style="color: #CD5555">"C:"</span>);
|
|
</pre></div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec16">Armadillo, simple examples </h2>
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span> <span style="color: #228B22">// submatrix types:</span>
|
|
<span style="color: #228B22">//</span>
|
|
<span style="color: #228B22">// .submat(first_row, first_column, last_row, last_column)</span>
|
|
<span style="color: #228B22">// .row(row_number)</span>
|
|
<span style="color: #228B22">// .col(column_number)</span>
|
|
<span style="color: #228B22">// .cols(first_column, last_column)</span>
|
|
<span style="color: #228B22">// .rows(first_row, last_row)</span>
|
|
|
|
cout << <span style="color: #CD5555">"C.submat(0,0,3,1) ="</span> << endl;
|
|
cout << C.submat(<span style="color: #B452CD">0</span>,<span style="color: #B452CD">0</span>,<span style="color: #B452CD">3</span>,<span style="color: #B452CD">1</span>) << endl;
|
|
|
|
<span style="color: #228B22">// generate the identity matrix</span>
|
|
mat D = eye<mat>(<span style="color: #B452CD">4</span>,<span style="color: #B452CD">4</span>);
|
|
|
|
D.submat(<span style="color: #B452CD">0</span>,<span style="color: #B452CD">0</span>,<span style="color: #B452CD">3</span>,<span style="color: #B452CD">1</span>) = C.cols(<span style="color: #B452CD">1</span>,<span style="color: #B452CD">2</span>);
|
|
D.print(<span style="color: #CD5555">"D:"</span>);
|
|
|
|
<span style="color: #228B22">// transpose</span>
|
|
cout << <span style="color: #CD5555">"trans(B) ="</span> << endl;
|
|
cout << trans(B) << endl;
|
|
|
|
<span style="color: #228B22">// maximum from each column (traverse along rows)</span>
|
|
cout << <span style="color: #CD5555">"max(B) ="</span> << endl;
|
|
cout << max(B) << endl;
|
|
</pre></div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec17">Armadillo, simple examples </h2>
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span> <span style="color: #228B22">// maximum from each row (traverse along columns)</span>
|
|
cout << <span style="color: #CD5555">"max(B,1) ="</span> << endl;
|
|
cout << max(B,<span style="color: #B452CD">1</span>) << endl;
|
|
<span style="color: #228B22">// maximum value in B</span>
|
|
cout << <span style="color: #CD5555">"max(max(B)) = "</span> << max(max(B)) << endl;
|
|
<span style="color: #228B22">// sum of each column (traverse along rows)</span>
|
|
cout << <span style="color: #CD5555">"sum(B) ="</span> << endl;
|
|
cout << sum(B) << endl;
|
|
<span style="color: #228B22">// sum of each row (traverse along columns)</span>
|
|
cout << <span style="color: #CD5555">"sum(B,1) ="</span> << endl;
|
|
cout << sum(B,<span style="color: #B452CD">1</span>) << endl;
|
|
<span style="color: #228B22">// sum of all elements</span>
|
|
cout << <span style="color: #CD5555">"sum(sum(B)) = "</span> << sum(sum(B)) << endl;
|
|
cout << <span style="color: #CD5555">"accu(B) = "</span> << accu(B) << endl;
|
|
<span style="color: #228B22">// trace = sum along diagonal</span>
|
|
cout << <span style="color: #CD5555">"trace(B) = "</span> << trace(B) << endl;
|
|
<span style="color: #228B22">// random matrix -- values are uniformly distributed in the [0,1] interval</span>
|
|
mat E = randu<mat>(<span style="color: #B452CD">4</span>,<span style="color: #B452CD">4</span>);
|
|
E.print(<span style="color: #CD5555">"E:"</span>);
|
|
</pre></div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec18">Armadillo, simple examples </h2>
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span> <span style="color: #228B22">// row vectors are treated like a matrix with one row</span>
|
|
rowvec r;
|
|
r << <span style="color: #B452CD">0.59499</span> << <span style="color: #B452CD">0.88807</span> << <span style="color: #B452CD">0.88532</span> << <span style="color: #B452CD">0.19968</span>;
|
|
r.print(<span style="color: #CD5555">"r:"</span>);
|
|
|
|
<span style="color: #228B22">// column vectors are treated like a matrix with one column</span>
|
|
colvec q;
|
|
q << <span style="color: #B452CD">0.81114</span> << <span style="color: #B452CD">0.06256</span> << <span style="color: #B452CD">0.95989</span> << <span style="color: #B452CD">0.73628</span>;
|
|
q.print(<span style="color: #CD5555">"q:"</span>);
|
|
|
|
<span style="color: #228B22">// dot or inner product</span>
|
|
cout << <span style="color: #CD5555">"as_scalar(r*q) = "</span> << as_scalar(r*q) << endl;
|
|
|
|
<span style="color: #228B22">// outer product</span>
|
|
cout << <span style="color: #CD5555">"q*r ="</span> << endl;
|
|
cout << q*r << endl;
|
|
|
|
|
|
<span style="color: #228B22">// sum of three matrices (no temporary matrices are created)</span>
|
|
mat F = B + C + D;
|
|
F.print(<span style="color: #CD5555">"F:"</span>);
|
|
|
|
<span style="color: #8B008B; font-weight: bold">return</span> <span style="color: #B452CD">0</span>;
|
|
</pre></div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec19">Armadillo, simple examples </h2>
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span><span style="color: #1e889b">#include</span> <span style="color: #228B22"><iostream></span><span style="color: #1e889b"></span>
|
|
<span style="color: #1e889b">#include</span> <span style="color: #228B22">"armadillo"</span><span style="color: #1e889b"></span>
|
|
<span style="color: #8B008B; font-weight: bold">using</span> <span style="color: #8B008B; font-weight: bold">namespace</span> arma;
|
|
<span style="color: #8B008B; font-weight: bold">using</span> <span style="color: #8B008B; font-weight: bold">namespace</span> std;
|
|
|
|
<span style="color: #00688B; font-weight: bold">int</span> <span style="color: #008b45">main</span>(<span style="color: #00688B; font-weight: bold">int</span> argc, <span style="color: #00688B; font-weight: bold">char</span>** argv)
|
|
{
|
|
cout << <span style="color: #CD5555">"Armadillo version: "</span> << arma_version::as_string() << endl;
|
|
|
|
mat A;
|
|
|
|
A << <span style="color: #B452CD">0.165300</span> << <span style="color: #B452CD">0.454037</span> << <span style="color: #B452CD">0.995795</span> << <span style="color: #B452CD">0.124098</span> << <span style="color: #B452CD">0.047084</span> << endr
|
|
<< <span style="color: #B452CD">0.688782</span> << <span style="color: #B452CD">0.036549</span> << <span style="color: #B452CD">0.552848</span> << <span style="color: #B452CD">0.937664</span> << <span style="color: #B452CD">0.866401</span> << endr
|
|
<< <span style="color: #B452CD">0.348740</span> << <span style="color: #B452CD">0.479388</span> << <span style="color: #B452CD">0.506228</span> << <span style="color: #B452CD">0.145673</span> << <span style="color: #B452CD">0.491547</span> << endr
|
|
<< <span style="color: #B452CD">0.148678</span> << <span style="color: #B452CD">0.682258</span> << <span style="color: #B452CD">0.571154</span> << <span style="color: #B452CD">0.874724</span> << <span style="color: #B452CD">0.444632</span> << endr
|
|
<< <span style="color: #B452CD">0.245726</span> << <span style="color: #B452CD">0.595218</span> << <span style="color: #B452CD">0.409327</span> << <span style="color: #B452CD">0.367827</span> << <span style="color: #B452CD">0.385736</span> << endr;
|
|
|
|
A.print(<span style="color: #CD5555">"A ="</span>);
|
|
|
|
<span style="color: #228B22">// determinant</span>
|
|
cout << <span style="color: #CD5555">"det(A) = "</span> << det(A) << endl;
|
|
</pre></div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec20">Armadillo, simple examples </h2>
|
|
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span> <span style="color: #228B22">// inverse</span>
|
|
cout << <span style="color: #CD5555">"inv(A) = "</span> << endl << inv(A) << endl;
|
|
<span style="color: #00688B; font-weight: bold">double</span> k = <span style="color: #B452CD">1.23</span>;
|
|
|
|
mat B = randu<mat>(<span style="color: #B452CD">5</span>,<span style="color: #B452CD">5</span>);
|
|
mat C = randu<mat>(<span style="color: #B452CD">5</span>,<span style="color: #B452CD">5</span>);
|
|
|
|
rowvec r = randu<rowvec>(<span style="color: #B452CD">5</span>);
|
|
colvec q = randu<colvec>(<span style="color: #B452CD">5</span>);
|
|
|
|
|
|
<span style="color: #228B22">// examples of some expressions</span>
|
|
<span style="color: #228B22">// for which optimised implementations exist</span>
|
|
<span style="color: #228B22">// optimised implementation of a trinary expression</span>
|
|
<span style="color: #228B22">// that results in a scalar</span>
|
|
cout << <span style="color: #CD5555">"as_scalar( r*inv(diagmat(B))*q ) = "</span>;
|
|
cout << as_scalar( r*inv(diagmat(B))*q ) << endl;
|
|
|
|
<span style="color: #228B22">// example of an expression which is optimised</span>
|
|
<span style="color: #228B22">// as a call to the dgemm() function in BLAS:</span>
|
|
cout << <span style="color: #CD5555">"k*trans(B)*C = "</span> << endl << k*trans(B)*C;
|
|
|
|
<span style="color: #8B008B; font-weight: bold">return</span> <span style="color: #B452CD">0</span>;
|
|
</pre></div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec21">Gaussian Elimination </h2>
|
|
|
|
<p>
|
|
We start with the linear set of equations
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A}\mathbf{x} = \mathbf{w}.
|
|
$$
|
|
<p> <br>
|
|
|
|
We assume also that the matrix \( \mathbf{A} \) is non-singular and that the
|
|
matrix elements along the diagonal satisfy \( a_{ii} \ne 0 \). Simple \( 4\times 4 \) example
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{bmatrix}
|
|
a_{11}& a_{12} &a_{13}& a_{14}\\
|
|
a_{21}& a_{22} &a_{23}& a_{24}\\
|
|
a_{31}& a_{32} &a_{33}& a_{34}\\
|
|
a_{41}& a_{42} &a_{43}& a_{44}\\
|
|
\end{bmatrix} \begin{bmatrix}
|
|
x_1\\
|
|
x_2\\
|
|
x_3 \\
|
|
x_4 \\
|
|
\end{bmatrix}
|
|
=\begin{bmatrix}
|
|
w_1\\
|
|
w_2\\
|
|
w_3 \\
|
|
w_4\\
|
|
\end{bmatrix}.
|
|
$$
|
|
<p> <br>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec22">Gaussian Elimination </h2>
|
|
or
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
a_{11}x_1 +a_{12}x_2 +a_{13}x_3 + a_{14}x_4=&w_1 \nonumber \\
|
|
a_{21}x_1 + a_{22}x_2 + a_{23}x_3 + a_{24}x_4=&w_2 \nonumber \\
|
|
a_{31}x_1 + a_{32}x_2 + a_{33}x_3 + a_{34}x_4=&w_3 \nonumber \\
|
|
a_{41}x_1 + a_{42}x_2 + a_{43}x_3 + a_{44}x_4=&w_4. \nonumber
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec23">Gaussian Elimination </h2>
|
|
|
|
<p>
|
|
The basic idea of Gaussian elimination is to use the first equation to eliminate the first unknown \( x_1 \)
|
|
from the remaining \( n-1 \) equations. Then we use the new second equation to eliminate the second unknown
|
|
\( x_2 \) from the remaining \( n-2 \) equations. With \( n-1 \) such eliminations
|
|
we obtain a so-called upper triangular set of equations of the form
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
b_{11}x_1 +b_{12}x_2 +b_{13}x_3 + b_{14}x_4=&y_1 \nonumber \\
|
|
b_{22}x_2 + b_{23}x_3 + b_{24}x_4=&y_2 \nonumber \\
|
|
b_{33}x_3 + b_{34}x_4=&y_3 \nonumber \\
|
|
b_{44}x_4=&y_4. \nonumber
|
|
\tag{1}
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
|
|
We can solve this system of equations recursively starting from \( x_n \) (in our case \( x_4 \)) and proceed with
|
|
what is called a backward substitution.
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec24">Gaussian Elimination </h2>
|
|
This process can be expressed mathematically as
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{equation}
|
|
x_m = \frac{1}{b_{mm}}\left(y_m-\sum_{k=m+1}^nb_{mk}x_k\right)\quad m=n-1,n-2,\dots,1.
|
|
\tag{2}
|
|
\end{equation}
|
|
$$
|
|
<p> <br>
|
|
|
|
To arrive at such an upper triangular system of equations, we start by eliminating
|
|
the unknown \( x_1 \) for \( j=2,n \). We achieve this by multiplying the first equation by \( a_{j1}/a_{11} \) and then subtract
|
|
the result from the $j$th equation. We assume obviously that \( a_{11}\ne 0 \) and that
|
|
\( \mathbf{A} \) is not singular.
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec25">Gaussian Elimination </h2>
|
|
|
|
<p>
|
|
Our actual \( 4\times 4 \) example reads after the first operation
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{bmatrix}
|
|
a_{11}& a_{12} &a_{13}& a_{14}\\
|
|
0& (a_{22}-\frac{a_{21}a_{12}}{a_{11}}) &(a_{23}-\frac{a_{21}a_{13}}{a_{11}}) & (a_{24}-\frac{a_{21}a_{14}}{a_{11}})\\
|
|
0& (a_{32}-\frac{a_{31}a_{12}}{a_{11}})& (a_{33}-\frac{a_{31}a_{13}}{a_{11}})& (a_{34}-\frac{a_{31}a_{14}}{a_{11}})\\
|
|
0&(a_{42}-\frac{a_{41}a_{12}}{a_{11}}) &(a_{43}-\frac{a_{41}a_{13}}{a_{11}}) & (a_{44}-\frac{a_{41}a_{14}}{a_{11}}) \\
|
|
\end{bmatrix} \begin{bmatrix}
|
|
x_1\\
|
|
x_2\\
|
|
x_3 \\
|
|
x_4 \\
|
|
\end{bmatrix}
|
|
=\begin{bmatrix}
|
|
y_1\\
|
|
w_2^{(2)}\\
|
|
w_3^{(2)} \\
|
|
w_4^{(2)}\\
|
|
\end{bmatrix},
|
|
$$
|
|
<p> <br>
|
|
|
|
or
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
b_{11}x_1 +b_{12}x_2 +b_{13}x_3 + b_{14}x_4=&y_1 \nonumber \\
|
|
a^{(2)}_{22}x_2 + a^{(2)}_{23}x_3 + a^{(2)}_{24}x_4=&w^{(2)}_2 \nonumber \\
|
|
a^{(2)}_{32}x_2 + a^{(2)}_{33}x_3 + a^{(2)}_{34}x_4=&w^{(2)}_3 \nonumber \\
|
|
a^{(2)}_{42}x_2 + a^{(2)}_{43}x_3 + a^{(2)}_{44}x_4=&w^{(2)}_4, \nonumber \\
|
|
\tag{3}
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec26">Gaussian Elimination </h2>
|
|
|
|
<p>
|
|
The new coefficients are
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{equation}
|
|
b_{1k} = a_{1k}^{(1)} \quad k=1,\dots,n,
|
|
\tag{4}
|
|
\end{equation}
|
|
$$
|
|
<p> <br>
|
|
|
|
where each \( a_{1k}^{(1)} \) is equal to the original \( a_{1k} \) element. The other coefficients are
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{equation}
|
|
a_{jk}^{(2)} = a_{jk}^{(1)}-\frac{a_{j1}^{(1)}a_{1k}^{(1)}}{a_{11}^{(1)}} \quad j,k=2,\dots,n,
|
|
\tag{5}
|
|
\end{equation}
|
|
$$
|
|
<p> <br>
|
|
|
|
with a new right-hand side given by
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{equation}
|
|
y_{1}=w_1^{(1)}, \quad w_j^{(2)} =w_j^{(1)}-\frac{a_{j1}^{(1)}w_1^{(1)}}{a_{11}^{(1)}} \quad j=2,\dots,n.
|
|
\tag{6}
|
|
\end{equation}
|
|
$$
|
|
<p> <br>
|
|
|
|
We have also set \( w_1^{(1)}=w_1 \), the original vector element.
|
|
We see that the system of unknowns \( x_1,\dots,x_n \) is transformed into an \( (n-1)\times (n-1) \) problem.
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec27">Gaussian Elimination </h2>
|
|
|
|
<p>
|
|
This step is called forward substitution.
|
|
Proceeding with these substitutions, we obtain the
|
|
general expressions for the new coefficients
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{equation}
|
|
a_{jk}^{(m+1)} = a_{jk}^{(m)}-\frac{a_{jm}^{(m)}a_{mk}^{(m)}}{a_{mm}^{(m)}} \quad j,k=m+1,\dots,n,
|
|
\tag{7}
|
|
\end{equation}
|
|
$$
|
|
<p> <br>
|
|
|
|
with \( m=1,\dots,n-1 \) and a
|
|
right-hand side given by
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{equation}
|
|
w_j^{(m+1)} =w_j^{(m)}-\frac{a_{jm}^{(m)}w_m^{(m)}}{a_{mm}^{(m)}}\quad j=m+1,\dots,n.
|
|
\tag{8}
|
|
\end{equation}
|
|
$$
|
|
<p> <br>
|
|
|
|
This set of \( n-1 \) elimations leads us to an equations which is solved by back substitution.
|
|
If the arithmetics is exact and the matrix \( \mathbf{A} \) is not singular, then the computed answer will be exact.
|
|
|
|
<p>
|
|
Even though the matrix elements along the diagonal are not zero,
|
|
numerically small numbers may appear and subsequent divisions may lead to large numbers, which, if added
|
|
to a small number may yield losses of precision. Suppose for example that our first division in \( (a_{22}-a_{21}a_{12}/a_{11}) \)
|
|
results in \( -10^{-7} \) and that \( a_{22} \) is one.
|
|
one. We are then
|
|
adding \( 10^7+1 \). With single precision this results in \( 10^7 \).
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec28">Linear Algebra Methods </h2>
|
|
|
|
<ul>
|
|
|
|
<p><li> Gaussian elimination, \( O(2/3n^3) \) flops, general matrix</li>
|
|
|
|
<p><li> LU decomposition, upper triangular and lower tridiagonal matrices, \( O(2/3n^3) \) flops, general matrix. Get easily the inverse, determinant and can solve linear equations with back-substitution only, \( O(n^2) \) flops</li>
|
|
|
|
<p><li> Cholesky decomposition. Real symmetric or hermitian positive definite matrix, \( O(1/3n^3) \) flops.</li>
|
|
|
|
<p><li> Tridiagonal linear systems, important for differential equations. Normally positive definite and non-singular. \( O(8n) \) flops for symmetric. Special case of banded matrices.</li>
|
|
|
|
<p><li> Singular value decomposition</li>
|
|
|
|
<p><li> the QR method will be discussed in chapter 7 in connection with eigenvalue systems. \( O(4/3n^3) \) flops.</li>
|
|
</ul>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec29">LU Decomposition </h2>
|
|
|
|
<p>
|
|
The LU decomposition method means that we can rewrite
|
|
this matrix as the product of two matrices \( \mathbf{L} \) and \( \mathbf{U} \)
|
|
where
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{bmatrix}
|
|
a_{11} & a_{12} & a_{13} & a_{14} \\
|
|
a_{21} & a_{22} & a_{23} & a_{24} \\
|
|
a_{31} & a_{32} & a_{33} & a_{34} \\
|
|
a_{41} & a_{42} & a_{43} & a_{44}
|
|
\end{bmatrix}
|
|
= \begin{bmatrix}
|
|
1 & 0 & 0 & 0 \\
|
|
l_{21} & 1 & 0 & 0 \\
|
|
l_{31} & l_{32} & 1 & 0 \\
|
|
l_{41} & l_{42} & l_{43} & 1
|
|
\end{bmatrix}
|
|
\begin{bmatrix}
|
|
u_{11} & u_{12} & u_{13} & u_{14} \\
|
|
0 & u_{22} & u_{23} & u_{24} \\
|
|
0 & 0 & u_{33} & u_{34} \\
|
|
0 & 0 & 0 & u_{44}
|
|
\end{bmatrix}.
|
|
$$
|
|
<p> <br>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec30">LU Decomposition </h2>
|
|
|
|
<p>
|
|
LU decomposition forms the backbone of other algorithms in linear algebra, such as the
|
|
solution of linear equations given by
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
a_{11}x_1 +a_{12}x_2 +a_{13}x_3 + a_{14}x_4=&w_1 \nonumber \\
|
|
a_{21}x_1 + a_{22}x_2 + a_{23}x_3 + a_{24}x_4=&w_2 \nonumber \\
|
|
a_{31}x_1 + a_{32}x_2 + a_{33}x_3 + a_{34}x_4=&w_3 \nonumber \\
|
|
a_{41}x_1 + a_{42}x_2 + a_{43}x_3 + a_{44}x_4=&w_4. \nonumber
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
|
|
The above set of equations is conveniently solved by using LU decomposition as an intermediate step.
|
|
|
|
<p>
|
|
The matrix \( \mathbf{A}\in \mathbb{R}^{n\times n} \) has an LU factorization if the determinant
|
|
is different from zero. If the LU factorization exists and \( \mathbf{A} \) is non-singular, then the LU factorization
|
|
is unique and the determinant is given by
|
|
|
|
<p> <br>
|
|
$$
|
|
det\{\mathbf{A}\}=det\{\mathbf{LU}\}= det\{\mathbf{L}\}det\{\mathbf{U}\}=u_{11}u_{22}\dots u_{nn}.
|
|
$$
|
|
<p> <br>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec31">LU Decomposition, why? </h2>
|
|
|
|
<p>
|
|
There are at least three main advantages with LU decomposition compared with standard Gaussian elimination:
|
|
|
|
<ul>
|
|
|
|
<p><li> It is straightforward to compute the determinant of a matrix</li>
|
|
|
|
<p><li> If we have to solve sets of linear equations with the same matrix but with different vectors \( \mathbf{y} \), the number of FLOPS is of the order \( n^3 \).</li>
|
|
|
|
<p><li> The inverse is such an operation</li>
|
|
</ul>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec32">LU Decomposition, linear equations </h2>
|
|
|
|
<p>
|
|
With the LU decomposition it is rather
|
|
simple to solve a system of linear equations
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
a_{11}x_1 +a_{12}x_2 +a_{13}x_3 + a_{14}x_4=&w_1 \nonumber \\
|
|
a_{21}x_1 + a_{22}x_2 + a_{23}x_3 + a_{24}x_4=&w_2 \nonumber \\
|
|
a_{31}x_1 + a_{32}x_2 + a_{33}x_3 + a_{34}x_4=&w_3 \nonumber \\
|
|
a_{41}x_1 + a_{42}x_2 + a_{43}x_3 + a_{44}x_4=&w_4. \nonumber
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
|
|
<p>
|
|
This can be written in matrix form as
|
|
|
|
<p> <br>
|
|
$$ \mathbf{Ax}=\mathbf{w}. $$
|
|
<p> <br>
|
|
|
|
<p>
|
|
where \( \mathbf{A} \) and \( \mathbf{w} \) are known and we have to solve for
|
|
\( \mathbf{x} \). Using the LU dcomposition we write
|
|
|
|
<p> <br>
|
|
$$ \mathbf{A} \mathbf{x} \equiv \mathbf{L} \mathbf{U} \mathbf{x} =\mathbf{w}. $$
|
|
<p> <br>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec33">LU Decomposition, linear equations </h2>
|
|
|
|
<p>
|
|
The previous equation can be calculated in two steps
|
|
|
|
<p> <br>
|
|
$$ \mathbf{L} \mathbf{y} = \mathbf{w};\qquad \mathbf{Ux}=\mathbf{y}. $$
|
|
<p> <br>
|
|
|
|
<p>
|
|
To show that this is correct we use to the LU decomposition
|
|
to rewrite our system of linear equations as
|
|
|
|
<p> <br>
|
|
$$ \mathbf{LUx}=\mathbf{w}, $$
|
|
<p> <br>
|
|
|
|
and since the determinat of \( \mathbf{L} \) is equal to 1 (by construction
|
|
since the diagonals of \( \mathbf{L} \) equal 1) we can use the inverse of
|
|
\( \mathbf{L} \) to obtain
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{Ux}=\mathbf{L^{-1}w}=\mathbf{y},
|
|
$$
|
|
<p> <br>
|
|
|
|
which yields the intermediate step
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{L^{-1}w}=\mathbf{y}
|
|
$$
|
|
<p> <br>
|
|
|
|
and as soon as we have \( \mathbf{y} \) we can obtain \( \mathbf{x} \)
|
|
through \( \mathbf{Ux}=\mathbf{y} \).
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec34">LU Decomposition, why? </h2>
|
|
|
|
<p>
|
|
For our four-dimentional example this takes the form
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
y_1=&w_1 \nonumber\\
|
|
l_{21}y_1 + y_2=&w_2\nonumber \\
|
|
l_{31}y_1 + l_{32}y_2 + y_3 =&w_3\nonumber \\
|
|
l_{41}y_1 + l_{42}y_2 + l_{43}y_3 + y_4=&w_4. \nonumber
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
|
|
<p>
|
|
and
|
|
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
u_{11}x_1 +u_{12}x_2 +u_{13}x_3 + u_{14}x_4=&y_1 \nonumber\\
|
|
u_{22}x_2 + u_{23}x_3 + u_{24}x_4=&y_2\nonumber \\
|
|
u_{33}x_3 + u_{34}x_4=&y_3\nonumber \\
|
|
u_{44}x_4=&y_4 \nonumber
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
|
|
<p>
|
|
This example shows the basis for the algorithm
|
|
needed to solve the set of \( n \) linear equations.
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec35">LU Decomposition, linear equations </h2>
|
|
|
|
<p>
|
|
The algorithm goes as follows
|
|
|
|
<ul>
|
|
|
|
<p><li> Set up the matrix \( \bf A \) and the vector \( \bf w \) with their correct dimensions. This determines the dimensionality of the unknown vector \( \bf x \).</li>
|
|
|
|
<p><li> Then LU decompose the matrix \( \bf A \) through a call to the function <code>ludcmp(double a, int n, int indx, double &d)</code>. This functions returns the LU decomposed matrix \( \bf A \), its determinant and the vector indx which keeps track of the number of interchanges of rows. If the determinant is zero, the solution is malconditioned.</li>
|
|
|
|
<p><li> Thereafter you call the function <code>lubksb(double a, int n, int indx, double w)</code> which uses the LU decomposed matrix \( \bf A \) and the vector \( \bf w \) and returns \( \bf x \) in the same place as \( \bf w \). Upon exit the original content in \( \bf w \) is destroyed. If you wish to keep this information, you should make a backup of it in your calling function.</li>
|
|
</ul>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec36">LU Decomposition, the inverse of a matrix </h2>
|
|
|
|
<p>
|
|
If the inverse exists then
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A}^{-1}\mathbf{A}=\mathbf{I},
|
|
$$
|
|
<p> <br>
|
|
|
|
the identity matrix. With an LU decomposed matrix we can rewrite the last equation as
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{LU}\mathbf{A}^{-1}=\mathbf{I}.
|
|
$$
|
|
<p> <br>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec37">LU Decomposition, the inverse of a matrix </h2>
|
|
|
|
<p>
|
|
If we assume that the first column (that is column 1) of the inverse matrix
|
|
can be written as a vector with unknown entries
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A}_1^{-1}= \begin{bmatrix}
|
|
a_{11}^{-1} \\
|
|
a_{21}^{-1} \\
|
|
\dots \\
|
|
a_{n1}^{-1} \\
|
|
\end{bmatrix},
|
|
$$
|
|
<p> <br>
|
|
|
|
then we have a linear set of equations
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{LU}\begin{bmatrix}
|
|
a_{11}^{-1} \\
|
|
a_{21}^{-1} \\
|
|
\dots \\
|
|
a_{n1}^{-1} \\
|
|
\end{bmatrix} =\begin{bmatrix}
|
|
1 \\
|
|
0 \\
|
|
\dots \\
|
|
0 \\
|
|
\end{bmatrix}.
|
|
$$
|
|
<p> <br>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec38">LU Decomposition, the inverse </h2>
|
|
|
|
<p>
|
|
In a similar way we can compute the unknow entries of the second column,
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{LU}\begin{bmatrix}
|
|
a_{12}^{-1} \\
|
|
a_{22}^{-1} \\
|
|
\dots \\
|
|
a_{n2}^{-1} \\
|
|
\end{bmatrix}=\begin{bmatrix}
|
|
0 \\
|
|
1 \\
|
|
\dots \\
|
|
0 \\
|
|
\end{bmatrix},
|
|
$$
|
|
<p> <br>
|
|
|
|
and continue till we have solved all \( n \) sets of linear equations.
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec39"><a href="https://github.com/CompPhysics/ComputationalPhysicsMSU/blob/master/doc/Programs/CppQtCodesLectures/MatrixTest/main.cpp" target="_blank">Using Armadillo to perform an LU decomposition</a> </h2>
|
|
<p>
|
|
|
|
<!-- code=c++ (!bc cppcod) typeset with pygments style "perldoc" -->
|
|
<div class="highlight" style="background: #eeeedd"><pre style="font-size: 80%; line-height: 125%"><span></span><span style="color: #1e889b">#include</span> <span style="color: #228B22"><iostream></span><span style="color: #1e889b"></span>
|
|
<span style="color: #1e889b">#include</span> <span style="color: #228B22">"armadillo"</span><span style="color: #1e889b"></span>
|
|
<span style="color: #8B008B; font-weight: bold">using</span> <span style="color: #8B008B; font-weight: bold">namespace</span> arma;
|
|
<span style="color: #8B008B; font-weight: bold">using</span> <span style="color: #8B008B; font-weight: bold">namespace</span> std;
|
|
|
|
<span style="color: #00688B; font-weight: bold">int</span> <span style="color: #008b45">main</span>()
|
|
{
|
|
mat A = randu<mat>(<span style="color: #B452CD">5</span>,<span style="color: #B452CD">5</span>);
|
|
vec b = randu<vec>(<span style="color: #B452CD">5</span>);
|
|
|
|
A.print(<span style="color: #CD5555">"A ="</span>);
|
|
b.print(<span style="color: #CD5555">"b="</span>);
|
|
<span style="color: #228B22">// solve Ax = b</span>
|
|
vec x = solve(A,b);
|
|
<span style="color: #228B22">// print x</span>
|
|
x.print(<span style="color: #CD5555">"x="</span>);
|
|
<span style="color: #228B22">// find LU decomp of A, if needed, P is the permutation matrix</span>
|
|
mat L, U;
|
|
lu(L,U,A);
|
|
<span style="color: #228B22">// print l</span>
|
|
L.print(<span style="color: #CD5555">" L= "</span>);
|
|
<span style="color: #228B22">// print U</span>
|
|
U.print(<span style="color: #CD5555">" U= "</span>);
|
|
<span style="color: #228B22">//Check that A = LU</span>
|
|
(A-L*U).print(<span style="color: #CD5555">"Test of LU decomposition"</span>);
|
|
<span style="color: #8B008B; font-weight: bold">return</span> <span style="color: #B452CD">0</span>;
|
|
}
|
|
</pre></div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec40">Iterative methods, Chapter 6 </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<ul>
|
|
<p><li> Direct solvers such as Gauss elimination and LU decomposition discussed in connection with project 1.</li>
|
|
<p><li> Iterative solvers such as Basic iterative solvers, Jacobi, Gauss-Seidel, Successive over-relaxation. These methods are easy to parallelize, as we will se later. Much used in solutions of partial differential equations.</li>
|
|
<p><li> Other iterative methods such as Krylov subspace methods with Generalized minimum residual (GMRES) and Conjugate gradient etc will not be discussed.</li>
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec41">Iterative methods, Jacobi's method </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
It is a simple method for solving
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A}\mathbf{x}=\mathbf{b},
|
|
$$
|
|
<p> <br>
|
|
|
|
where \( \mathbf{A} \) is a matrix and \( \mathbf{x} \) and \( \mathbf{b} \) are vectors. The vector \( \mathbf{x} \) is
|
|
the unknown.
|
|
|
|
<p>
|
|
It is an iterative scheme where we start with a guess for the unknown, and
|
|
after \( k+1 \) iterations we have
|
|
|
|
<p> <br>
|
|
$$
|
|
\mathbf{x}^{(k+1)}= \mathbf{D}^{-1}(\mathbf{b}-(\mathbf{L}+\mathbf{U})\mathbf{x}^{(k)}),
|
|
$$
|
|
<p> <br>
|
|
|
|
with \( \mathbf{A}=\mathbf{D}+\mathbf{U}+\mathbf{L} \) and
|
|
\( \mathbf{D} \) being a diagonal matrix, \( \mathbf{U} \) an upper triangular matrix and \( \mathbf{L} \) a lower triangular
|
|
matrix.
|
|
|
|
<p>
|
|
If the matrix \( \mathbf{A} \) is positive definite or diagonally dominant, one can show that this method will always converge to the exact solution.
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec42">Iterative methods, Jacobi's method </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
We can demonstrate Jacobi's method by this \( 4\times 4 \) matrix problem. We assume a guess
|
|
for the vector elements \( x_i^{(0)} \), a guess which represents our first iteration. The new
|
|
values are obtained by substitution
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
x_1^{(1)} =&(b_1-a_{12}x_2^{(0)} -a_{13}x_3^{(0)} - a_{14}x_4^{(0)})/a_{11} \nonumber \\
|
|
x_2^{(1)} =&(b_2-a_{21}x_1^{(0)} - a_{23}x_3^{(0)} - a_{24}x_4^{(0)})/a_{22} \nonumber \\
|
|
x_3^{(1)} =&(b_3- a_{31}x_1^{(0)} -a_{32}x_2^{(0)} -a_{34}x_4^{(0)})/a_{33} \nonumber \\
|
|
x_4^{(1)}=&(b_4-a_{41}x_1^{(0)} -a_{42}x_2^{(0)} - a_{43}x_3^{(0)})/a_{44}, \nonumber
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
|
|
which after \( k+1 \) iterations reads
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
x_1^{(k+1)} =&(b_1-a_{12}x_2^{(k)} -a_{13}x_3^{(k)} - a_{14}x_4^{(k)})/a_{11} \nonumber \\
|
|
x_2^{(k+1)} =&(b_2-a_{21}x_1^{(k)} - a_{23}x_3^{(k)} - a_{24}x_4^{(k)})/a_{22} \nonumber \\
|
|
x_3^{(k+1)} =&(b_3- a_{31}x_1^{(k)} -a_{32}x_2^{(k)} -a_{34}x_4^{(k)})/a_{33} \nonumber \\
|
|
x_4^{(k+1)}=&(b_4-a_{41}x_1^{(k)} -a_{42}x_2^{(k)} - a_{43}x_3^{(k)})/a_{44}, \nonumber
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec43">Iterative methods, Jacobi's method </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
We can generalize the above equations to
|
|
<p> <br>
|
|
$$
|
|
x_i^{(k+1)}=(b_i-\sum_{j=1, j\ne i}^{n}a_{ij}x_j^{(k)})/a_{ii}
|
|
$$
|
|
<p> <br>
|
|
|
|
or in an even more compact form as
|
|
<p> <br>
|
|
$$ \mathbf{x}^{(k+1)}= \mathbf{D}^{-1}(\mathbf{b}-(\mathbf{L}+\mathbf{U})\mathbf{x}^{(k)}),
|
|
$$
|
|
<p> <br>
|
|
|
|
with \( \mathbf{A}=\mathbf{D}+\mathbf{U}+\mathbf{L} \) and
|
|
\( \mathbf{D} \) being a diagonal matrix, \( \mathbf{U} \) an upper triangular matrix and \( \mathbf{L} \) a lower triangular
|
|
matrix.
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec44">Iterative methods, Gauss-Seidel's method </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
Our \( 4\times 4 \) matrix problem
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
x_1^{(k+1)} =&(b_1-a_{12}x_2^{(k)} -a_{13}x_3^{(k)} - a_{14}x_4^{(k)})/a_{11} \nonumber \\
|
|
x_2^{(k+1)} =&(b_2-a_{21}x_1^{(k)} - a_{23}x_3^{(k)} - a_{24}x_4^{(k)})/a_{22} \nonumber \\
|
|
x_3^{(k+1)} =&(b_3- a_{31}x_1^{(k)} -a_{32}x_2^{(k)} -a_{34}x_4^{(k)})/a_{33} \nonumber \\
|
|
x_4^{(k+1)}=&(b_4-a_{41}x_1^{(k)} -a_{42}x_2^{(k)} - a_{43}x_3^{(k)})/a_{44}, \nonumber
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
|
|
can be rewritten as
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
x_1^{(k+1)} =&(b_1-a_{12}x_2^{(k)} -a_{13}x_3^{(k)} - a_{14}x_4^{(k)})/a_{11} \nonumber \\
|
|
x_2^{(k+1)} =&(b_2-a_{21}x_1^{(k+1)} - a_{23}x_3^{(k)} - a_{24}x_4^{(k)})/a_{22} \nonumber \\
|
|
x_3^{(k+1)} =&(b_3- a_{31}x_1^{(k+1)} -a_{32}x_2^{(k+1)} -a_{34}x_4^{(k)})/a_{33} \nonumber \\
|
|
x_4^{(k+1)}=&(b_4-a_{41}x_1^{(k+1)} -a_{42}x_2^{(k+1)} - a_{43}x_3^{(k+1)})/a_{44}, \nonumber
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
|
|
which allows us to utilize the preceding solution (forward substitution). This improves normally the convergence
|
|
behavior and leads to the Gauss-Seidel method!
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec45">Iterative methods, Gauss-Seidel's method </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
We can generalize
|
|
<p> <br>
|
|
$$
|
|
\begin{align}
|
|
x_1^{(k+1)} =&(b_1-a_{12}x_2^{(k)} -a_{13}x_3^{(k)} - a_{14}x_4^{(k)})/a_{11} \nonumber \\
|
|
x_2^{(k+1)} =&(b_2-a_{21}x_1^{(k+1)} - a_{23}x_3^{(k)} - a_{24}x_4^{(k)})/a_{22} \nonumber \\
|
|
x_3^{(k+1)} =&(b_3- a_{31}x_1^{(k+1)} -a_{32}x_2^{(k+1)} -a_{34}x_4^{(k)})/a_{33} \nonumber \\
|
|
x_4^{(k+1)}=&(b_4-a_{41}x_1^{(k+1)} -a_{42}x_2^{(k+1)} - a_{43}x_3^{(k+1)})/a_{44}, \nonumber
|
|
\end{align}
|
|
$$
|
|
<p> <br>
|
|
|
|
to the following form
|
|
<p> <br>
|
|
$$
|
|
x^{(k+1)}_i = \frac{1}{a_{ii}} \left(b_i - \sum_{j > i}a_{ij}x^{(k)}_j - \sum_{j < i}a_{ij}x^{(k+1)}_j \right),\quad i=1,2,\ldots,n.
|
|
$$
|
|
<p> <br>
|
|
|
|
The procedure is generally continued until the changes made by an iteration are below some tolerance.
|
|
|
|
<p>
|
|
The convergence properties of the Jacobi method and the
|
|
Gauss-Seidel method are dependent on the matrix \( \mathbf{A} \). These methods converge when
|
|
the matrix is symmetric positive-definite, or is strictly or irreducibly diagonally dominant.
|
|
Both methods sometimes converge even if these conditions are not satisfied.
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec46">Iterative methods, Successive over-relaxation </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
Given a square system of n linear equations with unknown \( \mathbf x \):
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A}\mathbf x = \mathbf b
|
|
$$
|
|
<p> <br>
|
|
|
|
where
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A}=\begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\a_{n1} & a_{n2} & \cdots & a_{nn} \end{bmatrix}, \qquad \mathbf{x} = \begin{bmatrix} x_{1} \\ x_2 \\ \vdots \\ x_n \end{bmatrix} , \qquad \mathbf{b} = \begin{bmatrix} b_{1} \\ b_2 \\ \vdots \\ b_n \end{bmatrix}.
|
|
$$
|
|
<p> <br>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec47">Iterative methods, Successive over-relaxation </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
Then A can be decomposed into a diagonal component D, and strictly lower and upper triangular components L and U:
|
|
<p> <br>
|
|
$$
|
|
\mathbf{A} =\mathbf{D} + \mathbf{L} + \mathbf{U},
|
|
$$
|
|
<p> <br>
|
|
|
|
where
|
|
<p> <br>
|
|
$$
|
|
D = \begin{bmatrix} a_{11} & 0 & \cdots & 0 \\ 0 & a_{22} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\0 & 0 & \cdots & a_{nn} \end{bmatrix}, \quad L = \begin{bmatrix} 0 & 0 & \cdots & 0 \\ a_{21} & 0 & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\a_{n1} & a_{n2} & \cdots & 0 \end{bmatrix}, \quad U = \begin{bmatrix} 0 & a_{12} & \cdots & a_{1n} \\ 0 & 0 & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\0 & 0 & \cdots & 0 \end{bmatrix}.
|
|
$$
|
|
<p> <br>
|
|
|
|
The system of linear equations may be rewritten as:
|
|
<p> <br>
|
|
$$
|
|
(D+\omega L) \mathbf{x} = \omega \mathbf{b} - [\omega U + (\omega-1) D ] \mathbf{x}
|
|
$$
|
|
<p> <br>
|
|
|
|
for a constant \( \omega > 1 \).
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2 id="___sec48">Iterative methods, Successive over-relaxation </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
The method of successive over-relaxation is an iterative technique that solves the left hand side of this expression for \( x \), using previous value for \( x \) on the right hand side. Analytically, this may be written as:
|
|
<p> <br>
|
|
$$
|
|
\mathbf{x}^{(k+1)} = (D+\omega L)^{-1} \big(\omega \mathbf{b} - [\omega U + (\omega-1) D ] \mathbf{x}^{(k)}\big).
|
|
$$
|
|
<p> <br>
|
|
|
|
However, by taking advantage of the triangular form of \( (D+\omega L) \), the elements of \( x^{(k+1)} \) can be computed sequentially using forward substitution:
|
|
<p> <br>
|
|
$$
|
|
x^{(k+1)}_i = (1-\omega)x^{(k)}_i + \frac{\omega}{a_{ii}} \left(b_i - \sum_{j > i} a_{ij}x^{(k)}_j - \sum_{j < i} a_{ij}x^{(k+1)}_j \right),\quad i=1,2,\ldots,n.
|
|
$$
|
|
<p> <br>
|
|
|
|
The choice of relaxation factor is not necessarily easy, and depends upon the properties of the coefficient matrix. For symmetric, positive-definite matrices it can be proven that \( 0 < \omega < 2 \) will lead to convergence, but we are generally interested in faster convergence rather than just convergence.
|
|
</div>
|
|
</section>
|
|
|
|
|
|
|
|
</div> <!-- class="slides" -->
|
|
</div> <!-- class="reveal" -->
|
|
|
|
<script src="reveal.js/lib/js/head.min.js"></script>
|
|
<script src="reveal.js/js/reveal.js"></script>
|
|
|
|
<script>
|
|
// Full list of configuration options available here:
|
|
// https://github.com/hakimel/reveal.js#configuration
|
|
Reveal.initialize({
|
|
|
|
// Display navigation controls in the bottom right corner
|
|
controls: true,
|
|
|
|
// Display progress bar (below the horiz. slider)
|
|
progress: true,
|
|
|
|
// Display the page number of the current slide
|
|
slideNumber: true,
|
|
|
|
// Push each slide change to the browser history
|
|
history: false,
|
|
|
|
// Enable keyboard shortcuts for navigation
|
|
keyboard: true,
|
|
|
|
// Enable the slide overview mode
|
|
overview: true,
|
|
|
|
// Vertical centering of slides
|
|
//center: true,
|
|
center: false,
|
|
|
|
// Enables touch navigation on devices with touch input
|
|
touch: true,
|
|
|
|
// Loop the presentation
|
|
loop: false,
|
|
|
|
// Change the presentation direction to be RTL
|
|
rtl: false,
|
|
|
|
// Turns fragments on and off globally
|
|
fragments: true,
|
|
|
|
// Flags if the presentation is running in an embedded mode,
|
|
// i.e. contained within a limited portion of the screen
|
|
embedded: false,
|
|
|
|
// Number of milliseconds between automatically proceeding to the
|
|
// next slide, disabled when set to 0, this value can be overwritten
|
|
// by using a data-autoslide attribute on your slides
|
|
autoSlide: 0,
|
|
|
|
// Stop auto-sliding after user input
|
|
autoSlideStoppable: true,
|
|
|
|
// Enable slide navigation via mouse wheel
|
|
mouseWheel: false,
|
|
|
|
// Hides the address bar on mobile devices
|
|
hideAddressBar: true,
|
|
|
|
// Opens links in an iframe preview overlay
|
|
previewLinks: false,
|
|
|
|
// Transition style
|
|
transition: 'default', // default/cube/page/concave/zoom/linear/fade/none
|
|
|
|
// Transition speed
|
|
transitionSpeed: 'default', // default/fast/slow
|
|
|
|
// Transition style for full page slide backgrounds
|
|
backgroundTransition: 'default', // default/none/slide/concave/convex/zoom
|
|
|
|
// Number of slides away from the current that are visible
|
|
viewDistance: 3,
|
|
|
|
// Parallax background image
|
|
//parallaxBackgroundImage: '', // e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
|
|
|
|
// Parallax background size
|
|
//parallaxBackgroundSize: '' // CSS syntax, e.g. "2100px 900px"
|
|
|
|
theme: Reveal.getQueryHash().theme, // available themes are in reveal.js/css/theme
|
|
transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/none
|
|
|
|
});
|
|
|
|
Reveal.initialize({
|
|
dependencies: [
|
|
// Cross-browser shim that fully implements classList - https://github.com/eligrey/classList.js/
|
|
{ src: 'reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
|
|
|
|
// Interpret Markdown in <section> elements
|
|
{ src: 'reveal.js/plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
|
|
{ src: 'reveal.js/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
|
|
|
|
// Syntax highlight for <code> elements
|
|
{ src: 'reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
|
|
|
|
// Zoom in and out with Alt+click
|
|
{ src: 'reveal.js/plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
|
|
|
|
// Speaker notes
|
|
{ src: 'reveal.js/plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },
|
|
|
|
// Remote control your reveal.js presentation using a touch device
|
|
//{ src: 'reveal.js/plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } },
|
|
|
|
// MathJax
|
|
//{ src: 'reveal.js/plugin/math/math.js', async: true }
|
|
]
|
|
});
|
|
|
|
Reveal.initialize({
|
|
|
|
// The "normal" size of the presentation, aspect ratio will be preserved
|
|
// when the presentation is scaled to fit different resolutions. Can be
|
|
// specified using percentage units.
|
|
width: 1170, // original: 960,
|
|
height: 700,
|
|
|
|
// Factor of the display size that should remain empty around the content
|
|
margin: 0.1,
|
|
|
|
// Bounds for smallest/largest possible scale to apply to content
|
|
minScale: 0.2,
|
|
maxScale: 1.0
|
|
|
|
});
|
|
</script>
|
|
|
|
<!-- begin footer logo
|
|
<div style="position: absolute; bottom: 0px; left: 0; margin-left: 0px">
|
|
<img src="somelogo.png">
|
|
</div>
|
|
end footer logo -->
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|