серьезные научные вычисления с небольшими числами, с использованием различных методов

серьезные научные вычисления с небольшими числами, с использованием различных методов

Я застрял в проблеме с модулем pgfmath. При попытке вычислить следующие значения функций выводимый результат всегда равен нулю. Я предполагаю, что проблема в недорасходе области действия pgfmaths, и математический движок отсекает малые значения.

Это минимальный пример того, что я пытался объяснить во введении:

\documentclass[tikz]{standalone}
\usepackage[fleqn]{amsmath}
% physical constants:
\pgfmathdeclarefunction{m0}{0}{%
    \pgfmathparse{4*pi*1e-7}%
}

\pgfmathdeclarefunction{K}{0}{%
    \pgfmathparse{m0*pi/4}%
}
\pgfmathdeclarefunction{c1}{0}{% c1 = K/1.45
    \pgfmathparse{K/1.45}%
}
\pgfmathdeclarefunction{c2}{1}{% c2(gamma) = c1/gamma^2
    \pgfmathparse{c1/(#1)^2}%
}
\pgfmathdeclarefunction{c3}{2}{% c3(gamma,lambda)
    \pgfmathparse{K/((#1)*((#2)+0.45))}%
}
\pgfmathdeclarefunction{DL_rel}{2}{% DL_rel(lambda, gamma)
    \pgfmathparse{(2*sqrt((580*#1+261)*#2^3)+40*#1+18)/(29*#2^3-20*#1-9)}%
}

% the problematic pgfmath-function
\pgfmathdeclarefunction{N1}{5}{% N1(soluition, Lmin, gamma, lambda, d1)
    \pgfmathsetmacro\numa{(DL_rel(#4,#3)*#2)/2+#2}%
    \pgfmathsetmacro\numb{sqrt(\numa^2-c1*c3(#3,#4))/(4*c2(#3)^2)}%
    \pgfmathsetmacro\denom{2*c1*#5}%
    \pgfmathparse{(#1 -1) ?%
        (sqrt((\numa + \numb)/\denom))%
        :%
        (sqrt((\numa - \numb)/\denom))%
    }%
}

\begin{document}
    This is the equation im trying to solve:
    \begin{equation} \label{eq:N1}
    N_{1_{1,2}} =\sqrt{
        \frac{\frac{\Delta L}{2} +L_{min} \pm \sqrt{\left(\frac{\Delta L}{2} + L_{min}\right)^2 - \frac{c_1 c_3}{4\cdot c_2^2}\cdot \Delta L^2}}
        {2\cdot c_1 d_1}
    }
    \end{equation}
    This should print out its solution:
    \begin{equation*}
    N_{1_{1,2}} =
    \left\{ \begin{array}{l}
    \pgfmathparse{N1(1, 4e-4, 1.2, 0.466, 0.115)}\pgfmathresult\\
    \pgfmathparse{N1(2, 4e-4, 1.2, 0.466, 0.115)}\pgfmathresult
    \end{array}\right.
    \end{equation*}
\end{document}

введите описание изображения здесь

Мне потребовалось уже слишком много времени, чтобы дойти до этого, и мне было бы очень обидно остановиться здесь и выполнить все математические расчеты в другом приложении.

Может быть, у кого-то есть решение моей проблемы.

В любом случае, я хочу использовать этот пост, чтобы сказать спасибо! Это было чудесное место для изучения латекса, молодцы все!

решение1

обновление, чтобы вновь настоять на численной нестабильности

введите описание изображения здесь

Вот из лог-вывода, с использованием gamma=1.2, lambda=0.466и Lmin=4e-6, которые были значениями из исходного OP. Похожие, но отличающиеся результаты наблюдаются с gamma=1.2, lambda=0.44.

4: -1.00000e-13
5: 0
6: 0
7: 0
8: 0
9: 0
10: 2.00000e-19
11: 1.00000e-20
12: 2.00000e-21
13: 1.00000e-22
14: 1.00000e-23
15: 1.00000e-24
16: 0
17: 0
18: 0
19: 0
20: 1.00000e-29
21: 1.00000e-30
22: 0
23: 0
24: 1.00000e-33
25: 1.00000e-34
26: 0
27: 2.00000e-36
28: 0
29: 0
30: 0
31: -1.00000e-40
32: 2.00000e-41
33: 0
34: 2.00000e-43
35: 0
36: 1.00000e-45
37: 1.00000e-46
38: 0
39: -1.00000e-48
40: 0
41: 0
42: -1.00000e-51
43: 1.00000e-52
44: 1.00000e-53
45: 1.00000e-54
46: 0
47: 1.00000e-56
48: 1.00000e-57
49: 0
50: 1.00000e-59
51: 2.00000e-60
52: 0
53: 0
54: 2.00000e-63
55: 1.00000e-64
56: 2.00000e-65
57: 0
58: 0
59: 1.00000e-68
60: 1.00000e-69
61: 0
62: -1.00000e-71
63: 0
64: -1.00000e-73
65: 0
66: 0
67: 1.00000e-76
68: 0
69: 0
70: -1.00000e-79
71: 1.00000e-80
72: 0
73: 0
74: 0
75: 0
76: 0
77: 0
78: -1.00000e-87
79: 1.00000e-88
80: 1.00000e-89
81: 1.00000e-90
82: 1.00000e-91
83: 1.00000e-92
84: 1.00000e-93
85: 0
86: 0
87: 0
88: 1.00000e-97
89: 1.00000e-98
90: 1.00000e-99
91: 0
92: 1.00000e-101

Примечание: Я установил константу Kв значение 1, чтобы пропустить вычисления с Pi. Это изменяет результат здесь, поскольку операции округления float не совсем одинаковы.

Исходный код для генерации вышеуказанного.

\documentclass{article}
\usepackage{xintexpr}% tested with 1.2e release
%\xintverbosetrue

\usepackage[fleqn]{amsmath}

\begin{document}
This is the equation im trying to solve:
\begin{equation} \label{eq:N1}
    N_{1_{1,2}} =\sqrt{
      \frac{\frac{\Delta L}{2} +L_{min} \pm \sqrt{\left(\frac{\Delta L}{2} + L_{min}\right)^2 - \frac{c_1 c_3}{4\cdot c_2^2}\cdot \Delta L^2}}
           {2\cdot c_1 d_1}
    }
\end{equation}

The $\Delta L/L_{min}$, $c_1$, $c_2$, $c_3$ are functions of some parameters
($L_{min}$ is only an overall scaling) and these functions are set-up in such
a way that actually the square root at the numerator of the fraction vanishes
exactly, independently of the values of the parameters. Numerically though it
may be found non zero and this will then induce a catastrophic drop in
precision in the final result. And it may even happen that it will be found
negative, thus potentially raising an error in the complete evaluation.

See the compilation log for this problematic $\left(\frac{\Delta L}{2} +
  L_{min}\right)^2 - \frac{c_1 c_3}{4\cdot c_2^2}\cdot \Delta L^2$ evaluated
with the float precision set to various values. You will see it turns negative
at times.        

% \xintdeffloatvar pi:= 
% 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342;

\xintFor* #1 in {\xintSeq{4}{92}}\do
{
\xintDigits := #1;

% constants
% \xintdeffloatvar m0:= 4pi*1e-7;
% \xintdeffloatvar K := m0*pi/4;
\xintdeffloatvar K := 1;
\xintdeffloatvar c1:= K/1.45;


% functions
\xintdeffloatfunc c2(u)  := c1/u^2;
\xintdeffloatfunc c3(u,v):= K/(u(v+0.45));

% attention arguments like in OP-update, permuted compared to the OP-original
\xintdeffloatfunc DL_rel(u,v):= (2sqrt((580v+261)u^3)+40v+18)/(29u^3-20v-9);

\xintdeffloatfunc DL(t,u,v)  := DL_rel(u,v)*t;

% Notice that t=Lmin acts only as an overall scaling factor.
\xintdeffloatfunc numbsquared(t,u,v):=
                  subs((Z/2+t)^2-c1*c3(u,v)/(4*c2(u)^2)*Z^2, Z=DL(t,u,v));

\typeout{#1: \xintthefloatexpr [6] numbsquared (4e-6, 1.2, 0.466)\relax }

}

\end{document}

Я также протестировал Maple. Снова установил Kзначение 1.

numbsquared := proc (N)
local m0, K, c1, c2, c3, DL_rel, DL, localnumbsquared;
Digits:=N;
# m0 := 4*Pi*1e-7;
# K  :=  m0*Pi/4;
K  := 1;
c1 := K/1.45;
c2 := u->c1/u^2;
c3 := (u,v)->K/(u*(v+0.45));
DL_rel := (u,v)->(2*sqrt((580*v+261)*u^3)+40*v+18)/(29*u^3-20*v-9);
DL := (t,u,v)->DL_rel(u,v)*t;
localnumbsquared := (t,u,v)->subs(Z=DL(t,u,v),(Z/2+t)^2-c1*c3(u,v)/(4*c2(u)^2)*Z^2);
return localnumbsquared(4e-6, 1.2, 0.466)
end proc:
for N from 4 to 92 do printf("%2d, %e\n", N, numbsquared(N)) end do;

Результаты однотипны, но имеются как совпадения, так и различия.

 4, 0.000000e+00
 5, 0.000000e+00
 6, 0.000000e+00
 7, 0.000000e+00
 8, 0.000000e+00
 9, 1.000000e-18
10, 2.000000e-19
11, 1.000000e-20
12, -1.000000e-21
13, 1.000000e-22
14, -1.000000e-23
15, 1.000000e-24
16, 0.000000e+00
17, 0.000000e+00
18, 0.000000e+00
19, 0.000000e+00
20, 1.000000e-29
21, 1.000000e-30
22, 0.000000e+00
23, 1.000000e-32
24, -1.000000e-33
25, 1.000000e-34
26, 0.000000e+00
27, 2.000000e-36
28, 1.000000e-37
29, 0.000000e+00
30, 0.000000e+00
31, -1.000000e-40
32, 2.000000e-41
33, 0.000000e+00
34, 2.000000e-43
35, -1.000000e-44
36, 1.000000e-45
37, 1.000000e-46
38, 0.000000e+00
39, -1.000000e-48
40, 0.000000e+00
41, 0.000000e+00
42, -1.000000e-51
43, 1.000000e-52
44, -1.000000e-53
45, 1.000000e-54
46, 0.000000e+00
47, -1.000000e-56
48, 1.000000e-57
49, 0.000000e+00
50, 1.000000e-59
51, 0.000000e+00
52, 0.000000e+00
53, 0.000000e+00
54, 2.000000e-63
55, 1.000000e-64
56, 0.000000e+00
57, 0.000000e+00
58, 0.000000e+00
59, 1.000000e-68
60, 1.000000e-69
61, 0.000000e+00
62, -1.000000e-71
63, 0.000000e+00
64, -1.000000e-73
65, 0.000000e+00
66, 0.000000e+00
67, 1.000000e-76
68, -2.000000e-77
69, -1.000000e-78
70, -1.000000e-79
71, 1.000000e-80
72, 0.000000e+00
73, 0.000000e+00
74, 0.000000e+00
75, 0.000000e+00
76, 0.000000e+00
77, 0.000000e+00
78, 0.000000e+00
79, 1.000000e-88
80, -1.000000e-89
81, -1.000000e-90
82, 1.000000e-91
83, 0.000000e+00
84, -1.000000e-93
85, 0.000000e+00
86, 0.000000e+00
87, 0.000000e+00
88, -1.000000e-97
89, -2.000000e-98
90, 1.000000e-99
91, -2.000000e-100
92, 1.000000e-101

обновление для комментария интригующего числового любопытства/нестабильности

Первая версия OP запросила N1(1, 4e-6, 1.2, 0.466, 0.115), которая рассматривается ниже. Оказывается, по-видимому, что \numbв этом случае равно нулю. Но в зависимости от точности float он может быть найден или не быть равным нулю. То, \numaчто касается только 1e-5точности конечного результата, может быть радикально уменьшено небольшим, но ненулевым \numb.

Я сравнил xintс mapleи получил похожие результаты (отличаются только последней цифрой) для 16, 20, 24цифр точности (требуется время для использования maple, больше тестов в пути). Для Pi, я провел свои тесты, xintначав с 94десятичных дробей и умножив сначала на , 1.0чтобы сократить до указанного \xintDigits. Таким образом, я запустил код ниже с

\xintDigits := 16; % or 20, 24, 28, ... 
\xintdeffloatvar pi:= 1.*3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342;

На кленовой стороне Piрассматривается как символ до финала evalf.

Вот как выглядят результаты сбоку xintс более высокой и более высокой точностью с плавающей точкой:

8.038962683509860
8.0389626847662074875
8.03896268352242165100730
8.038962683509858157707745289
8.0389626835098594140570752438847
8.03896268350985817027123858823346261
8.038962683509858157707745288681429203705
8.0389626835098581577090016380113844070447859
8.03896268350985815770775785217472875573691848736

(это для решения с \numa+\numb). Обратите внимание, как выглядит результат с 16цифраминамного лучшечем тот, у которого есть 20цифры!!!!!!! и он дажегораздо лучшечем для 24цифр! (но не так хорошо, как 28цифры). Это связано с тем, что при 16цифрах и xint, и maple оказываются \numbравными нулю, но около 3e-15цифр 20, что приводит к большой ошибке в сумме, как \numaи около 1e-5.

С 92цифрами точности можно найти \numbоколо 3e-51численно. Если точное значение равно нулю, это означает, что оно портит цифры результата после около 46из них...

С 92точностью цифр Maple находит, \numbчто

> evalf(Q(4e-6, 1.2, 0.466, 0.115)); 
0.3162277660168379331998893544432718533719555139325216826857504852792594438\

                          -50
    6392382213442481084 10

И xintполучает

3.1622776601683793319988935444327185337195551393252168268575048527925944386392382213442481084e-51 вы можете видеть, что он совпадает до конца.;-)

обновлятьКакой же я дурак! Сколько лет прошло, прежде чем я узнал квадратный корень из 10???? обратите внимание, что выше по сути квадратный корень из 1e-101... причина кажется достаточно простой, что \numbэто квадратный корень из разности, и каким-то образом эта разность, вместо того чтобы быть найденной равной нулю, оказывается из- 1e-101за ошибки округления в последней, 92-й цифре каждого члена, которые, вероятно, имеют порядок 1e-10!!! Да, это должно объяснить это для всех уровней Nточности с плавающей точкой. Я думаю, иногда разность равна нулю, иногда она дает 1e-(9+N). Например, с N=20можно ожидать разность 1e-29, следовательно, около 3e-15на квадратный корень, который равенточно что наблюдается. Странно, что числа никогда не дают разницы, -1e-(9+N)которая бы повысилась при ошибке на квадратном корне.

Поскольку возвращаемые значения уменьшаются с увеличением точности, возможно, я могу доверять точному значению — нулю (я не занимался алгеброй). Если точное значение действительно равно нулю, добавление или вычитание указанного выше значения из чего-то, что равно нулю, 0.000010117182975...испортит его примерно после 46 значащих цифр, уничтожив 92-разрядные оценки с плавающей точкой, чтобы получить его...

Очень неожиданно ! (но прочитайте цитируемый выше блок)

Это следует учитывать при сравнении с любой другой математической машиной: формула численно нестабильна из-за возможного катастрофического сокращения при вычитании.


оригинальный ответ

Вот подход с использованием другой математической машины. Она знает только квадратный корень, но здесь этого достаточно. Обратите внимание, что в данном примере \numbполучается ровно ноль.

\documentclass[tikz]{standalone}
\usepackage{xintexpr}% tested with 1.2e release
\usepackage[fleqn]{amsmath}

% constants
\xintdeffloatvar pi:= 3.14159265358979323846;
\xintdeffloatvar m0:= 4pi*1e-7;
\xintdeffloatvar K := m0*pi/4;
\xintdeffloatvar c1:= K/1.45;

% functions
\xintdeffloatfunc c2(x)  := c1/x^2;

\xintdeffloatfunc c3(x,y):= K/(x(y+0.45));

\xintdeffloatfunc DL_rel(u,v):= 
    (2*sqrt((580*u+261)*v^3)+40*u+18)/(29*v^3-20*u-9);

% This is allowed by xint parser also (tacit multiplications):
% \xintdeffloatfunc DL_rel(u,v):= (2sqrt((580u+261)v^3)+40u+18)/(29v^3-20u-9);

% Of course we could simplify here by defining more intermediate functions.
% We could define "numa" and "numb" functions, and set them up as functions
% of an already computed "DL_rel" which serves in both.
% It is possible to use the "subs(expression, x=...)" syntax.
% Limitation is that the dummy parameter must be a single letter.
% Also, the inner-most subs will have the last defined thing, and the
% outer-most subs the first defined thing.
\xintdeffloatfunc N1(a,t,u,v,w):=
    subs(subs(subs(subs(
    if(a=1, sqrt((P+Q)/D), sqrt((P-Q)/D)),
% debugging because something is strange with Q = \numb which is zero
% (P, sqrt(c1*c3(u,v))/c2(u)*X ), 
% well after all it was CORRECT that Q was zero with these numerics
       Q = sqrt(P^2-c1*c3(u,v)/(c2(u)^2)*X^2)% =\numb,
                       ),
       P = X+t % P=\numa, and I think t is Lmin
                  ),
       X = DL_rel(v,u)*t/2 % X= DeltaL/2
              ),    
       D = 2c1*w % D=\denom
         )% must use single letters in subs
    ;%


\begin{document}
This is the equation im trying to solve:
\begin{equation} \label{eq:N1}
    N_{1_{1,2}} =\sqrt{
      \frac{\frac{\Delta L}{2} +L_{min} \pm \sqrt{\left(\frac{\Delta L}{2} + L_{min}\right)^2 - \frac{c_1 c_3}{4\cdot c_2^2}\cdot \Delta L^2}}
           {2\cdot c_1 d_1}
    }
\end{equation}

This should print out its solution:
\begin{equation*}
 N_{1_{1,2}} =
  \left\{ \begin{array}{l}
            \xintthefloatexpr N1(1, 4e-6, 1.2, 0.466, 0.115)\relax\\
            \xintthefloatexpr N1(2, 4e-6, 1.2, 0.466, 0.115)\relax
          \end{array}\right.
\end{equation*}
\end{document}

В этом примере два решения одинаковы, так как \numbобращается в нуль...

Цитата из блока

Обратите внимание, что решения вычисляются расширяемо. Для некоторых (дураков...) это имеет значение.

Если вам нужна большая точность, начните с:

\xintDigits := 32;
\xintdeffloatvar pi:= 3.141592653589793238462643383279503;

решение2

Вы можете попробовать пойти по этому lualatexпути и тогда иметь всю точность математики в lua, так что нет pgfвообще. Следующее может показать неправильный ответ, но это не из-за математических возможностей lua, скорее всего, просто довольно поспешный перевод требуемой формулы:

\documentclass[preview,border=5]{standalone}
\usepackage[fleqn]{amsmath}
\usepackage{luacode}
\begin{luacode*}
pi = math.pi
sqrt = math.sqrt
m0 = 4 * pi * 1e-7
K = m0 * pi / 4
c1 = K / 1.45
c2 = function (x) return c1 / (x^2); end 
c3 = function (x, y) return K / (x * (y + 0.45)); end
DLrel = function (x, y) 
  return (2 * sqrt((580 * x + 261) * y^3) + 40 * x + 18) /
    (29 * y^3 - 20 * x - 9)
end
N1 = function (s, Lmin, g, l, d1) 
  dL = DLrel(l, g) * Lmin
  nm = dL / 2 + Lmin
  rt = (nm^2 - c1 * c3(g, l) * 0.25 * c2(g)^-2 * dL^2)
  dn = 2 * c1 * d1
  s = -(s % 2) * 2 + 1
  return sqrt((nm + s * sqrt(rt)) / dn) 
end
\end{luacode*}
\def\luaprint#1{\directlua{tex.print(#1)}}
\begin{document}
\begin{equation*}
  N_{1_{1,2}} = \left\{ 
\begin{array}{l}
  \luaprint{N1(1, 4e-4, 1.2, 0.44, 0.115)}
\\    
  \luaprint{N1(2, 4e-4, 1.2, 0.44, 0.115)}
\end{array}\right.
\end{equation*}
\end{document}

введите описание изображения здесь

решение3

Обновление 1: pgfmath + fpu

Я немного поигрался с XINTtoday, но из-за отсутствия математических функций вернулся к своему pgfmathподходу. Есть еще несколько формул, которые мне нужно будет встроить позже, для которых мне нужны тригонометрические функции и т. д., и насколько я могу судить, для них нет доступной реализации в xint. С подсказкой Марка об использовании \usetikzlibrary{fpu}для более высокой точности я наконец-то заставил это работать, после некоторой настройки.

Вот мой код на данный момент:

\documentclass[tikz]{standalone}
\usepackage[fleqn]{amsmath}
\usetikzlibrary{fpu}

% physical constants:
\pgfmathdeclarefunction{m0}{0}{%
    \pgfmathparse{4*pi*1e-7}%
}

\pgfmathdeclarefunction{K}{0}{%
    \pgfmathparse{m0*pi/4}%
}
\pgfmathdeclarefunction{c1}{0}{% c1 = K/1.45
    \pgfmathparse{K/1.45}%
}
\pgfmathdeclarefunction{c2}{1}{% c2(gamma) = c1/gamma^2
    \pgfmathparse{c1/(#1)^2}%
}
\pgfmathdeclarefunction{c3}{2}{% c3(gamma,lambda)
    \pgfmathparse{K/((#1)*((#2)+0.45))}%
}
\pgfmathdeclarefunction{DL_rel}{2}{% DL_rel(gamma, lambda)
    \pgfmathparse{(2*sqrt((580*#2+261)*#1^3)+40*#2+18)/(29*#1^3-20*#2-9)}%
}

% the problematic pgfmath-function
%                                   #1         #2    #3     #4      #5
\pgfmathdeclarefunction{N1}{5}{% N1(soluition, Lmin, gamma, lambda, d1)
    \pgfmathsetmacro\DL{(DL_rel(#3,#4)*#2)}%
    \pgfmathsetmacro\numa{\DL/2+#2}%
    \pgfmathsetmacro\numb{sqrt(\numa^2 - c1*c3(#3,#4)/(4*c2(#3)^2)*\DL^2)}%
    \pgfmathsetmacro\denom{2*c1*#5}%
    \pgfmathfloatparse{(#1 == 1) ?%
        (sqrt((\numa + \numb)/\denom))%
        :%
        (sqrt((\numa - \numb)/\denom))%
    }%
}

\begin{document}
    \pgfkeys{/pgf/fpu=true}
    \pgfmathparse{N1(1, 4e-6, 1.2, 0.44, 0.115)}\pgfmathprintnumber[sci, precision=2]{\pgfmathresult}\\
    \pgfkeys{/pgf/fpu=false}
    This is the equation im trying to solve:
    \begin{equation} \label{eq:N1}
    N_{1_{1,2}} =\sqrt{
        \frac{\frac{\Delta L}{2} +L_{min} \pm \sqrt{\left(\frac{\Delta L}{2} + L_{min}\right)^2 - \frac{c_1 c_3}{4\cdot c_2^2}\cdot \Delta L^2}}
        {2\cdot c_1 d_1}
    }
    \end{equation}
    This should print out its solution:
    \pgfkeys{/pgf/fpu=true}
    \begin{equation*}
    N_{1_{1,2}} =
    \left\{ \begin{array}{l}
    \pgfmathparse{N1(1, 4e-6, 1.2, 0.44, 0.115)}\pgfmathprintnumber[fixed, precision=2]{\pgfmathresult}\\
    \pgfmathparse{N1(2, 4e-6, 1.2, 0.44, 0.115)}\pgfmathprintnumber[fixed, precision=2]{\pgfmathresult}
    \end{array}\right.
    \end{equation*}
    \pgfkeys{/pgf/fpu=false}
\end{document}

но я не уверен в точности результатов. по сравнению с решением jfbus и моим выводом из wxMaxima квадратный корень в числителе теперь больше не равен нулю, хотя он очень мал (e-18). Даже если это очень маленькая разница, меня интересует общая точность pgfmaths. потому что я планирую сделать всю математику в Latex позже, когда буду компилировать, и я вижу, как я подвергаю сомнению каждое вычисление впоследствии.

Итак, в общем, ребята, как вы думаете, хорошая ли это идея использовать pgfmath для такого рода приложений? Кто-нибудь делал что-то подобное, или это просто плохая идея доверять текстовому процессору в математике?

Кстати, я теперь использую \pgfmathsetmacroдля сохранения результатов, которые мне понадобятся позже. Есть ли лучшее решение, или это общепринятый способ?


Обновление 2: LuaTeX + luacode

Пока все хорошо. Я знаю pgfmath, что отказался от своего подхода из-за его неточности и теперь сосредоточился на версии LuaTeX Марка.

Это решение предлагает мне хороший способ встроить вычисленные решения в формулы и текст. Но чтобы сделать этот материал действительно полезным, мне нужно заставить его работать в pgfplotсреде. Вот пример:

\documentclass[preview,border=5]{standalone}
\usepackage[fleqn]{amsmath}
\usepackage{luacode}
\usepackage{tikz}
\usepackage{pgfplots}
\begin{luacode*}
    -- test
    pi = math.pi
    sqrt = math.sqrt
    m0 = 4 * pi * 1e-7
    K = m0 * pi / 4
    c1 = K / 1.45
    c2 = function (g) return c1 / (g^2); end 
    c3 = function (g, l) return K / (g * (l + 0.45)); end
    DLrel = function (g, l) 
        return  (2 * sqrt((580 * l + 261) * g^3) + 40 * l + 18) /
                (29 * g^3 - 20 * l - 9)
    end
    DLrel_lmd = function (l) return DLrel(sqrt(l^2+1),l); end

    N1 = function (s, Lmin, g, l, d1) 
        dL = DLrel(g, l) * Lmin
        nm = dL / 2 + Lmin
        rt = (nm^2 - c1 * c3(g, l) * 0.25 * c2(g)^-2 * dL^2)
        dn = 2 * c1 * d1
        s = -(s % 2) * 2 + 1
    return sqrt((nm + s * sqrt(rt)) / dn) 
    end

    print = function (d,s) 
        if d == 0 then
         format = "%d"
        else
         format = "%." .. d .. "f"
        end
        tex.sprint(string.format(format,s));
    end

\end{luacode*}
\newcommand{\lp}[2][16]{\directlua{print(#1,#2)}}

\begin{document}
    now i can do calculations in lua and print them out in formulas:
    \begin{equation*}
        N_{1_{1,2}} = \left\{ 
        \begin{array}{l}
            \lp[4]{N1(1, 4e-6, 1.2, 0.446, 0.115)}
            \\    
            \lp[4]{N1(2, 4e-6, 1.2, 0.446, 0.115)}
        \end{array}\right.
    \end{equation*}

    Some serious research done here..\\
    ..oh some new values i came across, i can embed them in my text:\\

\begin{luacode}
    now  = 42.42424242424242
\end{luacode}

    \(  now = \lp[4]{now}\)
    as you can see in this fancy plot:

    \begin{tikzpicture}
        \begin{axis}[
                width=0.5\linewidth,
                height=10cm,
                xmin=0, xmax=180,
                ymin=0, ymax=50,
                xlabel=$time$,
                ylabel=Questions accouring while learning LaTeX,
            ]
            \addplot[
            thick,
            blue,
            domain=0:180,
            samples=200,
            ]{42*sin(x)}; % This value should be taken from lua
            \addplot[
            red,
            only marks
            ] coordinates {
                (90, 42) % This value should be taken from lua
            }
            [yshift=10pt, xshift = 10pt]
            node[pos=0] {$now = 42$}; % This value should be taken from lua
        \end{axis}
    \end{tikzpicture}
\end{document}

введите описание изображения здесь

Связанный контент