From 16b4107f3a70f199b9c04d0346050f4f52b5114b Mon Sep 17 00:00:00 2001 From: couturie Date: Fri, 26 Jul 2013 20:47:21 +0200 Subject: [PATCH] new --- BookGPU/Chapters/chapter11/biblio11.bib | 29 ++-- BookGPU/Chapters/chapter11/ch11.tex | 153 ++++++++++-------- .../Chapters/chapter11/gregory1_plot2_b.pdf | Bin 45585 -> 21979 bytes .../Chapters/chapter11/gregory1_plot2_b.ps | 2 +- 4 files changed, 98 insertions(+), 86 deletions(-) diff --git a/BookGPU/Chapters/chapter11/biblio11.bib b/BookGPU/Chapters/chapter11/biblio11.bib index c6d75ac..de2eae4 100644 --- a/BookGPU/Chapters/chapter11/biblio11.bib +++ b/BookGPU/Chapters/chapter11/biblio11.bib @@ -1600,7 +1600,7 @@ Sci, Warrendi Rd, The Levels, SA 5095.}, @article{Beliakov2000_ata, author = {Beliakov, G.}, title = {Shape preserving approximation using least squares splines}, - journal = {Approximation theory and applications}, + journal = {Approximation Theory and Applications}, volume = {16}, pages = {80-98}, year = {2000} @@ -1854,7 +1854,7 @@ Technology. title = {Fitting Fuzzy Measures by Linear Programming. Programming Library Fmtools}, booktitle = {IEEE World Congress on Computational Intelligence }, address = {Hong Kong}, - publisher = {IEEE press}, + publisher = {IEEE Press}, pages = {862-867}, year = {2008} } @@ -2251,7 +2251,7 @@ Applied physics/condensed matter/materials science. Optics and acoustics.}, title = {Using Choquet Integrals for Knn Approximation and Classification}, booktitle = {IEEE World Congress on Computational Intelligence }, address = {Hong Kong}, - publisher = {IEEE press}, + publisher = {IEEE Press}, pages = {1311-1317}, year = {2008} } @@ -2325,7 +2325,7 @@ Hard/soft partial conjunction}, title = {Texture Recognition by Using Glcm and Various Aggregation Functions}, booktitle = {IEEE World Congress on Computational Intelligence }, address = {Hong Kong}, - publisher = {IEEE press}, + publisher = {IEEE Press}, pages = {1472-1476}, year = {2008} } @@ -4623,9 +4623,8 @@ Zero divisor}, @book{deboor2001_book, author = {De Boor, C.}, title = {A Practical Guide to Splines}, - publisher = {Springer}, + publisher = {Revised, Springer}, address = {New York}, - edition = {Revised }, year = {2001} } @@ -4926,8 +4925,8 @@ QSAR (Biochemistry)}, @book{Dierckx1995_book, author = {Dierckx, P.}, - title = {Curve and surface fitting with splines}, - publisher = {Clarendon press}, + title = {Curve and Surface Fitting with Splines}, + publisher = {Clarendon Press}, address = {Oxford}, year = {1995} } @@ -6673,7 +6672,7 @@ Schrödinger equation}, @article{Fritsch1980, author = {Fritsch, F. N. and Carlson, R. E.}, - title = {Monotone pieceuiuse cubic interpolation}, + title = {Monotone piecewise cubic interpolation}, journal = {SIAM J. Numer. Anal.}, volume = {17 }, pages = {238-246}, @@ -7706,7 +7705,7 @@ Fuzzy sets.}, year = {1993} } -@article{Hadi, +@article{Hadi, author = {Hadi, A.S. and Simonoff, J.S.}, title = {Procedures for the Identification of Multiple Outliers in Linear Models}, journal = {Journal of the American Statistical Association}, @@ -8280,7 +8279,7 @@ standard review}, @misc{Thrust, author = {Hoberock, J. and Bell, N.}, title = {Thrust, http://thrust.github.com/ Last accessed July 31, 2012}, - volume = {Last accessed July 31, 2012}, + volume = {Last accessed July 31}, year = {2012} } @@ -9825,7 +9824,7 @@ standard review}, @book{Kvasov2000_book, author = {Kvasov, B.}, - title = {Methods of shape preserving spline approximation}, + title = {Methods of Shape Preserving Spline Approximation}, publisher = {World Scientific}, address = {Singapore}, year = {2000} @@ -10826,7 +10825,7 @@ PRINCETON, NJ 08544, USA.}, @article{Lyche1973, author = {Lyche, T. and Schumaker, L. L.}, - title = {Computation of smoothing and interpolating naturel splines via local bases}, + title = {Computation of smoothing and interpolating natural splines via local bases}, journal = {SIAM J. Numer. Anal.}, volume = {10}, pages = {1027-1038}, @@ -13489,7 +13488,7 @@ IRAKLION, GREECE.}, author = {Robertson, T. and Wright, F. T. and Dykstra, R. L.}, title = {Order Restricted Statistical Inference}, publisher = {Wiley}, - address = {Chichester ; New York}, + address = {Chichester, New York}, year = {1988} } @@ -14262,7 +14261,7 @@ Reprint available from: Schoen F UNIV FLORENCE FLORENCE ITALY}, @book{Schumaker1981_book, author = {Schumaker, L. L.}, - title = {Spline functions: Basic theory}, + title = {Spline {F}unctions: Basic {T}heory}, publisher = {Wiley}, address = {New York}, year = {1981} diff --git a/BookGPU/Chapters/chapter11/ch11.tex b/BookGPU/Chapters/chapter11/ch11.tex index 85d5304..57b3328 100644 --- a/BookGPU/Chapters/chapter11/ch11.tex +++ b/BookGPU/Chapters/chapter11/ch11.tex @@ -3,56 +3,62 @@ %\chapterauthor{Shaowu Liu}{School of Information Technology, Deakin University, Burwood 3125, Australia} -\chapter{Parallel Monotone Spline Interpolation and Approximation on GPUs} +\chapter{Parallel monotone spline interpolation and approximation on GPUs} \section{Introduction} \label{ch11:Introduction} -Monotonicity preserving interpolation and approximation have received substantial attention in the last thirty years because of their numerous applications in computer aided design, statistics and machine learning \cite{Dierckx1995_book,Kvasov2000_book,deboor2001_book}. Constrained splines \index{spline} \index{constrained splines} \index{monotonicity} are particularly popular because of their flexibility in modelling different geometrical shapes, sound theoretical properties and availability of numerically stable algorithms \cite{Dierckx1995_book,Schumaker1981_book,deboor2001_book}. +Monotonicity preserving interpolation and approximation have received substantial attention in the last thirty years because of their numerous applications in computer aided-design, statistics, and machine learning \cite{Dierckx1995_book,Kvasov2000_book,deboor2001_book}. Constrained splines \index{spline}\index{constrained splines}\index{monotonicity} are particularly popular because of their flexibility in modeling different geometrical shapes, sound theoretical properties, and availability of numerically stable algorithms \cite{Dierckx1995_book,Schumaker1981_book,deboor2001_book}. % It is surprising though that few parallel spline algorithms are available. -In this work we examine parallelisation and adaptation for GPUs of a few algorithms of monotone spline interpolation and data smoothing, which arose in the context of estimating probability distributions. +In this work we examine parallelization and adaptation for GPUs of a few algorithms of monotone spline interpolation and data smoothing, which arose in the context of estimating probability distributions. -Estimating cumulative probability distribution functions (cdf) from data is quite common in data analysis. In our particular case we faced this problem in the context of partitioning univariate data with the purpose of efficient sorting. It was required to partition large data sets into chunks of approximately equal size, so that these chunks could be sorted independently and subsequently concatenated. In order to do that, empirical cdf of the data was used to find the quantiles, which served to partition the data. Cdf was estimated from the data based on a number of pairs $(x_i,y_i), i=1,\ldots,n$, where $y_i$ was the proportion of data no larger than $x_i$. As data could come from a variety of distributions, a distribution-free nonparametric fitting procedure was required to interpolate the above pairs. Needless to say that the whole process was aimed at GPU, and hence the use of CPU for invoking serial algorithms had to be minimised. +Estimating Cumulative Probability distribution Functions (CDF) from data is quite common in data analysis. In our particular case we faced this problem in the context of partitioning univariate data with the purpose of efficient sorting. It was necessary to partition large data sets into chunks of approximately equal size, so that these chunks could be sorted independently and subsequently concatenated. In order to do that, empirical CDF of the data was used to find the quantiles, which served to partition the data. CDF was estimated from the data based on a number of pairs $(x_i,y_i), i=1,\ldots,n$, where $y_i$ was the proportion of data no larger than $x_i$. As data could come from a variety of distributions, a distribution-free nonparametric fitting procedure was required to interpolate the above pairs. Needless to say the whole process was aimed at GPU, and hence the use of CPU for invoking serial algorithms had to be minimized. -The above mentioned application is one of many examples (e.g. mass spectrography \cite{Kearsley_2006}, global warming data \cite{Yohai} and so on) where univariate data needs to be fitted by monotonicity preserving interpolants. Of course, cdf is a monotone increasing function, whose inverse, called quantile function, can be used to calculate the quantiles. Spline interpolation would be the most suitable nonparametric method to fit the cdf, except that polynomial splines do not preserve monotonicity of the data, as illustrated on Figure \ref{ch11:fig1}. -The failure of splines to preserve monotonicity has prompted fundamental research in this area since 1960s. One of the first methods to remedy this problem were splines in tension by Schweikert \cite{Sch}, where a tension parameter controlled the shape of exponential splines \cite{Spath1969}. Later on several monotonicity preserving polynomial spline algorithms were proposed \cite{Schumaker1983,PasRoul1977,AndElf1987,Andersson1991_JAT,McAllister1981_ACM,PasRoul1977}. These algorithms typically rely on introducing additional spline knots between the abscissae of the data. Algorithmic developments are active to this day, see for example \cite{Kvasov2000_book,Abbas2011}. -When in addition to the pairs $(x_i, y_i)$ the slopes of the function are available, i.e., the data comes in triples $(x_i, y_i, p_i)$, the interpolation problem is called Hermite, and the Hermite splines are used. However, even when the sequence $y_i$ is increasing and the slopes $p_i$ are non-negative, cubic Hermite splines may still fail to be monotone, as illustrated in Figure \ref{ch11:fig2}. Thus monotone Hermite splines are needed \cite{Gregory1982}. \index{Hermite splines} -Another issue with monotone approximation is noisy data. In this case, inaccuracies in the data make the input sequence $y_i$ itself non-monotone, and hence monotone spline interpolation algorithms will fail. Monotone spline smoothing algorithms are available, e.g. \cite{Andersson1991_JAT,Elfving1989_NM}. Such algorithms are based on solving a quadratic (or another convex) programming problem numerically, and have not been yet adapted to parallel processing. -In this work we examined several monotone spline fitting algorithms, and selected the ones that we believe are most suitable for parallelisation on GPUs. We paid attention to numerical efficiency in terms of numerical calculations and memory access pattern, and favoured one-pass algorithms. We also looked at smoothing noisy data, and developed a parallel version of the Minimum Lower Sets algorithm for isotonic regression problem \cite{Best1990, Robertson_book}. -\index{isotone regression} - -The rest of the chapter is organised as follows. Section \ref{ch11:splines} discusses monotone spline interpolation methods and presents two parallel algorithms. Section \ref{ch11:smoothing} deals with smoothing problem. It presents isotonic regression problem and discusses the Pool Adjacent Violators (PAV) and Minimum Lower Sets (MLS) algorithms. Combined with monotone spline interpolation, the parallel MLS method makes it possible to build a monotone spline approximation to noisy data entirely on GPU. Section \ref{ch11:conc} concludes. - -\begin{figure}[h] +\begin{figure}[!b] \centering -\includegraphics[angle=0,width=8cm]{Chapters/chapter11/gregory1_plot1.pdf} +\includegraphics[angle=0,width=9cm]{Chapters/chapter11/gregory1_plot1.pdf} \caption[Cubic spline (solid) and monotone quadratic spline (dashed) interpolating monotone data]{Cubic spline (solid) and monotone quadratic spline (dashed) interpolating monotone data from \cite{Gregory1982}. Cubic spline fails to preserve monotonicity of the data.} \label{ch11:fig1} \end{figure} - -\begin{figure}[h] +\begin{figure}[!b] \centering -\includegraphics[angle=00,width=8cm]{Chapters/chapter11/gregory1_plot2_b.pdf} -\caption[Hermite cubic spline (solid) and Hermite rational spline interpolating monotone data]{Hermite cubic spline (solid) and Hermite rational spline interpolating monotone data from \cite{Gregory1982} with non-negative prescribed slopes. Despite non-negative slopes, Hermite cubic spline is not monotone.} +\includegraphics[angle=00,width=9cm]{Chapters/chapter11/gregory1_plot2_b.pdf} +\caption[Hermite cubic spline (solid) and Hermite rational spline interpolating monotone data]{Hermite cubic spline (solid) and Hermite rational spline interpolating monotone data from \cite{Gregory1982} with nonnegative prescribed slopes. Despite nonnegative slopes, the Hermite cubic spline is not monotone.} \label{ch11:fig2} \end{figure} + +The above mentioned application is one of many examples (e.g., mass spectrography \cite{Kearsley_2006} and global warming data \cite{Yohai}) where univariate data needs to be fitted by monotonicity preserving interpolants. Of course, CDF is a monotone increasing function, whose inverse, called quantile function, can be used to calculate the quantiles. Spline interpolation would be the most suitable nonparametric method to fit the CDF, except that polynomial splines do not preserve monotonicity of the data, as illustrated on Figure \ref{ch11:fig1}. + + +The failure of splines to preserve monotonicity has prompted fundamental research in this area since the 1960s. One of the first methods to remedy this problem was splines in tension by Schweikert \cite{Sch}, where a tension parameter controlled the shape of exponential splines \cite{Spath1969}. Later on several monotonicity preserving polynomial spline algorithms were proposed \cite{Schumaker1983,PasRoul1977,AndElf1987,Andersson1991_JAT,McAllister1981_ACM}. These algorithms typically rely on introducing additional spline knots between the abscissae of the data. Algorithmic developments are active to this day; see, for example, \cite{Kvasov2000_book,Abbas2011}. + +When in addition to the pairs $(x_i, y_i)$ the slopes of the function are available, i.e., the data comes in triples $(x_i, y_i, p_i)$, the interpolation problem is called Hermite, and the Hermite splines are used. However, even when the sequence $y_i$ is increasing and the slopes $p_i$ are nonnegative, cubic Hermite splines may still fail to be monotone, as illustrated in Figure \ref{ch11:fig2}. Thus, monotone Hermite splines are needed \cite{Gregory1982}. \index{Hermite splines} + +Another issue with monotone approximation is noisy data. In this case inaccuracies in the data make the input sequence $y_i$ itself nonmonotone; and hence monotone spline interpolation algorithms will fail. Monotone spline smoothing algorithms are available, e.g., \cite{Andersson1991_JAT,Elfving1989_NM}. Such algorithms are based on solving a quadratic (or another convex) programming problem numerically, and have not yet been adapted to parallel processing. + +In this work we examine several monotone spline fitting algorithms, and select the ones that we believe are most suitable for parallelization on GPUs. We pay attention to numerical efficiency in terms of numerical calculations and memory access pattern, and favor one-pass algorithms. We also look at smoothing noisy data and developed a parallel version of the Minimum Lower Sets (MLS) algorithm for the isotonic regression problem \cite{Best1990, Robertson_book}. +\index{isotone regression} + +The rest of the chapter is organized as follows. Section \ref{ch11:splines} discusses monotone spline interpolation methods and presents two parallel algorithms. Section \ref{ch11:smoothing} deals with the smoothing problem. It presents the isotonic regression problem and discusses the Pool Adjacent Violators (PAV) and MLS algorithms. Combined with monotone spline interpolation, the parallel MLS method makes it possible to build a monotone spline approximation to noisy data entirely on GPU. Section \ref{ch11:conc} concludes. + + \section{Monotone splines} \label{ch11:splines} \index{constrained splines} \index{monotonicity} -Splines are piecewise continuous functions very popular in numerical approximation and computer aided design \cite{deboor2001_book,Dierckx1995_book}. An example of a spline is broken line interpolation. Typically polynomial splines are used, and the first (and often second) derivatives of the polynomial pieces are required to match at the knots. The knots of the splines are usually the abscissae of the input data, although this condition is not always required (e.g., splines with free knots \cite{Jupp_1978,Dierckx1995_book,Beliakov2003_amc}). +Splines are piecewise continuous functions very popular in numerical approximation and computer-aided design \cite{deboor2001_book,Dierckx1995_book}. An example of a spline is the broken line interpolation. Typically, polynomial splines are used, and the first (and often second) derivatives of the polynomial pieces are required to match at the knots. The knots of the splines are usually the abscissae of the input data, although this condition is not always required (e.g., splines with free knots \cite{Jupp_1978,Dierckx1995_book,Beliakov2003_amc}). -Polynomial splines are often represented in the B-spline basis, in which case their coefficients are computed from the input data by solving a banded system of linear equations \cite{Lyche1973, Dierckx1995_book, deboor2001_book}. Tridiagonal systems arise in cubic spline interpolation, while pentadiagonal systems arise in cubic spline smoothing \cite{Lyche1973}. Spline possess important extremal properties \cite{Holladay1957,Lyche1973}, in particular splines of degree $2m-1$ are the most ``smooth" functions that interpolate (or approximate, in the least squares sense) the data. The smoothness term is Tihkonov regularisation functional, the $L_2$ norm of the $m$-th derivative of the interpolant \cite{Lyche1973}. +Polynomial splines are often represented in the B-spline basis, in which case their coefficients are computed from the input data by solving a banded system of linear equations \cite{Lyche1973, Dierckx1995_book, deboor2001_book}. Tridiagonal systems arise in cubic spline interpolation, while pentadiagonal systems arise in cubic spline smoothing \cite{Lyche1973}. Splines possess important extremal properties \cite{Holladay1957,Lyche1973}, in particular splines of degree $2m-1$ are the most ``smooth" functions that interpolate (or approximate, in the least squares sense) the data. The smoothness term is Tihkonov regularization functional, the $L_2$ norm of the $m$th derivative of the interpolant \cite{Lyche1973}. -When the data are known to come from a monotone function, the interpolant needs to be monotone as well. Even if the sequence of data ordinates $y_i, i=1,\ldots,n$ is non-decreasing, cubic (and higher degree) interpolating splines are not necessarily monotone, an example is shown in Figure \ref{ch11:fig1}. To deal with the problem of extraneous inflection points, Schweikert \cite{Sch} proposed splines in tension, which are piecewise exponential functions. Splines in tension were further explored in \cite{Spath1969, SapKak1988, SapKakLouk1988} and many subsequent works. +When the data are known to come from a monotone function, the interpolant needs to be monotone as well. Even if the sequence of data ordinates $y_i, i=1,\ldots,n$ is nondecreasing, cubic (and higher degree) interpolating splines are not necessarily monotone; an example is shown in Figure \ref{ch11:fig1}. To deal with the problem of extraneous inflection points, Schweikert \cite{Sch} proposed splines in tension, which are piecewise exponential functions. Splines in tension have been further explored in \cite{Spath1969, SapKak1988, SapKakLouk1988} and many subsequent works. \subsection{Monotone quadratic splines} -For polynomial splines, monotone or otherwise constrained splines were developed in \cite{Schumaker1983,AndElf1987,Andersson1991_JAT,McAllister1981_ACM,PasRoul1977}. Two monotone quadratic spline algorithms were published in the early 1980s \cite{McAllister1981_ACM, Schumaker1983}. Both algorithms are based on introducing additional interpolation knots under certain conditions, to facilitate preservation of monotonicity of the data. McAllister and Roulier's algorithm \cite{McAllister1981_ACM} introduces at most two extra knots between two neighbouring data, while Schumaker's algorithm \cite{Schumaker1983} introduces only one extra knot. In addition, Schumaker's algorithm is one pass, which is particularly suited for parallelisation, as no system of equations needs to be solved. While parallel tridiagonal linear systems solvers have been developed for GPUs \cite{tridiag_GPU}, the obvious advantage of a one-pass algorithm is the speed. -Because of that, we chose Schumaker's algorithm for GPU parallelisation. +For polynomial splines, monotone or otherwise constrained splines were developed in \cite{Schumaker1983,AndElf1987,Andersson1991_JAT,McAllister1981_ACM,PasRoul1977}. Two monotone quadratic spline algorithms were published in the early 1980s \cite{McAllister1981_ACM, Schumaker1983}. Both algorithms are based on introducing additional interpolation knots under certain conditions, to facilitate preservation of monotonicity of the data. McAllister and Roulier's algorithm \cite{McAllister1981_ACM} introduces at most two extra knots between two neighbouring data, while Schumaker's algorithm \cite{Schumaker1983} introduces only one extra knot. In addition, Schumaker's algorithm is one pass, which is particularly suited for parallelization, as no system of equations needs to be solved. While parallel tridiagonal linear systems solvers have been developed for GPUs \cite{tridiag_GPU}, the obvious advantage of a one-pass algorithm is the speed. +Because of that, we chose Schumaker's algorithm for GPU parallelization. Let us formally describe Schumaker's algorithm, with Butland's slopes \cite{Butland1980}. The spline is a piecewise quadratic polynomial in the form @@ -73,7 +79,7 @@ d_1=\left\{\begin{array}{ll} 2\delta_{1}-d_2, & \mbox{if } \delta_{1}(2\delta_1-d_2)>0, \\ 0 & \mbox{otherwise}, \end{array} - \right. + \right. $$ $$ d_n=\left\{\begin{array}{ll} @@ -83,7 +89,7 @@ d_1=\left\{\begin{array}{ll} \right. $$ -When $d_i+d_{i+1}=2\delta_i$, then a single quadratic polynomial interpolates the data on $[x_i,x_{i+1}]$ and $t_i=x_i$ $\alpha_i=y_i, \beta_i=d_i, \gamma_i=\frac{d_{i+1}-d_i}{2(x_{i+1}-x_i)}$. otherwise an additional knot $t_i$ is required, and +When $d_i+d_{i+1}=2\delta_i$, then a single quadratic polynomial interpolates the data on $[x_i,x_{i+1}]$ and $t_i=x_i$, $\alpha_i=y_i, \beta_i=d_i$, and $ \gamma_i=\frac{d_{i+1}-d_i}{2(x_{i+1}-x_i)}$. Otherwise an additional knot $t_i$ is required, and \begin{eqnarray*} \alpha_{i}&=&y_{i}, \beta_{i}=d_{i}, \gamma_{i}=\frac{(\bar{d}_{i}-d_{i})}{2(t_{i}-x_{i})}, x\in\left [ x_{i},t_{i} \right ],\\ \bar{\alpha}_{i}&=&y_{i}+d_{i}(t_{i}-x_{i})+\frac{(\bar{d}_{i}-d_{i})}{2(t_{i}-x_{i})}, \bar{\beta}_{i}=\bar{d}_{i}, \bar{\gamma}_{i}=\frac{(d_{i+1}-\bar{d}_{i})}{2(x_{i+1}-t_{i})}, x\in\left [ t_{i},x_{i+1} \right ], @@ -102,16 +108,16 @@ t_{i}= \end{cases} $$ -It is almost straightforward to parallelise this scheme for GPUs, by processing each subinterval $[x_i,x_{i+1}]$ independently in a separate thread. However, it is not known in advance whether an extra knot $t_i$ needs to be inserted or not, and therefore calculation of the position of the knot in the output sequence of knots ${t_i}$ is problematic for parallel implementation (for a sequential algorithm no such issue arises). To avoid serialisation, we decided to insert an additional knot in every interval $[x_i,x_{i+1}]$, but set $t_i=x_i$ when the extra knot is not actually needed. This way we know in advance the position of the output knots and the length of this sequence is $2(n-1)$, and therefore all calculations can now be performed independently. The price we pay is that some of the spline knots can coincide. However, this does not affect spline evaluation, as one of the coinciding knots is simply disregarded, and the spline coefficients are replicated (so for a double knot $t_i=t_{i+1}$, we have $\alpha_i=\alpha_{i+1}$, $\beta_i=\beta_{i+1}$, $\gamma_i=\gamma_{i+1}$). Our implementation is presented in Figures \ref{ch11:algcoef}-\ref{ch11:algcoef1}. +It is almost straightforward to parallelize this scheme for GPUs, by processing each subinterval $[x_i,x_{i+1}]$ independently in a separate thread. However, it is not known in advance whether an extra knot $t_i$ needs to be inserted, and therefore calculation of the position of the knot in the output sequence of knots ${t_i}$ is problematic for parallel implementation (for a sequential algorithm no such issue arises). To avoid serialization, we decided to insert an additional knot in every interval $[x_i,x_{i+1}]$, but set $t_i=x_i$ when the extra knot is not actually needed. This way we know in advance the position of the output knots and the length of this sequence is $2(n-1)$, and therefore all calculations can now be performed independently. The price we pay is that some of the spline knots can coincide. However, this does not affect spline evaluation, as one of the coinciding knots is simply disregarded, and the spline coefficients are replicated (so for a double knot $t_i=t_{i+1}$, we have $\alpha_i=\alpha_{i+1}$, $\beta_i=\beta_{i+1}$, $\gamma_i=\gamma_{i+1}$). Our implementation is presented in Listings \ref{ch11:algcoef1}-\ref{ch11:algcoef}. -\lstinputlisting[label=ch11:algcoef1,caption=Calculation of monotone spline knots and coefficients.]{Chapters/chapter11/code2.cu} +\lstinputlisting[label=ch11:algcoef1,caption=calculation of monotone spline knots and coefficients.]{Chapters/chapter11/code2.cu} -At the spline evaluation stage we need to compute $s(z_k)$ for a sequence of query values ${z_k}, k=1,\ldots,K$. For each $z_k$ we locate the interval $[t_i,t_{i+1}]$ containing $z_k$, using bisection algorithm presented in Figure \ref{ch11:algeval}, and then apply the appropriate coefficients of the quadratic function. This is also done in parallel. -The bisection algorithm could be implemented using texture memory (to cache the array \texttt{z}), but this is not shown in Figure \ref{ch11:algeval}. +At the spline evaluation stage we need to compute $s(z_k)$ for a sequence of query values ${z_k}, k=1,\ldots,K$. For each $z_k$ we locate the interval $[t_i,t_{i+1}]$ containing $z_k$, using the bisection algorithm presented in Listing \ref{ch11:algeval}, and then apply the appropriate coefficients of the quadratic function. This is also done in parallel. +The bisection algorithm could be implemented using texture memory (to cache the array \texttt{z}), but this is not shown in Listing \ref{ch11:algeval}. -\pagebreak -\lstinputlisting[label=ch11:algcoef,caption=Implementation of the kernel for calculating spline knots and coefficients. Function fmax is used to avoid division by zero for data with coinciding abscissae.]{Chapters/chapter11/code1.cu} +%\pagebreak +\lstinputlisting[label=ch11:algcoef,caption=Implementation of the kernel for calculating spline knots and coefficients; function fmax is used to avoid division by zero for data with coinciding abscissae.]{Chapters/chapter11/code1.cu} %% \begin{figure}[!hp] @@ -289,12 +295,12 @@ The bisection algorithm could be implemented using texture memory (to cache the %% \renewcommand{\baselinestretch}{2} %% \end{figure} -\lstinputlisting[label=ch11:algeval,caption=Implementation of the spline evaluation algorithm for GPU.]{Chapters/chapter11/code3.cu} +\lstinputlisting[label=ch11:algeval,caption=implementation of the spline evaluation algorithm for GPU.]{Chapters/chapter11/code3.cu} \subsection{Monotone Hermite splines} \index{Hermite splines} \index{monotonicity} -In this section, in addition to the points $(x_i,y_i)$ we have the slopes $p_i$, and hence we consider monotone Hermite interpolation. In our motivating application of cdf estimation, the values $p_i$ are easily obtained together with $y_i$, and their use may help to build a more accurate interpolant. -Of course, for monotone non-decreasing functions we must have $p_i\geq 0$. However this does not guarantee that the spline interpolant is monotone, as can be seen in Figure \ref{ch11:fig2}. Fritsch and Carlson \cite{Fritsch1980} show that non-negative $p_i$ is not a sufficient condition to guarantee monotonicity, and design a process for modification of derivatives, so that the necessary and sufficient conditions for monotonicity of a piecewise cubic are met. Hence the values $p_i$ are not matched exactly. In contrast, Gregory and Delbourgo \cite{Gregory1982} design piecewise rational quadratic spline, for which the non-negativity of $p_i$ is both necessary and sufficient condition. +In this section, in addition to the points $(x_i,y_i)$ we have the slopes $p_i$, and hence, we consider monotone Hermite interpolation. In our motivating application of CDF estimation, the values $p_i$ are easily obtained together with $y_i$, and their use may help to build a more accurate interpolant. +Of course, for monotone nondecreasing functions we must have $p_i\geq 0$. However, this does not guarantee that the spline interpolant is monotone, as can be seen in Figure \ref{ch11:fig2}. Fritsch and Carlson \cite{Fritsch1980} showed that nonnegative $p_i$ is not a sufficient condition to guarantee monotonicity, and designed a process for modification of derivatives, so that the necessary and sufficient conditions for monotonicity of a piecewise cubic are met. Hence, the values $p_i$ are not matched exactly. In contrast, Gregory and Delbourgo \cite{Gregory1982} designed piecewise rational quadratic spline, for which the nonnegativity of $p_i$ is both a necessary and sufficient condition. The rational quadratic spline in \cite{Gregory1982} is constructed as $$ @@ -321,42 +327,42 @@ with $$ Q_i(\theta)= \Delta_i+(p_{i+1}+p_i-2\Delta_i)\theta(1-\theta), $$ -provided $\Delta_i \neq 0$ ( $s'(x)=0$ otherwise), and this expression is non-negative. +provided $\Delta_i \neq 0$ ($s'(x)=0$ otherwise), and this expression is nonnegative. -It is clear that Gregory and Delbourgo's Hermite interpolant is trivially parallel, and the parameters $h_i=x_{i+1}-x_i$ and $\Delta_i$ are easily computed in a simple kernel. Evaluation of the spline and its derivative is accomplished by locating the interval containing the query point $x$ using bisection, as in Figure \ref{ch11:algeval}, and applying the above mentioned formulas. +It is clear that Gregory and Delbourgo's Hermite interpolant \cite{Gregory1982} is trivially parallel, and the parameters $h_i=x_{i+1}-x_i$ and $\Delta_i$ are easily computed in a simple kernel. Evaluation of the spline and its derivative is accomplished by locating the interval containing the query point $x$ using bisection, as in Listing \ref{ch11:algeval}, and applying the above-mentioned formulas. \section{Smoothing noisy data via parallel isotone regression} \label{ch11:smoothing} -Inaccuracies in the data are common in practice, and need to be accounted for during spline approximation process. Smoothing polynomial splines were presented in \cite{Lyche1973}, where the data are fitted in the least squares sense while also minimising the $L_2$ norm of the $m-$th derivative of the spline. Monotone smoothing splines were dealt with in several works, in particular we mention \cite{Andersson1991_JAT,Elfving1989_NM}. The presented algorithms rely on solving quadratic programming problems. Monotone approximating splines with fixed knots distinct form the data have been presented in \cite{Beliakov2000_ata}, where an instance of a quadrating programming problem is solved as well. +Inaccuracies in the data are common in practice and need to be accounted for during the spline approximation process. Smoothing polynomial splines were presented in \cite{Lyche1973}, where the data were fitted in the least squares sense while also minimizing the $L_2$ norm of the $m$th derivative of the spline. Monotone smoothing splines have been dealt with in several works, in particular we mention \cite{Andersson1991_JAT,Elfving1989_NM}. The presented algorithms rely on solving quadratic programming problems. Monotone approximating splines with fixed knots distinct form the data have been presented in \cite{Beliakov2000_ata}, where an instance of a quadrating programming problem is solved as well. \index{isotone regression} \index{monotonicity} -Another approach consists in monotonising the data, so that the sequence $y_i$ becomes monotone. This approach is known as isotone regression \cite{Best1990, Robertson_book}. It is different from monotone spline smoothing, as the regularisation term controlling the $L_2$ norm of the $m-$the derivative is not taken into account. Usually the data is monotonised by minimising the squared differences to the inputs. It becomes a quadratic programming problem, usually solved by active sets methods \cite{Best1990}. +Another approach consists of monotonizing the data, so that the sequence $y_i$ becomes monotone. This approach is known as isotone regression \cite{Best1990, Robertson_book}. It is different from monotone spline smoothing, as the regularization term controlling the $L_2$ norm of the $m$th derivative is not taken into account. Usually the data is monotonized by minimizing the squared differences to the inputs. It becomes a quadratic programming problem, usually solved by active sets methods \cite{Best1990}. A popular PAV algorithm (PAVA) is one method that provides efficient numerical solution. \index{PAV algorithm} - PAVA consists of the following steps. The sequence ${y_i}$ is processed form the start. If violation of monotonicity $y_i>y_{i+1}$ is found, both values $y_i$ and $y_{i+1}$ are replaced with their average $y'_i$, and both values form a block. Since the new value $y'_i$ is smaller than $y_i$, monotonicity may become violated with respect to the datum $y_{i-1}$. If this is the case, the $i-1$st, $i$th and $i+1$st data are merged into a block and their values are replaced with their average. We continue back-average as needed to get monotonicity. + PAVA consists of the following steps. The sequence ${y_i}$ is processed from the start. If violation of monotonicity $y_i>y_{i+1}$ is found, both values $y_i$ and $y_{i+1}$ are replaced with their average $y'_i$, and both values form a block. Since the new value $y'_i$ is smaller than $y_i$, monotonicity may become violated with respect to $y_{i-1}$. If this is the case, the $i-1$st, $i$th, and $i+1$st data are merged into a block and their values are replaced with their average. We continue to back-average as needed to get monotonicity. -Various serial implementations of the PAVA exist. It is noted \cite{Kearsley_2006} that in PAVA, which is based on the ideas from convex analysis, a decomposition theorem holds, namely performing PAVA separately on two contiguous subsets of data, and then performing PAVA on the result produces isotonic regression on the whole data set. Thus isotonic regression is parallelisable, and divide-and-conquer approach, decomposing the original problem into two smaller subproblems, can be implemented on multiple processors. However, to our knowledge, no parallel PAVA for many-core systems such as GPUs exist. +Various serial implementations of the PAVA exist. It is noted \cite{Kearsley_2006} that in PAVA, which is based on the ideas from convex analysis, a decomposition theorem holds, namely, performing PAVA separately on two contiguous subsets of data and then performing PAVA on the result produces isotonic regression on the whole data set. Thus, isotonic regression is parallelizable, and the divide-and-conquer approach, decomposing the original problem into two smaller subproblems, can be implemented on multiple processors. However, to our knowledge, no parallel PAVA for many-core systems such as GPUs exist. \index{MLS algorithm} \index{Minimum Lower Sets} -Another approach to isotonic regression is called the Minimum Lower Sets algorithm (MLS) -\cite{Best1990, Robertson_book}. It provides the same solution as the PAVA, but works differently. For each datum (or block), MLS selects the largest contiguous block of subsequent data with the smallest average. If this average is smaller than that of the preceding block, the blocks are merged, and the data in the block are replaced with their average. MLS is also an active set method \cite{Best1990}, but its complexity is $O(n^2)$ as opposed to $O(n)$ of the PAVA, and of another active set algorithm proposed in \cite{Best1990} under the name Algorithm A. +Another approach to isotonic regression is called the MLS algorithm +\cite{Best1990, Robertson_book}. It provides the same solution as the PAVA, but works differently. For each datum (or block), MLS selects the largest contiguous block of subsequent data with the smallest average. If this average is smaller than that of the preceding block, the blocks are merged, and the data in the block are replaced with their average. MLS is also an active set method \cite{Best1990}, but its complexity is $O(n^2)$ as opposed to $O(n)$ of the PAVA, and of another active set algorithm proposed in \cite{Best1990} by the name of Algorithm A. -In terms of GPU parallelisation, neither PAVA nor Algorithm A appear to be suitable, as the techniques that achieve $O(n)$ complexity are inheritably serial. -In this work we focused on parallelising MLS. First, we precompute the values +In terms of GPU parallelization, neither PAVA nor Algorithm A appears to be suitable, as the techniques that achieve $O(n)$ complexity are inheritably serial. +In this work we focus on parallelizing MLS. First, we precompute the values $$ z_i=\sum_{j=i}^n y_i $$ and $z_{n+1}=0$ -using parallel partial sum algorithm (\texttt{scan} algorithm from Thrust \cite{Thrust} library). +using the parallel partial sum algorithm (\texttt{scan} algorithm from Thrust \cite{Thrust} library). From these values we can compute the averages of the blocks of data with the indices $\{i,i+1,\ldots,j\}$ \begin{equation} \label{ch11:eq1} -P_{ij}=\frac{1}{j-i+1}\sum_{k=i}^j y_k = \frac{1}{j-i+1} (z_i-z_{j+1}) +P_{ij}=\frac{1}{j-i+1}\sum_{k=i}^j y_k = \frac{1}{j-i+1} (z_i-z_{j+1}). \end{equation} -As per MLS algorithm, for each fixed $i$ from 1 to $n$ we compute the smallest $P_{ij}$ starting from $j=i+1$ and fix the index $j^*$. If $y_i>P_{ij^*}$, we replace the values $y_i,\ldots,y_{j^*}$ with their average $P_{ij^*}$ otherwise we keep the value $y_i$. In case of replacement, we advance $i$ to position $j^*+1$. We check the condition $y_i>P_{i,j^*}$ to form a block, which is equivalent to $y_i>P_{i+1,j^*}$ as $P_{ij}=\frac{1}{j-i+1}((j-i) P_{i+1,j}+y_i)$, from which we deduce both inequalities hold simultaneously. +As per MLS algorithm, for each fixed $i$ from 1 to $n$, we compute the smallest $P_{ij}$ starting from $j=i+1$ and fix the index $j^*$. If $y_i>P_{ij^*}$, we replace the values $y_i,\ldots,y_{j^*}$ with their average $P_{ij^*}$; otherwise we keep the value $y_i$. In case of replacement, we advance $i$ to position $j^*+1$. We check the condition $y_i>P_{i,j^*}$ to form a block, which is equivalent to $y_i>P_{i+1,j^*}$ as $P_{ij}=\frac{1}{j-i+1}((j-i) P_{i+1,j}+y_i)$, from which we deduce that both inequalities hold simultaneously. %Also we note that $y_{j^*}\leq P_{ij^*}$, which means we @@ -367,10 +373,10 @@ As per MLS algorithm, for each fixed $i$ from 1 to $n$ we compute the smallest $ %Finally, in PAVA the value $y_k, i \leq k\leq j$ can be replaced several times at different back-averaging steps, the latest being $P_{ij}$ corresponding to the smallest $i$ for which $y_i>P_{i+1,j}$. In our version we start with the smallest $i$, and replace $y_k$ only once, and then advance to position $j$, so they are not overwritten. Therefore, our algorithm performs the same replacements as PAVA but in a different order, and the outputs are the same. Below we show that the order does not really matter if we perform replacements with the max operation. -Now the presented algorithm can be parallelised for GPUs: each datum $y_i$ is treated in its own thread. Calculation of the smallest $P_{ij}$ is performed serially within the $i$-th thread, or in parallel, by starting children threads. -Replacing the values $y_i,\ldots,y_{j^*}$ with $P_{ij^*}$ leads to potential clashes, as several threads can perform this operation on the same elements $y_k$. This can be circumvented by using max operation, i.e., $y_k\leftarrow \max(y_k,P_{ij})$. Note that thread $i$ replaces the value $y_k$, $k\geq i$ if $P_{ij}10^4$. While it is possible to transfer data from GPU to CPU and run PAVA there, it is warranted only for sufficiently large data $n\geq 5 \times 10^5$ , for otherwise the data transfer overheads will dominate CPU time. For smaller $n$, isotone regression is best performed on GPU. -We also see that the use of GPU accelerated MLS by a factor of at least 100. The cost of serial MLS is prohibitive for $n>10^6$. - -We should mention that not all isotone regression problems allow a PAV-like algorithm linear in time. When the data may contain large outliers, monotonizing the data is better done not in the least squares sense, but using other cost functionals, such as by minimizing the sum of absolute deviations \cite{Wang} or using M-estimators \cite{Yohai}, which are less sensitive to outliers. It is interesting than in all such cases the solution to isotone regression problem can be found by solving maximin problem -$$ -u_i=\max_{k\leq i} \min_{l \geq i} \hat y(k,l), -$$ -with $\hat y(k,l)$ being the unrestricted maximum likelihood estimator of $y_k\ldots,y_l$. For quadratic cost function $\hat y(k,l)$ is the mean, as in PAV and MLS algorithms, for the absolute deviations it becomes the median, and for other cost functions an M-estimator of location. The MLS algorithm can be applied to such isotone regression problems with very little modification, while linear in time algorithm may not be available. Our parallel MLS algorithm will be valuable in such cases. +As we mentioned, the complexity of the MLS algorithm is $O(n^2)$, due to the fact that for each datum, the smallest average $P_{ij}$ of the blocks of subsequent data is needed. Thus, each thread needs to perform $O(n)$ comparisons (the averages themselves are precomputed in $O(n)$ operations using the partial sum algorithm). It is interesting to compare the runtime of the PAVA algorithm on CPU and parallel MLS on GPU to establish for which $n$ parallel MLS is preferable. We performed such experiments on Tesla 2050 device connected to a four-core Intel i7 CPU with 4 GB RAM clocked at 2.8 GHz, running Linux (Fedora 16). +First we compared the serial versions of PAV and MLS algorithms. For this we used two packages in R environment, \texttt{stats} and \texttt{fdrtool}. The package \texttt{stats} offers function \texttt{isoreg}, which implements the MLS algorithm in C language, whereas package \texttt{fdrtool} offers PAVA, also implemented in C. Overheads of R environment can be neglected, as the input data are simply passed to C code, so we can compare the running time of both algorithms head to head. We generated input data of varying lengths $n$ from $10^4$ to $ 5 \times 10^7$ randomly, using $y_i=f(x_i)+\varepsilon_i$, where $f$ is a monotone test function and $\varepsilon$ is random noise. We also tried completely ordered isotone data, and antitone data, to check the performance for adversary inputs. Subsequently, we measured the runtime of our parallel version of MLS algorithm on Tesla 2050 GPU. The results are presented in Table \ref{ch11:table1}. %% %\renewcommand{\baselinestretch}{1} -\begin{table}[!h] +\begin{table}[htbp] \begin{center} \begin{tabular}{|r|r|r|r|} \hline @@ -435,9 +432,25 @@ $n=50 \times 10^6$ &11& 11& -- \\ \hline \end{tabular} \end{center} -\caption{The average CPU time (sec) of the serial PAVA, MLS and parallel MLS algorithms. } +\caption{The average CPU time (sec) of the serial PAVA, MLS, and parallel MLS algorithms. } \label{ch11:table1} \end{table} + + +As expected, the runtimes of both methods differed significantly, as shown in Table \ref{ch11:table1}, and clearly linear PAVA was superior to serial MLS algorithm. Even though for some special cases, e.g., test function $f=const$, both serial methods gave the same running time; this can be explained by the fact that large blocks of data allowed MLS to skip the majority of tests. This did not happen in the parallel version of MLS, where for each datum the smallest value of $P_{ij^*}$ was computed (in parallel), so the average CPU times were the same for all data. + +From the results in Table \ref{ch11:table1} we conclude that serial PAVA is superior to MLS for $n>10^4$. While it is possible to transfer data from GPU to CPU and run PAVA there, it is warranted only for sufficiently large data $n\geq 5 \times 10^5$, for otherwise the data transfer overheads will dominate CPU time. For smaller $n$, isotone regression is best performed on GPU. + + +We also see that the use of GPU accelerated MLS by a factor of at least 100, except for antitone data. The cost of serial MLS is prohibitive for $n>10^6$. + +We should mention that not all isotone regression problems allow a PAV-like algorithm linear in time. When the data may contain large outliers, monotonizing the data is better done not in the least squares sense, but using other cost functionals, such as by minimizing the sum of absolute deviations \cite{Wang} or using M-estimators \cite{Yohai}, which are less sensitive to outliers. It is interesting than in all such cases the solution to an isotone regression problem can be found by solving maximin problem +$$ +u_i=\max_{k\leq i} \min_{l \geq i} \hat y(k,l), +$$ +with $\hat y(k,l)$ being the unrestricted maximum likelihood estimator of $y_k\ldots,y_l$. For the quadratic cost function $\hat y(k,l)$ corresponds to the mean of these data (as in PAV and MLS algorithms), for the absolute deviations $\hat y(k,l)$ corresponds to the median, and for other cost functions it corresponds to an M-estimator of location. The MLS algorithm can be applied to such isotone regression problems with very little modification. However, we are unaware of other algorithms for solving the modified problem that linear in time. Our parallel MLS algorithm will be valuable in such cases. + + %% %\renewcommand{\baselinestretch}{2} @@ -499,11 +512,11 @@ $n=50 \times 10^6$ &11& 11& -- \\ %% \label{ch11:algMLS} %% \end{figure} -\lstinputlisting[label=ch11:algMLS,caption=Fragments of implementation of a parallel version of the MLS algorithm using Thrust library.]{Chapters/chapter11/code4.cu} + \section{Conclusion} \label{ch11:conc} -We presented three GPU-based parallel algorithms for approximating monotone data: monotone quadratic spline, monotone Hermite rational spline and minimum lower sets algorithm for monotonizing noisy data. These tools are valuable in a number of applications that involve large data sets modeled by monotone nonlinear functions. +We presented three GPU-based parallel algorithms for approximating monotone data: monotone quadratic spline, monotone Hermite rational spline, and minimum lower sets algorithm for monotonizing noisy data. These tools are valuable in a number of applications that involve large data sets modeled by monotone nonlinear functions. The source code of the package monospline is available from \texttt{www.deakin.edu.au/$\sim$gleb/monospline.html } diff --git a/BookGPU/Chapters/chapter11/gregory1_plot2_b.pdf b/BookGPU/Chapters/chapter11/gregory1_plot2_b.pdf index c7a9c0db0d1600879f4a03b7c677456aaddfaf96..57f845c2aba98ec85989731590827b66cd01c34f 100644 GIT binary patch literal 21979 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 literal 45585 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�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 U>mQZ?K^&ZX7<6>fDl!=V2Ycg~p8x;= diff --git a/BookGPU/Chapters/chapter11/gregory1_plot2_b.ps b/BookGPU/Chapters/chapter11/gregory1_plot2_b.ps index b770aec..58296d6 100644 --- a/BookGPU/Chapters/chapter11/gregory1_plot2_b.ps +++ b/BookGPU/Chapters/chapter11/gregory1_plot2_b.ps @@ -1851,7 +1851,7 @@ np o /Font1 findfont 12 s 120.24 516.25 (Her) 0 ta -0.300 (mite spline) tb gr +0.300 (mite cubic spline) tb gr 120.24 501.85 (Her) 0 ta 0.300 (mite monotone spline) tb gr ep -- 2.39.5