diff options
author | Karl Berry <karl@freefriends.org> | 2024-08-23 21:01:04 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2024-08-23 21:01:04 +0000 |
commit | e834b98ab00c19db970c5ce7b3e9eec54a4e0cb4 (patch) | |
tree | 101d9e0048c9f42cf40582eea462bd0e19c1919b | |
parent | d9c9c637f5b1c577c3f545b663655c1c7aa727a0 (diff) |
domaincoloring (23aug24)
git-svn-id: svn://tug.org/texlive/trunk@72095 c570f23f-e606-0410-a88d-b1316a301751
14 files changed, 1059 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/Changes b/Master/texmf-dist/doc/lualatex/domaincoloring/Changes new file mode 100644 index 00000000000..e49a69aac3c --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/Changes @@ -0,0 +1,4 @@ +0.02 2024-08-22 - edit option bgcolor + - reduced header for the intermediate eps + - renamed complex-numbers.lua +0.01 2024-08-18 - first CTAN version diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/README.md b/Master/texmf-dist/doc/lualatex/domaincoloring/README.md new file mode 100644 index 00000000000..9cff64e2f1e --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/README.md @@ -0,0 +1,12 @@ +# README # +Package domaincoloring creates a colored +representation of the domain of complex function. + +The package needs lualatex and does not work with pdflatex or xelatex! + +%% This program can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License Distributed from CTAN archives. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt + +hvoss@tug.org
\ No newline at end of file diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/doc/domaincoloring-doc.bib b/Master/texmf-dist/doc/lualatex/domaincoloring/doc/domaincoloring-doc.bib new file mode 100644 index 00000000000..d109070c927 --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/doc/domaincoloring-doc.bib @@ -0,0 +1,27 @@ +@online{wikipedia, + author = {{\WikipediA}}, + sortlabel = {Wikipedia}, + sortname = {Wikipedia}, + title = {DOmain Coloring}, + date = {2024-08-18}, + urldate = {2024-08-18}, + url = {https://en.wikipedia.org/wiki/Domain_coloring}, +} + +@online{features, + author = {{vismath}}, + title = {Thema Domain Coloring}, + date = {2024-08-18}, + urldate = {2024-08-18}, + url = {https://www.vismath.eu/de/blog/domain-coloring/}, +} + + +@online{fu, + author = {Konstantin Poelke and Konrad Polthier}, + title = {Domain Coloring of Complex Functions}, + url = {https://www.mi.fu-berlin.de/en/math/groups/ag-geom/publications/db/ieee_article_old_low_v3_1.pdf}, + urldate = {2024-08-18}, + date = {2024-08-18}, +} + diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/doc/domaincoloring-doc.pdf b/Master/texmf-dist/doc/lualatex/domaincoloring/doc/domaincoloring-doc.pdf Binary files differnew file mode 100644 index 00000000000..8a8b79e4d98 --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/doc/domaincoloring-doc.pdf diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/doc/domaincoloring-doc.tex b/Master/texmf-dist/doc/lualatex/domaincoloring/doc/domaincoloring-doc.tex new file mode 100644 index 00000000000..63c33ec368f --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/doc/domaincoloring-doc.tex @@ -0,0 +1,257 @@ +%% $Id: domaincoloring-doc.tex 952 2024-08-22 15:40:35Z herbert $ +% +\listfiles + +\DocumentMetadata{} +\documentclass[fontsize=11pt,english,BCOR=10mm,DIV=12,bibliography=totoc,parskip=false,headings=small, + headinclude=false,footinclude=false,oneside]{pst-doc} +\listfiles + +\usepackage{biblatex} +\addbibresource{\jobname.bib} + +\usepackage{booktabs} % for examples +\usepackage{xltabular} % for examples +\usepackage{enumitem} +\setlist{noitemsep,nosep} + +\usepackage{domaincoloring} +\let\DColFV\fileversion + +\usepackage{hvlogos} + +\usepackage{listings} +\lstset{columns=fixed,basicstyle=\ttfamily\small} + +\def\bgImage{\includegraphics[width=7cm]{titleImg}} + +\title{Domain Coloring of complex functions\\version \DColFV} +\author{Herbert Voß} +\begin{document} +\settitle +\tableofcontents + + +\section{Introduction} + +This package works only with \texttt{lualatex}! + +\subsection{Loading the package} +The package \texttt{domaincoloring} creates acolored interpretation of the +domain of a complex function. The package itself has no options and should be loaded as +usual: + +\begin{verbatim} +\usepackage{domaincoloring} +\end{verbatim} + +The needs the following Lua modules: + +\begin{itemize} +\item \texttt{domaincoloring.lua} the main module +\item \texttt{domaincoloring-complex-numbers.lua} for complex math operations +\item \texttt{domaincoloring-functions.lua} for predefined complex functions +\end{itemize} + +The function module has to be managed by the user himself, if needed. + + + +\subsection{Using the macro} + +There is only one macro which does the external call of the Lua program \verb|domaincoloring.lua|. +This program creates the image which is then included into the document. The \LaTeX-run needs +the \verb|--shell-escape| option to allow the external run of the program to convert the created +ppm-file into a png file.. + + +\begin{verbatim} +\DomainColoring[options]{complex function in Lua notation} +\end{verbatim} + +Every math function has to be preceeded by \texttt{cmath} if it has a complex argument. + +\subsection{Options} + +\noindent +\begin{xltabular}{\linewidth}{@{} >{\ttfamily}l l X @{}}\\\toprule +\emph{name} & \emph{value} &\emph{meaning}\\\midrule +domain & {-2,2,-2,2} & the (re,im)-coordinates for the complex system\\ +resolution & 500 & the number of steps for the re,im interval. At the moment only +for both coordinates the same. Will be in future +versions different for the both axes. \\ +filename & \Lcs{jobname-tmp} & name of the created external file, must be unique\\ +grfOptions &scale=0.5 & optional arguments for \Lcs{includegraphics}\\ +hsvrgb & {phi,1,r} & for the conversion into rgb\\ +funcName & & corresponding to external file\\ +bgcolor & 0 & change color to white as background for all values $r+g+b\le\text{bgcolor}$\\ +invers & false & inverted colors with $color=|color-255|$\\ +\bottomrule +\end{xltabular} + + + + +\section{Examples} + +\subsection{The default with function $f(z)=z$} +\begin{lstlisting} +\DomainColoring{z}\qquad % default filename \jobname-tmp.png +\end{lstlisting} + +\noindent +\DomainColoring{z}%\qquad +%\DomainColoring[filename=demo2.png,bgcolor=true]{z} + + + +\subsection{Defining domain, color mode, resolution and filename} + +\begin{align} + f(z) &= \cos(z)/\sin(z^4-1) +\end{align} + +in Lua-notation: \verb|cmath.cos(z)/cmath.sin(z^4-1)|. + +\begin{lstlisting} +\DomainColoring[domain={-2.5,2.5,-2.5,2.5},resolution=500, + grfOptions={width=0.32\linewidth}, + filename=\jobname-tmp1a]{cmath.cos(z)/cmath.sin(z^4-1)} +\hfill +\frame{\DomainColoring[domain={-2.5,2.5,-2.5,2.5},resolution=500, + bgcolor=true,grfOptions={width=0.32\linewidth},bgcolor=3, + filename=\jobname-tmp1b]{cmath.cos(z)/cmath.sin(z^4-1)}} +\hfill +\frame{\DomainColoring[domain={-2.5,2.5,-2.5,2.5},resolution=500, + invers=true,,grfOptions={width=0.32\linewidth}, + filename=\jobname-tmp1c]{cmath.cos(z)/cmath.sin(z^4-1)}} +\end{lstlisting} + +\noindent +\DomainColoring[domain={-2.5,2.5,-2.5,2.5},resolution=500,grfOptions={width=0.32\linewidth}, + filename=\jobname-tmp1a]{cmath.cos(z)/cmath.sin(z^4-1)} +\hfill +\frame{\DomainColoring[domain={-2.5,2.5,-2.5,2.5},resolution=500,bgcolor=3,grfOptions={width=0.32\linewidth}, + filename=\jobname-tmp1b]{cmath.cos(z)/cmath.sin(z^4-1)}} +\hfill +\frame{\DomainColoring[domain={-2.5,2.5,-2.5,2.5},resolution=500,invers=true,grfOptions={width=0.32\linewidth}, + filename=\jobname-tmp1c]{cmath.cos(z)/cmath.sin(z^4-1)}} + + +With \Lcs{bgcolor}\texttt{=<int>} all RGB-combinations with a sum $R+G+B <= \text{int}$ are set to +the color white. + +\subsection{Option for \Lcs{includegraphics}} +With \Lkeyword{grfOptions} one can define optional arguments for \Lcs{includegraphics}: + +\begin{lstlisting} +\DomainColoring[grfOptions={width=0.49\linewidth},filename=\jobname-tmp2a]{cmath.sin(z)}\hfill +\hfill +\DomainColoring[grfOptions={width=0.49\linewidth},filename=\jobname-tmp2b]{1/cmath.sin(z)} +\end{lstlisting} + +\noindent +\DomainColoring[grfOptions={width=0.49\linewidth},filename=\jobname-tmp2a]{cmath.sin(z)} +\hfill +\DomainColoring[grfOptions={width=0.49\linewidth},filename=\jobname-tmp2b]{1/cmath.sin(z)} + + +\subsection{Higher resolution} + +The resolution is more or less the number of pixels for the given domain. +In later versions of this package it may be possible to have different values +for the two coordinates. By now the one value for \Lkeyword{resolution} is for +both axes. + + +\begin{lstlisting} +\DomainColoring[filename=\jobname-tmp3,resolution=1000, + grfOptions={width=0.49\linewidth}]{z^3-1} +\hfill +\DomainColoring[filename=\jobname-tmp4,resolution=1000, + grfOptions={width=0.49\linewidth}]{(z+1)^2*(z-1)/((z+i)*(z-i)^2)} +\end{lstlisting} + +\noindent +\DomainColoring[filename=\jobname-tmp3,resolution=1000, + grfOptions={width=0.49\linewidth}]{z^3-1} +\hfill +\DomainColoring[filename=\jobname-tmp4,resolution=1000, + grfOptions={width=0.49\linewidth}]{cmath.sin(z)*cmath.cos(z)} + + +\subsection{hsv to rgb conversion} + +The color model (Wikipedia) + +\begin{center} +\includegraphics[width=0.5\linewidth]{hsv} + +\url{http://en.wikipedia.org/wiki/File:HSV_color_solid_cylinder_alpha_lowgamma.png} +\end{center} + + +The complex number $z=x+iy$ is converted into its trogonometrical representation $x=r\cdot \cos\phi$ +and $y=r\cdot \sin\phi$ with $r=\sqrt{x^2+y^2}$. The values $r$ and $\phi$ are now taken as values +for the hsv color model with a constant second value for saturation. $\phi$ is used +for hue. For example: \verb|hsvrgb=phi,1,r|, which gives + +\begin{lstlisting} +\DomainColoring[filename=\jobname-tmp5a,resolution=1000, + grfOptions={width=0.49\linewidth},hsvrgb={phi,1,r}]{cmath.sin(z)*cmath.sin(0.99*z)} +\hfill +\DomainColoring[filename=\jobname-tmp5b,resolution=1000, + grfOptions={width=0.49\linewidth}]{cmath.sin(z)*cmath.sin(0.99*z)} % the default +\end{lstlisting} + +\noindent +\DomainColoring[filename=\jobname-tmp5a,resolution=1000, + grfOptions={width=0.49\linewidth},funcName=f10,hsvrgb={phi,1,r}]{cmath.sin(z)*cmath.sin(0.99*z)} % the default +\hfill +\DomainColoring[filename=\jobname-tmp5b,resolution=1000, + grfOptions={width=0.49\linewidth}]{cmath.sin(z)*cmath.sin(0.99*z)} + +%For $r$ and $\phi$ we have to use $r$ and $phi$. +The optional argument \Lkeyword{hsvrgb} must define three values which can use the arguments +phi and r in any mathematical combination. It must only be compatible to the Lua math conventions, +e.g. \texttt{hsvrgb=\{phi+2,0.5,2/r\}} + + + + +\subsection{External function definition} +The already existing file \LFile{domaincoloring-functions.lua} collects sone +definitions of complex functions $f(z)$, which can be used from inside \LaTeX\ +with the optional argument \Lkeyword{funcName}. In this case the mandatory argument +of \Lcs{DomainColoring} has no meaning and can be empty. + +\begin{lstlisting} +\DomainColoring[filename=\jobname-tmp6a,resolution=1000, + domain={-1.5,1.5,-1.5,1.5}, grfOptions={width=0.49\linewidth}, + hsvrgb={phi+2*pi,1,1/r}, funcName=f12]{}% using predefined function +\hfill +\DomainColoring[filename=\jobname-tmp6b,resolution=2000, + domain={-2.3,0.7,-1.5,1.5}, grfOptions={width=0.49\linewidth}, + hsvrgb={phi+2*pi,1,1/r},funcName=f13]{} +\end{lstlisting} + +\noindent +\DomainColoring[filename=\jobname-tmp6a,resolution=1000, + domain={-1.5,1.5,-1.5,1.5}, grfOptions={width=0.49\linewidth}, + hsvrgb={phi+2*pi,1,1/r}, funcName=f12]{}% using predefined function +\hfill +\DomainColoring[filename=\jobname-tmp6b,resolution=2000, + domain={-2.3,0.7,-1.5,1.5}, grfOptions={width=0.49\linewidth}, + hsvrgb={phi+2*pi,1,1/r},funcName=f13]{} + + +The contents of the function file of the current version of \LPack{domaincoloring} is:: + +\lstinputlisting[language={[5.3]Lua},basicstyle=\small\ttfamily]{domaincoloring-functions.lua} + + + +\nocite{*} +\printbibliography + +\end{document} diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/doc/hsv.png b/Master/texmf-dist/doc/lualatex/domaincoloring/doc/hsv.png Binary files differnew file mode 100644 index 00000000000..4595b284aba --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/doc/hsv.png diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/doc/titleImg.pdf b/Master/texmf-dist/doc/lualatex/domaincoloring/doc/titleImg.pdf Binary files differnew file mode 100644 index 00000000000..e68120b481d --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/doc/titleImg.pdf diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/latex/domaincoloring.sty b/Master/texmf-dist/doc/lualatex/domaincoloring/latex/domaincoloring.sty new file mode 100644 index 00000000000..d668d057f03 --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/latex/domaincoloring.sty @@ -0,0 +1,73 @@ +%% $Id: domaincoloring.sty 952 2024-08-22 15:40:35Z herbert $ +%% This is file `domaincoloring.sty', +%% +%% Copyright (C) 2024- Herbert Voss +%% +%% This program can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License Distributed from CTAN archives. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt + +\NeedsTeXFormat{LaTeX2e} + +\RequirePackage{xkeyval} +\RequirePackage{graphicx} +\RequirePackage{shellesc} + +\def\fileversion{0.02} +\def\filedate{2024/08/22} +\message{`DCol' v\fileversion, \filedate} +\ProvidesPackage{domaincoloring} + [\filedate\ \fileversion\ 0.02 package for domain coloring of complex functions] + +\ifnum\ShellEscapeStatus < 1 + \PackageError{shellesc}{ShellEscape not enabled! Use --shell-escape}% +\fi + +% Change ^ to normal character to describe functions with lua +\catcode`\^=11\relax % for power symbol in Lua + +\define@key{DCol}{domain}{\def\@domaincoloring@domain{#1}} +\define@key{DCol}{resolution}{\def\@domaincoloring@res{#1,#1}} +\define@key{DCol}{bgcolor}{\def\@domaincoloring@bgcolor{#1}} +\define@key{DCol}{filename}{\def\@domaincoloring@filename{#1}} +\define@key{DCol}{hsvrgb}{\def\@domaincoloring@hsvrgb{#1}} +\define@key{DCol}{funcName}{\def\@domaincoloring@funcName{#1}} +\define@key{DCol}{invers}{\def\@domaincoloring@invers{#1}} +\define@key{DCol}{grfOptions}{\def\@domaincoloring@grf{#1}} + +\def\setDColkeys#1{\edef\x{\noexpand\setkeys{DCol}{#1}}\x} + +\setDColkeys{ + funcName={}, % corresponding to external file + hsvrgb={phi+3.14,1,r}, % given (r,phi) of the complex value + filename=\jobname-tmp, % the external image filename + resolution=500, % pixel per (x|y) interval + domain={-2,2,-2,2}, % x|y domain + bgcolor=0, % R+G+B value, changes only 0,0,0 -> 255,255,255 + invers=false, % 0 or 1 vor inverted colors + grfOptions={scale=0.5}, % LaTeX options for the included image +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\DomainColoring{\@ifnextchar[\DomainColoring@i{\DomainColoring@i[]}} +\def\DomainColoring@i[#1]#2{% + \begingroup + \setDColkeys{#1}% + \directlua{ + require("domaincoloring-complex-numbers") + require ("domaincoloring") + createData("#2",{\@domaincoloring@domain},{\@domaincoloring@res}, + "\@domaincoloring@funcName","\@domaincoloring@hsvrgb", + \@domaincoloring@bgcolor,"\@domaincoloring@invers")}% + \typeout{Convert domain.eps file to \@domaincoloring@filename.pdf}% + \ShellEscape{epstopdf domain.eps \@domaincoloring@filename.pdf}% + % + \expandafter\includegraphics\expandafter[\@domaincoloring@grf]{\@domaincoloring@filename.pdf}% + \endgroup + \ignorespaces +} + +\catcode`\^=7\relax +\endinput diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/lua/domaincoloring-complex-numbers.lua b/Master/texmf-dist/doc/lualatex/domaincoloring/lua/domaincoloring-complex-numbers.lua new file mode 100644 index 00000000000..7630433984c --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/lua/domaincoloring-complex-numbers.lua @@ -0,0 +1,357 @@ +--Complex Number Library by xXxMoNkEyMaNxXx (_G.cmath) +--[[ +In pure Lua, use: +num=complex(re,im) +or +num=cx'6+2.5i' + +In LuaJIT: +num=6+2.5i + +Functions and constants available in cmath: +Constants +-e=2.718281828459 +-i=sqrt(-1) +-pi=math.pi + +Complex creation and extraction functions +-complex(re,im) creates a complex number from real and imaginary components. +-re(z) real part of z +-im(z) imaginary part of z +-arg(z) argument of z + +-abs(z) absolute value of z +-sqrt(z) = z^0.5 +-pow(x,y) = x^y +-exp(z) = e^z +-ln(z) = e^? = z +-log(b,z) = ln(z)/ln(b) + +Trig functions +-sin(z) +-cos(z) +-tan(z) + +-sinh(z) +-cosh(z) +-tanh(z) + +-asin(z) +-acos(z) +-atan(z) +-atan2(y,x) + +-asinh(z) +-acosh(z) +-atanh(z) + +Miscellaneous functions +-polar(z) returns r,phi = cmath.abs(z),cmath.arg(z) +-rect(r,phi) returns a complex number from polar = r*e^(i*phi) +-diff(z) = re(z)^2-im(z)^2 +-zeta(z[,accuracy=1e4]) riemann zeta function +-lintegrate(f,H,[L=0,n=sensible for H]) +-cx(string) creates a complex number from a string (e.g. "1.1-i" -> 1.1+-1i) +-cx(re,im) = complex(re,im) + +]] + +local type=type +local select=select +local tonumber=tonumber +local tostring=tostring +local setmetatable=setmetatable + +e=math.exp(1) +pi=math.pi +abs=math.abs +exp=math.exp +log=math.log +cos=math.cos +sin=math.sin +cosh=math.cosh +sinh=math.sinh +sqrt=math.sqrt +atan2=math.atan2 + +forget=1e-14--Forget ridiculously small values. Remove if you want to keep all values. (Not recommended for sanity, shouldn't make a difference in performance or output.) +--The reason that this is here is because i^2 yields -1+0.0000000000000001i, and (-1)^0.5 yields 0.00000000000000006+i. (Should be just -1 and i) + +function istype(c) + local t=type(c) + return t=="table" and c.type or t +end + +local complex_mt +--Locally used and desirable functions-- +function re(n) + local t=type(n) + return t=="table" and (n.re or 0) or t=="number" and n or 0 +end + +function im(n) + return type(n)=="table" and n.im or 0 +end + +function complex(re,im) + if forget then + if re and abs(re)<=forget then + re=0 + end + if im and abs(im)<=forget then + im=0 + end + end + return setmetatable({re=re or 0,im=im or 0,type="complex"},complex_mt) +end + +function rect(r,phi)--r*e^(i*phi) -> x+iy + return complex(r*cos(phi),r*sin(phi)) +end + +function arg(z)--Lol, no documentation + return atan2(im(z),re(z)) +end + +function ln(c)--Natural logarithm + local r1,i1=re(c),im(c) + return complex(log(r1^2+i1^2)/2,atan2(i1,r1)) +end + +----------------------------------------- + +--Complex number metatable-- +complex_mt={ + __add=function(c1,c2) + return complex(re(c1)+re(c2),im(c1)+im(c2)) + end, + __sub=function(c1,c2) + return complex(re(c1)-re(c2),im(c1)-im(c2)) + end, + __mul=function(c1,c2) + local r1,i1,r2,i2=re(c1),im(c1),re(c2),im(c2) + return complex(r1*r2-i1*i2,r1*i2+r2*i1) + end, + __div=function(c1,c2) + local r1,i1,r2,i2=re(c1),im(c1),re(c2),im(c2) + local rsq=r2^2+i2^2 + return complex((r1*r2+i1*i2)/rsq,(r2*i1-r1*i2)/rsq) + end, + __pow=function(c1,c2)--Aww ye + local r1,i1,r2,i2=re(c1),im(c1),re(c2),im(c2) + local rsq=r1^2+i1^2 + if rsq==0 then--Things work better like this. + if r2==0 and i2==0 then + return 1 + end + return 0 + end + local phi=atan2(i1,r1) + return rect(rsq^(r2/2)*exp(-i2*phi),i2*log(rsq)/2+r2*phi) + end, + __unm=function(c) + return complex(-re(c),-im(c)) + end, + __tostring=function(c) + local iChar = "i" + local r,i=re(c),im(c) + if i==0 then + return tostring(r).." +0"..iChar + elseif r==0 then + if i==1 then + return iChar + elseif i==-1 then + return "-"..iChar + end + return i..iChar + elseif i<0 then + if i==-1 then + return r.."-"..iChar + end + return r.." -"..-i..iChar + else + if i==1 then + return r.."+"..iChar + end + return r.." +"..i..iChar + end + end +} +---------------------------- + +--Allow complex arguments for regular math functions with cmath namespace-- +--Note that all these functions still work for regular numbers! +--The added bonus is that they can handle things like (-1)^0.5. (=i) + +i=complex(0,1) +cmath={e=e,i=i,pi=pi,re=re,im=im,complex=complex,arg=arg,rect=rect,ln=ln} +_G.cmath=cmath + +function cmath.abs(c)--This always returns a pure real value + return sqrt(re(c)^2+im(c)^2) +end + +function cmath.diff(c) + return re(c)^2-im(c)^2 +end + +function cmath.exp(c) + return e^c +end + +function cmath.sqrt(c) + local num=istype(c)=="complex" and c^0.5 or complex(c)^0.5 + if im(num)==0 then + return re(num) + end + return num +end + +--Trig functions +function cmath.sin(c) + local r,i=re(c),im(c) + return complex(sin(r)*cosh(i),cos(r)*sinh(i)) +end +function cmath.cos(c) + local r,i=re(c),im(c) + return complex(cos(r)*cosh(i),sin(r)*sinh(i)) +end +function cmath.tan(c) + local r,i=2*re(c),2*im(c) + local div=cos(r)+cosh(i) + return complex(sin(r)/div,sinh(i)/div) +end + +--Hyperbolic trig functions +function cmath.sinh(c) + local r,i=re(c),im(c) + return complex(cos(i)*sinh(r),sin(i)*cosh(r)) +end +function cmath.cosh(c) + local r,i=re(c),im(c) + return complex(cos(i)*cosh(r),sin(i)*sinh(r)) +end +function cmath.tanh(c) + local r,i=2*re(c),2*im(c) + local div=cos(i)+cosh(r) + return complex(sinh(r)/div,sin(i)/div) +end + +--Caution! Mathematical laziness beyond this point! + +--Inverse trig functions +function cmath.asin(c) + return -i*ln(i*c+(1-c^2)^0.5) +end +function cmath.acos(c) + return pi/2+i*ln(i*c+(1-c^2)^0.5) +end +function cmath.atan(c) + local r2,i2=re(c),im(c) + local c3,c4=complex(1-i2,r2),complex(1+r2^2-i2^2,2*r2*i2) + return complex(arg(c3/c4^0.5),-ln(cmath.abs(c3)/cmath.abs(c4)^0.5)) +end +function cmath.atan2(c2,c1)--y,x + local r1,i1,r2,i2=re(c1),im(c1),re(c2),im(c2) + if r1==0 and i1==0 and r2==0 and i2==0 then--Indeterminate + return 0 + end + local c3,c4=complex(r1-i2,i1+r2),complex(r1^2-i1^2+r2^2-i2^2,2*(r1*i1+r2*i2)) + return complex(arg(c3/c4^0.5),-ln(cmath.abs(c3)/cmath.abs(c4)^0.5)) +end + +--Inverse hyperbolic trig functions. Why do they all look different but give correct results!? e.e +function cmath.asinh(c) + return ln(c+(1+c^2)^0.5) +end +function cmath.acosh(c) + return 2*ln((c-1)^0.5+(c+1)^0.5)-log(2) +end +function cmath.atanh(c) + return (ln(1+c)-ln(1-c))/2 +end + +--Miscellaneous functions +function cmath.zeta(s,a) + local sum=0 + for n=a,accuracy or 10000 do + sum=sum+n^-s + end + return sum +end + +--End of non-optimized terrors. + +--Linear integration, evenly spaced slices +--f=function(x),low=0,high=100,slices=10000 +function cmath.lintegrate(f,H,L,n) + n=n or floor(10*sqrt(H)) + L=L or 0 + local LH=H-L + local A=(f(L)+f(H))/2 + for x=1,n-1 do + A=A+f(L+LH*x/n) + end + return A/n +end + +--cmath.log: Complex base logarithm! One argument (z=c1) gives log(z). Two arguments (b=c1,z=c2) gives log_b(z), which is identical to log(c2)/log(c1). +function cmath.log(c2,c1) + local r1,i1=re(c1),im(c1) + local r2,i2=re(c2),im(c2) + local r3,i3=log(r1^2+i1^2)/2,atan2(i1,r1) + local r4,i4=log(r2^2+i2^2)/2,atan2(i2,r2) + local rsq=r4^2+i4^2 + return complex((r3*r4+i3*i4)/rsq,(r4*i3-r3*i4)/rsq) +end + +cmath.pow=complex_mt.__pow +--------------------------------------------------------------------------- + +--These are just some useful tools when working with complex numbers.-- + +--cmath.polar: x+iy -> r*e^(i*phi) One complex argument, or two real arguments can be given. +--This is basically return cmath.abs(z),cmath.arg(z) +function cmath.polar(cx,oy) + local x,y + if oy then + x,y=cx,oy + else + x,y=re(cx),im(cx) + end + return sqrt(x^2+y^2),atan2(y,x) +end + +--cmath.cx: Define complex numbers from a string. +function cmath.cx(a,b) + local r,i=0,0 + if type(a)=="string" and type(b)=="nil" then + local query=a:gsub("[^%d.+-i]","") + if #query>0 then + for sgn,im in query:gmatch'([+-]*)(%d*%.?%d*)i' do + i=i+(-1)^select(2,sgn:gsub("-",""))*(tonumber(im) or 1) + end + for sgn,re in query:gsub("[+-]*%d*%.?%d*i",""):gmatch'([+-]*)(%d*%.?%d*)()' do + r=r+(-1)^select(2,sgn:gsub("-",""))*(tonumber(re) or #sgn>0 and 1 or 0) + end + end + else + r,i=tonumber(a) or 0,tonumber(b) or 0 + end + if forget then + if abs(r)<=forget then + r=0 + end + if abs(i)<=forget then + i=0 + end + end + return complex(r,i) +end +----------------------------------------------------------------------- + +--Globalize. +_G.cmath=cmath + +-- print(cmath.e^(cmath.i*cmath.pi)+1) + diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/lua/domaincoloring-functions.lua b/Master/texmf-dist/doc/lualatex/domaincoloring/lua/domaincoloring-functions.lua new file mode 100644 index 00000000000..84cfd65d7c6 --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/lua/domaincoloring-functions.lua @@ -0,0 +1,74 @@ +-- $Id: domaincoloring-functions.lua 946 2024-08-21 19:32:10Z herbert $ + +kpse.set_program_name("luatex") + +function f0(z) + return cmath.sin(1/z)*cmath.cos(1/z)/z^3+1/z +end + +function f1(z) + return cmath.cos(z)/cmath.sin(z^4-1) +end + +function f2(z) + local c = complex(1,-1) + local d = complex(0,0.28) + return cmath.cos(c^2*z^2)/cmath.cos(c*(z-d)) +end + +function f3(z) + return z*(z+i)^2/(z-i)^2 +end + +function f4(z) + if abs(z) < 0.1 then + return complex(0.001,0.001) + else + return cmath.sin(1/(z*z)) + end +end + +function f5(z) + return cmath.sqrt(1-1/(z*z)+z^3) +end + +function f9(z) + local c = complex(1,-1) + local d = complex(1,1) + return z^2*c^2*(z*c-1-i)/(z*c-2*d) +end + +function f10(z) + local sum = complex(0,0) + for n=1,20 do + sum = sum + z^n/(1-z^n) + end + return sum +end + +function f11(z) + local iterateNo = 3 + for n=1,iterateNo do + z = z^2 + end + return z +end + +function f12(z) -- julia + local iterateNo = 15 + for n=1,iterateNo do + z = z^2 + complex(0.25,-0.5) + end + return z +end + +function f13(z) -- mandelbrot + local iterateNo = 15 + local c = z + z = complex(0,0) + for n=1,iterateNo do + z = z^2 + c + end + return z +end + diff --git a/Master/texmf-dist/doc/lualatex/domaincoloring/lua/domaincoloring.lua b/Master/texmf-dist/doc/lualatex/domaincoloring/lua/domaincoloring.lua new file mode 100644 index 00000000000..2b2ae177ead --- /dev/null +++ b/Master/texmf-dist/doc/lualatex/domaincoloring/lua/domaincoloring.lua @@ -0,0 +1,253 @@ +-- $Id: domaincoloring.lua 952 2024-08-22 15:40:35Z herbert $ + +----------------------------------------------------------------------- +-- FILE: domaincoloring.lua +-- DESCRIPTION: create a visual reprensation of a complex function +-- REQUIREMENTS: +-- AUTHOR: Herbert Voß +-- LICENSE: LPPL 1.3 +-- +----------------------------------------------------------------------- + +local version = 0.02 + +kpse.set_program_name("luatex") + +require("domaincoloring-complex-numbers") + +local func = io.open("domaincoloring-functions.lua","r") +if func~=nil then + io.close(func) + dofile("domaincoloring-functions.lua") +end + +local function HSVtoRGB(h, s, v) + local i = math.floor(h * 6) + local f = h * 6 - i + local p = v * (1 - s) + local q = v * (1 - f * s) + local t = v * (1 - (1 - f) * s) + local no = i % 6 + if no == 0 then return v,t,p + elseif no == 1 then return q,v,p + elseif no == 2 then return p,v,t + elseif no == 3 then return p,q,v + elseif no == 4 then return t,p,v + else return v,p,q + end +end + +function my_color_scheme(z,hsvrgb) + r, phi = cmath.polar(z) +-- phi is in -pi,+pi; change it to [0;2pi] + phi = phi+pi + h_str,s_str,v_str = hsvrgb:match("([^,]+),([^,]+),([^,]+)") +-- h = load("return "..h_str)() +-- s = load("return "..s_str)() +-- v = load("return "..v_str)() + --h,s,v = loadstring("return"..hsvrgb) + -- R,G,B, is [0,...,1] + R,G,B = HSVtoRGB(load("return "..h_str)(),load("return "..s_str)(),load("return "..v_str)()) -- h,s,v) -- (phi+3.14,1,r) + return { math.fmod(math.floor(R*255+0.5),255), + math.fmod(math.floor(G*255+0.5),255), + math.fmod(math.floor(B*255+0.5),255) } +end + + +--[[ +A raster of Height rows, in order from top to bottom. +Each row consists of Width pixels, in order from left to +right. Each pixel is a triplet of red, green, and blue samples, +in that order. Each sample is represented in pure binary by +either 1 or 2 bytes. If the Maxval is less than 256, it is +1 byte. Otherwise, it is 2 bytes. The most significant byte is first. +A row of an image is horizontal. A column is vertical. +The pixels in the image are square and contiguous. +]] + +function write_eps_data(name,data,res) + print("Lua: writing data file "..name.." ...") +-- print(data) + outFile = io.open(name,"w+") -- Dateiname + outFile:write([[ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (Herbert Voss) +%%Title: (domain.eps) +%%CreationDate: (]]) + outFile:write(os.date("%Y-%m-%d-%H.%M.%S")..")\n") + outFile:write("%%BoundingBox: -0 -0 "..res[1].." "..res[2].."\n") + outFile:write("%%HiResBoundingBox: 0 0 "..res[1].." "..res[2].."\n") + outFile:write([[ +%%DocumentData: Clean7Bit +%%LanguageLevel: 2 +%%Pages: 1 +%%EndComments +%%BeginDefaults +%%EndDefaults +%%BeginProlog +/DirectClassPacket { + currentfile color_packet readhexstring pop pop + /number_pixels 3 def + 0 3 number_pixels 1 sub { pixels exch color_packet putinterval } for + pixels 0 number_pixels getinterval +} bind def +/DirectClassImage{ + columns rows 8 [ columns 0 0 rows neg 0 rows ] + { DirectClassPacket } false 3 colorimage +} bind def +/DisplayImage { + gsave + /buffer 512 string def + /byte 1 string def + /color_packet 3 string def + /pixels 768 string def + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + DirectClassImage + grestore +} bind def +%%EndProlog +%%Page: 1 1 +]]) + outFile:write("%%PageBoundingBox: 0 0 "..res[1].." "..res[2].."\n") + outFile:write([[userdict begin +DisplayImage +0 0 +]]) + outFile:write(res[1].." "..res[2].."\n") + outFile:write("12\n") + outFile:write(res[1].." "..res[2].."\n") + outFile:write([[0 +0 +]]) + local i = 0 + for row = 1, res[2] do -- alle Zeilen + for col = 1, res[1] do -- alle Spalten + for k = 1,3 do + if data[row][col][k] ~= data[row][col][k] then -- check for nan + outFile:write("FF") + else + local num = data[row][col][k] + if num < 16 then + hex = string.format("0%X", num) + else + hex = string.format("%X", num) + end + outFile:write(hex) + end + i = i + 1 + if i == 39 then + outFile:write("\n") -- neue Zeile + i = 0 + end + end + end + end + outFile:write("\n") -- neue Zeile + outFile:write([[end % of userdict +%%PageTrailer +%%Trailer +%%EOF +]]) + outFile:close() -- Datei schließen + --os.execute("pnmtopng apfel.ppm >"..fileName..".png") -- ppm -> png Format +end + +function write_data(name,data,res) -- only valid for writing ppm files + print("\nLua: writing data file "..name.." ...") +-- print(data) + outFile = io.open(name,"w+") -- Dateiname + outFile:write("P3 ") -- Grafictype R G B + outFile:write(res[1].." "..res[2].." ") -- Anzahl Pixel: Breite x Höhe (cols x rows) + outFile:write("255\n") -- Höchster Zahlenwert (0..255) + for row = 1, res[2] do -- alle Zeilen + for col = 1, res[1] do -- alle Spalten + for k = 1,3 do + if data[row][col][k] ~= data[row][col][k] then -- check for nan + outFile:write("255 ") + else + outFile:write(data[row][col][k].." " ) + end + end + end + outFile:write("\n") -- neue Zeile + end + outFile:close() -- Datei schließen + --os.execute("pnmtopng apfel.ppm >"..fileName..".png") -- ppm -> png Format +end + +function plot(fString, domain, res, funcName, hsvrgb, bgColor, invers) + local left = domain[1] + local right = domain[2] + local bottom = domain[3] + local top = domain[4] + local dx = (right-left)/res[1] + local dy = (top-bottom)/res[2] + local img = {} -- mxn-Matrix (rows x colums) img[row][col] + for row = 1,res[2] do + img[row] = {} + for col = 1,res[1] do + img[row][col] = 0 + end + end + for row = 1, res[2] do + y = top-dy*row + for col = 1,res[1] do +-- print(j,i) + x = left+dx*col + z = complex(x, y) + if funcName then + fz = fString(z) -- use func number from external file + else + fz = load("return "..fString)() -- for example: cmath.cos(z)/cmath.sin(z^4-1) + end + color = my_color_scheme(fz,hsvrgb) + if invers == "true" then + for c=1,#color do + color[c] = math.abs(color[c]-255) + end + end + if bgColor > 0 then + if color[1] + color[2] + color[3] <= bgColor then + color = { 255, 255, 255 } + end + end +-- print(x,y,color[1],color[2],color[3]) + img[row][col] = color + end + end + return img +end + +--[[ + f: function as string if funcName is False + as funcName from external file if funcName is TRUE + Domain: xMin,xMax,yMin,yMax + Resolution: (points per Interval) xRes,yRes + funcName: true/false (see f) +]] +function createData(f,Domain,Resolution,funcName,hsvrgb,bgColor,invers) + if funcName == "" then + img = plot(f,Domain,Resolution,false,hsvrgb,bgColor,invers) + else + img = plot(load("return "..funcName)(),Domain,Resolution,true,hsvrgb,bgColor,invers) + end +-- write_data("domain.ppm",img,Resolution) + write_eps_data("domain.eps",img,Resolution) +end + diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 69b3e678ed6..4bcd8d46a5b 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -274,7 +274,7 @@ my @TLP_working = qw( dk-bib dlfltxb dnaseq dnp doc-pictex docbytex doclicense docmfp docmute docshots docsurvey doctools documentation docutils - doi doibanner doipubmed domitian + doi doibanner doipubmed domaincoloring domitian dosepsbin dotlessi dot2texi dotarrow dotseqn dottex doublestroke doulossil dowith download dox dozenal dpcircling dpfloat dprogress diff --git a/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc b/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc index f7392151044..a53579610c0 100644 --- a/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc @@ -78,6 +78,7 @@ depend derivative depend diffcoeff depend digiconfigs depend dijkstra +depend domaincoloring depend drawmatrix depend drawstack depend dyntree diff --git a/Master/tlpkg/tlpsrc/domaincoloring.tlpsrc b/Master/tlpkg/tlpsrc/domaincoloring.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/domaincoloring.tlpsrc |