Me quedé atrapado en un problema con el módulo pgfmath. Al intentar calcular los siguientes valores de funciones, el resultado que se imprime es siempre cero. Supongo que el problema es un desbordamiento insuficiente del codominio de pgfmaths y el motor matemático corta los valores pequeños.
Este es un ejemplo mínimo de lo que intentaba explicar en la introducción:
\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}
Ya me tomó mucho tiempo llegar tan lejos y sería muy frustrante para mí detenerme aquí y hacer todos los cálculos en una aplicación diferente.
Quizás alguien tenga una solución a mi problema.
De todos modos quiero usar esta publicación para decir ¡gracias! Este ha sido un lugar maravilloso para aprender látex hasta ahora, ¡buen trabajo a todos!
Respuesta1
actualización para volver a insistir en la inestabilidad numérica
Aquí está la salida del registro, usando gamma=1.2
y , lambda=0.466
que Lmin=4e-6
eran los valores del OP original. Se observan resultados similares, pero diferentes, con 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
Nota: He configurado la constante K
en valor 1
para omitir los cálculos con Pi
. Esto modifica el resultado aquí ya que las operaciones flotantes de redondeo no son exactamente iguales.
Código fuente para generar lo anterior.
\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}
También lo he probado con Maple. Nuevamente configurando K
a 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;
Los resultados son del mismo tipo pero con coincidencias y diferencias.
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
actualizar para comentar una curiosidad/inestabilidad numérica intrigante
Se solicitó la primera versión de OP N1(1, 4e-6, 1.2, 0.466, 0.115)
, que se trata a continuación. Aparentemente resulta que \numb
en ese caso es cero. Pero dependiendo de la precisión del flotador, se puede encontrar que es cero o no. El \numa
hecho de que sólo se trate de 1e-5
la precisión del resultado final puede reducirse drásticamente a valores pequeños pero distintos de cero \numb
.
Comparé y xint
obtuve maple
resultados similares (difieren solo en el último dígito) para 16
,, 20
dígitos 24
de precisión (lleva tiempo usar maple, hay más pruebas en camino). Para Pi
, hice mis pruebas xint
comenzando con 94
decimales y multiplicando primero por 1.0
para reducir a lo indicado \xintDigits
. Así ejecuté el siguiente código con
\xintDigits := 16; % or 20, 24, 28, ...
\xintdeffloatvar pi:= 1.*3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342;
Por el lado del Arce, Pi
se trata como un símbolo hasta el final evalf
.
Así es como se ven los resultados en el xint
lado con una precisión de flotación cada vez mayor:
8.038962683509860
8.0389626847662074875
8.03896268352242165100730
8.038962683509858157707745289
8.0389626835098594140570752438847
8.03896268350985817027123858823346261
8.038962683509858157707745288681429203705
8.0389626835098581577090016380113844070447859
8.03896268350985815770775785217472875573691848736
(Esto es para la solución con \numa+\numb
). Observe cómo el resultado con 16
dígitos esmucho mejorque el que tiene 20
dígitos!!!!!!! y es inclusoBastante mejorque el de 24
dígitos! (pero no tan bueno como 28
los dígitos). Esto se debe al hecho de que en los 16
dígitos, tanto xint como maple resultan \numb
ser cero, pero aproximadamente 3e-15
en los 20
dígitos induce un gran error en la suma, al igual que \numa
aproximadamente 1e-5
.
Con 92
dígitos de precisión se encuentra \numb
numéricamente 3e-51
. Si el valor exacto es cero, esto significa que estropea los dígitos del resultado después de aproximadamente 46
de ellos...
Con 92
dígitos de precisión, Maple descubre \numb
que
> evalf(Q(4e-6, 1.2, 0.466, 0.115));
0.3162277660168379331998893544432718533719555139325216826857504852792594438\
-50
6392382213442481084 10
y xint
obtiene
3.1622776601683793319988935444327185337195551393252168268575048527925944386392382213442481084e-51
Puedes ver que coincide hasta el final.;-)
actualizar¡Qué clase de tonto soy! ¿Cuántos años antes de reconocer la raíz cuadrada de
10
???? observe que lo anterior es esencialmente la raíz cuadrada de1e-101
... la razón parece bastante simple,\numb
es una raíz cuadrada de una diferencia, y de alguna manera esta diferencia, en lugar de ser cero, resulta1e-101
deberse a un error de redondeo en el último, Dígito 92 de cada término, que probablemente sean del orden de1e-10
!!! Sí, esto debería explicarlo para todos los nivelesN
de precisión de flotación. Supongo que a veces la diferencia es cero, a veces da1e-(9+N)
. Por ejemplo,N=20
se puede esperar una diferencia de1e-29
, por lo tanto, aproximadamente3e-15
en la raíz cuadrada, que esexactamente lo que se observa. Curiosamente, los números nunca parecen dar una diferencia-1e-(9+N)
que generaría un error en la raíz cuadrada.
A medida que los valores devueltos disminuyen al aumentar la precisión, tal vez pueda confiar en que el valor exacto es cero (no he hecho el álgebra). Si el valor exacto es realmente cero, sumar o restar lo anterior a algo que lo sea 0.000010117182975...
lo corromperá después de aproximadamente 46 dígitos significativos, destruyendo las evaluaciones flotantes de 92 dígitos para obtenerlo...
Muy sorprendente ! (pero lea el bloque citado arriba)
Esto debe tenerse en cuenta al comparar con cualquier otro motor matemático: la fórmula es numéricamente inestable debido a una posible cancelación catastrófica en una resta.
respuesta original
A continuación se muestra un enfoque que utiliza otro motor matemático. Sólo conoce la raíz cuadrada, pero aquí esto es suficiente. Tenga en cuenta que en el ejemplo dado \numb
resulta ser exactamente cero.
\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}
En este ejemplo, las dos soluciones son las mismas, ya que los \numb
desvanecimientos...
Observe que las soluciones se calculan de manera expandible. Eso les importa a algunos (tontos...).
Si desea más precisión, comience con:
\xintDigits := 32;
\xintdeffloatvar pi:= 3.141592653589793238462643383279503;
Respuesta2
Podrías intentar seguir la lualatex
ruta y luego tener toda la precisión de las matemáticas lua
, así que no, pgf
en absoluto. Lo siguiente puede mostrar la respuesta incorrecta, pero eso no se debe a las capacidades matemáticas de lua
, sino más bien a una traducción bastante apresurada de la fórmula requerida:
\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}
Respuesta3
Actualización 1: pgfmath + fpu
He jugado un poco con XINT
el día de hoy pero debido a su falta de funciones matemáticas volví a mi pgfmath
enfoque. Hay algunas fórmulas más que necesito incorporar más adelante, para quienes necesito funciones trigonométricas, etc. y, hasta donde puedo ver, no hay ninguna implementación disponible para aquellas en xint. Con la sugerencia de Mark sobre su uso \usetikzlibrary{fpu}
para mayor precisión, finalmente lo hice funcionar, después de algunos ajustes.
Ese es mi código hasta ahora:
\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}
pero no estoy seguro de la precisión de los resultados. en comparación con la solución jfbus y mi salida de wxMaxima, la raíz cuadrada en el numerador ahora ya no es cero, aunque es muy pequeña (e-18). Incluso si es una diferencia muy pequeña, estoy interesado en la precisión general de pgfmaths. porque estoy planeando hacer todos los cálculos en Latex más adelante, cuando esté compilando, y me veo cuestionando cada cálculo después.
Considerándolo todo, ¿creen que es una buena idea usar pgfmath para este tipo de aplicaciones? ¿Alguien ha hecho algo similar o es simplemente una mala idea confiar en un procesador de textos en matemáticas?
Por cierto, ahora lo he usado \pgfmathsetmacro
para guardar los resultados que necesito más adelante. ¿Existe una solución mejor o es esta la forma común?
Actualización 2: LuaTeX + luacode
Hasta ahora, todo bien. Sé que abandoné mi pgfmath
enfoque debido a su inexactitud y ahora me concentro en la versión luaTeX de Mark.
Esta solución me ofrece una buena manera de incorporar las soluciones calculadas en fórmulas y texto. pero para que esto sea realmente útil, necesito que funcione en pgfplot
el entorno. Aquí hay un ejemplo:
\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}