diff options
author | Norbert Preining <norbert@preining.info> | 2024-06-11 03:01:33 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2024-06-11 03:01:33 +0000 |
commit | b5949874de738aa89ec22e206dc2d1ab647bb231 (patch) | |
tree | 3814af95d930d62f868277637dbf8c2dee0f409e /macros | |
parent | bfc721e3f53794233ef294d666fa1965254c6b8c (diff) |
CTAN sync 202406110301
Diffstat (limited to 'macros')
-rw-r--r-- | macros/latex/contrib/easybook/easybook.dtx | 14 | ||||
-rw-r--r-- | macros/latex/contrib/easybook/easybook.pdf | bin | 633407 -> 633451 bytes | |||
-rw-r--r-- | macros/latex/contrib/easybook/easybook.tex | 25 | ||||
-rw-r--r-- | macros/latex/contrib/linearregression/README.txt | 41 | ||||
-rw-r--r-- | macros/latex/contrib/linearregression/linearregression.dtx | 1235 | ||||
-rw-r--r-- | macros/latex/contrib/linearregression/linearregression.pdf | bin | 0 -> 391146 bytes | |||
-rw-r--r-- | macros/latex/contrib/linearregression/linearregressionpkg.ins | 20 | ||||
-rw-r--r-- | macros/luatex/generic/luamplib/NEWS | 6 | ||||
-rw-r--r-- | macros/luatex/generic/luamplib/luamplib.dtx | 259 | ||||
-rw-r--r-- | macros/luatex/generic/luamplib/luamplib.pdf | bin | 198713 -> 208716 bytes | |||
-rw-r--r-- | macros/luatex/generic/luamplib/test-luamplib-latex.tex | 35 | ||||
-rw-r--r-- | macros/luatex/generic/luamplib/test-luamplib-plain.tex | 35 |
12 files changed, 1644 insertions, 26 deletions
diff --git a/macros/latex/contrib/easybook/easybook.dtx b/macros/latex/contrib/easybook/easybook.dtx index 5a63b316b7..788bb2fa32 100644 --- a/macros/latex/contrib/easybook/easybook.dtx +++ b/macros/latex/contrib/easybook/easybook.dtx @@ -14,7 +14,7 @@ % This work has the LPPL maintenance status `maintained'. %<*class> \NeedsTeXFormat{LaTeX2e}[2021/11/15] -\ProvidesExplClass{easybook}{2024/06/08}{2024bx} +\ProvidesExplClass{easybook}{2024/06/10}{2024bz} {Easily typesetting Chinese theses or books} \bool_new:N \l__eb_compile_draft_bool @@ -301,7 +301,7 @@ %<*package> \NeedsTeXFormat{LaTeX2e}[2021/11/15] \RequirePackage{etoolbox} -\ProvidesExplPackage{easybase}{2024/06/08}{2024bx} +\ProvidesExplPackage{easybase}{2024/06/10}{2024bz} {Easily typesetting Chinese theses or books} \cs_generate_variant:Nn \dim_set:Nn { NV } @@ -2380,7 +2380,7 @@ } } -\cs_new:Npn \eb@lst@if@display #1#2 +\cs_new:Npn \lstifdisplay #1#2 { \lst@ifdisplaystyle #1\else #2\fi } \lstdefinestyle{lst-base} { @@ -2408,9 +2408,9 @@ { style = lst-base, language = [LaTeX]TeX, - texcsstyle = *\color{ctex@verb}\eb@lst@if@display{\bfseries}{}, - basicstyle = \ttfamily\eb@lst@if@display{\small}{\color{ctex@verb}}, - keywordstyle = \color{ctex@verb}\eb@lst@if@display{\bfseries}{} + texcsstyle = *\color{ctex@verb}\lstifdisplay{\bfseries}{}, + basicstyle = \ttfamily\lstifdisplay{\small}{\color{ctex@verb}}, + keywordstyle = \color{ctex@verb}\lstifdisplay{\bfseries}{} } \lstset{style = lst-latex} \lstloadlanguages{C,C++,Java,Python,Matlab} @@ -2596,7 +2596,7 @@ } %</package> %<*tcolorbox> -\ProvidesExplFile{eb-tcolorbox.cfg}{2024/06/08}{2024bx} +\ProvidesExplFile{eb-tcolorbox.cfg}{2024/06/10}{2024bz} {Customization of tcolorbox for easybook} \cs_set_protected:Npn \addtotcbstyle #1#2 diff --git a/macros/latex/contrib/easybook/easybook.pdf b/macros/latex/contrib/easybook/easybook.pdf Binary files differindex 458a1f1ae1..5e4686284c 100644 --- a/macros/latex/contrib/easybook/easybook.pdf +++ b/macros/latex/contrib/easybook/easybook.pdf diff --git a/macros/latex/contrib/easybook/easybook.tex b/macros/latex/contrib/easybook/easybook.tex index 0d7eff5753..b4f13b3c32 100644 --- a/macros/latex/contrib/easybook/easybook.tex +++ b/macros/latex/contrib/easybook/easybook.tex @@ -23,8 +23,8 @@ name = easybook, color-scheme = blue, title = EASYBOOK使用手册, - version = v2024bx, - date = 2024/06/08, + version = v2024bz, + date = 2024/06/10, authors = 瞿毅, info = 简便地排版中文学位论文或书籍, email = toquyi@163.com, @@ -121,7 +121,9 @@ \@firstofone } % A tag that distinguishes the options for different paths -\NewDocumentCommand{\dtag}{sO{\ding{73}}} +\newcommand{\hface}{$\symbol{"263A}$} +\newcommand{\sface}{$\symbol{"263B}$} +\NewDocumentCommand{\dtag}{sO{\hface}} { \begingroup \reversemarginpar @@ -256,7 +258,8 @@ cells = {cmd = \pkg*}, cell{1}{3,4} = PaleTurquoise, cell{2}{5} = PaleTurquoise, - cell{3}{2,4} = PaleTurquoise, + cell{3}{2} = PaleTurquoise, + cell{4}{5} = PaleTurquoise, cell{5}{1} = GreenYellow, cell{1}{2} = GreenYellow, cell{3}{1,4} = GreenYellow @@ -270,7 +273,7 @@ \section{文档类选项} \label{sec:document class options} -文档类选项应当在使用 \easybook{} 文档类或 \pkg*{easybase} 宏包(部分支持)时指定,可见\ref{subsec:basic usage} 的例子。选项前带有 \ding{73} 符号表示只可用于文档类,否则文档类与宏包都适用。除了下面列举的选项以外,还支持标准和 \CTeX 文档类的选项。 +文档类选项应当在使用 \easybook{} 文档类或 \pkg*{easybase} 宏包(部分支持)时指定,可见\ref{subsec:basic usage} 的例子。选项前带有\hface 符号表示只可用于文档类,否则文档类与宏包都适用。除了下面列举的选项以外,还支持标准和 \CTeX 文档类的选项。 \subsection{基本选项} \begin{cnltxlist} @@ -832,7 +835,7 @@ \subsection[目录]{目录\smodule{toc}} \label{subsec:catalog} -模块 \module*{toc} 将使用 \pkg*{titletoc} 宏包处理目录样式。默认包括 \module*{part}$\longrightarrow$\module*{subparagraph}、\module*{figure}、\module*{table} 和 \module*{lstlisting} 条目名的键路径。选项前带有 \ding{73} 符号表示支持所有相应\textbf{条目名}的路径,其它选项则处于 \module*{toc} 键路径下。目录选项均支持标题编号判定命令 \cs{CTEXifname}。目前支持多数学术论文目录样式,更复杂的样式可以查看 \pkg*{titletoc} 的相关用法。 +模块 \module*{toc} 将使用 \pkg*{titletoc} 宏包处理目录样式。默认包括 \module*{part}$\longrightarrow$\module*{subparagraph}、\module*{figure}、\module*{table} 和 \module*{lstlisting} 条目名的键路径。选项前带有\hface 符号表示支持所有相应\textbf{条目名}的路径,其它选项则处于 \module*{toc} 键路径下。目录选项均支持标题编号判定命令 \cs{CTEXifname}\footnote{此功能需要\textbf{2023/06/01}以后的 \hologo{LaTeX} 内核支持。}。目前支持多数学术论文目录样式,更复杂的样式可以查看 \pkg*{titletoc} 的相关用法。 \begin{cnltxlist} \keyval{tocformat}{条目格式}\dtag 目录中各类型条目的格式。可以设置条目字体和加入垂直间距等,垂直间距最好使用防止垂直间距重合的 \cs*{addvspace} 命令。如果是段落型目录,格式代码仅在段落中当前级别条目前执行一次。也可以用 \cs{CTEXifname} 命令或 \option{tocformat*} 选项给有无编号的标题分别设置格式。 @@ -856,7 +859,7 @@ 目录条目标签与标题间的代码,默认为插入 \code{1em} 横向距离。 \keyval{tocbelow}{距离命令}\dtag 在目录条目下方执行的代码,可以插入垂直距离等命令。 - \keyval{tocline}{标题定义}\dtag[\textcolor{red}{\ding{73}}] + \keyval{tocline}{标题定义}\dtag[\textcolor{red}{\sface}] 这个选项在章节标题基础上扩展了浮动环境的题注标题在目录文件中的定义。章节和题注标题选项中参数 \code{\#1} 代表标题编号 \cs*{the}\meta{计数器} 对应的计数器名称,参数 \code{\#2} 则代表相应标题内容。 \begin{ctexexam} \ctexset @@ -874,7 +877,7 @@ } \end{ctexexam} \command{RegisterTocName}[\sarg\marg{条目名列表}]\newtagv[Changed]{2024bo}% - 给 \meta{条目名列表} 中的每个 \meta{条目名} 标题注册用于设置目录样式的选项,即选项前有符号 \ding{73} 表示需要注册后使用。前面提到的条目类型均已注册,新类型的条目注册后默认格式与图表条目相同。这个命令可以重复使用,会重置目录条目为默认格式。带有星号参数的命令使注册目录的条目形成一个段落,此时多出下面三个选项可用: + 给 \meta{条目名列表} 中的每个 \meta{条目名} 标题注册用于设置目录样式的选项,即选项前有符号\hface 表示需要注册后使用。前面提到的条目类型均已注册,新类型的条目注册后默认格式与图表条目相同。这个命令可以重复使用,会重置目录条目为默认格式。带有星号参数的命令使注册目录的条目形成一个段落,此时多出下面三个选项可用: \keyval{tocbegin}{开始代码}\dtag\newtagv{2024as}% 当前级别目录条目第一个标题前的代码,仅在存在更高级别的条目时有效。 \keyval{tocsep}{中间代码}\dtag\Default{\Marg{.—}}\newtagv{2024as}% @@ -884,7 +887,7 @@ \command{contentsuse}[\marg{条目名}\marg{扩展名}] 激活条目类型名称为 \meta{条目名} 的目录定制功能,它使用的目录文件后缀为 \meta{扩展名}。需要在激活条目后再使用命令 \cs{RegisterTocName} 注册选项。 \command{DeclareFloatList}[\marg{条目名}\marg{扩展名}] - 声明一种条目类型的目录命令 \cs*{listof}\meta{条目名}\code{\textcolor{cs}{s}},并且支持\ref{subsec:directory command} 中图表目录命令的机制。使用这个命令要确保将条目加入目录的机制已经存在,例如搭配 \pkg*{newfloat} 宏包创建新的浮动环境。选项前有红色符号 \textcolor{red}{\ding{73}}(仍包含黑色符号选项的性质)表示在声明后可用。下面举一个声明算法环境和对应题注目录的例子: + 声明一种条目类型的目录命令 \cs*{listof}\meta{条目名}\code{\textcolor{cs}{s}},并且支持\ref{subsec:directory command} 中图表目录命令的机制。使用这个命令要确保将条目加入目录的机制已经存在,例如搭配 \pkg*{newfloat} 宏包创建新的浮动环境。选项前有实心符号 \textcolor{red}{\sface}(仍包含空心符号\hface 选项的性质)表示在声明后可用。下面举一个声明算法环境和对应题注目录的例子: \begin{ctexexam} \usepackage{newfloat} \DeclareFloatingEnvironment[ @@ -911,7 +914,7 @@ \printlist[fancy]{loa}{}{} \end{ctexexam} \command{SetTocStyle}[\marg{条目名}\marg{风格名}\marg{键值列表}] - 定义条目类型名称为 \meta{风格名} 的目录风格。使用 \cs*{ctexset} 命令设置目录样式时,除了条目标题定义选项 \option{tocline},其它选项只有在目录输出命令前设置才有效,定义完目录风格后用 \cs{UseTocStyle} 命令可以在正文中任意位置生效。如果是没有 \ding{73} 符号的选项,\meta{条目名} 设置为 \module*{toc}。 + 定义条目类型名称为 \meta{风格名} 的目录风格。使用 \cs*{ctexset} 命令设置目录样式时,除了条目标题定义选项 \option{tocline},其它选项只有在目录输出命令前设置才有效,定义完目录风格后用 \cs{UseTocStyle} 命令可以在正文中任意位置生效。如果是没有\hface 符号的选项,\meta{条目名} 设置为 \module*{toc}。 \command{UseTocStyle}[\marg{条目名}\marg{风格名}\marg{扩展名}] 使用对应条目类型名称为 \meta{风格名} 的目录风格,随后标题在目录中的格式会改变。本命令导言区和正文区均可使用,第三个必选参数还需要指定条目标题加入目录文件的 \meta{扩展名}。 \begin{ctexexam} @@ -933,7 +936,7 @@ 悬挂缩进选项 \option{hang} 使目录条目为悬挂缩进形式。缩进距离为条目标签及其与标题内容间距的长度和。通常情况下会统一设置条目标题是否悬挂缩进,因此这个选项被设计为对所有类型条目生效。 \keyval{lolskip}{弹性长度}\Default{10pt} 代码目录中每章第一个条目上方增加的垂直距离。与 \CTeX 的表格和图片目录中每章间的条目距离选项 \option*{lotskip} 和 \option*{lofskip} 类似,在 \cls*{article} 模式中此选项失效。 - \keyval{between}{代码钩子}\dtag[\textcolor{red}{\ding{73}}] + \keyval{between}{代码钩子}\dtag[\textcolor{red}{\sface}] 目录标题与条目内容间的钩子(作用于标题下方间距之后),如果是 \cls*{book} 模式则默认插入 \code{-10pt} 垂直距离抵消首行目录的额外垂直间距,这是由于图表和 由 \pkg*{newfloat} 宏包所创建环境的目录默认每使用一次章标题在题注目录中插入 \code{10pt} 距离。除了条目名的键路径外,此选项也可用于 \module*{toc} 路径中,表示章节标题目录标题代码钩子,如果是 \cls*{book} 模式则默认插入 \code{-1pc} 垂直距离。 \keyval{bibetween}{代码钩子} 与选项 \option{between} 类似,是英文章节标题目录(如果启用)标题代码钩子。 diff --git a/macros/latex/contrib/linearregression/README.txt b/macros/latex/contrib/linearregression/README.txt new file mode 100644 index 0000000000..5283d9b1b6 --- /dev/null +++ b/macros/latex/contrib/linearregression/README.txt @@ -0,0 +1,41 @@ +2024-06-10 +--------------------------------------------------------------------- +This file is ** README.txt ** for the ** linearregression ** package +--------------------------------------------------------------------- +Author: Battista Benciolini <benciolinibattista at gmail dot com> +--------------------------------------------------------------------- + +The package ** linearregression ** provides the definition of some +document-level commands (and some auxiliary functions) that perform +the linear regression on a set of data and present the data and +the results in tabular and in graphic form. + + *************************************************************** + *** The author would strongly appreciate to receive *** + *** any comment, criticism and just usage reports *** + *************************************************************** + +The expl3 syntax is used in the definition of most of +the commands and functions. + +The distribution includes: + README.txt (this file) + linearregression.dtx (a self extracting and self documenting file) + linearregressionpkg.ins (used to only extract the package) + linearregression.pdf (documentation) + +Running pdflatex linearregression.dtx generates: + linearregression.pfd (full documentation, three pass needed) + mainlinearregression.tex (interactive main-program document) + linearregression.sty (package) + sampledata.txt (as the name says) + +Running pdflatex linearregressionpkg.ins generates: linearregression.sty +(and linearregressionpkg.log) + +This program may be used, distributed and modified under +the conditions of the LaTeX Project Public License. +(see:http://www.latex-project.org/lppl.txt) + +===================== END of README file ====================== + diff --git a/macros/latex/contrib/linearregression/linearregression.dtx b/macros/latex/contrib/linearregression/linearregression.dtx new file mode 100644 index 0000000000..2eeea126f8 --- /dev/null +++ b/macros/latex/contrib/linearregression/linearregression.dtx @@ -0,0 +1,1235 @@ +%\iffalse +% file: linearregression.dtx +% author: Battista Benciolini +% contact: benciolinibattista at gmail dot com +% date: see preamble +% +% process this file with pdflatex to obtain: +% +% - linearregression.pfd (full documentation, three pass needed) +% - mainlinearregression.tex (interactive main-program document) +% - linearregression.sty (package) +% - sampledata.txt (as the name says) +% +% The author would strongly appreciate to receive +% any comment, criticism and just usage report +% +%\fi +%\iffalse +%<*ins> +\begingroup +\input docstrip.tex +\keepsilent +\preamble +------------------------------------------------------------------------ +[2024-06-10] +This file is part of the (expanded) distribution of linearregression +The author of linearregression is Battista Benciolini +<benciolinibattista at gmail dot com > +------------------------------------------------------------------------ +The author would strongly appreciate to receive +any comment, criticism and just usage report +------------------------------------------------------------------------ +This program may be used, distributed and modified under +the conditions of the LaTeX Project Public License. +(see: http://www.latex-project.org/lppl.txt) +------------------------------------------------------------------------ +\endpreamble +\askforoverwritefalse +\generate{\file{linearregression.sty}{\from{linearregression.dtx}{package}}} +\generate{\file{mainlinearregression.tex}{\from{linearregression.dtx}{main}}} +\nopreamble\nopostamble +\generate{\file{sampledata.txt}{\from{linearregression.dtx}{data}}} +\endgroup +%</ins> +%\fi +%\iffalse +%<*driver> +\documentclass[a4paper,10pt]{ltxdoc} +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage[lite,nobysame,non-compressed-cites]{amsrefs} +\usepackage{amsmath,amssymb,amsfonts} +\usepackage{multicol} +\usepackage{linearregression} +\usepackage{graphics} +\DeclareRobustCommand*{\Ars}{\textsf{% +\lower -.48ex\hbox{\rotatebox{-20}{A}}\kern -.3em{rs}}% +\discretionary{-}{}{\kern -.05em}\TeX\discretionary{-}{}{% +\kern -.17em}\lower -.357ex\hbox{nica}}% excerpt from some GUIT sty file +\NewDocumentCommand\vect{m}{\underline{#1}} % vector +\NewDocumentCommand\barycenter{m}{\overline{#1}} % barycenter +\NewDocumentCommand\point{}{\vect{y}} % point +\NewDocumentCommand\coeff{}{\vect{x}} % direction +\NewDocumentCommand\dx{}{\vect\delta} % direction variation +\NewDocumentCommand\vv{}{\vect{v}} % barycentric coordinates +\NewDocumentCommand\trasp{}{^{\mathsf{T}}} % traspose +\NewDocumentCommand\Renne{}{\mathbb{R}^n} % vector space +\NewDocumentCommand\dor{}{f} % distance from origin +\NewDocumentCommand\ipoint{}{i} % index for points +\NewDocumentCommand\pointsum{}{\sum_{\ipoint=1}^m} % sum over points +\NewDocumentCommand\reff{m}{(\ref{#1})} % ref in ( ) +\NewDocumentCommand\matr{m}{{#1}} % matrix +\NewDocumentCommand\mC{}{\matr{C}} % matrix C +\NewDocumentCommand\mc{}{k} % elements of matrix C +\NewDocumentCommand\mL{}{\matr{\Lambda}} % matrix lambda +\NewDocumentCommand\mX{}{\matr{X}} % matrix X +\NewDocumentCommand\spm{}{\phantom{-}} % space for the sign +\NewDocumentCommand\ctext{}{caption} % caption (a variable !) +\NewDocumentCommand\matrixtwotwo{mmmm}{ % | 2 x 2 +\begin{pmatrix} #1 & #2 \\ #3 & #4 \end{pmatrix}} % | matrix +\DeclareMathOperator\tr{tr} % trace +\DeclareMathOperator\sgn{sgn} % signum +\title{Linear regression with \LaTeX} +\author{Battista Benciolini} +\NewDocumentCommand\titleauthorfootnote{}{\begingroup% Not an elegant solution +\let\thefootnote\relax % but it is ok at the moment +\footnote{Linear regression with LaTeX - available in CTAN}% +\footnote{Battista Benciolini - contact: benciolinibattista at gmail dot com}% +\endgroup\setcounter{footnote}{0}}% +\parindent=0pt +\begin{document} +\hypersetup{hidelinks} +\maketitle +\titleauthorfootnote +\tableofcontents +\vfill +\DocInput{linearregression.dtx} +\end{document} +%</driver> +%\fi +% +% \section{Introduction: first description of the problem\label{intro}} +% I start with a quote from \Ars\ (April 2021, number 31, page 73): +% \begin{quotation} +% The physicist Mario Rossi is investigating a phenomenon, +% presumably linear, and he performs measurements in his laboratory +% to verify his hypothesis; he measures the quantity $x$ which generates +% the phenomenon and he measures also one of the characteristics +% $y$ showed by the phenomenon under the effect of the stimulation $x$. +% \\ ... \par +% Subsequently Mario graphs the data of the table to judge if the points +% reasonably follow a linear trend or not; in this regard he computes the +% parameters of the regression line and he draws this line on the graph +% in order to judge the quality of the obtained results. +% \\ ... \par +% Being a \LaTeX\ user, he thinks to kill two birds with one stone: +% using \LaTeX\ to draw the graph with the experimental data consisting +% in the $x$, $y$ points and, at the same time, to compute the +% parameter $a$ e $b$ of the regression line $y = ax+b$, +% and finally to draw also this line on the same graph. +% \end{quotation} +% A summary description of the the problem is therefore the following. +% A set of data pairs is available and each pair is represented as a point +% in the plain. A straight line is searched that optimally approximates +% the points. The first step is therefore the choice of an optimality criterion. +% This choice is the topic of the next section. \par +% From the text we also know that the possible deviation of $y$ +% with respect to the model is quite larger than the uncertainty of $x$. +% \par +% After reading the description of the problem +% of Mario Rossi I tried to produce a solution. +% In this work I will use $y_1$ and $y_2$ +% instead of $x$ and $y$ for the two measured quantities that +% will become the first and second coordinate, or abscissa and ordinate, +% in the Cartesian plane. +% \par +% The problem can be treated as a mere problem of approximation or +% alternatively as an estimation problem in the frame of a +% probabilistic description of the uncertainty. The two treatments are +% conceptually different. The probabilistic treatment produces some more +% results, but the estimation of the parameters is the same. +% On the other hand the treatment as an approximation problem is in some sense +% more immediate and requires a less extended theoretical background. +% For this reason it will be preferred here. +% I consider the original problem and also a variation +% of it based on the assumption that the two variables are known with +% the same uncertainty. The two considered situations will prove +% to be quite different. +% +% \section{Geometric definition of there optimality criteria} +% \begin{figure} +% \setlength\unitlength{4cm} +% \begin{picture}(1, 0.7)(0.,0.) +% \multiput(0.,0.)(1.1,0){3}{\line(1,0){1}} +% \multiput(0.,0.)(1.1,0){3}{\line(0,1){1}} +% \multiput(1,1)(1.1,0){3}{\line(-1,0){1}} +% \multiput(1,1)(1.1,0){3}{\line(0,-1){1}} +% \thicklines +% \multiput(0.08,0.06)(1.1,0){3}{\line(4,3){0.88}} +% \multiput(0.26,0.09)(1.1,0){3}{\circle{0.03}} +% \multiput(0.45,0.65)(1.1,0){3}{\circle{0.03}} +% \multiput(0.92,0.44)(1.1,0){3}{\circle{0.03}} +% \put(0.26,0.09){\line(0,1){0.1050}} +% \put(0.45,0.65){\line(0,-1){0.3125}} +% \put(0.92,0.44){\line(0,1){0.2500}} +% \put(1.36,0.09){\line(-1,0){0.14}} +% \put(1.55,0.65){\line( 1,0){0.4167}} +% \put(2.02,0.44){\line(-1,0){0.3333}} +% \put(2.46,0.09){\line(-3,4){0.05}} +% \put(2.65,0.65){\line(3,-4){0.15}} +% \put(3.12,0.44){\line(-3,4){0.12}} +% \end{picture} +% \caption{The three kinds of segments +% used in the definition of the objective function} +% \label{fig:criteria} +% \end{figure} +% For each point given in the plane we can consider the corresponding point +% with the same abscissa and belonging to the line. +% Remember that the line is exactly what has to be determined. +% The distance between the given point and the just defined point on the line +% is a reasonable measure of the discrepancy between the empirical data and the +% corresponding theoretical model. +% The distances we are speaking about are the length of the segments shown +% in the leftmost scheme of figure (\ref{fig:criteria}). +% To obtain a global discrepancy measure that considers all the points +% at once we perform the sum of the squares of the lengths +% of the mentioned segments. It is now clear that the two coordinates +% of the points are treated quite differently and play a different role in +% the definition of the optimality criterion. This choice is reasonable when +% the measuring errors only (or mainly) affect the second coordinate. +% The optimal line is the line that minimize the just defined +% global discrepancy. The procedure for the determination of the optimal line +% is named linear regression. +% In this work it is named \textit{classical linear regression}. +% We can easily exchange the role of the two quantities, i.e.\ we can +% imagine that the first quantity is affected by errors. +% The problem is not conceptually different. The segments plotted in the +% central picture +% of figure (\ref{fig:criteria}) represent the discrepancy between +% the empirical data and the model. +% This other procedure is named \textit{classical linear regression +% with inverted role of the coordinates}.\par +% The situation is really different if the two coordinates have to be treated +% symmetrically. +% In this case the discrepancy between +% the empirical data and the model must be defined in a purely geometrical way. +% Just the line and the points enter in the definition without any special role +% for any predefined direction. With these requirements it is quite natural +% to use the distance of each point from the line. +% Remember that the distance of a point +% from a line is intended along the shortest path, i.e.\ measured in the +% direction orthogonal to the line itself. The rightmost scheme of +% figure (\ref{fig:criteria}) shows the segments that are considered. +% The global measure of discrepancy is again obtained as the sum +% of the squares of the length of the mentioned orthogonal segments. +% The procedure that obtain the optimal line that +% minimize the just defined global discrepancy is named +% \textit{symmetrical linear regression}.\par +% Some arguments of the present section will be repeated in section +% \ref{package} from the algebraic and computational point of view. +% +% \section{General information on the proposed solution, including limitations} +% The code that implements the solution is recorded in two files, that are +% a package (sty) file and a main interactive document. +% The file |linearregression.sty| provides several commands +% that can be used in any document. The file |mainlinearregression.tex| +% provides a simple interactive user interface. +% The package described in the sections \ref{manual} and +% \ref{package} (user manual and implementation) provides the +% functions that execute the various needed operations, i.e.\ +% data input, computations, printing the numerical results and +% generating a graphic representation of data and results. +% Some auxiliary functions complete the package. +% The design of the output (tables and plots) includes some arbitrary choices. +% The style of the graphic output is quite minimalist +% (e.g.:\ no colors, no variations of line styles).\par +% +% \section{Some comments about the programming aspect of the package +% and its documentation} +% Large part of the code is written using the |expl3| language. +% (Is it also named simply L3 ? Does expl still means experimental ?) +% I have tried to be compliant with the various recommendations and +% prescriptions for a correct use of the language, +% but I probably only partly succeeded.\par +% Different more elegant and more coherent solutions probably exist +% both for the general structure of the package and for some specific part +% of the code, but this is what I have been able to do. +% Some perhaps problematic aspects are mentioned here after\par +% Several used variables are global and they are accessed by various functions. +% This makes the various parts of the package +% quite connected to each other and creates strong dependencies. \par +% The layered programming style is only partially applied. +% The partition between document command and lower level functions is present, +% but part of the low level code is directly in the document commands. +% Variants are not used.\par +% One more remarks concern the documentation. +% I was uncertain about the opportunity of using the class |l3doc|. I decided to +% remain using |ltxdoc|. This is the reason why I do not use the environment +% |macro| and the command |\cs| in the documentation of some auxiliary +% functions named according with the |expl3| standard. +% (I have just an interim far from optimal solution +% for a reasonable formatting.) +% +% \section{A ready to use simple user interface\label{main}} +% The main file asks the user for the name of a +% file containing the data and generates a one (or two) page output. +%\iffalse +%<*main> +%\fi +% \begin{macrocode} +\documentclass[a4paper]{article} +\usepackage{lmodern} +\usepackage{linearregression} +\begin{document} +\pagestyle{empty} +\lraskfilename +\lrcomputation +\lrplot{12.0}{+}{+}{-}{-} +\lrprint +\end{document} +% \end{macrocode} +%\iffalse +%</main> +%\fi +% +% \section{A user manual for the package\label{manual}} +% The various analysis of a data set and the representation of the data +% and of the results is obtained with a sequence of several commands. +% The main operations are: +% (i) selection of the data file, (ii) data imput and computation, +% (iii) printing of a table, +% (iv) printing of a picture (that can be repeated with different parameters). +% It is generally convenient to put the table and the picture(s) +% in a proper floating environment. +% The commands for the four mentioned operations are described here after. +% The first needed operation is to set the name of the data file. +% This is done with the command \DescribeMacro{\lrfilename} +% \cs{lrfilename}\marg{file} that has a mandatory argument. +% The argument is the name of the data file. As an alternative the +% command \DescribeMacro{\lraskfilename} \cs{lraskfilename} can be used. +% It asks the user to type the name of the data file in the terminal. +% \par +% The macro \DescribeMacro{\lrcomputation} +% \cs{lrcomputation} reads the data +% and performs all the computations. +% The results of the computations remain available in internal +% variables and are then used by the macro that print them +% or generates a plot. +%\par +% The macro \DescribeMacro{\lrprint} +% \cs{lrprint} generates a table with all the estimated +% parameters and some information about the data. +% \par +% The macro \DescribeMacro{\lrplot} +% \cs{lrplot}\marg{imagewidth}\marg{key1}\marg{key2}\marg{key3}\marg{key4} +% really generates the plot. The first argument is the +% width of the plot, while the height is computed according +% to the distribution of the points. The other four arguments are referred +% to the data points, to the lines determined with classical regression, +% with classical regression with inverted role of the coordinates and +% with symmetric regression. +% The four items, i.e.\ the set of points and the three lines, are drawn +% or not according to the corresponding character found in |key|$i$. +% Each item is not plotted if the character is a |-|, it is plotted in any other +% case. Furthermore the lines are accompanied by a label made by the +% corresponding |key|, unless it is just a |+|. +% \par +% Few words are necessary about the format of the data file. +% Each record of the file hold the two values related to a point. +% The two values must be separated by any number (one is needed as a minimum) of +% space and comma characters. No character different from space +% can be accepted before the first value and after the second value. +% +% \section{An example\label{example}} +% The data reported here after will be available in |sampledata.txt| +% and will be used in the example presented in this section . +%\iffalse +%<*data> +%\fi +% \begin{multicols}{4} +% \begin{macrocode} +-0.546 0.107 + 1.093 -0.510 + 1.440 1.995 + 1.414 0.991 + 0.735 1.585 +-1.848 -0.235 +-0.203 -0.292 + 1.517 0.779 + 0.559 -1.341 +-0.462 -0.437 +-0.785 -0.661 +-0.558 0.397 + 0.181 -2.616 + 0.619 1.859 +-0.223 -1.915 + 0.629 -0.534 +-1.989 -2.300 +-0.241 1.098 +-0.931 -1.613 +-1.070 0.592 + 2.341 0.413 + 1.993 -0.111 +-2.357 -0.312 +-1.975 0.140 +% \end{macrocode} +% \end{multicols} +%\iffalse +%</data> +%\fi +% +% The analysis of the sample data and the generation of a numeric table +% is operated by a code similar to the following +% (see table \ref{tab:sampledata}). \\ +% |\lrfilename{sampledata.txt}| \\ |\lrcomputation| \\ +% |\begin{table}| \\ +% | \lrprint| \\ +% | \caption{Analysis of ... }| \\ |\label{tab:sampledata}\end{table}| +% \par +% The generation of some different graphical representation of the data and of +% the results is operated by a code similar to the following +% (see figures \ref{fig:sampledataB} ).\\ +% \RenewDocumentCommand\ctext{}{LEFT The three lines are obtained with the three +% optimality criteria. (AA) classical linear regression; (BB) classical linear +% regression with inverted role of the coordinates; (S) symmetric linear +% regression. RIGHT Data points and line estimated with +% symmetric linear regression.} +% |\begin{figure}|\\|\lrplot{10.}{-}{AA}{BB}{S}| \\ +% |\lrplot{10.}{+}{-}{-}{+}| +% \\ |\caption{|\ctext|}|\\ | \label{fig:sampledataB} \end{figure}| +% +% \lrfilename{sampledata.txt} \lrcomputation +% \begin{table} \lrprint \caption{Analysis of the sample data} +% \label{tab:sampledata} \end{table} +% \begin{figure} \lrplot{6.}{-}{AA}{BB}{S} \hfill \lrplot{6.}{+}{-}{-}{+} +% \caption{\ctext} \label{fig:sampledataB} \end{figure} +% +% \section{A package for linear regression +% and the theory behind it\label{package}} +%\iffalse +%<*package> +%\fi +% +% \subsection{Math preliminaries and notation \label{prelim}} +% The coordinates of a set of $m$ points on the plane are available. +% A straight line is searched that optimally approximates the points.\par +% The coordinates of a generic point are $y_1$ and $y_2$ +% and they are collected in the vector $\point$. +% Any given point is identified with the index $\ipoint$. +% (Explicit indices $(\dots)_1$ or $(\dots)_2$ always refer to the first +% or second coordinate of a point or to the first or second component +% of a vector in the plane. +% Symbolic index $(\dots)\ipoint$ always refers to the different points. Few +% formulas require both indices $(\dots)_{1\ipoint}$, $(\dots)_{2\ipoint}$.)\par +% With more then two points a criterion of best approximation +% is needed to select the optimal line that describes the data. \par +% Lower case symbols are used for scalars. Lower case underlined +% symbols are used for vectors in the plane. Upper case symbols +% are used for matrices. +% \par +% It is possible that certain data generate an ambiguity or a singularity +% in the computation. +% The following mathematical treatment of the problem +% do not mention these situations and the code does not deal with them. +% +% \subsection{Package declaration, required package and definition of variables} +% The various macro will be provided in a package file +% that is introduced as usual. Most of the macros require +% the \LaTeX3 syntax. +% \begin{macrocode} +\ProvidesPackage{linearregression}[2024-06-10] +\RequirePackage{pict2e} +\ExplSyntaxOn +% \end{macrocode} +% The variables used in the package are defined hereafter. +% \begin{macrocode} +\ior_new:N \g_BBLR_file_ior +\tl_new:N \g_BBLR_file_name_tl +\int_new:N \g_BBLR_number_of_points_int +\fp_new:N \g_BBLR_abscissa_fp +\fp_new:N \g_BBLR_ordinate_fp +\fp_new:N \g_BBLR_mean_abscissa_fp +\fp_new:N \g_BBLR_mean_ordinate_fp +\fp_new:N \g_BBLR_abscissa_SecOrdMoment_fp +\fp_new:N \g_BBLR_ordinate_SecOrdMoment_fp +\fp_new:N \g_BBLR_mixed_SecOrdMoment_fp +\fp_new:N \g_BBLR_slope_A_fp +\fp_new:N \g_BBLR_slope_B_fp +\fp_new:N \g_BBLR_slope_S_fp +\fp_new:N \g_BBLR_intercept_A_fp +\fp_new:N \g_BBLR_intercept_B_fp +\fp_new:N \g_BBLR_intercept_S_fp +\fp_new:N \g_BBLR_cos_fp +\fp_new:N \g_BBLR_sin_fp +\fp_new:N \g_BBLR_sig_sin_fp +\fp_new:N \g_BBLR_eig_diff_fp +\fp_new:N \g_BBLR_diag_diff_fp +\tl_new:N \g_BBLR_file_line_tl +\fp_new:N \g_BBLR_min_abscissa_fp +\fp_new:N \g_BBLR_min_ordinate_fp +\fp_new:N \g_BBLR_max_abscissa_fp +\fp_new:N \g_BBLR_max_ordinate_fp +\fp_new:N \g_BBLR_min_draw_abscissa_fp +\fp_new:N \g_BBLR_max_draw_abscissa_fp +\bool_new:N \g_BBLR_data_eof_bool +\int_new:N \g_BBLR_record_length_int +\int_new:N \g_BBLR_rec_count_int +\int_new:N \g_BBLR_first_separator_int +\int_new:N \g_BBLR_last_separator_int +\str_const:Nn \c_BBLR_space_str {~} +\str_const:Nn \c_BBLR_comma_str {,} +\str_const:Nn \c_BBLR_plus_str {+} +\str_const:Nn \c_BBLR_minus_str {-} +\bool_new:N \g_BBLR_plot_points_bool +\bool_new:N \g_BBLR_plot_lineA_bool +\bool_new:N \g_BBLR_plot_lineB_bool +\bool_new:N \g_BBLR_plot_lineS_bool +\fp_new:N \g_BBLR_base_fp +\fp_new:N \g_BBLR_height_fp +\fp_new:N \g_BBLR_Xbase_fp +\fp_new:N \g_BBLR_Xheight_fp +\fp_new:N \g_BBLR_Dabscissa_fp +\fp_new:N \g_BBLR_Dordinate_fp +\fp_new:N \g_BBLR_diameter_fp +\fp_gset:Nn \g_BBLR_diameter_fp{0.2} +\fp_new:N \g_BBLR_line_base_length_fp +\fp_new:N \g_BBLR_scale_factor_fp +\str_new:N \c_BBLR_point_code_str +\str_new:N \g_BBLR_labelA_str +\str_new:N \g_BBLR_labelB_str +\str_new:N \g_BBLR_labelS_str +% \end{macrocode} +% +% \subsection{Preparing data input} +% \begin{macro}{\lrfilename} +% The command \cs{lrfilename} records the file name passed as argument. +% \begin{macrocode} +\NewDocumentCommand{\lrfilename}{m}{ +\tl_gset:Nn \g_BBLR_file_name_tl {#1} +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\lraskfilename} +% The command \cs{lraskfilename} asks for the data file name from the terminal. +% \begin{macrocode} +\NewDocumentCommand{\lraskfilename}{}{ +\ior_get_term:nN {filename ? } \g_BBLR_file_name_tl +\tl_trim_spaces:N \g_BBLR_file_name_tl +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Main command declaration, computation of +% first and second order moments} +% \begin{macro}{\lrcomputation} +% The command \cs{lrcomputation} reads the data file and +% performs all the relevant computations to solve the +% proposed problem. +% \begin{macrocode} +\NewDocumentCommand{\lrcomputation}{}{% +% \end{macrocode} +% +% In the sequel it will results that the first and second order moments +% of the data provide everything needed to solve the problem. +% The barycenter of the data is defined as +% \begin{equation} +% \barycenter{\point}=\frac{1}{m}\pointsum \point_\ipoint. +% \label{barycenter} \end{equation} +% It is convenient to scan the data to accumulate the sum +% that appears in \reff{barycenter}. +% The coordinates of each point are read from the file +% and they are immediately used. +% It is therefore not necessary to globally record the data. +% \begin{macrocode} +\bool_gset_false:N \g_BBLR_data_eof_bool +\int_zero:N \g_BBLR_number_of_points_int +\fp_zero:N \g_BBLR_mean_abscissa_fp +\fp_zero:N \g_BBLR_mean_ordinate_fp +\ior_open:Nn \g_BBLR_file_ior \g_BBLR_file_name_tl +\bool_until_do:Nn \g_BBLR_data_eof_bool { + \ior_str_get:NN \g_BBLR_file_ior \g_BBLR_file_line_tl + \if_eof:w \g_BBLR_file_ior + \bool_gset_true:N \g_BBLR_data_eof_bool + \else: + \int_incr:N \g_BBLR_number_of_points_int + \BBLR_decode_data: + \fp_gset:Nn \g_BBLR_mean_abscissa_fp + {\g_BBLR_mean_abscissa_fp + \g_BBLR_abscissa_fp} + \fp_gset:Nn \g_BBLR_mean_ordinate_fp + {\g_BBLR_mean_ordinate_fp + \g_BBLR_ordinate_fp} + \fi: +} +% \end{macrocode} +% Loop ended. Now close the file and divide by the number of points. +% \begin{macrocode} +\ior_close:N \g_BBLR_file_ior +\fp_gset:Nn \g_BBLR_mean_abscissa_fp +{\g_BBLR_mean_abscissa_fp / \g_BBLR_number_of_points_int} +\fp_gset:Nn \g_BBLR_mean_ordinate_fp +{\g_BBLR_mean_ordinate_fp / \g_BBLR_number_of_points_int} +% \end{macrocode} +% +% The barycentric coordinates are defined for each point +% \begin{equation} \vv_\ipoint= \point_\ipoint - \barycenter{\point} +% \label{residual} \end{equation} +% and the empirical dispersion matrix is defined as: +% \begin{equation} \mC=\frac{1}{m}\pointsum \vv_\ipoint\vv_\ipoint\trasp . +% \label{matrixC} \end{equation} +% Superscript as in $()\trasp$ means transpose. The elements of $\mC$ are the +% second order central moments and they are denoted as: +% \begin{equation} \mC=\matrixtwotwo{\mc_{11}}{\mc_{12}}{\mc_{12}}{\mc_{22}}. +% \label{matrixCc} \end{equation} +% A second scan of the data is performed to compute the +% sums that appears in \reff{matrixC} and to determine the +% the extremal values of the coordinates. Record scan can be regulated +% by a record counter, because the the number of points is now known. +% \begin{macrocode} +\fp_zero:N \g_BBLR_abscissa_SecOrdMoment_fp +\fp_zero:N \g_BBLR_ordinate_SecOrdMoment_fp +\fp_zero:N \g_BBLR_mixed_SecOrdMoment_fp +\fp_gset_eq:NN \g_BBLR_min_abscissa_fp \g_BBLR_mean_abscissa_fp +\fp_gset_eq:NN \g_BBLR_min_ordinate_fp \g_BBLR_mean_ordinate_fp +\fp_gset_eq:NN \g_BBLR_max_abscissa_fp \g_BBLR_mean_abscissa_fp +\fp_gset_eq:NN \g_BBLR_max_ordinate_fp \g_BBLR_mean_ordinate_fp +\ior_open:Nn \g_BBLR_file_ior \g_BBLR_file_name_tl +\int_zero:N \g_BBLR_rec_count_int +\int_do_until:nn +{\g_BBLR_rec_count_int = \g_BBLR_number_of_points_int} +{ + \ior_str_get:NN \g_BBLR_file_ior \g_BBLR_file_line_tl + \int_incr:N \g_BBLR_rec_count_int + \BBLR_decode_data: + \fp_gset:Nn \g_tmpa_fp + {\g_BBLR_abscissa_fp - \g_BBLR_mean_abscissa_fp} + \fp_gset:Nn \g_tmpb_fp + {\g_BBLR_ordinate_fp - \g_BBLR_mean_ordinate_fp} + \fp_gset:Nn \g_BBLR_abscissa_SecOrdMoment_fp + {\g_BBLR_abscissa_SecOrdMoment_fp + \g_tmpa_fp * \g_tmpa_fp} + \fp_gset:Nn \g_BBLR_mixed_SecOrdMoment_fp + {\g_BBLR_mixed_SecOrdMoment_fp + \g_tmpa_fp * \g_tmpb_fp} + \fp_gset:Nn \g_BBLR_ordinate_SecOrdMoment_fp + {\g_BBLR_ordinate_SecOrdMoment_fp + \g_tmpb_fp * \g_tmpb_fp} +\fp_gset:Nn \g_BBLR_min_abscissa_fp +{min(\g_BBLR_min_abscissa_fp, \g_BBLR_abscissa_fp)} +\fp_gset:Nn \g_BBLR_min_ordinate_fp +{min(\g_BBLR_min_ordinate_fp, \g_BBLR_ordinate_fp)} +\fp_gset:Nn \g_BBLR_max_abscissa_fp +{max(\g_BBLR_max_abscissa_fp, \g_BBLR_abscissa_fp)} +\fp_gset:Nn \g_BBLR_max_ordinate_fp +{max(\g_BBLR_max_ordinate_fp, \g_BBLR_ordinate_fp)} +} +\ior_close:N \g_BBLR_file_ior +\fp_gset:Nn \g_BBLR_abscissa_SecOrdMoment_fp +{\g_BBLR_abscissa_SecOrdMoment_fp / \g_BBLR_number_of_points_int} +\fp_gset:Nn \g_BBLR_mixed_SecOrdMoment_fp +{\g_BBLR_mixed_SecOrdMoment_fp / \g_BBLR_number_of_points_int} +\fp_gset:Nn \g_BBLR_ordinate_SecOrdMoment_fp +{\g_BBLR_ordinate_SecOrdMoment_fp / \g_BBLR_number_of_points_int} +\fp_gset:Nn \g_BBLR_Dabscissa_fp +{\g_BBLR_max_abscissa_fp - \g_BBLR_min_abscissa_fp } +\fp_gset:Nn \g_BBLR_Dordinate_fp +{\g_BBLR_max_ordinate_fp - \g_BBLR_min_ordinate_fp } +% \end{macrocode} +% A single pass algorithm exists, but it is numerically less stable. +% +% \subsection{Classical linear regression \label{classical}} +% A line in the plane is described by the equation +% \begin{equation} y_2=ay_1+b \label{eqab} \end{equation} +% that contains the parameters $a$ and $b$. +% For each point it is possible to define a distance or a discrepancy +% of the experimental data with respect to the model. +% In the given problem the second coordinate is much more affected by +% errors than the first coordinate. It is therefore reasonable +% to define the approximation error of each point as +% \begin{equation} e_\ipoint=y_{2\ipoint}-ay_{1\ipoint}-b +% \label{e}\end{equation} +% i.e.\ the difference between the empirical value $y_{2\ipoint}$ +% and its model counterpart $ay_{1\ipoint}+b$. +% The global discrepancy between the data and the model is measured by the +% least square objective function defined by: +% \begin{equation} \psi=\pointsum e_\ipoint^2 \label{psiab} \end{equation} +% and the parameters $a$ and $b$ will be determined +% just by the minimization of the function $\psi$ defined in \reff{psiab}. +% \par +% In the present treatment of the regression problem as a pure +% approximation problem the definition of $\psi$ in \reff{psiab} +% seams quite arbitrary. It is anyway a convenient choice. +% \par +% Expression \reff{e} can be rewritten in the different form +% \begin{equation} +% e_\ipoint=v_{2\ipoint}-av_{1\ipoint}+\barycenter{y}_2-a\barycenter{y}_1-b +% \label{e2}\end{equation} +% so that the function to be minimized can be expressed +% as the sum of two quadratic functions: +% \begin{equation} +% \psi= +% \pointsum (v_{2\ipoint}-av_{1\ipoint})^2+ +% m(\barycenter{y}_2-a\barycenter{y}_1-b)^2 +% \label{psiab2} \end{equation} +% and the minimum can be attained considering +% the two terms one at a time. +% The second term in the right-hand side of \reff{psiab2} +% vanishes if the choice of $b$ is: +% \begin{equation} b=\barycenter{y}_2-a\barycenter{y}_1. +% \label{estb} \end{equation} +% The first term in the right-hand side of \reff{psiab2} becomes: +% \begin{equation} \psi_{(a)}=m\left(\mc_{22}-2a\mc_{12}+a^2\mc_{11}\right). +% \label{parabola} \end{equation} +% Searching the minimum of $\psi$ w.r.t.\ $a$ is therefore the search +% of the abscissa of the vertex of a parabola +% with axis parallel to the second coordinated axis. +% The result is: +% \begin{equation} a=\mc_{12}/\mc_{11} +% \label{esta} \end{equation} +% Now the slope $a$ and the intercept $b$ can be actually computed. +% \begin{macrocode} +\fp_gset:Nn \g_BBLR_slope_A_fp +{\g_BBLR_mixed_SecOrdMoment_fp / \g_BBLR_abscissa_SecOrdMoment_fp } +\fp_gset:Nn \g_BBLR_intercept_A_fp +{\g_BBLR_mean_ordinate_fp - \g_BBLR_slope_A_fp * \g_BBLR_mean_abscissa_fp} +% \end{macrocode} +% \par +% The empirical data and the estimated values of $a$ and $b$ +% can be used to compute +% the value actually attained by the residuals $e_\ipoint$ and +% by the function $\psi$. Then the index +% \begin{equation} \hat\sigma_0^2=\psi/(m-2)\end{equation} +% can be used to evaluate the general quality of the data and of the model. +% This claim is clearly quite generic. A complete understanding +% of this evaluation would require to treat the linear regression +% problem in the framework of the probabilistic estimation theory. +% The used notation is derived from that theory.\par +% If the role of the two coordinates is exchanged the result +% for $a$ becomes (still with reference to \reff{eqab}) +% \begin{equation} a=\mc_{22}/\mc_{12}.\end{equation} +% A complete treatment of this different situation would include +% the redefinition of $e_\ipoint$ and of $\psi$. +% The slope and the intercept can be computed according with +% the different assumption. +% \begin{macrocode} +\fp_gset:Nn \g_BBLR_slope_B_fp +{\g_BBLR_ordinate_SecOrdMoment_fp / \g_BBLR_mixed_SecOrdMoment_fp} +\fp_gset:Nn \g_BBLR_intercept_B_fp +{\g_BBLR_mean_ordinate_fp - \g_BBLR_slope_B_fp * \g_BBLR_mean_abscissa_fp} +% \end{macrocode} +% +% \subsection{Symmetric linear regression \label{symmetric}} +% If both the coordinates of the experimental points are affected +% by the same uncertainty it is advisable to use a more symmetric +% optimality criterion and it is convenient to use a different model equation. +% \par +% The same line can be described by a different equation, i.e.\ +% \begin{equation} x_1y_1+x_2y_2=\dor \end{equation} +% or in vector form: +% \begin{equation} \coeff\trasp\point=\dor. \label{eqvx} \end{equation} +% The parameters in \reff{eqvx} +% are the scalar $\dor$ and the elements +% of the vector $\coeff$, i.e.\ $x_1$ and $x_2$. +% The line described by \reff{eqvx} is obviously +% invariant when the three parameters are simultaneously +% scaled by a constant. The normalization condition +% \begin{equation} \coeff\trasp\coeff=1, \label{norm} \end{equation} +% supplemented by $\dor\ge 0$, +% is quite convenient because the parameters will assume +% a significant geometrical meaning: +% $\coeff$ is the unit vector orthogonal to the line and $\dor$ +% is the distance of the line from the origin. +% The expression +% \begin{equation} d=\dor-\coeff\trasp\point \label{distance} \end{equation} +% is the distance of the generic point $\point$ from the line +% with a sign that is positive for points on the same side of the origin. +% \par +% The distance of each given point from the desired optimal line +% is denoted by $d_\ipoint$. +% It has a clear intrinsic geometrical meaning and it does not +% privileges one coordinate w.r.t.\ the other. +% The function to be minimized by the optimal line is +% \begin{equation} +% \phi=\frac{1}{m}\pointsum d_\ipoint^2. \label{phi1} \end{equation} +% The parameters of \reff{eqvx} are determined by the minimization +% of the function $\phi$ that can be expressed as: +% \begin{equation} +% \phi=\frac{1}{m}\pointsum (\coeff\trasp\point_{\ipoint}-\dor)^{2} +% \label{phi2} \end{equation} +% and then, after some algebraic manipulations: +% \begin{equation} +% \phi=\coeff\trasp\mC\coeff+(\dor-\coeff\trasp\barycenter{\point})^2 +% \label{phi3}. \end{equation} +% The function $\phi$ is composed (as it was the function $\psi$) by the sum +% of two parts. The second term in the right-hand side of \reff{phi3} +% vanishes if the choice of $\dor$ is: +% \begin{equation} \dor=\coeff\trasp\barycenter{\point}. +% \label{estd} \end{equation} +% Then it is necessary to minimize the function +% \begin{equation} \phi_{(\coeff)} = \coeff\trasp\mC\coeff +% \label{quadraticfun} \end{equation} +% with the constrain $\coeff\trasp\coeff=1$. +% It can be proved that the function $\phi_{(\coeff)}$ +% is stationary if $\coeff$ is an eigenvector of \mC. \par +% The function $\phi_{(\coeff)}$ and the constrain must be combined +% using a Lagrange multiplier: +% \begin{equation} +% \Phi= \coeff\trasp\mC\coeff+\lambda(1-\coeff\trasp\coeff). +% \label{Phi} \end{equation} +% Then the stationarity points of $\Phi$ must be determined. +% Equating to zero the derivatives of $\Phi$ gives +% \begin{equation} +% \mC\coeff=\lambda\coeff +% \label{auto} \end{equation} +% i.e.\ $\coeff$ is an eigenvector of $\mC$. \par +% The same result is obtained with the following argument. +% The function $\phi_{(\coeff)}$ is stationary if its first variation +% is zero. The variation of $\coeff$ is named $\dx$ . +% It must respect the constrain, that becomes $\dx\trasp\coeff=0$. +% The first variation of $\phi_{(\coeff)}$ is $2\dx\trasp\mC\coeff$, +% and it is zero if and only if the following implication is valid: +% $\dx\trasp\coeff=0 \implies \dx\trasp\mC\coeff=0$, +% and the implication is valid if and only if the vector +% $\mC\coeff$ has the same direction of $\coeff$, i.e.\ if +% $\coeff$ is an eigenvector of $\mC$. +% \par +% The result on the optimal line +% can be described geometrically in the following way: +% (i) the optimal line includes the barycenter of the data; +% (ii) the optimal line is orthogonal to the eigenvector of +% $\mC$ corresponding to the minimum eigenvalue.\par +% The obtained result is also valid in $\Renne$. +% A set of points in $\Renne$ must be approximated by an $(n-1)$-dimensional +% affine subspace. (Other more general situations can be considered.) +% \par +% The trace of the matrix $\mC$, denoted as $\tr(\mC)$, is a measure of the +% global dispersion of the set of points. +% The minimum eigenvalue $\lambda_{\textrm{min}}$ of $\mC$ is a measure +% of the dispersion of the set of points with +% respect to the optimal affine subspace. Therefore the index +% \begin{equation} \frac{n\lambda_{\textrm{min}}}{\tr(\mC)} +% \end{equation} +% can be used as an indicator of the relative residual +% dispersion of the data around the optimal line. +% The defined index is dimensionless and it is +% always between $0$ and $1$. +% \par +% For the actual computation of $\coeff$ it is convenient to consider +% the spectral factorization of the matrix $\mC$, i.e.\ +% $\mC=\mX\mL\mX\trasp$ where $\mL$ is a diagonal matrix +% whose diagonal elements are the eigenvalues of $\mC$ +% and $\mX$ is an orthonormal matrix whose columns are +% the eigenvectors of $\mC$. The spectral factorization exists +% for any symmetric matrix, but it is specially simple for +% a $2\times 2$ matrix. +% \begin{equation} +% \matrixtwotwo{\mc_{11}}{\mc_{12}}{\mc_{12}}{\mc_{22}}= +% \matrixtwotwo{c}{-s}{s}{\spm c} +% \matrixtwotwo{\lambda_1}{0}{0}{\lambda_2} +% \matrixtwotwo{\spm c}{s}{-s}{c} +% \label{spectral}\end{equation} +% The eigenvalues can be easily obtained because +% their sum is the trace of $\mC$ +% \begin{equation} +% \lambda_1 + \lambda_2 = \mc_{11}+\mc_{22} +% \label{Sum}\end{equation} +% and their product +% is the determinant of the same matrix. +% Therefore after some manipulations it results: +% \begin{equation} +% \lambda_1 - \lambda_2 = \sqrt{(\mc_{11}-\mc_{22})^2+4\mc_{12}^2} +% \label{Difference}\end{equation} +% and the two eigenvalues are then immediately obtained. \par +% It is convenient to compute the difference of the two diagonal elements +% of the dispersion matrix and the difference of its eigenvalues. +% \begin{macrocode} +\fp_gset:Nn \g_BBLR_diag_diff_fp +{\g_BBLR_abscissa_SecOrdMoment_fp - \g_BBLR_ordinate_SecOrdMoment_fp} +\fp_gset:Nn \g_BBLR_eig_diff_fp +{sqrt(\g_BBLR_diag_diff_fp * \g_BBLR_diag_diff_fp + + 4 * \g_BBLR_mixed_SecOrdMoment_fp * \g_BBLR_mixed_SecOrdMoment_fp)} +% \end{macrocode} +% The computation of $c$ and $s$ is obtained from \reff{spectral} +% taking into account that $c^2+s^2=1$. +% From \reff{spectral} it results: +% \begin{equation} \mc_{11}-\mc_{22}=(\lambda_1-\lambda_2)(c^2-s^2) +% \label{Cos2A}\end{equation} +% and also +% \begin{equation} \mc_{12}=(\lambda_1-\lambda_2)cs +% \label{Sin2A}\end{equation} +% that is only used to determine the sign of $cs$. +% The expression for the parameters $c$ and $s$ are: +% \begin{equation} +% c=\sqrt{\frac{1}{2}+\frac{\mc_{11}-\mc_{22}}{2(\lambda_1-\lambda_2)}} +% \label{cos}\end{equation} +% \begin{equation} +% s=\sgn(\mc_{12}) +% \sqrt{\frac{1}{2}-\frac{\mc_{11}-\mc_{22}}{2(\lambda_1-\lambda_2)}} +% \label{sin}\end{equation} +% The parameters $s$ and $c$ are the sine and cosine +% of the angle between the axis of $y_1$ and the eigenvector +% corresponding to the maximum eigenvalue. \par +% They are computed using the already defined elements. +% \begin{macrocode} +\fp_gset:Nn \g_BBLR_cos_fp% +{sqrt((1 + \g_BBLR_diag_diff_fp / \g_BBLR_eig_diff_fp) / 2)} +\fp_gset:Nn \g_BBLR_sig_sin_fp {\fp_sign:n {\g_BBLR_mixed_SecOrdMoment_fp}} +\fp_gset:Nn \g_BBLR_sin_fp +{\g_BBLR_sig_sin_fp*sqrt((1-\g_BBLR_diag_diff_fp / \g_BBLR_eig_diff_fp) / 2)} +% \end{macrocode} +% The vector $\coeff$ is : +% \begin{equation} +% \coeff=\sgn(-s\barycenter{y}_1+c\barycenter{y}_2) +% \begin{pmatrix} -s \\ c\end{pmatrix}. +% \label{xhat}\end{equation} +% +%\par +% The parameter $a$ of model \reff{eqab} can be obtained as: +% \begin{equation} +% a=s/c +% \end{equation} +% Now the slope and the intercept of the optimal line corresponding to the +% symmetric criterion can be computed. +% +% \begin{macrocode} +\fp_gset:Nn \g_BBLR_slope_S_fp +{\g_BBLR_sin_fp / \g_BBLR_cos_fp } +\fp_gset:Nn \g_BBLR_intercept_S_fp +{\g_BBLR_mean_ordinate_fp - \g_BBLR_slope_S_fp * \g_BBLR_mean_abscissa_fp} +} +% \end{macrocode} +% +% The theoretical treatment of the proposed problem and the +% implementation of its numerical solution end here. +% \end{macro} +% +% \subsection{Print of table of results} +% \begin{macro}{\lrprint} +% The command \cs{lrprint} prints some info on the data +% and the results of the computations in tabular form. +% \begin{macrocode} +\NewDocumentCommand{\lrprint}{}{ +\begin{center} +\begin{tabular}{| l | r |} \hline + Data~File: & \g_BBLR_file_name_tl \\ \hline + Number~of~points: & \int_use:N\g_BBLR_number_of_points_int \\ \hline + Mean~values~of~the~coordinates: &% + $\fp_use:N \g_BBLR_mean_abscissa_fp$ \\ & + $\fp_use:N \g_BBLR_mean_ordinate_fp$ \\ \hline + Minimum~values~of~the~coordinates: &% + $\fp_use:N \g_BBLR_min_abscissa_fp$ \\ & + $\fp_use:N \g_BBLR_min_ordinate_fp$ \\ \hline + Maximum~values~of~the~coordinates: &% + $\fp_use:N \g_BBLR_max_abscissa_fp$ \\ & + $\fp_use:N \g_BBLR_max_ordinate_fp$ \\ \hline + {Second~order~moments}\phantom{xxxxxxxxx}{abscissa} &% + $\fp_use:N \g_BBLR_abscissa_SecOrdMoment_fp$ \\ + \multicolumn{1}{|r|}{mixed} & % +$\fp_use:N \g_BBLR_mixed_SecOrdMoment_fp$ ~ \\ +\multicolumn{1}{|r|}{ordinate} & % +$\fp_use:N \g_BBLR_ordinate_SecOrdMoment_fp$ \\ \hline + Slope~and~intercept~of~optimal~line & $\fp_use:N \g_BBLR_slope_A_fp$ \\ + (estimated~with~errors~in~ordinate)&$\fp_use:N \g_BBLR_intercept_A_fp$\\ \hline + Slope~and~intercept~of~optimal~line & $\fp_use:N \g_BBLR_slope_B_fp$ \\ + (estimated~with~errors~in~abscissa)&$\fp_use:N \g_BBLR_intercept_B_fp$\\ \hline + Components~of~unit~vector~along~the~line & $\fp_use:N \g_BBLR_cos_fp$ \\ + & $\fp_use:N \g_BBLR_sin_fp$ \\ + Slope~and~intercept~of~optimal~line &$\fp_use:N \g_BBLR_slope_S_fp$ \\ +(estimated~with~symmetric~regression) & + $\fp_use:N \g_BBLR_intercept_S_fp$\\ \hline +\end{tabular} +\end{center} +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Plot of points and lines} +% \begin{macro}{\lrplot} +% The command \cs{lrplot} produce a framed plot of the data +% and of the regression line(s). The size of the plot and its actual +% content are determined by the arguments. +% \begin{macrocode} +\NewDocumentCommand{\lrplot}{mmmmm}{% +% \end{macrocode} +% The plotting area is divided into a main plotting area for +% the representation of points and line(s) and a small surrounding free space. +% The height is computed taking into account the distribution of the points. +% \begin{macrocode} +\fp_gset:Nn \g_BBLR_base_fp {#1} +\fp_gset:Nn \g_BBLR_Xbase_fp {\g_BBLR_base_fp - 0.6} +\fp_gset:Nn \g_BBLR_scale_factor_fp{\g_BBLR_Xbase_fp / \g_BBLR_Dabscissa_fp} +\fp_gset:Nn \g_BBLR_Xheight_fp {\g_BBLR_Dordinate_fp * \g_BBLR_scale_factor_fp} +\fp_gset:Nn \g_BBLR_height_fp {\g_BBLR_Xheight_fp + 0.6} +% \end{macrocode} +% The information about the items to be plotted is in the remaining arguments. +% \begin{macrocode} +\str_gset:Nn \g_BBLR_point_code_str {#2} +\str_gset:Nn \g_BBLR_labelA_str {#3} +\str_gset:Nn \g_BBLR_labelB_str {#4} +\str_gset:Nn \g_BBLR_labelS_str {#5} +\bool_gset:Nn \g_BBLR_plot_points_bool +{!(\str_if_eq_p:NN \g_BBLR_point_code_str \c_BBLR_minus_str)} +\bool_gset:Nn \g_BBLR_plot_lineA_bool +{!(\str_if_eq_p:NN \g_BBLR_labelA_str \c_BBLR_minus_str)} +\bool_gset:Nn \g_BBLR_plot_lineB_bool +{!(\str_if_eq_p:NN \g_BBLR_labelB_str \c_BBLR_minus_str)} +\bool_gset:Nn \g_BBLR_plot_lineS_bool +{!(\str_if_eq_p:NN \g_BBLR_labelS_str \c_BBLR_minus_str)} +% \end{macrocode} +% The unit of length is $1$ centimeter. The plotting area is framed. +% \begin{macrocode} +\setlength{\unitlength}{1.0cm} +\fp_gset:Nn \g_tmpa_fp {\g_BBLR_Xbase_fp +0.2} +\fp_gset:Nn \g_tmpb_fp {\g_BBLR_Xheight_fp +0.1} +\begin{picture}(\fp_use:N\g_BBLR_base_fp,\fp_use:N\g_BBLR_height_fp)(-0.3,-0.3) +\put(-0.1,-0.1){\line(1,0){\fp_use:N\g_tmpa_fp}} +\put(-0.1,\fp_use:N\g_tmpb_fp){\line(1,0){\fp_use:N\g_tmpa_fp}} +\fp_gset:Nn \g_tmpa_fp {\g_tmpa_fp -0.1} +\fp_gset:Nn \g_tmpb_fp {\g_tmpb_fp +0.1} +\put(-0.1,-0.1){\line(0,1){\fp_use:N\g_tmpb_fp}} +\put(\fp_use:N\g_tmpa_fp,-0.1){\line(0,1){\fp_use:N\g_tmpb_fp}} +% \end{macrocode} +% The plot of points and line(s) is obtained using auxiliary functions. +% \begin{macrocode} +\thicklines +\bool_if:nT {\g_BBLR_plot_points_bool}{\BBLR_plot_points:} +\bool_if:nT {\g_BBLR_plot_lineA_bool}{ +\BBLR_draw_line:NNN \g_BBLR_slope_A_fp\g_BBLR_intercept_A_fp\g_BBLR_labelA_str} +\bool_if:nT {\g_BBLR_plot_lineB_bool}{ +\BBLR_draw_line:NNN \g_BBLR_slope_B_fp\g_BBLR_intercept_B_fp\g_BBLR_labelB_str} +\bool_if:nT {\g_BBLR_plot_lineS_bool}{ +\BBLR_draw_line:NNN \g_BBLR_slope_S_fp\g_BBLR_intercept_S_fp\g_BBLR_labelS_str} +\end{picture} +}% +% \end{macrocode} +% \end{macro} +% +% \subsection{Functions for internal use} +% The functions listed here after are for internal +% use and are just minimally documented. \par +% The function |\BBLR_decode_data:| +% \marginpar{\raggedleft\texttt{ +% \textbackslash{}BBLR\textunderscore{}decode\textunderscore{}data:}} +% extract two numeric values from the string read from the file. +% Some tricky actions are necessary because +% a so called csv file sometime do not contains the separating commas. +% \begin{macrocode} +\cs_new_protected:Nn \BBLR_decode_data: { +\tl_trim_spaces:N \g_BBLR_file_line_tl +\int_gzero:N \g_tmpa_int +\int_gzero:N \g_BBLR_first_separator_int +\int_gzero:N \g_BBLR_last_separator_int +\int_gset:Nn \g_BBLR_record_length_int { +\str_count:N \g_BBLR_file_line_tl} +\str_map_variable:NNn \g_BBLR_file_line_tl \g_tmpa_str { +\int_gincr:N \g_tmpa_int +\bool_lazy_or:nnTF +{\str_if_eq_p:NN \g_tmpa_str \c_BBLR_comma_str} +{\str_if_eq_p:NN \g_tmpa_str \c_BBLR_space_str} +{\int_gset_eq:NN \g_BBLR_last_separator_int \g_tmpa_int +\int_if_zero:nTF {\g_BBLR_first_separator_int} +{\int_gset_eq:NN \g_BBLR_first_separator_int \g_tmpa_int +}{\prg_do_nothing:} +}{\prg_do_nothing:} +} +\int_gincr:N \g_BBLR_last_separator_int +\int_gdecr:N \g_BBLR_first_separator_int +\fp_gset:Nn \g_BBLR_abscissa_fp{ +\str_range:Nnn \g_BBLR_file_line_tl{1}{\g_BBLR_first_separator_int}} +\fp_gset:Nn \g_BBLR_ordinate_fp{ +\str_range:Nnn \g_BBLR_file_line_tl +{\g_BBLR_last_separator_int}{\g_BBLR_record_length_int}} +} +% \end{macrocode} +% The function |\BBLR_plot_points:| \marginpar{\raggedleft\texttt{ +% \textbackslash{}BBLR\textunderscore{}plot\textunderscore{}points:}} +% scans the data file to read the coordinates and +% it draws a circle for each point. +% +% \begin{macrocode} +\cs_new_protected:Nn \BBLR_plot_points: { +\ior_open:Nn \g_BBLR_file_ior \g_BBLR_file_name_tl +\int_zero:N \g_BBLR_rec_count_int +\int_do_until:nn +{\g_BBLR_rec_count_int = \g_BBLR_number_of_points_int} +{ + \ior_str_get:NN \g_BBLR_file_ior \g_BBLR_file_line_tl + \int_incr:N \g_BBLR_rec_count_int + \BBLR_decode_data: + \fp_gset:Nn \g_tmpa_fp{(\g_BBLR_abscissa_fp-\g_BBLR_min_abscissa_fp)* + \g_BBLR_scale_factor_fp} + \fp_gset:Nn \g_tmpb_fp{(\g_BBLR_ordinate_fp-\g_BBLR_min_ordinate_fp)* + \g_BBLR_scale_factor_fp} + \put(\fp_use:N\g_tmpa_fp, \fp_use:N\g_tmpb_fp){ + {\circle*{\fp_use:N\g_BBLR_diameter_fp}}} +} +\ior_close:N \g_BBLR_file_ior +} +% \end{macrocode} +% The function |\BBLR_draw_line:NNN| \marginpar{\raggedleft\texttt{ +% \textbackslash{}BBLR\textunderscore{}draw\textunderscore{}line:NNN}} +% draws the line. The first two parameters given as arguments +% are the slope and the intercept. The third parameter is a label. +% \par The next code finds the intersection of the line with the plotting area. +% \begin{macrocode} +\cs_new_protected:Nn \BBLR_draw_line:NNN { +\fp_gset:Nn \fp_tmpa_fp {#1 * \g_BBLR_min_abscissa_fp + #2 } +\fp_compare:nTF{\fp_tmpa_fp > \g_BBLR_max_ordinate_fp}{ +\fp_gset:Nn \g_BBLR_min_draw_abscissa_fp {(\g_BBLR_max_ordinate_fp -#2) / #1} +}{ +\fp_compare:nTF{\fp_tmpa_fp < \g_BBLR_min_ordinate_fp}{ +\fp_gset:Nn \g_BBLR_min_draw_abscissa_fp {(\g_BBLR_min_ordinate_fp - #2) / #1} +}{ +\fp_gset:Nn \g_BBLR_min_draw_abscissa_fp { \g_BBLR_min_abscissa_fp } +}} +\fp_gset:Nn \fp_tmpa_fp {#1 * \g_BBLR_max_abscissa_fp + #2 } +\fp_compare:nTF{\fp_tmpa_fp > \g_BBLR_max_ordinate_fp}{ +\fp_gset:Nn \g_BBLR_max_draw_abscissa_fp {(\g_BBLR_max_ordinate_fp -#2) / #1} +}{ +\fp_compare:nTF{\fp_tmpa_fp < \g_BBLR_min_ordinate_fp}{ +\fp_gset:Nn \g_BBLR_max_draw_abscissa_fp { (\g_BBLR_min_ordinate_fp - #2) / #1} +}{ +\fp_gset:Nn \g_BBLR_max_draw_abscissa_fp { \g_BBLR_max_abscissa_fp } +}} +% \end{macrocode} +% Some parameters (i.e.\ starting point and base-length) +% are computed and the line is drawn. +% \begin{macrocode} +\fp_gset:Nn \fp_tmpa_fp {(\g_BBLR_min_draw_abscissa_fp - +\g_BBLR_min_abscissa_fp)* \g_BBLR_scale_factor_fp} +\fp_gset:Nn \fp_tmpb_fp {(#1 * \g_BBLR_min_draw_abscissa_fp + #2 - +\g_BBLR_min_ordinate_fp)* \g_BBLR_scale_factor_fp} +\fp_gset:Nn \fp_BBLR_line_base_length_fp{(\g_BBLR_max_draw_abscissa_fp - +\g_BBLR_min_draw_abscissa_fp) * \g_BBLR_scale_factor_fp} +\put(\fp_use:N\fp_tmpa_fp, \fp_use:N\fp_tmpb_fp){ +\line(1.,\fp_use:N #1){\fp_use:N\fp_BBLR_line_base_length_fp}} +% \end{macrocode} +%The third parameter is used as a label, if it is not a |+|. +% \begin{macrocode} +\bool_if:nF {\str_if_eq_p:NN #3 \c_BBLR_plus_str}{ +\fp_gset:Nn \fp_tmpa_fp +{0.08 * \g_BBLR_min_draw_abscissa_fp + 0.92 * \g_BBLR_max_draw_abscissa_fp} +\fp_gset:Nn \fp_tmpb_fp {#1 * \fp_tmpa_fp + #2 } +\fp_gset:Nn \fp_tmpa_fp +{(\fp_tmpa_fp-\g_BBLR_min_abscissa_fp)*\g_BBLR_scale_factor_fp ++ 0.3 * #1 /sqrt(1.+#1*#1)} +\fp_gset:Nn \fp_tmpb_fp +{(\fp_tmpb_fp-\g_BBLR_min_ordinate_fp)* \g_BBLR_scale_factor_fp +- 0.3 /sqrt(1.+#1*#1)} +\put(\fp_use:N\fp_tmpa_fp, \fp_use:N\fp_tmpb_fp){#3} +} +} +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% +%\iffalse +%</package> +%\fi +% +% \section{Acknowledgments} +% The colleagues Paolo Zatelli, Alfonso Vitti and Giulia Graldi +% read some preliminary version +% of this text and suggested several improvements. \par +% +% \section{About the references} +% \subsection*{Mathematics} +% The books by Lang \cite{Lang} and by Strang \cite{Strang} give +% all the background on linear algebra.\par +% The texts by Sansò \cites{Sanso1, Sanso2} (in italian) treat the +% teory of probability and its application to metrology. +% See: |http://www.geolab.polimi.it/text-books/|.\par +% The paper by Karl Pearson \cite{Pearson} is the oldest text that +% I have found on the symmetric regression, or total regression. +% \subsection*{Programming} +% The two documents \cites{L3A, L3B} are the fountamental and official guide +% for \LaTeX3 programming. The books by Donald Knuth \cites{Knuth} +% and Leslie Lamport \cites{Lamport} are still essential references. +% The papers by Enrico Gregorio \cites{egreg1, egreg2, egreg3, egreg4, egreg5} +% explain some general and some special aspect of \LaTeX3 programming. +% +% \section{References} +% \begin{biblist}[\normalsize] +% \bib{egreg1}{article}{ +% author={Gregorio, Enrico}, +% journal={ArsTeXnica}, +% number={14},pages={41\ndash 47}, date={2012}, +% title={\LaTeX3: un nuovo gioco per i maghi e per diventarlo}, +% } +% \bib{egreg2}{article}{ +% author={Gregorio, Enrico}, +% journal={ArsTeXnica}, +% number={22},pages={69\ndash 77}, date={2016}, +% title={Liste, cicli, \LaTeX3}, +% } +% \bib{egreg3}{article}{ +% author={Gregorio, Enrico}, +% journal={ArsTeXnica}, +% number={24},pages={37\ndash 44}, date={2017}, +% title={Condizionali in \LaTeX}, +% } +% \bib{egreg4}{article}{ +% author={Gregorio, Enrico}, +% journal={ArsTeXnica}, +% number={30},pages={36\ndash 45}, date={2020}, +% title={Funzioni e |expl3|}, +% } +% \bib{egreg5}{article}{ +% author={Gregorio, Enrico}, +% journal={TUGboat}, +% volume={41},number={3},pages={299\ndash 307}, date={2020}, +% title={Functions and |expl3|}, +% } +% \bib{Knuth}{book}{ +% author={Knuth, Donald}, +% title={The TeXbook}, +% date={1986}, +% publisher={American Mathematical Society and Addison-Wesley}, +% } +% \bib{Lang}{book}{ +% author={Lang, Serge}, +% title={Linear Algebra}, +% date={1987}, +% publisher={Springer-Verlag}, +% place={Berlin Heidelberg}, +% } +% \bib{Lamport}{book}{ +% author={Lamport, Leslie}, +% title={LaTeX - A document preparation system (2nd ed.\ )}, +% date={1994}, +% publisher={Addison-Wesley}, +% note={something interesting in the fist edition, too}, +% } +% \bib{L3A}{article}{ +% title={The |expl3| package and LaTeX3 programming}, +% author={The LaTeX project team}, date={2024}, +% note={file: |expl3.pdf| available in CTAN in l3kernel}, +% } +% \bib{L3B}{article}{ +% title={The \LaTeX3 interface}, +% author={The LaTeX project team}, date={2024}, +% note={file: |interface3.pdf| available in CTAN in l3kernel} +% } +% \bib{Pearson}{article}{ +% title={On lines and planes of closest fit to systems of points in space}, +% author={Pearson, Karl}, date={1901}, +% journal={Philosophical Magazine}, +% volume={2},number={11},pages={559\ndash 572}, +% } +% \bib{Sanso1}{book}{ +% author={Sansò, Fernando}, +% title={Elementi di teoria della probabilità}, +% date={1996}, +% publisher={Città-Studi}, +% place={Milano}, +% } +% \bib{Sanso2}{book}{ +% author={Sansò, Fernando}, +% title={La teoria della stima}, +% date={1996}, +% publisher={Città-Studi}, +% place={Milano}, +% } +% \bib{Strang}{book}{ +% author={Strang, Gilbert}, +% title={Introduction to linear algebra}, +% date={2009}, +% publisher={Wellesley-Cambridge press,}, +% } +% \end{biblist} +% +% \par\vfill\centerline{\small ***}\vfill +% \end{document} +% +%\iffalse +% END OF FILE linearregression.dtx +%\fi diff --git a/macros/latex/contrib/linearregression/linearregression.pdf b/macros/latex/contrib/linearregression/linearregression.pdf Binary files differnew file mode 100644 index 0000000000..5d28931c1a --- /dev/null +++ b/macros/latex/contrib/linearregression/linearregression.pdf diff --git a/macros/latex/contrib/linearregression/linearregressionpkg.ins b/macros/latex/contrib/linearregression/linearregressionpkg.ins new file mode 100644 index 0000000000..699f767b62 --- /dev/null +++ b/macros/latex/contrib/linearregression/linearregressionpkg.ins @@ -0,0 +1,20 @@ +\input docstrip.tex +\keepsilent +\preamble +------------------------------------------------------------------------ +[2024-06-10] +This file is part of the (expanded) distribution of linearregression +The author of linearregression is Battista Benciolini +<benciolinibattista at gmail dot com > +------------------------------------------------------------------------ +The author would strongly appreciate to receive +any comment, criticism and just usage report +------------------------------------------------------------------------ +This program may be used, distributed and modified under +the conditions of the LaTeX Project Public License. +(see: http://www.latex-project.org/lppl.txt) +------------------------------------------------------------------------ +\endpreamble +\askforoverwritefalse +\generate{\file{linearregression.sty}{\from{linearregression.dtx}{package}}} +\endbatchfile diff --git a/macros/luatex/generic/luamplib/NEWS b/macros/luatex/generic/luamplib/NEWS index 8339e9ce65..67dcb5814f 100644 --- a/macros/luatex/generic/luamplib/NEWS +++ b/macros/luatex/generic/luamplib/NEWS @@ -1,5 +1,11 @@ History of the luamplib package +2024/06/10 2.32.0 + * \mppattern{<name>} ... \endmppattern defines a tiling pattern which can be + used with 'withpattern' operator to fill a closed path by replicating the tile + horizontally and vertically. \begin{mppattern} ... \end{mppattern} is exactly + the same as \mppattern ... \endmppattern. See luamplib manual for details. + 2024/05/30 2.31.2 * support vertical writing mode in mpliboutlinetext (presently luatexko package only, and except horizontal mode inside vertical mode) diff --git a/macros/luatex/generic/luamplib/luamplib.dtx b/macros/luatex/generic/luamplib/luamplib.dtx index dc4a9c6570..ce4b4409f2 100644 --- a/macros/luatex/generic/luamplib/luamplib.dtx +++ b/macros/luatex/generic/luamplib/luamplib.dtx @@ -85,7 +85,7 @@ See source file '\inFileName' for licencing and contact information. %<*driver> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{luamplib.drv}% - [2024/05/30 v2.31.2 Interface for using the mplib library]% + [2024/06/10 v2.32.0 Interface for using the mplib library]% \documentclass{ltxdoc} \usepackage{metalogo,multicol,mdwlist,fancyvrb,xspace} \usepackage[x11names]{xcolor} @@ -153,7 +153,7 @@ See source file '\inFileName' for licencing and contact information. % \author{Hans Hagen, Taco Hoekwater, Elie Roux, Philipp Gesang and Kim Dohyun\\ % Maintainer: LuaLaTeX Maintainers --- % Support: \email{lualatex-dev@tug.org}} -% \date{2024/05/30 v2.31.2} +% \date{2024/06/10 v2.32.0} % % \maketitle % @@ -541,6 +541,81 @@ See source file '\inFileName' for licencing and contact information. % \textsc{n.b.} As Unicode grapheme cluster is not considered in the array, a unit that must be % a single cluster might be separated apart. % +% \paragraph{\cs{mppattern} \ldots\ \cs{endmppattern}, \texttt{withpattern}} +% |\mppattern{<name>}| \ldots\ |\endmppattern| defines a tiling pattern +% associated with the |<name>|. +% MetaPost operator |withpattern|, the syntax being +% \textit{path} |withpattern| \textit{string}, will return a metapost picture which fills +% the given path with a tiling pattern of the |<name>|. +% \begin{verbatim} +% \mppattern{mypatt} % or \begin{mppattern}{mypatt} +% [ xstep = 10, ystep = 12 ] % options: see below +% \mpfig % or any other TeX code, +% picture q; +% q := btex Q etex; +% fill bbox q withcolor .8[red,white]; +% draw q withcolor .8red; +% \endmpfig +% \endmppattern % or \end{mppattern} +% +% \mpfig +% fill fullcircle scaled 100 withpostscript "collect"; +% draw unitsquare shifted - center unitsquare scaled 45 +% withpattern "mypatt" +% withpostscript "evenodd" ; +% \endmpfig +% \end{verbatim} +% The available options are: +% +% \bigskip +% \begin{tabular}{lll}\hline +% Key & Value Type & Explanation\\\hline +% |xstep| &\textit{number} & horizontal spacing between pattern cells\\ +% |ystep| &\textit{number} & vertical spacing between pattern cells\\ +% |xshift| &\textit{number} & horizontal shifting of pattern cells\\ +% |yshift| &\textit{number} & vertical shifting of pattern cells\\ +% |bbox| &\textit{string} & |llx| |lly| |urx| |ury| values separated by spaces\\ +% |matrix| &\textit{string} & |xx| |xy| |yx| |yy| values separated by spaces\\ +% |resources|&\textit{string} & PDF resources if needed\\ +% |colored| &\textit{boolean}& |false| for uncolored pattern. default: |true|\\\hline +% \end{tabular} +% \bigskip +% +% When you use special effects such as transparency in a pattern, +% |resources| option might be needed: for instance, |resources="/ExtGState 1 0 R"|. +% +% Option |colored=false| will generate an uncolored pattern which shall have no color at all. +% Uncolored pattern will be painted later by the color of a metapost object. +% An example: +% \begin{verbatim} +% \begin{mppattern}{pattuncolored} +% [ +% colored = false, +% matrix = "0.7071 0.7071 -0.7071 0.7071", +% ] +% \tiny\TeX +% \end{mppattern} +% +% \begin{mplibcode} +% beginfig(1) +% picture tex; tex := mpliboutlinetext.p ("\bfseries \TeX"); +% i:=0; +% for item within tex: +% i:=i+1; +% if i < length tex: +% fill pathpart item scaled 10 +% withpostscript "collect"; +% else: +% draw pathpart item scaled 10 +% withpattern "pattuncolored" +% withcolor 0.7 blue % paints the pattern +% ; +% fi +% endfor +% endfig; +% \end{mplibcode} +% \end{verbatim} +% % \paragraph{About figure box metrics} % Notice that, after each figure is processed, macro \cs{MPwidth} stores % the width value of latest figure; \cs{MPheight}, the height value. @@ -573,8 +648,8 @@ See source file '\inFileName' for licencing and contact information. luatexbase.provides_module { name = "luamplib", - version = "2.31.2", - date = "2024/05/30", + version = "2.32.0", + date = "2024/06/10", description = "Lua package to typeset Metapost with LuaTeX's MPLib.", } @@ -1625,6 +1700,7 @@ end luamplib.graphictext = function (text, fakebold, fc, dc) local fmt = process_tex_text(text):sub(1,-2) local id = tonumber(fmt:match"mplibtexboxid=(%d+):") + emboldenfonts.width = nil local box = texgetbox(id) box.head = embolden(box, box.head, fakebold) local fill = graphictextcolor(fc,"fill") @@ -2224,6 +2300,9 @@ vardef mpliboutlinetext@# (expr t) text rest = fi; ) mplib_do_outline_options_r; ) enddef ; +primarydef t withpattern p = + image( fill t withprescript "mplibpattern=" & if numeric p: decimal fi p; ) +enddef; ]], legacyverbatimtex = [[ def specialVerbatimTeX (text t) = runscript("luamplibprefig{"&t&"}") enddef; @@ -2620,7 +2699,8 @@ if pdfmode then end end else - texsprint("\\special{pdf:obj @MPlibTr<<>>}","\\special{pdf:obj @MPlibSh<<>>}") + texsprint("\\special{pdf:obj @MPlibTr<<>>}","\\special{pdf:obj @MPlibSh<<>>}", + "\\special{pdf:obj @MPlibCS<<>>}","\\special{pdf:obj @MPlibPt<<>>}") end % \end{macrocode} @@ -2772,10 +2852,11 @@ pdfetcs.clrspcs = setmetatable({ }, { __index = function(t,names) end }) local function do_preobj_SH(object,prescript) - if object.postscript == "collect" then return end local shade_no local sh_type = prescript and prescript.sh_type - if sh_type then + if not sh_type then + return + else local domain = prescript.sh_domain or "0 1" local centera = prescript.sh_center_a or "0 0"; centera = centera:explode() local centerb = prescript.sh_center_b or "0 0"; centerb = centerb:explode() @@ -2889,6 +2970,129 @@ end % \end{macrocode} % +% Patterns +% \begin{macrocode} +patterns = { c_l_r_s_p_c_s_ = { } } +function luamplib.registerpattern ( boxid, name, opts ) + local box = texgetbox(boxid) + if opts.xstep == 0 then opts.xstep = nil end + if opts.ystep == 0 then opts.ystep = nil end + if opts.colored == nil then opts.colored = true end + local attr = { + "/Type/Pattern", + "/PatternType 1", + format("/PaintType %i", opts.colored and 1 or 2), + "/TilingType 2", + format("/XStep %.3f", opts.xstep or box.width/factor), + format("/YStep %.3f", opts.ystep or (box.height+box.depth)/factor), + format("/Matrix [%s %s %s]", opts.matrix or "1 0 0 1", opts.xshift or 0, opts.yshift or 0), + } + if pdfmode then + if opts.bbox then + attr[#attr+1] = format("/BBox [%s]", opts.bbox) + end + local index = tex.saveboxresource(boxid,tableconcat(attr),opts.resources,true,opts.bbox and 4 or 1) + patterns[name] = { id = index, colored = opts.colored } + else + local objname = "@mplibpattern"..name + local metric = opts.bbox and format("bbox %s",opts.bbox) or + format([[width \the\wd%i \space height \the\ht%i \space depth \the\dp%i]],boxid,boxid,boxid) + texsprint { + [[\ifvmode\nointerlineskip\fi]], + format([[\hbox to0pt{\vbox to0pt{\hsize=\wd %i\vss\noindent]], boxid), -- force horiz mode? + [[\special{pdf:bcontent}]], + [[\special{pdf:bxobj ]], objname, format(" %s}", metric), + format([[\box %i]], boxid), + [[\special{pdf:exobj <<]], tableconcat(attr), ">>}", + [[\special{pdf:econtent}]], + [[\par}\hss}]], + } + patterns[#patterns+1] = objname + patterns[name] = { id = #patterns, colored = opts.colored } + end +end +local function pattern_colorspace (cs, ref) + local on, new = update_pdfobjs(format("[/Pattern %s]", ref or format("/%s",cs))) + if new then + local key = format("MPlibCS%i",on) + local val = pdfmode and format("%i 0 R",on) or format("@mplibpdfobj%i",on) + if pdfmanagement then + texsprint(ccexplat,format("\\pdfmanagement_add:nnn{Page/Resources/ColorSpace}{%s}{%s}",key,val)) + else + local res = format("/%s %s", key, val) + if is_defined"pgf@sys@addpdfresource@colorspaces@plain" then + texsprint(catat11, format("\\pgf@sys@addpdfresource@colorspaces@plain{%s}", res)) + elseif pdfmode then + if not pdfetcs.ColorSpace_res then + pdfetcs.initialize_resources"ColorSpace" + end + pdfetcs.fallback_update_resources("ColorSpace", res) + else + texsprint(format("\\special{pdf:put @MPlibCS<<%s>>}", res)) + texsprint"\\special{pdf:put @resources<</ColorSpace @MPlibCS>>}" + end + end + patterns.c_l_r_s_p_c_s_[cs] = on + end + return on +end +local function do_preobj_PAT(object, prescript) + local name = prescript and prescript.mplibpattern + if not name then return end + local patt = patterns[name] + local index = patt and patt.id or err("cannot get pattern object '%s'", name) + local key = format("MPlibPt%s",index) + if patt.colored then + pdf_literalcode("/Pattern cs /%s scn", key) + else + local color = prescript.mpliboverridecolor + if not color then + local t = object.color + color = t and #t>0 and luamplib.colorconverter(t) + end + if not color then return end + local csobj, cs, ref + if color:find" cs " or color:find"@pdf.obj" then + local t = color:explode() + if pdfmode then + cs = t[1]:sub(2,-1) + ref = format("%s 0 R", ltx.pdf.object_id(cs)) + color = t[3] + else + cs, ref = t[2], t[2] + color = t[3]:match"%[(.+)%]" + end + else + local t = colorsplit(color) + cs = #t == 4 and "DeviceCMYK" or #t == 3 and "DeviceRGB" or "DeviceGray" + color = tableconcat(t," ") + end + csobj = patterns.c_l_r_s_p_c_s_[cs] or pattern_colorspace(cs, ref) + pdf_literalcode("/MPlibCS%i cs %s /%s scn", csobj, color, key) + end + if patt.done then return end + local val = pdfmode and format("%s 0 R",index) or patterns[index] + if pdfmanagement then + texsprint(ccexplat, format("\\pdfmanagement_add:nnn{Page/Resources/Pattern}{%s}{%s}",key,val)) + else + local res = format("/%s %s", key, val) + if is_defined"pgf@sys@addpdfresource@patterns@plain" then + texsprint(catat11, format("\\pgf@sys@addpdfresource@patterns@plain{%s}", res)) + elseif pdfmode then + if not pdfetcs.Pattern_res then + pdfetcs.initialize_resources"Pattern" + end + pdfetcs.fallback_update_resources("Pattern", res) + else + texsprint(format("\\special{pdf:put @MPlibPt<<%s>>}", res)) + texsprint"\\special{pdf:put @resources<</Pattern @MPlibPt>>}" + end + end + patt.done = true +end + +% \end{macrocode} +% % Finally, flush figures by inserting PDF literals. % \begin{macrocode} function luamplib.flush (result,flusher) @@ -2991,6 +3195,7 @@ function luamplib.flush (result,flusher) % Added instead : shading stuff % \begin{macrocode} local shade_no = do_preobj_SH(object,prescript) -- shading + local pattern_ = do_preobj_PAT(object,prescript) -- pattern local ml = object.miterlimit if ml and ml ~= miterlimit then miterlimit = ml @@ -3176,7 +3381,7 @@ end \else \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{luamplib} - [2024/05/30 v2.31.2 mplib package for LuaTeX] + [2024/06/10 v2.32.0 mplib package for LuaTeX] \ifx\newluafunction\@undefined \input ltluatex \fi @@ -3240,6 +3445,44 @@ end \def\mplibputtextbox#1{\vbox to 0pt{\vss\hbox to 0pt{\raise\dp#1\copy#1\hss}}} % \end{macrocode} % +% Patterns +% \begin{macrocode} +{\def\:{\global\let\mplibsptoken= } \: } +\protected\def\mppattern#1{% + \begingroup + \def\mplibpatternname{#1}% + \mplibpatterngetnexttok +} +\def\mplibpatterngetnexttok{\futurelet\nexttok\mplibpatternbranch} +\def\mplibpatternskipspace{\afterassignment\mplibpatterngetnexttok\let\nexttok= } +\def\mplibpatternbranch{% + \ifx [\nexttok + \expandafter\mplibpatternopts + \else + \ifx\mplibsptoken\nexttok + \expandafter\expandafter\expandafter\mplibpatternskipspace + \else + \let\mplibpatternoptions\empty + \expandafter\expandafter\expandafter\mplibpatternmain + \fi + \fi +} +\def\mplibpatternopts[#1]{% + \def\mplibpatternoptions{#1}% + \mplibpatternmain +} +\def\mplibpatternmain{% + \setbox\mplibscratchbox\hbox\bgroup\ignorespaces +} +\protected\def\endmppattern{% + \egroup + \directlua{ luamplib.registerpattern( + \the\mplibscratchbox, '\mplibpatternname', {\mplibpatternoptions} + )}% + \endgroup +} +% \end{macrocode} +% % simple way to use mplib: % |\mpfig draw fullcircle scaled 10; \endmpfig| % \begin{macrocode} diff --git a/macros/luatex/generic/luamplib/luamplib.pdf b/macros/luatex/generic/luamplib/luamplib.pdf Binary files differindex c3e099a5d9..dd732665bb 100644 --- a/macros/luatex/generic/luamplib/luamplib.pdf +++ b/macros/luatex/generic/luamplib/luamplib.pdf diff --git a/macros/luatex/generic/luamplib/test-luamplib-latex.tex b/macros/luatex/generic/luamplib/test-luamplib-latex.tex index 2d1994d535..b3ba66c7fe 100644 --- a/macros/luatex/generic/luamplib/test-luamplib-latex.tex +++ b/macros/luatex/generic/luamplib/test-luamplib-latex.tex @@ -244,6 +244,41 @@ draw mpliboutlinetext.b ("$\displaystyle\frac{1}{1-x^2}$") ) scaled 4; \endmpfig +\par\leavevmode +\mppattern{mypatt} + \mpfig + picture q; + q := btex Q etex; + fill bbox q withcolor .8[red,white]; + draw q withcolor .8red; + \endmpfig +\endmppattern +\mpfig + fill fullcircle scaled 100 withpostscript "collect"; + draw unitsquare shifted - center unitsquare scaled 45 + withpattern "mypatt" + withpostscript "evenodd" + ; +\endmpfig +\begin{mppattern}{pattuncolored} + [ + colored = false, + matrix = "0.7071 0.7071 -0.7071 0.7071", + ] + \tiny\TeX +\end{mppattern}\relax +\mpfig + picture tex; tex := mpliboutlinetext.p ("\bfseries \TeX"); + i:=0; + for item within tex: + i:=i+1; + if i < length tex: + fill pathpart item scaled 10 withpostscript "collect"; + else: + draw pathpart item scaled 10 withpattern "pattuncolored" withcolor 0.7 blue; + fi + endfor +\endmpfig \tracingcommands0 \vskip 2\baselineskip diff --git a/macros/luatex/generic/luamplib/test-luamplib-plain.tex b/macros/luatex/generic/luamplib/test-luamplib-plain.tex index bc955d2f8f..9c0dbccd9c 100644 --- a/macros/luatex/generic/luamplib/test-luamplib-plain.tex +++ b/macros/luatex/generic/luamplib/test-luamplib-plain.tex @@ -237,6 +237,41 @@ draw mpliboutlinetext.b ("$\overbrace{x+\cdots+x}^k$") ) scaled 4; \endmpfig +\par\leavevmode +\mppattern{mypatt} + \mpfig + picture q; + q := btex Q etex; + fill bbox q withcolor .8[red,white]; + draw q withcolor .8red; + \endmpfig +\endmppattern +\mpfig + fill fullcircle scaled 100 withpostscript "collect"; + draw unitsquare shifted - center unitsquare scaled 45 + withpattern "mypatt" + withpostscript "evenodd" + ; +\endmpfig +\mppattern{pattuncolored} + [ + colored = false, + matrix = "0.7071 0.7071 -0.7071 0.7071", + ] + \fiverm\TeX +\endmppattern +\mpfig + picture tex; tex := mpliboutlinetext.p ("\bf \TeX"); + i:=0; + for item within tex: + i:=i+1; + if i < length tex: + fill pathpart item scaled 10 withpostscript "collect"; + else: + draw pathpart item scaled 10 withpattern "pattuncolored" withcolor 0.7 blue; + fi + endfor +\endmpfig \tracingcommands0 \vskip 2\baselineskip |