Складання функції Вейерштрасса

Я намагаюся побудувати функцію Weierstrass , використовуючи лише базові функції зображення TikZ (не gnuplot або whatnot). Як використовувати суму в малюнку ? Чи потрібно мені робити нову команду? Використовувати цикл?

Альтернативне (потворне) рішення з ручним підсумовуванням:

\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}
21
@Puffton: Так, я вважаю, що ви =)
додано Автор Jake, джерело
@Puffton: Коли ви говорите "базові функції зображення TikZ", це також виключає PGFPlots (який також робить його обчислення в LaTeX)?
додано Автор Jake, джерело
Я особисто голосую, що прошу LaTeX робити розрахунки (принаймні, не раз). Я зазвичай вважаю за краще зберегти дані у файл, а потім побудувати дані з цього файлу .txt.
додано Автор Mike Gale, джерело
@Jake: Серйозно, чи можна передати складний код PostScript до макросів PGF або TikZ?
додано Автор kiss my armpit, джерело
Не намагаючись, я відчуваю, що ви потрапите в проблеми, оскільки функція передбачає «підсумовування» до нескінченності.
додано Автор Juri, джерело
Намагаючись уникнути PGFPlots, вони, як правило, виглядають огидними, але, можливо, це тільки я, хто не може правильно стилювати їх ...
додано Автор Kazim Noorani, джерело
Він все ще може бути побудований на певному дозволі або "рівні масштабування" без будь-яких проблем. Якщо ви подивитеся на Вікіпедію, ви можете побачити сюжет більше [-2,2] в конкретному масштабі, наприклад.
додано Автор Kazim Noorani, джерело

8 Відповіді

Пакет pst-func знає psweierstrass ( x0, x1) [a] {a або b} . Він використовує функцію з http://mathworld.wolfram.com/WeierstrassFunction.html або, якщо дається необов'язковий аргумент, оригінальний, наведений тут http://en.wikipedia.org/wiki/Weierstrass_function :

\documentclass[pstricks,border=10pt]{standalone}
\usepackage{pst-func}   
\begin{document}

\psset{yunit=10,xunit=5}
\begin{pspicture}(-0.1,-0.5)(2.1,0.5)
\psaxes[Dx=0.2,Dy=0.1,ticksize=-4pt 0,labelFontSize=\scriptstyle]{->}(0,0)(0,-0.5)(2.1,0.5)
\psWeierstrass[linecolor=red](0,2){2}
\psWeierstrass[linecolor=green](0,2){3}
\psWeierstrass[linecolor=blue](0,2){4}
\end{pspicture}

\end{document}

Run the example with xelatex or latex->dvips->ps2pdf. You need the latest version of pst-funx.tex from http://texnik.dante.de/tex/generic/pst-func/ or tomorrows update of TeX Live/MiKTeX.

output

і те ж саме з оригінальним визначенням Weierstraß і змінним номером інтервалу:

\documentclass{article}
\usepackage{ifxetex} 
\ifxetex\usepackage{fontspec}\else\usepackage[utf8]{inputenc}\fi
\usepackage{pst-func}   
\begin{document}

The original Weierstraß function
\[ f(x)= \sum_{n=0}^\infty a^n \cos(b^n \pi x) \]

\psset{unit=2cm,linewidth=0.5pt,plotpoints=5000}
\begin{pspicture}(-2.1,-2.1)(2.1,2.1)
\psaxes[Dx=0.5,Dy=0.5,ticksize=-2pt 0,labelFontSize=\scriptstyle]{->}(0,0)(-2,-2)(2,2)
\psWeierstrass[linecolor=red](-2,2)[0.5]{3}
\psWeierstrass[linecolor=blue!70](-2,2)[0.5]{10}
\end{pspicture}

\end{document}

enter image description here

А тепер версія LuaTeX з pgf, яка також має різноманітну кількість ітерацій:

\documentclass[tikz,border=0.125cm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
\usepackage{luacode}
\begin{luacode}
function weierstrass(x0, x1, n, a, b, epsilon)
 local dx = (x1-x0)/n 
 local x = x0
 local out=assert(io.open("tmp.data","w"))
 local y,k,dy
 while (x <= x1) do
   y = 0
   k = 0
   repeat
      dy = math.pow(a,k) * math.cos(math.pow(b,k)*math.pi*x)
      y = y + dy
      k = k + 1
   until (math.abs(dy) < epsilon)
   out:write(x, " ", y, "\string\n") 
   x = x + dx
 end
 out:close()
end
\end{luacode}

\begin{document}

\begin{tikzpicture}
\directlua{weierstrass(-2,2,5000,0.3,5,1.e-12)}%
\begin{axis}[axis lines=middle,domain=-2:2]
\addplot [thick, black, line join=round] table {tmp.data};
\end{axis}
\end{tikzpicture}

\end{document}
19
додано
можливо psWeierstrass [a] {b} або psWeierstrass {a}
додано Автор Herbert, джерело
@Puffton: останній приклад!
додано Автор Herbert, джерело
dup abs 1e-8 gt {ps @ WS додати/ps @ WS ED} {ps @ WS додати вихід} ifelse також можна спростити як dup ps @ WS add/ps @ WS ED abs 1e-8 lt {exit} if ...} петля ps @ WS
додано Автор kiss my armpit, джерело
@Puffton: Дозволено відповідати за допомогою PSTricks для інших читачів.
додано Автор kiss my armpit, джерело
Це не використовує базову функціональність зображення TikZ.
додано Автор Kazim Noorani, джерело

Ось визначення pgfmath функції оригінальна функція Вейерштрасса : weierstrass (x, a, b, i) . i - кількість ітерацій, які будуть використовуватися для апроксимації функції.

\documentclass{article}
\usepackage{pgfplots}

\makeatletter
\pgfmathdeclarefunction{weierstrass}{4}{%
    \[email protected]{#4}%
    \afterassignment\[email protected]%
    \expandafter\[email protected]@counta\pgfmathresult pt\relax%
    \pgfmathfloatcreate{1}{0.0}{0}%
    \let\[email protected]@TMPr=\pgfmathresult
    \[email protected]%
    \let\[email protected]@TMPp=\pgfmathresult%
    \edef\[email protected]@TMPx{#1}%
    \edef\[email protected]@TMPa{#2}%
    \edef\[email protected]@TMPb{#3}%
    \pgfmathloop
        \ifnum\[email protected]@counta>-1\relax%
            \pgfmathfloatparsenumber{\the\[email protected]@counta}%
            \let\[email protected]@TMPn=\pgfmathresult%
            \pgfmathpow{\[email protected]@TMPa}{\[email protected]@TMPn}%
            \let\[email protected]@TMPe=\pgfmathresult%
            \pgfmathpow{\[email protected]@TMPb}{\[email protected]@TMPn}%
            \pgfmathmultiply{\pgfmathresult}{\[email protected]@TMPp}%
            \pgfmathmultiply{\pgfmathresult}{\[email protected]@TMPx}%
            \pgfmathdeg{\pgfmathresult}%
            \pgfmathcos{\pgfmathresult}%
            \pgfmathmultiply{\pgfmathresult}{\[email protected]@TMPe}%
            \pgfmathadd{\pgfmathresult}{\[email protected]@TMPr}%
            \let\[email protected]@TMPr=\pgfmathresult
            \advance\[email protected]@counta by-1\relax%
    \repeatpgfmathloop%
}

\begin{document}
\begin{tikzpicture}
\begin{axis}[axis lines=middle, axis equal image, enlarge y limits=true]
\addplot [thick, black, samples=301, line join=round, domain=-2:2] {weierstrass(x,0.5,3,10)};
\end{axis}
\end{tikzpicture}
\end{document}

Ось версія з MathWorld , яка реалізована в PSTricks:

\documentclass{article}
\usepackage{pgfplots}

\makeatletter
\pgfmathdeclarefunction{weierstrass}{3}{%
    \[email protected]{#3}%
    \afterassignment\[email protected]%
    \expandafter\[email protected]@counta\pgfmathresult pt\relax%
    \pgfmathfloatcreate{1}{0.0}{0}%
    \let\[email protected]@TMPa=\pgfmathresult
    \[email protected]%
    \let\[email protected]@TMPd=\pgfmathresult%
    \edef\[email protected]@TMPb{#1}%
    \edef\[email protected]@TMPc{#2}%
    \pgfmathloop
        \ifnum\[email protected]@counta>0\relax%
            \pgfmathfloatparsenumber{\the\[email protected]@counta}%
            \pgfmathpow{\pgfmathresult}{\[email protected]@TMPc}%
            \[email protected]{\pgfmathresult}{\[email protected]@TMPd}%
            \let\[email protected]@TMPe=\pgfmathresult%
            \pgfmathmultiply{\pgfmathresult}{\[email protected]@TMPb}%
            \pgfmathdeg{\pgfmathresult}%
            \pgfmathsin{\pgfmathresult}%
            \pgfmathdivide{\pgfmathresult}{\[email protected]@TMPe}%
            \pgfmathadd{\pgfmathresult}{\[email protected]@TMPa}%
            \let\[email protected]@TMPa=\pgfmathresult
            \advance\[email protected]@counta by-1\relax%
    \repeatpgfmathloop%
}
\makeatother

\begin{document}
\begin{tikzpicture}
\begin{axis}[axis lines=middle,
    xmin=0, xmax=2,
    ymin=-0.5, ymax=0.5,
    axis equal image
]
\addplot [red, samples=300, domain=0:2] {weierstrass(x,2,15)};
\addplot [green, samples=300, domain=0:2] {weierstrass(x,3,15)};
\addplot [blue, samples=300, domain=0:2] {weierstrass(x,4,15)};
\end{axis}
\end{tikzpicture}

\end{document}
15
додано
У версії tikz , a = 0.5 та b = 3 . Проте функція Weierstrass вимагає ab> 1 + 3 . Крім того, weierstrass (x, 0.6,13,7) працює в TeXLive2017, але не в TeXLive2018.
додано Автор Matt Bishop, джерело
15 ітерацій для суми, яка визначена для k = 1, .., інверсія трохи обману :-). Втім, молодець!
додано Автор Herbert, джерело

Рішення sagetex у поєднанні з пакетом tkz-fct для налаштування осей і запуску в Cloud Cloud . Значення x, що виконуються до 2.01, пов'язані з тим, що Python не реалізує останнє число, тому фактично зупиняється на 2.

\documentclass{scrartcl}
\usepackage{sagetex}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{tkz-fct}
\pagestyle{empty}

\begin{document}
\begin{sagesilent}
y=var('y')
a = .5
b = 3
n = 100
t = var('t')
def weierstrass(t,a,b,n):
    answer = 0
    for i in range(0,n):
        answer += a^i*cos(b^i*pi*t).n(digits=5)

    return answer

x_coords = [t for t in srange(-2,2.01,.01)]
y_coords = [weierstrass(t,a,b,n).n(digits=6) for t in srange(-2,2.01,.01)]

output = ""
for i in range(0,len(x_coords)-1):
    output += r"\draw[blue, thin] (%f cm ,%f cm)--(%f cm ,%f cm);"%(x_coords[i],y_coords[i],x_coords[i+1],y_coords[i+1])
\end{sagesilent}
\begin{tikzpicture}[scale=1.25]
\tkzInit[xmin=-2,xmax=2,ymin=-2,ymax=2]
\tkzAxeXY
\sagestr{output}
\end{tikzpicture}
\end{document}

enter image description here

12
додано

Метод Джейка використовує lualatex з pgfplots . Деякі дурниці, здається, потрібно перетворити на та з внутрішнього представлення чисел, які використовуються pgfplots , що робить це неприємним неприємним.

\documentclass[tikz,border=0.125cm]{standalone}
\usepackage{pgfplots}
\directlua{%
  function weierstrass(x, a, b, N)
    local y, n
    y = 0
    for n = 0,N do
      y = y + math.pow(a,n) * math.cos(math.pow(b, n)*math.pi*x)
    end
    return y
  end
}

\pgfmathdeclarefunction{weierstrass}{4}{%
  \begingroup%
    \pgfkeys{/pgf/number format/.cd,assume math mode,verbatim}%
    \pgfmathprintnumberto{#1}{\x}\pgfmathprintnumberto{#2}{\a}%
    \pgfmathprintnumberto{#3}{\b}\pgfmathprintnumberto{#4}{\N}%
    \edef\pgfmathresult{\directlua{tex.print("" .. weierstrass(\x,\a,\b,\N))}}%
   \expandafter\endgroup\expandafter%
    \pgfmathfloatparsenumber\expandafter{\pgfmathresult}%
}
\begin{document}

\begin{tikzpicture}
\begin{axis}[axis lines=middle, axis equal image, enlarge y limits=true]
\addplot [thick, black, samples=301, line join=round, domain=-2:2] 
  {weierstrass(x,0.5,3,100)};
\end{axis}
\end{tikzpicture}

\end{document}

enter image description here

12
додано

Наступний метод оптимізований для простоти і читаності, а не швидкості компіляції або гнучкості. Код уникає використання LuaTeX, PSTricks або навіть команд, що починаються з pgfmath . Основна ідея полягає в тому, щоб побудувати підсумок вихідного питання як рядок (за винятком того, що, наприклад, 32 записується як 2 * 2 * 2 * 2 * 2 * 1), а потім передають цей рядок до малюнка звичайним чином.

\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}

Ось результат:

enter image description here

11
додано
@Jake: Я отримав функцію від ОП. Я не знаю, звідки він отримав його.
додано Автор Tim Trueman, джерело
@Jake Hardy довів у 1916 році, що сума a ^ n cos (b ^ nx) з a <1 і ab 1 ніде дифференцируема, і йде з синусом. Див. це посилання . Я думаю, що цей документ містить простіший доказ, але я не впевнений, що ви можете завантажити його. Вихідний критерій Вейерштрасса був з ab> 1 + 3pi/2 .
додано Автор Rodrigo, джерело
@Jake, я думаю, що той, що має n ^ 2 , називається функцією Рімана (з sin я думаю), і його дослідження є набагато більш делікатним, ніж "Weierstrass" з кодом < > a ^ n cos (b ^ nx) (або pi * x ). Я тепер забув, але у Рімана є точки виводимості (я думаю, що в конкретних раціонах).
додано Автор Rodrigo, джерело
@Jake рівняння з cos (2 ^ n * x)/2 ^ n , тоді як інші відповіді використовують переважно cos (3 ^ n * pi * x)/2 ^ n . Моя власна відповідь спочатку використовує cos (2 ^ n * pi * x)/2 ^ n як загальний термін, можливо, я розширю його, щоб зробити також cos (3 ^ n * pi * x) )/2 ^ n , але спочатку мені потрібно зрозуміти, як використовувати fpu для всіх речей у ділянці або, можливо, по-іншому з координатами .
додано Автор Rodrigo, джерело
Яке це рівняння? Здається, що функція Вайєрштрасса не описується в MathWorld, оскільки вона використовує n ^ 2 , але якщо я правильно розумію ваш код, ви використовуєте 2 ^ n (а ви використовуєте cos замість sin ), і це не виглядає як оригінальна функція Вайєрштрасса, тому що використовує a ^ n з 0 <1 і b ^ n з b позитивним непарним цілим числом. Чи я щось не розумію?
додано Автор Jake, джерело
@jfbu: Дякуємо за інформацію. Можливо, у вас є посилання на рівняння cos (2 ^ n * pi * x)/2 ^ n ?
додано Автор Jake, джерело

updated: package xinttools (for \xintListWithSep) for example, needs explicit loading: since 1.1 (2014/10/28), it is not loaded by xintfrac anymore.

last edit: added a method using the fpu library with pgfplots, for the general \sum_n a^n*cos(b^n x) Weierstrass function. The powers a^n and b^n are pre-computed as floating point numbers with xintfrac, which also prepares the complete partial sum. I kept only 6 digits of precision as anyhow the fpu library mantissa computations are between 4 and 7 digits of precision.

Оскільки вісь x буде вказана в градусах, тобто як cos і sin , не потрібно турбуватися про pi , це все в горизонтальному масштабі.

Дивіться нижню частину відповіді за результат.


Взявши на себе рішення Чарльза , з тією відмінністю, що повноваження двох попередньо обчислюються. Виконання часткової суми готується за допомогою xint для переходу до ділянки tikz, з завантаженою бібліотекою fpu .

edit: the plots now use an odd number of sample points (101 vs 100, or 201 vs 200); hence are better looking at x=0. (only second image replaced, the one with n=20).

Примітка. Я не знаю, як інтерфейс fpu tikz має інтерфейс із командою plot , і я помітив, що з занадто довгою частковою сумою (скажімо n = 30 ) виникає помилка: Розмір занадто великий (але, мабуть, немає сенсу обробляти багато термінів, які будуть зовсім незначними). Таким чином, здається, що деякі обчислення принаймні не обробляються бібліотекою з плаваючою точкою, імовірно, принаймні, доповненнями? якщо все було оброблено fpu , помилка Dimension () не існує, чи не так?

Крім того, я використовую тільки 200 зразки для n = 20 , інакше це занадто повільно.

\documentclass[multi=preview]{standalone}
\usepackage{tikz}
\usetikzlibrary{fpu}
\usepackage{xint, xinttools}

\makeatletter
% general term will compute 1/2^n*cos(2^n pi x), or 1/2^n*sin(2^n pi x)
% (where 2^n is already evaluated)
% we need pi and r to use radians. 
% (I don't know if loading the tikz library fpu increased the precision of pi, 
%  perhaps it does not)

\def\@weierstrassgeneralterm #1#2#3{(1/#3*#2(#3*#1*pi r))}

\def\@weierstrassseries #1#2#3{% 
% #1 will be \x or \y etc... 
% #2=cos or sin 
% #3=summation will be from 0 to #3
    \xintListWithSep{+}
                    {\xintApply {\@weierstrassgeneralterm{#1}{#2}}
                                {\xintApply{\xintiiPow {2}}{\xintSeq {0}{#3}}}}%
}

% \fdef is defined by xint, it expands fully the first token. Hence no need
% to protect the \x, or \y which will be passed as argument.

% (initial version used \edef, see below)

\def\SetWeierstrass #1#2{% #1=\x or \y, etc..., #2=summation from 0 to #2
    \fdef\weierstrasscos {\@weierstrassseries {#1}{cos}{#2}}%
    \fdef\weierstrasssin {\@weierstrassseries {#1}{sin}{#2}}%
}%

% earlier version:
%
%\def\SetWeierstrass #1#2{% #1=\x or \y, etc..., #2=summation from 0 to #2
%    \edef\weierstrasscos {\@weierstrassseries {#1}{cos}{#2}}%
%    \edef\weierstrasssin {\@weierstrassseries {#1}{sin}{#2}}%
%}%

% \edef in \SetWeierstrass meant we had to use \noexpand here:

%\def\@weierstrassseries #1#2#3{% 
% #1 will be \x or \y etc... \noexpand as it will then end up in an \edef 
% #2=cos or sin 
% #3=summation will be from 0 to #3
%    \xintListWithSep{+}
%                    {\xintApply {\@weierstrassgeneralterm{\noexpand#1}{#2}}
%                                {\xintApply{\xintiiPow {2}}{\xintSeq {0}{#3}}}}%
%}

\makeatother

\begin{document}

% % debugging
% \SetWeierstrass \x{10}
% \show\weierstrasscos
% \show\weierstrasssin
% \stop

\begin{preview}
\begin{tikzpicture}\SetWeierstrass \x{0}
    \draw[thick, color=lightgray,step=0.25cm,solid] (-2,-1.5) grid (2,2);
    \draw[->] (-2.1,0) -- (2.1,0) ;
    \draw[->] (0,-1.6) -- (0,2.1) ;
    \draw[color=blue, thick, domain=-2:2, samples=101, /pgf/fpu, 
          /pgf/fpu/output format=fixed] 
       plot (\x, {\weierstrasscos}) ;
    \draw[color=red, thick, domain=-2:2, samples=101, /pgf/fpu, 
          /pgf/fpu/output format=fixed] 
       plot (\x, {\weierstrasssin}) ;
\end{tikzpicture}

\begin{tikzpicture}\SetWeierstrass \x{1}
    \draw[thick, color=lightgray,step=0.25cm,solid] (-2,-1.5) grid (2,2);
    \draw[->] (-2.1,0) -- (2.1,0) ;
    \draw[->] (0,-1.6) -- (0,2.1) ;
    \draw[color=blue, thick, domain=-2:2, samples=101, /pgf/fpu, 
          /pgf/fpu/output format=fixed] 
       plot (\x, {\weierstrasscos}) ;
    \draw[color=red, thick, domain=-2:2, samples=101, /pgf/fpu, 
          /pgf/fpu/output format=fixed] 
       plot (\x, {\weierstrasssin}) ;
\end{tikzpicture}

\begin{tikzpicture}\SetWeierstrass \x{2}
    \draw[thick, color=lightgray,step=0.25cm,solid] (-2,-1.5) grid (2,2);
    \draw[->] (-2.1,0) -- (2.1,0) ;
    \draw[->] (0,-1.6) -- (0,2.1) ;
    \draw[color=blue, thick, domain=-2:2, samples=101, /pgf/fpu, 
          /pgf/fpu/output format=fixed] 
       plot (\x, {\weierstrasscos}) ;
    \draw[color=red, thick, domain=-2:2, samples=101, /pgf/fpu, 
          /pgf/fpu/output format=fixed] 
       plot (\x, {\weierstrasssin}) ;
\end{tikzpicture}
\begin{tikzpicture}\SetWeierstrass \x{3}
    \draw[thick, color=lightgray,step=0.25cm,solid] (-2,-1.5) grid (2,2);
    \draw[->] (-2.1,0) -- (2.1,0) ;
    \draw[->] (0,-1.6) -- (0,2.1) ;
    \draw[color=blue, thick, domain=-2:2, samples=101, /pgf/fpu, 
          /pgf/fpu/output format=fixed] 
       plot (\x, {\weierstrasscos}) ;
    \draw[color=red, thick, domain=-2:2, samples=101, /pgf/fpu, 
          /pgf/fpu/output format=fixed] 
       plot (\x, {\weierstrasssin}) ;
\end{tikzpicture}
\end{preview}

% odd number of sample points to get it right at the origin.
\begin{preview}
\begin{tikzpicture}[scale=2]\SetWeierstrass \x{20}
    \draw[thick, color=lightgray,step=0.25cm,solid] (-2,-1.5) grid (2,2);
    \draw[->] (-2.1,0) -- (2.1,0) ;
    \draw[->] (0,-1.6) -- (0,2.1) ;
    \draw[color=blue, thick, domain=-2:2, samples=201, /pgf/fpu, 
          /pgf/fpu/output format=fixed] 
       plot (\x, {\weierstrasscos}) ;
    \draw[color=red, thick, domain=-2:2, samples=201, /pgf/fpu, 
          /pgf/fpu/output format=fixed] 
       plot (\x, {\weierstrasssin}) ;
\end{tikzpicture}
\end{preview}

\end{document}

weierstrass functions n=0,1,2,3

weierstrass n=20

\documentclass[multi=preview]{standalone}
\usepackage{tikz}
\usetikzlibrary{fpu}
\usepackage{pgfplots}
\usepackage{xintfrac, xinttools}

\makeatletter

\def\SetWeierstrass #1#2#3#4{% 
% #1=typically 'x' for pgfplots expression, 
% #2=sum will be from n=0 to #2
% formula will be:  sum of a^n * (cos or sin) (b^n x)
% a=#3, b=#4, may be fractions, numbers in scientific notations, fixed point ...
% their powers will be computed as float with only 6 digits precision
    \def\@weierX {\noexpand #1}% in case one has some \x, rather
    \def\@weierA {#3}%           perhaps with an \@weierstrassgeneralterm
    \def\@weierB {#4}%           not using floating point numbers...
    \def\@weierN {#2}%
    \edef\weierstrasscos {\@weierstrassseries {cos}}%
    \edef\weierstrasssin {\@weierstrassseries {sin}}%
}%
\def\@weierstrassseries #1{% #1 = cos or sin
    \xintListWithSep{+}
    {\xintApply{\@weierstrassgeneralterm {#1}}{\xintSeq {0}{\@weierN}}}%
}
\def\@weierstrassgeneralterm #1#2% [6] means 6 digits of precision
  {(\xintFloatPow [6]{\@weierA}{#2}*% #1= cos or sin
                #1(\xintFloatPow [6]{\@weierB}{#2}*\@weierX))}


\makeatother


\begin{document}

% debugging
% \SetWeierstrass x{5}{1/2}{3}
% \show\weierstrasscos
% % e.g. [was with 8 digits precision]
% % (1.0000000e0*cos(1.0000000e0*x))+(5.0000000e-1*cos(3.0000000e0*x))+
% % (2.5000000e-1*cos(9.0000000e0*x))+(1.2500000e-1*cos(2.7000000e1*x))+
% % (6.2500000e-2*cos(8.1000000e1*x))+(3.1250000e-2*cos(2.4300000e2*x)).
% \show\weierstrasssin

\begin{preview}
\begin{tikzpicture}[domain=-360:360]\SetWeierstrass {x}{10}{1/2}{3}%
    \begin{axis}[xmin=-360, xmax=+360, ymin=-2, ymax=+2, width=12cm,
      height=12cm, scale only axis]% ENFIN!
    \addplot [color=blue, samples=601] {\weierstrasscos} ;
    \addplot [color=red, samples=601]  {\weierstrasssin} ;
    \end{axis}
\end{tikzpicture}
\end{preview}

\begin{preview}
\begin{tikzpicture}[domain=-360:360]\SetWeierstrass {x}{0}{1/2}{3}%
    \begin{axis}[xmin=-360, xmax=+360, ymin=-2, ymax=+2, width=2.8cm,
      height=2.8cm, scale only axis]%
    \addplot [color=blue, samples=301] {\weierstrasscos} ;
    \addplot [color=red, samples=301]  {\weierstrasssin} ;
    \end{axis}
\end{tikzpicture}

\begin{tikzpicture}[domain=-360:360]\SetWeierstrass {x}{1}{1/2}{3}%
    \begin{axis}[xmin=-360, xmax=+360, ymin=-2, ymax=+2, width=2.8cm,
      height=2.8cm, scale only axis]%
    \addplot [color=blue, samples=301] {\weierstrasscos} ;
    \addplot [color=red, samples=301]  {\weierstrasssin} ;
    \end{axis}
\end{tikzpicture}

\begin{tikzpicture}[domain=-360:360]\SetWeierstrass {x}{2}{1/2}{3}%
    \begin{axis}[xmin=-360, xmax=+360, ymin=-2, ymax=+2, width=2.8cm,
      height=2.8cm, scale only axis]%
    \addplot [color=blue, samples=301] {\weierstrasscos} ;
    \addplot [color=red, samples=301]  {\weierstrasssin} ;
    \end{axis}
\end{tikzpicture}

\begin{tikzpicture}[domain=-360:360]\SetWeierstrass {x}{3}{1/2}{3}%
    \begin{axis}[xmin=-360, xmax=+360, ymin=-2, ymax=+2, width=2.8cm,
      height=2.8cm, scale only axis]%
    \addplot [color=blue, samples=301] {\weierstrasscos} ;
    \addplot [color=red, samples=301]  {\weierstrasssin} ;
    \end{axis}
\end{tikzpicture}

\end{preview}
\end{document}

weierstrass with pgfplots A weierstrass with pgfplots B

9
додано

Оскільки багато хто з вас запропонували не-tikz рішення, я відчував себе вільним запропонувати той, який використовує MetaPost. Вона запозичила багато елементів дуже чіткого Луа-розчину Герберта.

З самого недавнього впровадження арифметики з плаваючою комою в її ядрі, MetaPost став здатним виконувати цей вид обчислень. Було дуже приємно грати з нею і функцію Вейерштрасса, що нагадує мені про час мого студента математики :-)

Якщо ви хочете виконати наступну програму, якщо вона отримала назву weierstrass.mp , запустіть наступний командний рядок з форматом Metafun і прапором чисел встановлений на < код> подвійний :

mpost --mem = metafun --numbersystem = "double" weierstrass.mp

Для PDF-версії графіка запустіть mptopdf weierstrass.1 .

input latexmp ;
setupLaTeXMP(options="12pt", textextlabel = enable, mode = rerun);

% The pi number as defined in the current metafun format is too inaccurate
% for the new floating-point arithmetic of MetaPost, so I redefine it more precisely
pi := 3.14159265358979323846;

% Weierstrass sum (heavily inspired by Herbert's Lua code)
vardef weierstrass_sum(expr x, a, b, epsilon) =
    save k, y, dy; 
    y = 0; k = 0;
    forever:
        dy := a**k*cos(b**k*pi*x);
        y := y + dy; k := k + 1;
        exitif abs(dy) < epsilon;
    endfor;
    y
enddef;

% Weirstrass curve (also heavily inspired by Herbert's Lua code)
vardef weierstrass_curve(expr xs, xf, n, a, b, epsilon) =
    save k, x, dx;
    dx = (xf-xs)/n;
    (xs, weierstrass_sum(xs, a, b, epsilon))
    for x= xs+dx step dx until xf:
        -- (x, weierstrass_sum(x, a, b, epsilon))
    endfor
enddef;

beginfig(1); 
    % For scaling
    u := 4cm;
    % Weierstrass curve between -2 and 2, with n = 5000, a = 0.5, b = 3 and epsilon = 1e-12
    draw weierstrass_curve(-2, 2, 5000, 0.5, 3, 1e-12) xyscaled u withcolor red;
    % Axes
    drawarrow (-2u, 0) -- (2u, 0);
    drawarrow (0, -2.25u) -- (0, 2.25u);
    % Marking and labels
    eps := 3bp;
    labeloffset:=6bp;
    for x = -2, -1, 1, 2:
        draw (x*u, -eps)--(x*u, eps); label.bot("$" & decimal(x) & "$", (x*u, 0));
        draw (-eps, x*u)--(eps, x*u); label.lft("$" & decimal(x) & "$", (0, x*u));
    endfor;
endfig;

end.

enter image description here

8
додано

Спрощення рішення Джейка і його було взято (або викрадено) з ідеї Герберта.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot}
\begin{document}
\begin{pspicture}(-\psPi,-3)(\psPi,3)
    \psaxes(0,0)(-\psPi,-3)(\psPi,3)
    \psplot[linecolor=blue,plotpoints=1000]{Pi neg}{Pi}
    [userdict begin /a .5 def /b 3 def /n 15 def end]
    {userdict begin /out 0 def 0 1 n {dup a exch exp exch b exch exp Pi mul x mul RadtoDeg cos mul out add /out ED} for out end}
\end{pspicture}
\end{document}

enter image description here

7
додано
Не могли б ви додати інформацію про , де , щоб отримати більше інформації/Посилання на програмування PostScript команд userdict start/out 0 def 0 1 n {dup a ex ex exp b exch exp Pi ​​mul x mul RadtoDeg cos mul out додавання/видалення ED} для кінця і того, що вони означають, що я поняття не маю?
додано Автор Eric Lennartsson, джерело
psplot [...] {Pi neg} {Pi} [/ a .5 def/b 3 def/n 15 def] {/ out 0 def ...} , потім a, b, і n визначаються тільки один раз.
додано Автор Herbert, джерело
@Jake або обробляти документ безпосередньо за допомогою xelatex .
додано Автор Gonzalo Medina, джерело
Як ви компілюєте це? Я отримую ! Невизначена послідовність керування. c @ lor @ to @ ps ?
додано Автор Jake, джерело
Я починаю любити програмування PostScript ...
додано Автор kiss my armpit, джерело
@texenthusiast: Я оновлю цю відповідь, щоб він міг відповісти на ваш коментар пізніше, можливо, сьогодні або завтра. Я навчився писати псевдокод, щоб пояснити його.
додано Автор kiss my armpit, джерело
@Herbert: ОК. Дякуємо за інформацію про цю найкращу практику.
додано Автор kiss my armpit, джерело
@Jake: компілюйте послідовність latex-dvips-ps2pdf .
додано Автор kiss my armpit, джерело