├── outcome ├── data │ ├── iterc.mat │ ├── iterr.mat │ ├── iters.mat │ ├── errorc.mat │ ├── errorr.mat │ └── errors.mat └── images │ ├── 1.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ └── 5.png ├── README.md ├── matlab ├── kaczmarz.m ├── simplerandkaczmarz.m ├── driver_as_function.m ├── randkaczmarz.m └── driver.m ├── lazbibreg.bib ├── Project_MATH_881_Lee.Rmd └── jabes.bst /outcome/data/iterc.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/data/iterc.mat -------------------------------------------------------------------------------- /outcome/data/iterr.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/data/iterr.mat -------------------------------------------------------------------------------- /outcome/data/iters.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/data/iters.mat -------------------------------------------------------------------------------- /outcome/images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/images/1.png -------------------------------------------------------------------------------- /outcome/images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/images/2.png -------------------------------------------------------------------------------- /outcome/images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/images/3.png -------------------------------------------------------------------------------- /outcome/images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/images/4.png -------------------------------------------------------------------------------- /outcome/images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/images/5.png -------------------------------------------------------------------------------- /outcome/data/errorc.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/data/errorc.mat -------------------------------------------------------------------------------- /outcome/data/errorr.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/data/errorr.mat -------------------------------------------------------------------------------- /outcome/data/errors.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeeeeLy/Randomized-Kaczmarz-Algorithm/HEAD/outcome/data/errors.mat -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Randomized-Kaczmarz-Algorithm 2 | A semester project on Randomized Kaczmarz Algorithm 3 | 4 | This project provides experiments about the performance of Randomized Kaczmarz’s 5 | method: 6 | * Classical Kaczmarz Method 7 | * Simple Randomized Kaczmarz Method 8 | * Randomized Kaczmarz Method introduced by [Strohmer T, Vershynin R. A randomized Kaczmarz algorithm with exponential convergence[J]. Journal of Fourier Analysis and Applications, 2009, 15(2): 262-278.](https://arxiv.org/abs/math/0702226) 9 | 10 | 11 | -------------------------------------------------------------------------------- /matlab/kaczmarz.m: -------------------------------------------------------------------------------- 1 | function [x,iter,error] = kaczmarz(A, b, x0,maxit,tol,exactx) 2 | % classical kaczmarz 3 | % 4 | % Ax = b 5 | % A - input matrix 6 | % b - right vector 7 | % x0 - initial x 8 | % 9 | % x - the approximated x 10 | % iter - number of iterations before convergence (= maxit if maxit is given) 11 | % error - the norm of difference in x and exact solution after every 12 | % iteration 13 | 14 | m = size(A,1); 15 | n = size(A,2); 16 | 17 | x = x0; 18 | error = []; 19 | 20 | if isempty(tol) 21 | iter = maxit; 22 | for i=1:maxit 23 | pickedi = mod(i,m)+1; 24 | row = A(pickedi, :); 25 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 26 | e = norm(x-exactx); 27 | error = [error,e]; 28 | end 29 | else 30 | iter = 1; 31 | e = 1; 32 | while e >= tol 33 | pickedi = mod(iter,m)+1; 34 | row = A(pickedi, :); 35 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 36 | e = norm(x-exactx); 37 | error = [error,e]; 38 | iter = iter+1; 39 | end 40 | end 41 | end -------------------------------------------------------------------------------- /lazbibreg.bib: -------------------------------------------------------------------------------- 1 | 2 | @article{strohmer2009randomized, 3 | title={A randomized Kaczmarz algorithm with exponential convergence}, 4 | author={Strohmer, Thomas and Vershynin, Roman}, 5 | journal={Journal of Fourier Analysis and Applications}, 6 | volume={15}, 7 | number={2}, 8 | pages={262}, 9 | year={2009}, 10 | publisher={Springer} 11 | } 12 | 13 | @article{kaczmarz1937angenaherte, 14 | title={Angenaherte Auflosung von Systemen linearer Gleichungen: Bulletin International de l’Acad{\'e}mie Polonaise des Sciences et des Lettres}, 15 | author={Kaczmarz, S}, 16 | year={1937} 17 | } 18 | 19 | @article{demmel1988probability, 20 | title={The probability that a numerical analysis problem is difficult}, 21 | author={Demmel, James W}, 22 | journal={Mathematics of Computation}, 23 | volume={50}, 24 | number={182}, 25 | pages={449--480}, 26 | year={1988} 27 | } 28 | 29 | @article{grochenig1999irregular, 30 | title={Irregular sampling, Toeplitz matrices, and the approximation of entire functions of exponential type}, 31 | author={Gr{\"o}chenig, Karlheinz}, 32 | journal={Mathematics of Computation}, 33 | volume={68}, 34 | number={226}, 35 | pages={749--765}, 36 | year={1999} 37 | } 38 | -------------------------------------------------------------------------------- /matlab/simplerandkaczmarz.m: -------------------------------------------------------------------------------- 1 | function [x,iter,error] = simplerandkaczmarz(A, b, x0,maxit,tol,exactx) 2 | % simplerandomized kaczmarz mentioned by fig 1 3 | % Ax = b 4 | % A - input matrix 5 | % b - right vector 6 | % x0 - initial x 7 | % 8 | % x - the approximated x 9 | % iter - number of iterations before convergence (= maxit if maxit is given) 10 | % error - the norm of difference in x and exact solution after every 11 | % iteration 12 | m = size(A,1); 13 | n = size(A,2); 14 | 15 | x = x0; 16 | %iter = 0; 17 | error = []; 18 | e = 1; 19 | 20 | if isempty(tol) 21 | iter = maxit; 22 | for i = 1:maxit 23 | %randsample to generate weighted random number from given vector 24 | pickedi = randi(m); 25 | 26 | row = A(pickedi, :); 27 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 28 | e = norm(x-exactx); 29 | error = [error,e]; 30 | %iter = iter+1; 31 | end 32 | else 33 | iter = 1; 34 | e = 1; 35 | while e >= tol 36 | pickedi = randi(m); 37 | 38 | row = A(pickedi, :); 39 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 40 | e = norm(x-exactx); 41 | error = [error,e]; 42 | iter = iter+1; 43 | end 44 | end 45 | end -------------------------------------------------------------------------------- /matlab/driver_as_function.m: -------------------------------------------------------------------------------- 1 | function [classical_iter_or_error,simple_iter_or_error,rand_iter_or_error] = driver_as_function(iter,tol) 2 | %% set the dimention 3 | r = 50; 4 | m = 700; 5 | n = 2*r+1; 6 | 7 | %% generate nodes 8 | %tj are drawing randomly from a uniform distribution in [0,1] 9 | t = rand(m,1); 10 | 11 | %then ordering by magnitude (since they are all positive, just sort) 12 | t = sort(t); 13 | % just to assign the size 14 | w = zeros(m,1); 15 | x = zeros(n,1); 16 | %% generate x 17 | realx = randn(n,1); 18 | imgx = randn(n,1); 19 | for l = 1:n 20 | x(l) = realx(l)+1i*imgx(l); 21 | end 22 | %% generate A and b 23 | A = zeros(m,n); 24 | for j = 1:m 25 | % dealing with special cases when reach the endpoints(nodes) 26 | if j == 1 27 | w(j) = (t(2)-t(end)-1)/2; 28 | elseif j == m 29 | w(j) = (t(1)+1-t(m-1))/2; 30 | else 31 | w(j) = (t(j+1)-t(j-1))/2; 32 | end 33 | for k = -r:r 34 | A(j,k+r+1) =sqrt(w(j))*exp(2*pi*1i*k*t(j)); 35 | end 36 | end 37 | b = A*x; 38 | x0 = zeros(n,1); 39 | 40 | [x1,iter1,error1] = kaczmarz(A,b,x0,iter,tol,x); 41 | [x2,iter2,error2] = simplerandkaczmarz(A,b,x0,iter,tol,x); 42 | [x3,iter3,error3] = randkaczmarz(A,b,x0,iter,tol,x); 43 | if isempty(tol) 44 | classical_iter_or_error = error1; 45 | simple_iter_or_error = error2; 46 | rand_iter_or_error = error3; 47 | else 48 | classical_iter_or_error = iter1; 49 | simple_iter_or_error = iter2; 50 | rand_iter_or_error = iter3; 51 | end -------------------------------------------------------------------------------- /matlab/randkaczmarz.m: -------------------------------------------------------------------------------- 1 | function [x,iter,error] = randkaczmarz(A, b, x0,maxit,tol,exactx) 2 | % randomized kaczmarz by Algorithm 1 3 | % Ax = b 4 | % A - input matrix 5 | % b - right vector 6 | % x0 - initial x 7 | % 8 | % x - the approximated x 9 | % iter - number of iterations before convergence (= maxit if maxit is given) 10 | % error - the norm of difference in x and exact solution after every 11 | % iteration 12 | m = size(A,1); 13 | n = size(A,2); 14 | 15 | x = x0; 16 | %iter = 0; 17 | error = []; 18 | e = 1; 19 | 20 | normrow = []; 21 | index = []; 22 | %compute norm per row also store the corresponding index 23 | 24 | for i = 1:m 25 | normrow = [normrow,norm(A(i,:))]; 26 | index = [index,i]; 27 | end 28 | 29 | weight = normrow/sum(normrow); 30 | if isempty(tol) 31 | iter = maxit; 32 | for i = 1:maxit 33 | %randsample to generate weighted random number from given vector 34 | pickedi = randsample(index,1,true,weight); 35 | 36 | row = A(pickedi, :); 37 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 38 | e = norm(x-exactx); 39 | error = [error,e]; 40 | %iter = iter+1; 41 | end 42 | else 43 | iter = 1; 44 | e = 1; 45 | while e >= tol 46 | %randsample to generate weighted random number from given vector 47 | pickedi = randsample(index,1,true,weight); 48 | 49 | row = A(pickedi, :); 50 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 51 | e = norm(x-exactx); 52 | error = [error,e]; 53 | iter = iter+1; 54 | end 55 | end 56 | end -------------------------------------------------------------------------------- /matlab/driver.m: -------------------------------------------------------------------------------- 1 | %driver 2 | 3 | %% experiment 1 (presentation) comparing rate of convergence among 3 versions with maxit = 15000 (same experiment as from the original paper) 4 | [error1,error2,error3] = driver_as_function(15000,[]); 5 | 6 | figure (1) 7 | semilogy(1:maxit,error1,'k--'); 8 | title('comparing rate of convergence among 3 versions with maxit = 15000') 9 | ylabel('Least squares error') 10 | xlabel('Number of iterations') 11 | hold on 12 | semilogy(1:maxit,error2,'b--'); 13 | semilogy(1:maxit,error3,'r--'); 14 | hold off 15 | legend('classical kaczmarz','simple randomized kaczmarz','randomized kaczmarz') 16 | %% experiment 2 (report) Running 100 times with random input and maxit = 5000 - statistical analysis 17 | error_c = []; 18 | error_s = []; 19 | error_r = []; 20 | for n = 1:100 21 | [error1,error2,error3] = driver_as_function(5000,[]); 22 | error_c = [error_c,error1(5000)]; 23 | error_s = [error_s,error2(5000)]; 24 | error_r = [error_r,error3(5000)]; 25 | end 26 | % histogram 27 | figure (2) 28 | title('errors') 29 | h3 = histogram(error_c); 30 | ylabel('frequency') 31 | xlabel('Least squares error at the 5000th iteration') 32 | hold on 33 | h4 = histogram(error_s); 34 | h5 = histogram(error_r); 35 | hold off 36 | legend('classical kaczmarz','simple randomized kaczmarz','randomized kaczmarz') 37 | 38 | 39 | figure (3) 40 | h1 = histogram(error_s); 41 | ylabel('Frequency') 42 | xlabel('Least squares error at the 5000th iteration') 43 | hold on 44 | h2 = histogram(error_r); 45 | hold off 46 | legend('simple randomized kaczmarz','randomized kaczmarz') 47 | 48 | %% experiment 3 (report) Running 100 times with random input and tol = 10^(-4) - statistical analysis 49 | iter_c = []; 50 | iter_s = []; 51 | iter_r = []; 52 | for n = 1:100 53 | [iter1,iter2,iter3] = driver_as_function([],0.0001); 54 | iter_c = [iter_c,iter1]; 55 | iter_s = [iter_s,iter2]; 56 | iter_r = [iter_r,iter3]; 57 | end 58 | % histogram 59 | figure (4) 60 | title('iterations') 61 | h6 = histogram(iter_c); 62 | ylabel('Frequency') 63 | xlabel('Number of iterations to reach the tolerrance') 64 | hold on 65 | h7 = histogram(iter_s); 66 | h8 = histogram(iter_r); 67 | hold off 68 | legend('classical kaczmarz','simple randomized kaczmarz','randomized kaczmarz') 69 | figure (5) 70 | title('iterations') 71 | h9 = histogram(iter_s); 72 | ylabel('Frequency') 73 | xlabel('Number of iterations to reach the tolerrance') 74 | hold on 75 | h10 = histogram(iter_r); 76 | hold off 77 | legend('simple randomized kaczmarz','randomized kaczmarz') -------------------------------------------------------------------------------- /Project_MATH_881_Lee.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | geometry: margin=1in 3 | fontsize: 12pt 4 | documentclass: report 5 | output: 6 | pdf_document: 7 | fig_caption: yes 8 | citation_package: natbib 9 | highlight: tango 10 | bibliography: lazbibreg.bib 11 | biblio-style: jabes 12 | subparagraph: yes 13 | header-includes: 14 | 15 | \usepackage{mdwlist} 16 | \usepackage[compact]{titlesec} 17 | \usepackage{titling} 18 | \usepackage[font=small,labelfont=bf,tableposition=top]{caption} 19 | \usepackage{float} 20 | \floatstyle{plaintop} 21 | \restylefloat{table} 22 | \usepackage{lastpage} 23 | \usepackage{hyperref} 24 | \usepackage{colortbl} 25 | \usepackage{array} 26 | \hypersetup{backref,colorlinks=true} 27 | \usepackage{framed,color} 28 | \definecolor{shadecolor}{rgb}{0.95, 0.92, 0.88} 29 | \usepackage{graphicx} 30 | \usepackage{booktabs} 31 | \usepackage{fancyhdr} 32 | \usepackage[none]{hyphenat} 33 | \raggedright 34 | \usepackage{amsmath, amsthm, amssymb, bm} 35 | \usepackage{marginnote} 36 | \usepackage{subfig} 37 | \def\mygraphcaption{Here are my graphs.} 38 | \newlength{\mygraphwidth}\setlength{\mygraphwidth}{0.9\textwidth} 39 | \usepackage{listings} 40 | --- 41 | \lstset{ 42 | basicstyle=\small\ttfamily, 43 | columns=flexible, 44 | breaklines=true} 45 | 46 | \pagestyle{fancy} 47 | \fancyhead[L]{\textbf{Xiaowen(Lee) Li}} 48 | \fancyhead[C]{} 49 | \fancyhead[R]{\textbf{MATH 881 Project}} 50 | \fancyfoot[L]{} 51 | \fancyfoot[C]{} 52 | \fancyfoot[R]{Page -\thepage- of \pageref{LastPage}} 53 | \fancypagestyle{plain}{\pagestyle{fancy}} 54 | \renewcommand{\headrulewidth}{2pt} 55 | \renewcommand{\footrulewidth}{2pt} 56 | 57 | \hypersetup{ 58 | colorlinks = true, 59 | citecolor = blue, 60 | linkcolor = black, 61 | urlcolor = blue 62 | } 63 | 64 | \begin{titlepage} 65 | \begin{center} 66 | \vspace*{2cm} 67 | 68 | \vspace{0.5cm} 69 | 70 | \textbf{\textit{\LARGE Randomized Kaczmarz Algorithm}} 71 | 72 | \vspace{0.5cm} 73 | 74 | \textbf{\Large Math 881: Fall Class Project, 2020} 75 | 76 | \vspace{0.5cm} 77 | 78 | \textbf{\large Xiaowen(Lee) Li} 79 | 80 | \vfill 81 | 82 | \vspace{0.7cm} 83 | 84 | \includegraphics[width=0.4\textwidth]{figures/ku} 85 | 86 | \large Department of Mathematics \\ 87 | University of Kansas, USA \\ 88 | `r format(Sys.time(), '%B %e, %Y')` 89 | 90 | \end{center} 91 | \end{titlepage} 92 | 93 | ```{r setup, include=FALSE} 94 | # load packages 95 | library(knitr) 96 | library(formatR) 97 | library(stargazer) 98 | library(xtable) 99 | library(png) 100 | library(R.matlab) 101 | knitr::opts_chunk$set(echo = TRUE) 102 | options(digits = 5, width = 60, xtable.comment = FALSE) 103 | opts_chunk$set(tidy.opts = list(width.cutoff=60), tidy=TRUE) 104 | out_type <- knitr::opts_knit$get("rmarkdown.pandoc.to") 105 | ``` 106 | 107 | \setlength{\headheight}{45pt} 108 | 109 | \thispagestyle{empty} 110 | \newpage 111 | \pagenumbering{roman} 112 | \setcounter{page}{1} 113 | \pagestyle{plain} 114 | \tableofcontents 115 | \cleardoublepage 116 | \phantomsection 117 | \listoffigures 118 | \phantomsection 119 | \listoftables 120 | \newpage 121 | \pagenumbering{arabic} 122 | 123 | \section{Abstract} 124 | 125 | \subsection{Introduction} 126 | This report provides experiments about the performance of Randomized Kaczmarz's method that is introduced in the paper \citet{strohmer2009randomized} [: A randomized Kaczmarz algorithm with 127 | exponential convergence](https://www.math.ucdavis.edu/~strohmer/papers/2007/kaczmarz.pdf) compares to Classical Randomized Kaczmarz's method and Simple Randomized Kaczmarz's method. 128 | 129 | \subsection{Experiments} 130 | This report contains following experiments: first, the rate of connvergence among all three versions of Kaczmarz's methods with input ramdomly draw from a nonuniform sampling distribution; Then repeating this experiment 100 times and analysising the least squares errors with fixed number of iterations as well as number of iterations with fixed degree of accuracy. 131 | 132 | \subsection{Conclusion} 133 | The Randomized Kaczmarz’s method significantly outperforms the other Kaczmarz methods in all experiments which meets the result from the paper \citet{strohmer2009randomized}. 134 | 135 | \newpage 136 | 137 | \section{Introduction} 138 | 139 | \subsection{Classical Kaczmarz's Method} 140 | 141 | Kaczmarz's method \citet{kaczmarz1937angenaherte} is one of the most popular algorithm in solving the system of equations \[Ax = b,\] where \(A\) is a full rank \(m\times n\) matrix with \(m\geq n\), and \(b\in \mathbb{C}^{m}\). 142 | 143 | To denote the rows of \(A\) by \(a_1^{*},...,a_m^{*}\) and let \(b = (b_1,...,b_m)^{T}\), The classical kaczmarz method picks the row of \(A\) in a cylic manner. The algorithm takes the form 144 | \[x_{k+1} = x_k + \frac{b_i - }{\|{a_i}\|_2^2}*a_i,\] 145 | where \(i = k\) mod \(m+1\). 146 | 147 | The theoretical estimates of the rate of converge of Kaczmarz's method are difficult to obtain for any matrix \(A\) with \(m>2\). All known estimates for certain examples are based on quantities of the matrix \(A\) which make the rate of convergence hard to compute and difficult to make comparision with convergence properties of other iterative methods. 148 | 149 | \subsection{Simple Randomized Kaczmarz's Method} 150 | 151 | To apply the idea from randomized algorithms to Classical Kaczmarz's method, Simple randomized Kaczmarz's Method use the rows of A in Kaczmarz's Method in random order, rather than in their given order. 152 | This algorithm takes the form 153 | \[x_{k+1} = x_k + \frac{b_{s(i)} - }{\|{a_{s(i)}}\|_2^2}*a_{s(i)},\] 154 | where \(s(i)\) is choosen from the set \(\{1,2,...,m\}\) at random. 155 | 156 | No guarantees of its rate of convergence have been known. 157 | 158 | \subsection{Randomized Kaczmarz's Method} 159 | 160 | In the paper \citet{strohmer2009randomized}, authors proposed a new version of Randomized Kaczmarz's method, which picks the rows of matrix \(A\) randomly with probability proportional to the square of its Euclidean norm. This algorithm takes the form 161 | \[x_{k+1} = x_k + \frac{b_{r(i)} - }{\|{a_{r(i)}}\|_2^2}*a_{r(i)},\] 162 | where \(r(i)\) is choosen from the set \(\{1,2,...,m\}\) at random with probability proportional to \(\|a_{r(i)}\|_2^2\). 163 | 164 | And this randomized version of Kaczmarz's method can be proved with exponential expected rate of converegence. 165 | 166 | \subsubsection{Ideas behind choosing the probabilities according to the row-norms} 167 | 168 | \begin{itemize} 169 | \item Choosing the probabilities according to the row-norms is related to the idea of preconditioning a matrix by row-scaling. 170 | \item From the viewpoint of preconditioning, it is clear that other methods of choosing a diagonal preconditioner will in general perform better. 171 | \item However, finding the optimal diagonal preconditioner for the system Ax = b can be very expensive while inverting the entire matrix A when A is large in size. 172 | \item Therefore, a cheaper, suboptimal alternative is needed. Scaling by the inverses of the squared row norms has been shown to be an efficient means to balance computational costs with optimality. 173 | \end{itemize} 174 | 175 | 176 | \section{Theoretical Approach} 177 | 178 | \subsection{Rate of convergence for Randomized Kazmarz Algorithm} 179 | 180 | Consider the linear system of equations \(Ax = b\), where \(A\) is a full rank \(m\times n\) matrix with \(m\geq n\), and \(b\in \mathbb{C}^{m}\).Let \(x\) be its solution. 181 | Then Randomized Kazcmarz Algorithm converges to x in expectation, with the average error 182 | \[\mathbb{E}\|x_k-x\|_2^2\leq(1-\kappa(A)^{-2})^k\cdot \|x_0-x\|_2^2\] 183 | for all \(k = 1,2,...\) 184 | Where \(\kappa(A)\) is the scaled conditional number \citet{demmel1988probability} of matrix \(A\) that is defined as \(\| A \|_F \cdot \| A^{-1} \|_2\). 185 | 186 | 187 | \subsection{Optimality for Randomized Kazmarz Algorithm} 188 | 189 | \subsubsection{General Lower Estimate} 190 | Consider the same kind of linear system of equations as defined above, then there exists an initial approximation \(x_0\) such that 191 | \[\mathbb{E}\|x_k-x\|_2^2\geq(1-\frac{2k}{\kappa(A)^2})\cdot \|x_0-x\|_2^2\] 192 | for all \(k = 1,2,...\) 193 | 194 | \subsubsection{The Upper Estimate is Attained} 195 | If \(\kappa(A) = \sqrt{n}\), then \[\mathbb{E}\|x_k-x\|_2^2=(1-\kappa(A)^{-2})^k\cdot \|x_0-x\|_2^2\] 196 | 197 | \subsection{Discussion} 198 | 199 | From the above theoretical approaches, there are several advantages and disadvantages for Randomized Kaczmarz Method. 200 | 201 | \subsubsection{PROS} 202 | \begin{itemize} 203 | \item The rate of convergence is expressible in terms of standard quantities in numerical analysis and does not depend on the number of equations in the linear system. 204 | \item In terms of accuracy, the average error has an upper bound. 205 | \end{itemize} 206 | 207 | \subsubsection{CONS} 208 | \begin{itemize} 209 | \item As stated above, the estimate cannot be improved beyond a constant factor. 210 | \item In terms of computational cost, the cost for computing all row norms of matrix \(A\) is \(m\times n\) operations. 211 | \end{itemize} 212 | 213 | \section{Numerical Experiments} 214 | 215 | \subsection{Input} 216 | In order to show Randomized Kaczmarz Algorithm is efficient in general matrices. The experiment picked input randomly by a nonuniform sampling distribution. 217 | In this model, the problem has be formulated as follows: 218 | Define \[f(t) = \sum_{l = -r}^{r} x_le^{2\pi ilt},\] 219 | where \(x = \{x_l\}_{l=-r}^{r}\in \mathbb{C} ^{2r+1}.\)\citet{grochenig1999irregular} 220 | 221 | Take nodes \(\{t_k\}_{k=1}^m\) to be non-uniformly spaced by generating the sampling points \(t_j\) randomly between \([0,1]\) and then sort them from smallest to largest. 222 | We arrive at the linear system of equations:\[ Ax = b,\] 223 | where \(A_{j,k} = \sqrt{w_j}e^{2\pi ilt_j}, b_j = \sqrt{w_j}f(t_j), w_j=\frac{t_{j+1}-t_{j-1}}{2},\) 224 | 225 | with \(j = 1,...m; k = -r,...,r; n = 2r+1.\) 226 | 227 | In the experiment, it takes \(r = 50, m = 700\), which makes \(A\) a \(700\times 101\) matrix. 228 | 229 | \subsection{Experiment 1} 230 | 231 | This experiment applies the Classical Kaczmarz's Method, the Simple Randomized Kaczmarz's Method, and the Randomized Kaczmarz's Method and plots the least squares error \(\|x-x_k\|_2\) versus the number of 232 | projections (max iterations = 15000)s, cf. Figure 1. 233 | ```{r figure1, echo=FALSE, include=TRUE, message=FALSE, fig.cap="Comparison of rate of convergence for 3 methods", fig.pos="H", fig.align='center', out.width="0.6\\linewidth"} 234 | img1_path <- "images/1.png" 235 | include_graphics(img1_path) 236 | ``` 237 | \subsubsection{Observation} 238 | Figure 1 clearly shows that the Randomized Kaczmarz Algorithm converges much faster than the orther methods. It also generates smaller error than orther methods. 239 | 240 | \subsection{Experiment 2} 241 | This experiment applies all 3 methods with the described random input matrix \(A\). Each method is terminated after reaching 5000 iterations. After repeating this experiment 100 times, the following histogram shows the least square error \(\|x-x_{5000}\|_2\) for every method. 242 | 243 | ```{r figure2, echo=FALSE, include=TRUE, message=FALSE, fig.cap="Error for 3 methods with fixed 5000 iterations in 100 runs", fig.pos="H", fig.align='center', out.width="0.6\\linewidth"} 244 | img2_path <- "images/2.png" 245 | include_graphics(img2_path) 246 | ``` 247 | 248 | In figure 2, there is a big gap between errors generated by the Classical Kaczmarz's Method and the orther two randomized versions of Kaczmarz's method. 249 | I also came up with Figure 3 which shows the comparison within only two randomized versions of Kaczmarz's method. 250 | 251 | ```{r figure3, echo=FALSE, include=TRUE, message=FALSE, fig.cap="Error for 2 methods with fixed 5000 iterations in 100 runs", fig.pos="H", fig.align='center', out.width="0.6\\linewidth"} 252 | img3_path <- "images/3.png" 253 | include_graphics(img3_path) 254 | ``` 255 | 256 | The statistical summary for above data is given below: 257 | 258 | ```{r tab1, echo=FALSE, results="asis", message=FALSE, tidy.opts = list(width.cutoff=30)} 259 | errorc <- readMat("data/errorc.mat") 260 | errors <- readMat("data/errors.mat") 261 | errorr <- readMat("data/errorr.mat") 262 | c_name <- "Classical" 263 | s_name <- "Simple Randomized" 264 | r_name <- "Randomized" 265 | 266 | df <- data.frame(t(errorc$error.c),t(errors$error.s),t(errorr$error.r)) 267 | names(df) <- c(c_name,s_name,r_name) 268 | 269 | kable(summary(df),caption = "Least squares error for 3 methods with fixed 5000 iterations") 270 | ``` 271 | 272 | 273 | \subsubsection{Observation} 274 | 275 | From figure 2 and 3, we can tell that while the errors by Classical Kaczmarz's method is widely spreading between 0.5 to 1.5, even the errors by Simple Randomized Kaczmarz Algorithm is spreading bwtween 0 to 1.2e-2, the errors by the Randomized Kaczmarz Algorithm is squeezed close to 0. 276 | 277 | Table 1 also shows how close the errors are for Randomized Kaczmarz Algorithm, with min to be 0 (this cannot be more accurate due to the limit of precision can be computed by MatLab), and the max to be as small as 2.42e-04 and a mean at 7.13e-06 which is 1e-02 more accurate than Simple Randomized Kaczmarz Algorithm and 1e-05 more accurate than Classical Kaczmarz Algorithm. 278 | 279 | \subsection{Experiment 3} 280 | This experiment applies all 3 methods with the described random input matrix \(A\). Each method is terminated after reaching the required accuracy \(\varepsilon = 10^{-4}\). After repeating this experiment 100 times, the following histogram shows the number of iterations until terminating for every method. 281 | 282 | ```{r figure4, echo=FALSE, include=TRUE, message=FALSE, fig.cap="Number of iterations for 3 methods with fixed tolerrance in 100 runs", fig.pos="H", fig.align='center', out.width="0.6\\linewidth"} 283 | img4_path <- "images/4.png" 284 | include_graphics(img4_path) 285 | ``` 286 | 287 | The statistical summary for above data is given below: 288 | ```{r tab2, echo=FALSE, results="asis", message=FALSE, tidy.opts = list(width.cutoff=30)} 289 | iterc <- readMat("data/iterc.mat") 290 | iters <- readMat("data/iters.mat") 291 | iterr <- readMat("data/iterr.mat") 292 | c_name <- "Classical" 293 | s_name <- "Simple Randomized" 294 | r_name <- "Randomized" 295 | 296 | dff <- data.frame(t(iterc$iter.c),t(iters$iter.s),t(iterr$iter.r)) 297 | names(dff) <- c(c_name,s_name,r_name) 298 | 299 | kable(summary(dff),caption = "Number of iterations for 3 methods with fixed tolerrance") 300 | ``` 301 | 302 | \subsubsection{Observation} 303 | 304 | Figure 4 shows that the number of iterations required for Randomized Kaczmarz Algorithm to reach the tolerrance is less than the Simple Randomized Kaczmarz Algorithm and much less than the Classical Kaczmarz Algorithm. 305 | 306 | Table 2 also provide the same observation: Randomized Kaczmarz Algorithm has a mean value of iterations at 2906 while Simple Randomized Kaczmarz Algorithm's has it at 3926 and the Classical Kaczmarz Algorithm has it at 37509. 307 | 308 | \section{Conclusion} 309 | The Randomized Kaczmarz Algorithm significantly outperforms the other Kaczmarz methods both in the rate of convergence and the opration cost, demonstrating not only the power of choosing the projections at random but also the importance of choosing the projections according to their relevance. 310 | \section{Future Work} 311 | \begin{itemize} 312 | \item We have shown that the Randomized Kaczmarz Algorithm is a very efficient way to work with general full rank matrices. But with some specifically determined matrices, there are known specific numerical methods to solve them, and it will be interesting to compare the performance of the Randomized Kaczmarz Algorithm with those methods with carefully structured inputs. 313 | \item All the theoretical analysis from the paper \citet{strohmer2009randomized} and the experiments we did in this report assume the consistency of the system of equations - with some appropriate underrelaxation, it will be interesting to see if the Randomized Kaczmarz Algorithm can also do a great job in solving inconsistent systems. 314 | \end{itemize} 315 | 316 | 317 | \newpage 318 | 319 | \section{Appendix: MatLab-code} 320 | 321 | \subsection{Classical Kaczmarz Function} 322 | \begin{lstlisting} 323 | 324 | function [x,iter,error] = kaczmarz(A, b, x0,maxit,tol,exactx) 325 | % classical kaczmarz 326 | % 327 | % Ax = b 328 | % A - input matrix 329 | % b - right vector 330 | % x0 - initial x 331 | % 332 | % x - the approximated x 333 | % iter - number of iterations before convergence (= maxit if maxit is given) 334 | % error - the norm of difference in x and exact solution after every 335 | % iteration 336 | 337 | m = size(A,1); 338 | n = size(A,2); 339 | 340 | x = x0; 341 | error = []; 342 | 343 | if isempty(tol) 344 | iter = maxit; 345 | for i=1:maxit 346 | pickedi = mod(i,m)+1; 347 | row = A(pickedi, :); 348 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 349 | e = norm(x-exactx); 350 | error = [error,e]; 351 | end 352 | else 353 | iter = 1; 354 | e = 1; 355 | while e >= tol 356 | pickedi = mod(iter,m)+1; 357 | row = A(pickedi, :); 358 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 359 | e = norm(x-exactx); 360 | error = [error,e]; 361 | iter = iter+1; 362 | end 363 | end 364 | end 365 | 366 | \end{lstlisting} 367 | \subsection{Simple Randomized Kaczmarz Function} 368 | \begin{lstlisting} 369 | 370 | function [x,iter,error] = randkaczmarz(A, b, x0,maxit,tol,exactx) 371 | % randomized kaczmarz by Algorithm 1 372 | % Ax = b 373 | % A - input matrix 374 | % b - right vector 375 | % x0 - initial x 376 | % 377 | % x - the approximated x 378 | % iter - number of iterations before convergence (= maxit if maxit is given) 379 | % error - the norm of difference in x and exact solution after every 380 | % iteration 381 | m = size(A,1); 382 | n = size(A,2); 383 | 384 | x = x0; 385 | %iter = 0; 386 | error = []; 387 | e = 1; 388 | 389 | normrow = []; 390 | index = []; 391 | %compute norm per row also store the corresponding index 392 | 393 | for i = 1:m 394 | normrow = [normrow,norm(A(i,:))]; 395 | index = [index,i]; 396 | end 397 | 398 | weight = normrow/sum(normrow); 399 | if isempty(tol) 400 | iter = maxit; 401 | for i = 1:maxit 402 | %randsample to generate weighted random number from given vector 403 | pickedi = randsample(index,1,true,weight); 404 | 405 | row = A(pickedi, :); 406 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 407 | e = norm(x-exactx); 408 | error = [error,e]; 409 | %iter = iter+1; 410 | end 411 | else 412 | iter = 1; 413 | e = 1; 414 | while e >= tol 415 | %randsample to generate weighted random number from given vector 416 | pickedi = randsample(index,1,true,weight); 417 | 418 | row = A(pickedi, :); 419 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 420 | e = norm(x-exactx); 421 | error = [error,e]; 422 | iter = iter+1; 423 | end 424 | end 425 | end 426 | 427 | \end{lstlisting} 428 | \subsection{Randomized Kaczmarz Function} 429 | \begin{lstlisting} 430 | 431 | function [x,iter,error] = simplerandkaczmarz(A, b, x0,maxit,tol,exactx) 432 | % simplerandomized kaczmarz mentioned by fig 1 433 | % Ax = b 434 | % A - input matrix 435 | % b - right vector 436 | % x0 - initial x 437 | % 438 | % x - the approximated x 439 | % iter - number of iterations before convergence (= maxit if maxit is given) 440 | % error - the norm of difference in x and exact solution after every 441 | % iteration 442 | m = size(A,1); 443 | n = size(A,2); 444 | 445 | x = x0; 446 | %iter = 0; 447 | error = []; 448 | e = 1; 449 | 450 | if isempty(tol) 451 | iter = maxit; 452 | for i = 1:maxit 453 | %randsample to generate weighted random number from given vector 454 | pickedi = randi(m); 455 | 456 | row = A(pickedi, :); 457 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 458 | e = norm(x-exactx); 459 | error = [error,e]; 460 | %iter = iter+1; 461 | end 462 | else 463 | iter = 1; 464 | e = 1; 465 | while e >= tol 466 | pickedi = randi(m); 467 | 468 | row = A(pickedi, :); 469 | x = x + ( b(pickedi) - (row * x) ) / (row * row') * row'; 470 | e = norm(x-exactx); 471 | error = [error,e]; 472 | iter = iter+1; 473 | end 474 | end 475 | end 476 | 477 | \end{lstlisting} 478 | \subsection{Input Function} 479 | \begin{lstlisting} 480 | 481 | function [classical_iter_or_error,simple_iter_or_error,rand_iter_or_error] = Input(iter,tol) 482 | %% set the dimention 483 | r = 50; 484 | m = 700; 485 | n = 2*r+1; 486 | 487 | %% generate nodes 488 | %tj are drawing randomly from a uniform distribution in [0,1] 489 | t = rand(m,1); 490 | 491 | %then ordering by magnitude (since they are all positive, just sort) 492 | t = sort(t); 493 | % just to assign the size 494 | w = zeros(m,1); 495 | x = zeros(n,1); 496 | %% generate x 497 | realx = randn(n,1); 498 | imgx = randn(n,1); 499 | for l = 1:n 500 | x(l) = realx(l)+1i*imgx(l); 501 | end 502 | %% generate A and b 503 | A = zeros(m,n); 504 | for j = 1:m 505 | % dealing with special cases when reach the endpoints(nodes) 506 | if j == 1 507 | w(j) = (t(2)-t(end)-1)/2; 508 | elseif j == m 509 | w(j) = (t(1)+1-t(m-1))/2; 510 | else 511 | w(j) = (t(j+1)-t(j-1))/2; 512 | end 513 | for k = -r:r 514 | A(j,k+r+1) =sqrt(w(j))*exp(2*pi*1i*k*t(j)); 515 | end 516 | end 517 | b = A*x; 518 | x0 = zeros(n,1); 519 | 520 | [x1,iter1,error1] = kaczmarz(A,b,x0,iter,tol,x); 521 | [x2,iter2,error2] = simplerandkaczmarz(A,b,x0,iter,tol,x); 522 | [x3,iter3,error3] = randkaczmarz(A,b,x0,iter,tol,x); 523 | if isempty(tol) 524 | classical_iter_or_error = error1; 525 | simple_iter_or_error = error2; 526 | rand_iter_or_error = error3; 527 | else 528 | classical_iter_or_error = iter1; 529 | simple_iter_or_error = iter2; 530 | rand_iter_or_error = iter3; 531 | end 532 | 533 | \end{lstlisting} 534 | \subsection{Driver} 535 | \begin{lstlisting} 536 | 537 | %% experiment 1 (presentation) comparing rate of convergence among 3 versions with 538 | %maxit = 15000 539 | %(same experiment as from the original paper) 540 | [error1,error2,error3] = Input(15000,[]); 541 | 542 | figure (1) 543 | semilogy(1:maxit,error1,'k--'); 544 | title('comparing rate of convergence among 3 versions with maxit = 15000') 545 | ylabel('Least squares error') 546 | xlabel('Number of iterations') 547 | hold on 548 | semilogy(1:maxit,error2,'b--'); 549 | semilogy(1:maxit,error3,'r--'); 550 | hold off 551 | legend('classical kaczmarz','simple randomized kaczmarz','randomized kaczmarz') 552 | %% experiment 2 (report) Running 100 times with random input and maxit = 5000 553 | %- statistical analysis 554 | error_c = []; 555 | error_s = []; 556 | error_r = []; 557 | for n = 1:100 558 | [error1,error2,error3] = Input(5000,[]); 559 | error_c = [error_c,error1(5000)]; 560 | error_s = [error_s,error2(5000)]; 561 | error_r = [error_r,error3(5000)]; 562 | end 563 | % histogram 564 | figure (2) 565 | title('errors') 566 | h3 = histogram(error_c); 567 | hold on 568 | h4 = histogram(error_s); 569 | h5 = histogram(error_r); 570 | hold off 571 | legend('classical kaczmarz','simple randomized kaczmarz','randomized kaczmarz') 572 | 573 | 574 | figure (3) 575 | title('errors') 576 | h1 = histogram(error_s); 577 | hold on 578 | h2 = histogram(error_r); 579 | hold off 580 | legend('simple randomized kaczmarz','randomized kaczmarz') 581 | 582 | %% experiment 3 (report) Running 100 times with random input and tol = 10^(-4) 583 | %- statistical analysis 584 | iter_c = []; 585 | iter_s = []; 586 | iter_r = []; 587 | for n = 1:100 588 | [iter1,iter2,iter3] = Input([],0.0001); 589 | iter_c = [iter_c,iter1]; 590 | iter_s = [iter_s,iter2]; 591 | iter_r = [iter_r,iter3]; 592 | end 593 | % histogram 594 | figure (4) 595 | title('iterations') 596 | h3 = histogram(iter_c); 597 | hold on 598 | h4 = histogram(iter_s); 599 | h5 = histogram(iter_r); 600 | hold off 601 | legend('classical kaczmarz','simple randomized kaczmarz','randomized kaczmarz') 602 | figure (5) 603 | title('iterations') 604 | h1 = histogram(iter_s); 605 | hold on 606 | h2 = histogram(iter_r); 607 | hold off 608 | legend('simple randomized kaczmarz','randomized kaczmarz') 609 | 610 | \end{lstlisting} 611 | 612 | \newpage 613 | 614 | \section{Appendix: R-code} 615 | \begin{lstlisting} 616 | library(knitr) 617 | library(formatR) 618 | library(stargazer) 619 | library(xtable) 620 | library(png) 621 | library(R.matlab) 622 | knitr::opts_chunk$set(echo = TRUE) 623 | options(digits = 5, width = 60, xtable.comment = FALSE) 624 | opts_chunk$set(tidy.opts = list(width.cutoff=60), tidy=TRUE) 625 | out_type <- knitr::opts_knit$get("rmarkdown.pandoc.to") 626 | #Figure 1 627 | img1_path <- "images/1.png" 628 | include_graphics(img1_path) 629 | #Figure 2 630 | img2_path <- "images/2.png" 631 | include_graphics(img2_path) 632 | #Figure 3 633 | img3_path <- "images/3.png" 634 | include_graphics(img3_path) 635 | #Figure 4 636 | img4_path <- "images/4.png" 637 | include_graphics(img4_path) 638 | #Table 1 639 | errorc <- readMat("data/errorc.mat") 640 | errors <- readMat("data/errors.mat") 641 | errorr<- readMat("data/errorr.mat") 642 | c_name <- "Classical" 643 | s_name <- "Simple Randomized" 644 | r_name <- "Randomized" 645 | 646 | df <- data.frame(t(errorc$error.c),t(errors$error.s),t(errorr$error.r)) 647 | names(df) <- c(c_name,s_name,r_name) 648 | kable(summary(df),caption = "Least squares error for 3 methods") 649 | #Table 2 650 | iterc <- readMat("data/iterc.mat") 651 | iters <- readMat("data/iters.mat") 652 | iterr <- readMat("data/iterr.mat") 653 | c_name <- "Classical" 654 | s_name <- "Simple Randomized" 655 | r_name <- "Randomized" 656 | 657 | dff <- data.frame(t(iterc$iter.c),t(iters$iter.s),t(iterr$iter.r)) 658 | names(dff) <- c(c_name,s_name,r_name) 659 | 660 | kable(summary(dff),caption = "Number of iterations for 3 methods with fixed tolerrance") 661 | \end{lstlisting} -------------------------------------------------------------------------------- /jabes.bst: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `jbs.bst', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% merlin.mbs (with options: `ay,nat,nm-rev,jnrlst,nmdash,dt-beg,yr-par,note-yr,tit-qq,thtit-a,vnum-x,volp-com,pp-last,num-xser,add-pub,pre-edn,edpar,edby,edbyx,blk-com,blknt,pp,ed,abr,ednx,ord,url,url-blk,em-it,nfss') 8 | %% ---------------------------------------- 9 | %% *** JABES *** 10 | %% 11 | %% Copyright 1994-2002 Patrick W Daly 12 | % =============================================================== 13 | % IMPORTANT NOTICE: 14 | % This bibliographic style (bst) file has been generated from one or 15 | % more master bibliographic style (mbs) files, listed above. 16 | % 17 | % This generated file can be redistributed and/or modified under the terms 18 | % of the LaTeX Project Public License Distributed from CTAN 19 | % archives in directory macros/latex/base/lppl.txt; either 20 | % version 1 of the License, or any later version. 21 | % =============================================================== 22 | % Name and version information of the main mbs file: 23 | % \ProvidesFile{merlin.mbs}[2002/01/14 4.03 (PWD, AO, DPC)] 24 | % For use with BibTeX version 0.99a or later 25 | %------------------------------------------------------------------- 26 | % This bibliography style file is intended for texts in ENGLISH 27 | % This is an author-year citation style bibliography. As such, it is 28 | % non-standard LaTeX, and requires a special package file to function properly. 29 | % Such a package is natbib.sty by Patrick W. Daly 30 | % The form of the \bibitem entries is 31 | % \bibitem[Jones et al.(1990)]{key}... 32 | % \bibitem[Jones et al.(1990)Jones, Baker, and Smith]{key}... 33 | % The essential feature is that the label (the part in brackets) consists 34 | % of the author names, as they should appear in the citation, with the year 35 | % in parentheses following. There must be no space before the opening 36 | % parenthesis! 37 | % With natbib v5.3, a full list of authors may also follow the year. 38 | % In natbib.sty, it is possible to define the type of enclosures that is 39 | % really wanted (brackets or parentheses), but in either case, there must 40 | % be parentheses in the label. 41 | % The \cite command functions as follows: 42 | % \citet{key} ==>> Jones et al. (1990) 43 | % \citet*{key} ==>> Jones, Baker, and Smith (1990) 44 | % \citep{key} ==>> (Jones et al., 1990) 45 | % \citep*{key} ==>> (Jones, Baker, and Smith, 1990) 46 | % \citep[chap. 2]{key} ==>> (Jones et al., 1990, chap. 2) 47 | % \citep[e.g.][]{key} ==>> (e.g. Jones et al., 1990) 48 | % \citep[e.g.][p. 32]{key} ==>> (e.g. Jones et al., p. 32) 49 | % \citeauthor{key} ==>> Jones et al. 50 | % \citeauthor*{key} ==>> Jones, Baker, and Smith 51 | % \citeyear{key} ==>> 1990 52 | %--------------------------------------------------------------------- 53 | 54 | ENTRY 55 | { address 56 | author 57 | booktitle 58 | chapter 59 | edition 60 | editor 61 | howpublished 62 | institution 63 | journal 64 | key 65 | month 66 | note 67 | number 68 | organization 69 | pages 70 | publisher 71 | school 72 | series 73 | title 74 | type 75 | url 76 | volume 77 | year 78 | } 79 | {} 80 | { label extra.label sort.label short.list } 81 | INTEGERS { output.state before.all mid.sentence after.sentence after.block } 82 | FUNCTION {init.state.consts} 83 | { #0 'before.all := 84 | #1 'mid.sentence := 85 | #2 'after.sentence := 86 | #3 'after.block := 87 | } 88 | STRINGS { s t} 89 | FUNCTION {output.nonnull} 90 | { 's := 91 | output.state mid.sentence = 92 | { ", " * write$ } 93 | { output.state after.block = 94 | { add.period$ write$ 95 | newline$ 96 | "\newblock " write$ 97 | } 98 | { output.state before.all = 99 | 'write$ 100 | { add.period$ " " * write$ } 101 | if$ 102 | } 103 | if$ 104 | mid.sentence 'output.state := 105 | } 106 | if$ 107 | s 108 | } 109 | FUNCTION {output} 110 | { duplicate$ empty$ 111 | 'pop$ 112 | 'output.nonnull 113 | if$ 114 | } 115 | FUNCTION {output.check} 116 | { 't := 117 | duplicate$ empty$ 118 | { pop$ "empty " t * " in " * cite$ * warning$ } 119 | 'output.nonnull 120 | if$ 121 | } 122 | FUNCTION {fin.entry} 123 | { add.period$ 124 | write$ 125 | newline$ 126 | } 127 | 128 | FUNCTION {new.block} 129 | { output.state before.all = 130 | 'skip$ 131 | { after.block 'output.state := } 132 | if$ 133 | } 134 | FUNCTION {new.sentence} 135 | { output.state after.block = 136 | 'skip$ 137 | { output.state before.all = 138 | 'skip$ 139 | { after.sentence 'output.state := } 140 | if$ 141 | } 142 | if$ 143 | } 144 | FUNCTION {add.blank} 145 | { " " * before.all 'output.state := 146 | } 147 | 148 | FUNCTION {date.block} 149 | { 150 | skip$ 151 | } 152 | 153 | FUNCTION {not} 154 | { { #0 } 155 | { #1 } 156 | if$ 157 | } 158 | FUNCTION {and} 159 | { 'skip$ 160 | { pop$ #0 } 161 | if$ 162 | } 163 | FUNCTION {or} 164 | { { pop$ #1 } 165 | 'skip$ 166 | if$ 167 | } 168 | FUNCTION {non.stop} 169 | { duplicate$ 170 | "}" * add.period$ 171 | #-1 #1 substring$ "." = 172 | } 173 | 174 | FUNCTION {new.block.checkb} 175 | { empty$ 176 | swap$ empty$ 177 | and 178 | 'skip$ 179 | 'new.block 180 | if$ 181 | } 182 | FUNCTION {field.or.null} 183 | { duplicate$ empty$ 184 | { pop$ "" } 185 | 'skip$ 186 | if$ 187 | } 188 | FUNCTION {emphasize} 189 | { duplicate$ empty$ 190 | { pop$ "" } 191 | { "\textit{" swap$ * "}" * } 192 | if$ 193 | } 194 | FUNCTION {tie.or.space.prefix} 195 | { duplicate$ text.length$ #3 < 196 | { "~" } 197 | { " " } 198 | if$ 199 | swap$ 200 | } 201 | 202 | FUNCTION {capitalize} 203 | { "u" change.case$ "t" change.case$ } 204 | 205 | FUNCTION {space.word} 206 | { " " swap$ * " " * } 207 | % Here are the language-specific definitions for explicit words. 208 | % Each function has a name bbl.xxx where xxx is the English word. 209 | % The language selected here is ENGLISH 210 | FUNCTION {bbl.and} 211 | { "and"} 212 | 213 | FUNCTION {bbl.etal} 214 | { "et~al." } 215 | 216 | FUNCTION {bbl.editors} 217 | { "eds." } 218 | 219 | FUNCTION {bbl.editor} 220 | { "ed." } 221 | 222 | FUNCTION {bbl.edby} 223 | { "edited by" } 224 | 225 | FUNCTION {bbl.edition} 226 | { "ed." } 227 | 228 | FUNCTION {bbl.volume} 229 | { "vol." } 230 | 231 | FUNCTION {bbl.of} 232 | { "of" } 233 | 234 | FUNCTION {bbl.number} 235 | { "no." } 236 | 237 | FUNCTION {bbl.nr} 238 | { "no." } 239 | 240 | FUNCTION {bbl.in} 241 | { "in" } 242 | 243 | FUNCTION {bbl.pages} 244 | { "pp." } 245 | 246 | FUNCTION {bbl.page} 247 | { "p." } 248 | 249 | FUNCTION {bbl.chapter} 250 | { "chap." } 251 | 252 | FUNCTION {bbl.techrep} 253 | { "Technical Report" } 254 | 255 | FUNCTION {bbl.mthesis} 256 | { "Master's thesis" } 257 | 258 | FUNCTION {bbl.phdthesis} 259 | { "PhD thesis" } 260 | 261 | FUNCTION {bbl.first} 262 | { "1st" } 263 | 264 | FUNCTION {bbl.second} 265 | { "2nd" } 266 | 267 | FUNCTION {bbl.third} 268 | { "3rd" } 269 | 270 | FUNCTION {bbl.fourth} 271 | { "4th" } 272 | 273 | FUNCTION {bbl.fifth} 274 | { "5th" } 275 | 276 | FUNCTION {bbl.st} 277 | { "st" } 278 | 279 | FUNCTION {bbl.nd} 280 | { "nd" } 281 | 282 | FUNCTION {bbl.rd} 283 | { "rd" } 284 | 285 | FUNCTION {bbl.th} 286 | { "th" } 287 | 288 | MACRO {jan} {"Jan."} 289 | 290 | MACRO {feb} {"Feb."} 291 | 292 | MACRO {mar} {"Mar."} 293 | 294 | MACRO {apr} {"Apr."} 295 | 296 | MACRO {may} {"May"} 297 | 298 | MACRO {jun} {"Jun."} 299 | 300 | MACRO {jul} {"Jul."} 301 | 302 | MACRO {aug} {"Aug."} 303 | 304 | MACRO {sep} {"Sep."} 305 | 306 | MACRO {oct} {"Oct."} 307 | 308 | MACRO {nov} {"Nov."} 309 | 310 | MACRO {dec} {"Dec."} 311 | 312 | FUNCTION {eng.ord} 313 | { duplicate$ "1" swap$ * 314 | #-2 #1 substring$ "1" = 315 | { bbl.th * } 316 | { duplicate$ #-1 #1 substring$ 317 | duplicate$ "1" = 318 | { pop$ bbl.st * } 319 | { duplicate$ "2" = 320 | { pop$ bbl.nd * } 321 | { "3" = 322 | { bbl.rd * } 323 | { bbl.th * } 324 | if$ 325 | } 326 | if$ 327 | } 328 | if$ 329 | } 330 | if$ 331 | } 332 | 333 | MACRO {acmcs} {"ACM Computing Surveys"} 334 | 335 | MACRO {acta} {"Acta Informatica"} 336 | 337 | MACRO {cacm} {"Communications of the ACM"} 338 | 339 | MACRO {ibmjrd} {"IBM Journal of Research and Development"} 340 | 341 | MACRO {ibmsj} {"IBM Systems Journal"} 342 | 343 | MACRO {ieeese} {"IEEE Transactions on Software Engineering"} 344 | 345 | MACRO {ieeetc} {"IEEE Transactions on Computers"} 346 | 347 | MACRO {ieeetcad} 348 | {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} 349 | 350 | MACRO {ipl} {"Information Processing Letters"} 351 | 352 | MACRO {jacm} {"Journal of the ACM"} 353 | 354 | MACRO {jcss} {"Journal of Computer and System Sciences"} 355 | 356 | MACRO {scp} {"Science of Computer Programming"} 357 | 358 | MACRO {sicomp} {"SIAM Journal on Computing"} 359 | 360 | MACRO {tocs} {"ACM Transactions on Computer Systems"} 361 | 362 | MACRO {tods} {"ACM Transactions on Database Systems"} 363 | 364 | MACRO {tog} {"ACM Transactions on Graphics"} 365 | 366 | MACRO {toms} {"ACM Transactions on Mathematical Software"} 367 | 368 | MACRO {toois} {"ACM Transactions on Office Information Systems"} 369 | 370 | MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"} 371 | 372 | MACRO {tcs} {"Theoretical Computer Science"} 373 | FUNCTION {bibinfo.check} 374 | { swap$ 375 | duplicate$ missing$ 376 | { 377 | pop$ pop$ 378 | "" 379 | } 380 | { duplicate$ empty$ 381 | { 382 | swap$ pop$ 383 | } 384 | { swap$ 385 | pop$ 386 | } 387 | if$ 388 | } 389 | if$ 390 | } 391 | FUNCTION {bibinfo.warn} 392 | { swap$ 393 | duplicate$ missing$ 394 | { 395 | swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ 396 | "" 397 | } 398 | { duplicate$ empty$ 399 | { 400 | swap$ "empty " swap$ * " in " * cite$ * warning$ 401 | } 402 | { swap$ 403 | pop$ 404 | } 405 | if$ 406 | } 407 | if$ 408 | } 409 | FUNCTION {format.url} 410 | { url empty$ 411 | { "" } 412 | { "\urlprefix\url{" url * "}" * } 413 | if$ 414 | } 415 | 416 | STRINGS { bibinfo} 417 | INTEGERS { nameptr namesleft numnames } 418 | 419 | FUNCTION {format.names} 420 | { 'bibinfo := 421 | duplicate$ empty$ 'skip$ { 422 | 's := 423 | "" 't := 424 | #1 'nameptr := 425 | s num.names$ 'numnames := 426 | numnames 'namesleft := 427 | { namesleft #0 > } 428 | { s nameptr 429 | "{vv~}{ll}{, f.}{, jj}" 430 | format.name$ 431 | bibinfo bibinfo.check 432 | 't := 433 | nameptr #1 > 434 | { 435 | namesleft #1 > 436 | { ", " * t * } 437 | { 438 | numnames #2 > 439 | { "," * } 440 | 'skip$ 441 | if$ 442 | s nameptr "{ll}" format.name$ duplicate$ "others" = 443 | { 't := } 444 | { pop$ } 445 | if$ 446 | t "others" = 447 | { 448 | " " * bbl.etal * 449 | } 450 | { 451 | bbl.and 452 | space.word * t * 453 | } 454 | if$ 455 | } 456 | if$ 457 | } 458 | 't 459 | if$ 460 | nameptr #1 + 'nameptr := 461 | namesleft #1 - 'namesleft := 462 | } 463 | while$ 464 | } if$ 465 | } 466 | FUNCTION {format.names.ed} 467 | { 468 | 'bibinfo := 469 | duplicate$ empty$ 'skip$ { 470 | 's := 471 | "" 't := 472 | #1 'nameptr := 473 | s num.names$ 'numnames := 474 | numnames 'namesleft := 475 | { namesleft #0 > } 476 | { s nameptr 477 | "{f.~}{vv~}{ll}{, jj}" 478 | format.name$ 479 | bibinfo bibinfo.check 480 | 't := 481 | nameptr #1 > 482 | { 483 | namesleft #1 > 484 | { ", " * t * } 485 | { 486 | numnames #2 > 487 | { "," * } 488 | 'skip$ 489 | if$ 490 | s nameptr "{ll}" format.name$ duplicate$ "others" = 491 | { 't := } 492 | { pop$ } 493 | if$ 494 | t "others" = 495 | { 496 | 497 | " " * bbl.etal * 498 | } 499 | { 500 | bbl.and 501 | space.word * t * 502 | } 503 | if$ 504 | } 505 | if$ 506 | } 507 | 't 508 | if$ 509 | nameptr #1 + 'nameptr := 510 | namesleft #1 - 'namesleft := 511 | } 512 | while$ 513 | } if$ 514 | } 515 | FUNCTION {format.key} 516 | { empty$ 517 | { key field.or.null } 518 | { "" } 519 | if$ 520 | } 521 | 522 | FUNCTION {format.authors} 523 | { author "author" format.names 524 | } 525 | FUNCTION {get.bbl.editor} 526 | { editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } 527 | 528 | FUNCTION {format.editors} 529 | { editor "editor" format.names duplicate$ empty$ 'skip$ 530 | { 531 | " " * 532 | get.bbl.editor 533 | "(" swap$ * ")" * 534 | * 535 | } 536 | if$ 537 | } 538 | FUNCTION {format.note} 539 | { 540 | note empty$ 541 | { "" } 542 | { note #1 #1 substring$ 543 | duplicate$ "{" = 544 | 'skip$ 545 | { output.state mid.sentence = 546 | { "l" } 547 | { "u" } 548 | if$ 549 | change.case$ 550 | } 551 | if$ 552 | note #2 global.max$ substring$ * "note" bibinfo.check 553 | } 554 | if$ 555 | } 556 | 557 | FUNCTION {format.title} 558 | { title 559 | duplicate$ empty$ 'skip$ 560 | { "t" change.case$ } 561 | if$ 562 | "title" bibinfo.check 563 | duplicate$ empty$ 'skip$ 564 | { 565 | "\enquote{" swap$ * 566 | non.stop 567 | { ",} " * } 568 | { "} " * } 569 | if$ 570 | } 571 | if$ 572 | } 573 | FUNCTION {end.quote.title} 574 | { title empty$ 575 | 'skip$ 576 | { before.all 'output.state := } 577 | if$ 578 | } 579 | FUNCTION {format.full.names} 580 | {'s := 581 | "" 't := 582 | #1 'nameptr := 583 | s num.names$ 'numnames := 584 | numnames 'namesleft := 585 | { namesleft #0 > } 586 | { s nameptr 587 | "{vv~}{ll}" format.name$ 588 | 't := 589 | nameptr #1 > 590 | { 591 | namesleft #1 > 592 | { ", " * t * } 593 | { 594 | s nameptr "{ll}" format.name$ duplicate$ "others" = 595 | { 't := } 596 | { pop$ } 597 | if$ 598 | t "others" = 599 | { 600 | " " * bbl.etal * 601 | } 602 | { 603 | numnames #2 > 604 | { "," * } 605 | 'skip$ 606 | if$ 607 | bbl.and 608 | space.word * t * 609 | } 610 | if$ 611 | } 612 | if$ 613 | } 614 | 't 615 | if$ 616 | nameptr #1 + 'nameptr := 617 | namesleft #1 - 'namesleft := 618 | } 619 | while$ 620 | } 621 | 622 | FUNCTION {author.editor.key.full} 623 | { author empty$ 624 | { editor empty$ 625 | { key empty$ 626 | { cite$ #1 #3 substring$ } 627 | 'key 628 | if$ 629 | } 630 | { editor format.full.names } 631 | if$ 632 | } 633 | { author format.full.names } 634 | if$ 635 | } 636 | 637 | FUNCTION {author.key.full} 638 | { author empty$ 639 | { key empty$ 640 | { cite$ #1 #3 substring$ } 641 | 'key 642 | if$ 643 | } 644 | { author format.full.names } 645 | if$ 646 | } 647 | 648 | FUNCTION {editor.key.full} 649 | { editor empty$ 650 | { key empty$ 651 | { cite$ #1 #3 substring$ } 652 | 'key 653 | if$ 654 | } 655 | { editor format.full.names } 656 | if$ 657 | } 658 | 659 | FUNCTION {make.full.names} 660 | { type$ "book" = 661 | type$ "inbook" = 662 | or 663 | 'author.editor.key.full 664 | { type$ "proceedings" = 665 | 'editor.key.full 666 | 'author.key.full 667 | if$ 668 | } 669 | if$ 670 | } 671 | 672 | FUNCTION {output.bibitem} 673 | { newline$ 674 | "\bibitem[{" write$ 675 | label write$ 676 | ")" make.full.names duplicate$ short.list = 677 | { pop$ } 678 | { * } 679 | if$ 680 | "}]{" * write$ 681 | cite$ write$ 682 | "}" write$ 683 | newline$ 684 | "" 685 | before.all 'output.state := 686 | } 687 | 688 | FUNCTION {n.dashify} 689 | { 690 | 't := 691 | "" 692 | { t empty$ not } 693 | { t #1 #1 substring$ "-" = 694 | { t #1 #2 substring$ "--" = not 695 | { "--" * 696 | t #2 global.max$ substring$ 't := 697 | } 698 | { { t #1 #1 substring$ "-" = } 699 | { "-" * 700 | t #2 global.max$ substring$ 't := 701 | } 702 | while$ 703 | } 704 | if$ 705 | } 706 | { t #1 #1 substring$ * 707 | t #2 global.max$ substring$ 't := 708 | } 709 | if$ 710 | } 711 | while$ 712 | } 713 | 714 | FUNCTION {word.in} 715 | { bbl.in 716 | " " * } 717 | 718 | FUNCTION {format.date} 719 | { year "year" bibinfo.check duplicate$ empty$ 720 | { 721 | "empty year in " cite$ * "; set to ????" * warning$ 722 | pop$ "????" 723 | } 724 | 'skip$ 725 | if$ 726 | extra.label * 727 | before.all 'output.state := 728 | " (" swap$ * ")" * 729 | } 730 | FUNCTION {format.btitle} 731 | { title "title" bibinfo.check 732 | duplicate$ empty$ 'skip$ 733 | { 734 | emphasize 735 | } 736 | if$ 737 | } 738 | FUNCTION {either.or.check} 739 | { empty$ 740 | 'pop$ 741 | { "can't use both " swap$ * " fields in " * cite$ * warning$ } 742 | if$ 743 | } 744 | FUNCTION {format.bvolume} 745 | { volume empty$ 746 | { "" } 747 | { bbl.volume volume tie.or.space.prefix 748 | "volume" bibinfo.check * * 749 | series "series" bibinfo.check 750 | duplicate$ empty$ 'pop$ 751 | { swap$ bbl.of space.word * swap$ 752 | emphasize * } 753 | if$ 754 | "volume and number" number either.or.check 755 | } 756 | if$ 757 | } 758 | FUNCTION {format.number.series} 759 | { volume empty$ 760 | { number empty$ 761 | { series field.or.null } 762 | { series empty$ 763 | { number "number" bibinfo.check } 764 | { output.state mid.sentence = 765 | { bbl.number } 766 | { bbl.number capitalize } 767 | if$ 768 | number tie.or.space.prefix "number" bibinfo.check * * 769 | bbl.in space.word * 770 | series "series" bibinfo.check * 771 | } 772 | if$ 773 | } 774 | if$ 775 | } 776 | { "" } 777 | if$ 778 | } 779 | FUNCTION {is.num} 780 | { chr.to.int$ 781 | duplicate$ "0" chr.to.int$ < not 782 | swap$ "9" chr.to.int$ > not and 783 | } 784 | 785 | FUNCTION {extract.num} 786 | { duplicate$ 't := 787 | "" 's := 788 | { t empty$ not } 789 | { t #1 #1 substring$ 790 | t #2 global.max$ substring$ 't := 791 | duplicate$ is.num 792 | { s swap$ * 's := } 793 | { pop$ "" 't := } 794 | if$ 795 | } 796 | while$ 797 | s empty$ 798 | 'skip$ 799 | { pop$ s } 800 | if$ 801 | } 802 | 803 | FUNCTION {convert.edition} 804 | { extract.num "l" change.case$ 's := 805 | s "first" = s "1" = or 806 | { bbl.first 't := } 807 | { s "second" = s "2" = or 808 | { bbl.second 't := } 809 | { s "third" = s "3" = or 810 | { bbl.third 't := } 811 | { s "fourth" = s "4" = or 812 | { bbl.fourth 't := } 813 | { s "fifth" = s "5" = or 814 | { bbl.fifth 't := } 815 | { s #1 #1 substring$ is.num 816 | { s eng.ord 't := } 817 | { edition 't := } 818 | if$ 819 | } 820 | if$ 821 | } 822 | if$ 823 | } 824 | if$ 825 | } 826 | if$ 827 | } 828 | if$ 829 | t 830 | } 831 | 832 | FUNCTION {format.edition} 833 | { edition duplicate$ empty$ 'skip$ 834 | { 835 | convert.edition 836 | output.state mid.sentence = 837 | { "l" } 838 | { "t" } 839 | if$ change.case$ 840 | "edition" bibinfo.check 841 | " " * bbl.edition * 842 | } 843 | if$ 844 | } 845 | INTEGERS { multiresult } 846 | FUNCTION {multi.page.check} 847 | { 't := 848 | #0 'multiresult := 849 | { multiresult not 850 | t empty$ not 851 | and 852 | } 853 | { t #1 #1 substring$ 854 | duplicate$ "-" = 855 | swap$ duplicate$ "," = 856 | swap$ "+" = 857 | or or 858 | { #1 'multiresult := } 859 | { t #2 global.max$ substring$ 't := } 860 | if$ 861 | } 862 | while$ 863 | multiresult 864 | } 865 | FUNCTION {format.pages} 866 | { pages duplicate$ empty$ 'skip$ 867 | { duplicate$ multi.page.check 868 | { 869 | bbl.pages swap$ 870 | n.dashify 871 | } 872 | { 873 | bbl.page swap$ 874 | } 875 | if$ 876 | tie.or.space.prefix 877 | "pages" bibinfo.check 878 | * * 879 | } 880 | if$ 881 | } 882 | FUNCTION {format.journal.pages} 883 | { pages duplicate$ empty$ 'pop$ 884 | { swap$ duplicate$ empty$ 885 | { pop$ pop$ format.pages } 886 | { 887 | ", " * 888 | swap$ 889 | n.dashify 890 | "pages" bibinfo.check 891 | * 892 | } 893 | if$ 894 | } 895 | if$ 896 | } 897 | FUNCTION {format.vol.num.pages} 898 | { volume field.or.null 899 | duplicate$ empty$ 'skip$ 900 | { 901 | "volume" bibinfo.check 902 | } 903 | if$ 904 | } 905 | 906 | FUNCTION {format.chapter.pages} 907 | { chapter empty$ 908 | { "" } 909 | { type empty$ 910 | { bbl.chapter } 911 | { type "l" change.case$ 912 | "type" bibinfo.check 913 | } 914 | if$ 915 | chapter tie.or.space.prefix 916 | "chapter" bibinfo.check 917 | * * 918 | } 919 | if$ 920 | } 921 | 922 | FUNCTION {format.booktitle} 923 | { 924 | booktitle "booktitle" bibinfo.check 925 | emphasize 926 | } 927 | FUNCTION {format.in.ed.booktitle} 928 | { format.booktitle duplicate$ empty$ 'skip$ 929 | { 930 | editor "editor" format.names.ed duplicate$ empty$ 'pop$ 931 | { 932 | get.bbl.editor 933 | " " * swap$ * 934 | swap$ 935 | "," * 936 | " " * swap$ 937 | * } 938 | if$ 939 | word.in swap$ * 940 | } 941 | if$ 942 | } 943 | FUNCTION {format.thesis.type} 944 | { type duplicate$ empty$ 945 | 'pop$ 946 | { swap$ pop$ 947 | "t" change.case$ "type" bibinfo.check 948 | } 949 | if$ 950 | } 951 | FUNCTION {format.tr.number} 952 | { number "number" bibinfo.check 953 | type duplicate$ empty$ 954 | { pop$ bbl.techrep } 955 | 'skip$ 956 | if$ 957 | "type" bibinfo.check 958 | swap$ duplicate$ empty$ 959 | { pop$ "t" change.case$ } 960 | { tie.or.space.prefix * * } 961 | if$ 962 | } 963 | FUNCTION {format.article.crossref} 964 | { 965 | word.in 966 | " \cite{" * crossref * "}" * 967 | } 968 | FUNCTION {format.book.crossref} 969 | { volume duplicate$ empty$ 970 | { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ 971 | pop$ word.in 972 | } 973 | { bbl.volume 974 | swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word * 975 | } 976 | if$ 977 | " \cite{" * crossref * "}" * 978 | } 979 | FUNCTION {format.incoll.inproc.crossref} 980 | { 981 | word.in 982 | " \cite{" * crossref * "}" * 983 | } 984 | FUNCTION {format.org.or.pub} 985 | { 't := 986 | "" 987 | address empty$ t empty$ and 988 | 'skip$ 989 | { 990 | address "address" bibinfo.check * 991 | t empty$ 992 | 'skip$ 993 | { address empty$ 994 | 'skip$ 995 | { ": " * } 996 | if$ 997 | t * 998 | } 999 | if$ 1000 | } 1001 | if$ 1002 | } 1003 | FUNCTION {format.publisher.address} 1004 | { publisher "publisher" bibinfo.warn format.org.or.pub 1005 | } 1006 | 1007 | FUNCTION {format.organization.address} 1008 | { organization "organization" bibinfo.check format.org.or.pub 1009 | } 1010 | 1011 | STRINGS {oldname} 1012 | 1013 | FUNCTION {name.or.dash} 1014 | { 's := 1015 | oldname empty$ 1016 | { s 'oldname := s } 1017 | { s oldname = 1018 | { "---" } 1019 | { s 'oldname := s } 1020 | if$ 1021 | } 1022 | if$ 1023 | } 1024 | 1025 | FUNCTION {article} 1026 | { output.bibitem 1027 | format.authors "author" output.check 1028 | author format.key output 1029 | name.or.dash 1030 | format.date "year" output.check 1031 | date.block 1032 | format.title "title" output.check 1033 | end.quote.title 1034 | crossref missing$ 1035 | { 1036 | journal 1037 | "journal" bibinfo.check 1038 | emphasize 1039 | "journal" output.check 1040 | format.vol.num.pages output 1041 | } 1042 | { format.article.crossref output.nonnull 1043 | } 1044 | if$ 1045 | format.journal.pages 1046 | format.url output 1047 | new.sentence 1048 | format.note output 1049 | fin.entry 1050 | } 1051 | FUNCTION {book} 1052 | { output.bibitem 1053 | author empty$ 1054 | { format.editors "author and editor" output.check 1055 | editor format.key output 1056 | name.or.dash 1057 | } 1058 | { format.authors output.nonnull 1059 | name.or.dash 1060 | crossref missing$ 1061 | { "author and editor" editor either.or.check } 1062 | 'skip$ 1063 | if$ 1064 | } 1065 | if$ 1066 | format.date "year" output.check 1067 | date.block 1068 | format.btitle "title" output.check 1069 | crossref missing$ 1070 | { format.bvolume output 1071 | format.number.series output 1072 | format.edition output 1073 | format.publisher.address output 1074 | } 1075 | { 1076 | format.book.crossref output.nonnull 1077 | } 1078 | if$ 1079 | format.url output 1080 | new.sentence 1081 | format.note output 1082 | fin.entry 1083 | } 1084 | FUNCTION {booklet} 1085 | { output.bibitem 1086 | format.authors output 1087 | author format.key output 1088 | name.or.dash 1089 | format.date "year" output.check 1090 | date.block 1091 | format.title "title" output.check 1092 | end.quote.title 1093 | howpublished "howpublished" bibinfo.check output 1094 | address "address" bibinfo.check output 1095 | format.url output 1096 | new.sentence 1097 | format.note output 1098 | fin.entry 1099 | } 1100 | 1101 | FUNCTION {inbook} 1102 | { output.bibitem 1103 | author empty$ 1104 | { format.editors "author and editor" output.check 1105 | editor format.key output 1106 | name.or.dash 1107 | } 1108 | { format.authors output.nonnull 1109 | name.or.dash 1110 | crossref missing$ 1111 | { "author and editor" editor either.or.check } 1112 | 'skip$ 1113 | if$ 1114 | } 1115 | if$ 1116 | format.date "year" output.check 1117 | date.block 1118 | format.btitle "title" output.check 1119 | crossref missing$ 1120 | { 1121 | format.bvolume output 1122 | format.chapter.pages "chapter and pages" output.check 1123 | format.number.series output 1124 | format.edition output 1125 | format.publisher.address output 1126 | } 1127 | { 1128 | format.chapter.pages "chapter and pages" output.check 1129 | format.book.crossref output.nonnull 1130 | } 1131 | if$ 1132 | format.pages "pages" output.check 1133 | format.url output 1134 | new.sentence 1135 | format.note output 1136 | fin.entry 1137 | } 1138 | 1139 | FUNCTION {incollection} 1140 | { output.bibitem 1141 | format.authors "author" output.check 1142 | author format.key output 1143 | name.or.dash 1144 | format.date "year" output.check 1145 | date.block 1146 | format.title "title" output.check 1147 | end.quote.title 1148 | crossref missing$ 1149 | { format.in.ed.booktitle "booktitle" output.check 1150 | format.bvolume output 1151 | format.number.series output 1152 | format.edition output 1153 | format.chapter.pages output 1154 | format.publisher.address output 1155 | } 1156 | { format.incoll.inproc.crossref output.nonnull 1157 | format.chapter.pages output 1158 | } 1159 | if$ 1160 | format.pages "pages" output.check 1161 | format.url output 1162 | new.sentence 1163 | format.note output 1164 | fin.entry 1165 | } 1166 | FUNCTION {inproceedings} 1167 | { output.bibitem 1168 | format.authors "author" output.check 1169 | author format.key output 1170 | name.or.dash 1171 | format.date "year" output.check 1172 | date.block 1173 | format.title "title" output.check 1174 | end.quote.title 1175 | crossref missing$ 1176 | { format.in.ed.booktitle "booktitle" output.check 1177 | format.bvolume output 1178 | format.number.series output 1179 | publisher empty$ 1180 | { format.organization.address output } 1181 | { organization "organization" bibinfo.check output 1182 | format.publisher.address output 1183 | } 1184 | if$ 1185 | } 1186 | { format.incoll.inproc.crossref output.nonnull 1187 | format.pages output 1188 | } 1189 | if$ 1190 | format.pages "pages" output.check 1191 | format.url output 1192 | new.sentence 1193 | format.note output 1194 | fin.entry 1195 | } 1196 | FUNCTION {conference} { inproceedings } 1197 | FUNCTION {manual} 1198 | { output.bibitem 1199 | format.authors output 1200 | author format.key output 1201 | name.or.dash 1202 | format.date "year" output.check 1203 | date.block 1204 | format.btitle "title" output.check 1205 | organization "organization" bibinfo.check output 1206 | address "address" bibinfo.check output 1207 | format.edition output 1208 | format.url output 1209 | new.sentence 1210 | format.note output 1211 | fin.entry 1212 | } 1213 | 1214 | FUNCTION {mastersthesis} 1215 | { output.bibitem 1216 | format.authors "author" output.check 1217 | author format.key output 1218 | name.or.dash 1219 | format.date "year" output.check 1220 | date.block 1221 | format.title 1222 | "title" output.check 1223 | end.quote.title 1224 | bbl.mthesis format.thesis.type output.nonnull 1225 | school "school" bibinfo.warn output 1226 | address "address" bibinfo.check output 1227 | format.url output 1228 | new.sentence 1229 | format.note output 1230 | fin.entry 1231 | } 1232 | 1233 | FUNCTION {misc} 1234 | { output.bibitem 1235 | format.authors output 1236 | author format.key output 1237 | name.or.dash 1238 | format.date "year" output.check 1239 | date.block 1240 | format.title output 1241 | end.quote.title 1242 | howpublished "howpublished" bibinfo.check output 1243 | format.url output 1244 | new.sentence 1245 | format.note output 1246 | fin.entry 1247 | } 1248 | FUNCTION {phdthesis} 1249 | { output.bibitem 1250 | format.authors "author" output.check 1251 | author format.key output 1252 | name.or.dash 1253 | format.date "year" output.check 1254 | date.block 1255 | format.title 1256 | "title" output.check 1257 | end.quote.title 1258 | bbl.phdthesis format.thesis.type output.nonnull 1259 | school "school" bibinfo.warn output 1260 | address "address" bibinfo.check output 1261 | format.url output 1262 | new.sentence 1263 | format.note output 1264 | fin.entry 1265 | } 1266 | 1267 | FUNCTION {proceedings} 1268 | { output.bibitem 1269 | format.editors output 1270 | editor format.key output 1271 | name.or.dash 1272 | format.date "year" output.check 1273 | date.block 1274 | format.btitle "title" output.check 1275 | format.bvolume output 1276 | format.number.series output 1277 | publisher empty$ 1278 | { format.organization.address output } 1279 | { organization "organization" bibinfo.check output 1280 | format.publisher.address output 1281 | } 1282 | if$ 1283 | format.url output 1284 | new.sentence 1285 | format.note output 1286 | fin.entry 1287 | } 1288 | 1289 | FUNCTION {techreport} 1290 | { output.bibitem 1291 | format.authors "author" output.check 1292 | author format.key output 1293 | name.or.dash 1294 | format.date "year" output.check 1295 | date.block 1296 | format.title 1297 | "title" output.check 1298 | end.quote.title 1299 | format.tr.number output.nonnull 1300 | institution "institution" bibinfo.warn output 1301 | address "address" bibinfo.check output 1302 | format.url output 1303 | new.sentence 1304 | format.note output 1305 | fin.entry 1306 | } 1307 | 1308 | FUNCTION {unpublished} 1309 | { output.bibitem 1310 | format.authors "author" output.check 1311 | author format.key output 1312 | name.or.dash 1313 | format.date "year" output.check 1314 | date.block 1315 | format.title "title" output.check 1316 | end.quote.title 1317 | format.url output 1318 | new.sentence 1319 | format.note "note" output.check 1320 | fin.entry 1321 | } 1322 | 1323 | FUNCTION {default.type} { misc } 1324 | READ 1325 | FUNCTION {sortify} 1326 | { purify$ 1327 | "l" change.case$ 1328 | } 1329 | INTEGERS { len } 1330 | FUNCTION {chop.word} 1331 | { 's := 1332 | 'len := 1333 | s #1 len substring$ = 1334 | { s len #1 + global.max$ substring$ } 1335 | 's 1336 | if$ 1337 | } 1338 | FUNCTION {format.lab.names} 1339 | { 's := 1340 | "" 't := 1341 | s #1 "{vv~}{ll}" format.name$ 1342 | s num.names$ duplicate$ 1343 | #2 > 1344 | { pop$ 1345 | " " * bbl.etal * 1346 | } 1347 | { #2 < 1348 | 'skip$ 1349 | { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = 1350 | { 1351 | " " * bbl.etal * 1352 | } 1353 | { bbl.and space.word * s #2 "{vv~}{ll}" format.name$ 1354 | * } 1355 | if$ 1356 | } 1357 | if$ 1358 | } 1359 | if$ 1360 | } 1361 | 1362 | FUNCTION {author.key.label} 1363 | { author empty$ 1364 | { key empty$ 1365 | { cite$ #1 #3 substring$ } 1366 | 'key 1367 | if$ 1368 | } 1369 | { author format.lab.names } 1370 | if$ 1371 | } 1372 | 1373 | FUNCTION {author.editor.key.label} 1374 | { author empty$ 1375 | { editor empty$ 1376 | { key empty$ 1377 | { cite$ #1 #3 substring$ } 1378 | 'key 1379 | if$ 1380 | } 1381 | { editor format.lab.names } 1382 | if$ 1383 | } 1384 | { author format.lab.names } 1385 | if$ 1386 | } 1387 | 1388 | FUNCTION {editor.key.label} 1389 | { editor empty$ 1390 | { key empty$ 1391 | { cite$ #1 #3 substring$ } 1392 | 'key 1393 | if$ 1394 | } 1395 | { editor format.lab.names } 1396 | if$ 1397 | } 1398 | 1399 | FUNCTION {calc.short.authors} 1400 | { type$ "book" = 1401 | type$ "inbook" = 1402 | or 1403 | 'author.editor.key.label 1404 | { type$ "proceedings" = 1405 | 'editor.key.label 1406 | 'author.key.label 1407 | if$ 1408 | } 1409 | if$ 1410 | 'short.list := 1411 | } 1412 | 1413 | FUNCTION {calc.label} 1414 | { calc.short.authors 1415 | short.list 1416 | "(" 1417 | * 1418 | year duplicate$ empty$ 1419 | { pop$ "????" } 1420 | 'skip$ 1421 | if$ 1422 | * 1423 | 'label := 1424 | } 1425 | 1426 | FUNCTION {sort.format.names} 1427 | { 's := 1428 | #1 'nameptr := 1429 | "" 1430 | s num.names$ 'numnames := 1431 | numnames 'namesleft := 1432 | { namesleft #0 > } 1433 | { s nameptr 1434 | "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" 1435 | format.name$ 't := 1436 | nameptr #1 > 1437 | { 1438 | " " * 1439 | namesleft #1 = t "others" = and 1440 | { "zzzzz" * } 1441 | { t sortify * } 1442 | if$ 1443 | } 1444 | { t sortify * } 1445 | if$ 1446 | nameptr #1 + 'nameptr := 1447 | namesleft #1 - 'namesleft := 1448 | } 1449 | while$ 1450 | } 1451 | 1452 | FUNCTION {sort.format.title} 1453 | { 't := 1454 | "A " #2 1455 | "An " #3 1456 | "The " #4 t chop.word 1457 | chop.word 1458 | chop.word 1459 | sortify 1460 | #1 global.max$ substring$ 1461 | } 1462 | FUNCTION {author.sort} 1463 | { author empty$ 1464 | { key empty$ 1465 | { "to sort, need author or key in " cite$ * warning$ 1466 | "" 1467 | } 1468 | { key sortify } 1469 | if$ 1470 | } 1471 | { author sort.format.names } 1472 | if$ 1473 | } 1474 | FUNCTION {author.editor.sort} 1475 | { author empty$ 1476 | { editor empty$ 1477 | { key empty$ 1478 | { "to sort, need author, editor, or key in " cite$ * warning$ 1479 | "" 1480 | } 1481 | { key sortify } 1482 | if$ 1483 | } 1484 | { editor sort.format.names } 1485 | if$ 1486 | } 1487 | { author sort.format.names } 1488 | if$ 1489 | } 1490 | FUNCTION {editor.sort} 1491 | { editor empty$ 1492 | { key empty$ 1493 | { "to sort, need editor or key in " cite$ * warning$ 1494 | "" 1495 | } 1496 | { key sortify } 1497 | if$ 1498 | } 1499 | { editor sort.format.names } 1500 | if$ 1501 | } 1502 | FUNCTION {presort} 1503 | { calc.label 1504 | label sortify 1505 | " " 1506 | * 1507 | type$ "book" = 1508 | type$ "inbook" = 1509 | or 1510 | 'author.editor.sort 1511 | { type$ "proceedings" = 1512 | 'editor.sort 1513 | 'author.sort 1514 | if$ 1515 | } 1516 | if$ 1517 | #1 entry.max$ substring$ 1518 | 'sort.label := 1519 | sort.label 1520 | * 1521 | " " 1522 | * 1523 | title field.or.null 1524 | sort.format.title 1525 | * 1526 | #1 entry.max$ substring$ 1527 | 'sort.key$ := 1528 | } 1529 | 1530 | ITERATE {presort} 1531 | SORT 1532 | STRINGS { last.label next.extra } 1533 | INTEGERS { last.extra.num number.label } 1534 | FUNCTION {initialize.extra.label.stuff} 1535 | { #0 int.to.chr$ 'last.label := 1536 | "" 'next.extra := 1537 | #0 'last.extra.num := 1538 | #0 'number.label := 1539 | } 1540 | FUNCTION {forward.pass} 1541 | { last.label label = 1542 | { last.extra.num #1 + 'last.extra.num := 1543 | last.extra.num int.to.chr$ 'extra.label := 1544 | } 1545 | { "a" chr.to.int$ 'last.extra.num := 1546 | "" 'extra.label := 1547 | label 'last.label := 1548 | } 1549 | if$ 1550 | number.label #1 + 'number.label := 1551 | } 1552 | FUNCTION {reverse.pass} 1553 | { next.extra "b" = 1554 | { "a" 'extra.label := } 1555 | 'skip$ 1556 | if$ 1557 | extra.label 'next.extra := 1558 | extra.label 1559 | duplicate$ empty$ 1560 | 'skip$ 1561 | { "{\natexlab{" swap$ * "}}" * } 1562 | if$ 1563 | 'extra.label := 1564 | label extra.label * 'label := 1565 | } 1566 | EXECUTE {initialize.extra.label.stuff} 1567 | ITERATE {forward.pass} 1568 | REVERSE {reverse.pass} 1569 | FUNCTION {bib.sort.order} 1570 | { sort.label 1571 | " " 1572 | * 1573 | year field.or.null sortify 1574 | * 1575 | " " 1576 | * 1577 | title field.or.null 1578 | sort.format.title 1579 | * 1580 | #1 entry.max$ substring$ 1581 | 'sort.key$ := 1582 | } 1583 | ITERATE {bib.sort.order} 1584 | SORT 1585 | FUNCTION {begin.bib} 1586 | { preamble$ empty$ 1587 | 'skip$ 1588 | { preamble$ write$ newline$ } 1589 | if$ 1590 | "\begin{thebibliography}{" number.label int.to.str$ * "}" * 1591 | write$ newline$ 1592 | "\newcommand{\enquote}[1]{``#1''}" 1593 | write$ newline$ 1594 | "\expandafter\ifx\csname natexlab\endcsname\relax\def\natexlab#1{#1}\fi" 1595 | write$ newline$ 1596 | "\expandafter\ifx\csname url\endcsname\relax" 1597 | write$ newline$ 1598 | " \def\url#1{\texttt{#1}}\fi" 1599 | write$ newline$ 1600 | "\expandafter\ifx\csname urlprefix\endcsname\relax\def\urlprefix{URL }\fi" 1601 | write$ newline$ 1602 | } 1603 | EXECUTE {begin.bib} 1604 | EXECUTE {init.state.consts} 1605 | ITERATE {call.type$} 1606 | FUNCTION {end.bib} 1607 | { newline$ 1608 | "\end{thebibliography}" write$ newline$ 1609 | } 1610 | EXECUTE {end.bib} 1611 | %% End of customized bst file 1612 | %% 1613 | %% End of file `jbs.bst'. 1614 | --------------------------------------------------------------------------------