[Tex/LaTex] Plotting Weierstrass function

plottikz-pgf

I'm trying to plot Weierstrass function using only basic TikZ picture functionality (no gnuplot or whatnot). How do I use sum in a \draw? Do I have to make a new command? Use a loop?

An alternative (ugly) solution with manual summation:

\begin{tikzpicture}[xscale=2.2,yscale=2.7]
\draw[thick, color=lightgrey,step=0.25cm,solid] (-2,-0.75) grid (2,0.75);
\draw[<->] (-2.1,0) -- (2.1,0) node[below right] {$x$};
\draw[<->] (0,-0.9) -- (0,0.9) node[left] {$y$};
\draw[color=newblue, thick, domain=-2:2,samples=500,/pgf/fpu,/pgf/fpu/output format=fixed] plot (\x, {(1/2)*sin(2*\x r) + (1/4)*sin(4*\x r) + (1/8)*sin(8*\x r) + (1/16)*sin(16*\x r) +
(1/32)*sin(32*\x r) + (1/64)*sin(64*\x r) + (1/128)*sin(128*\x r) + (1/256)*sin(256*\x r) +
(1/512)*sin(512*\x r) + (1/1024)*sin(1024*\x r) + (1/2048)*sin(2048*\x r) +
(1/4096)*sin(4096*\x r) + (1/8192)*sin(8192*\x r) + (1/16384)*sin(16384*\x r) +
(1/32768)*sin(32768*\x r) + (1/65536)*sin(65536*\x r) + (1/131072)*sin(131072*\x r) +
(1/262144)*sin(262144*\x r) + (1/524288)*sin(524288*\x r) +
(1/1048576)*sin(1048576*\x r) }) node[right, black] {};
\end{tikzpicture}

Best Answer

The following method is optimized for simplicity and readability rather than compilation speed or flexibility. The code avoids using LuaTeX, PSTricks, or even commands beginning with \pgfmath. The basic idea is to build the summation from the original question as a string (except that, e.g., 32 gets written as 2*2*2*2*2*1) and then pass this string to \draw plot in the usual fashion.

\documentclass[margin=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{fpu}
\def\x{\noexpand\x}    % Prevent \x from being expanded inside an \edef
\edef\weierstrass{0}     % weierstrass = 0;
\edef\currentbn{1}        % b_n = 1;
\foreach \i in {1,...,19} {
    % \global makes these definitions last beyond the current iteration
    \global\edef\currentbn{2*\currentbn}    % b_n = 2 * b_n;
    \global\edef\weierstrass{\weierstrass + (1/(\currentbn)*cos((\currentbn*\x) r))}    % weierstrass = weierstrass + (1/b_n) cos(b_n*\x radians);
}
\begin{document}
\begin{tikzpicture}
    \draw[thick, color=lightgray,step=0.25cm,solid] (-2,-0.75) grid (2,1.0);
    \draw[<->] (-2.1,0) -- (2.1,0) node[below right] {$x$};
    \draw[<->] (0,-0.9) -- (0,1.1) node[left] {$y$};
    \draw[color=blue, thick, domain=-2:2, samples=501, /pgf/fpu, /pgf/fpu/output format=fixed] 
        plot (\x, {\weierstrass});
\end{tikzpicture}
\end{document}

Here's the output:

enter image description here