ernsthaftes wissenschaftliches Rechnen mit kleinen Zahlen, unter Anwendung verschiedener Methoden

ernsthaftes wissenschaftliches Rechnen mit kleinen Zahlen, unter Anwendung verschiedener Methoden

Ich stecke bei einem Problem mit dem pgfmath-Modul fest. Beim Versuch, die folgenden Funktionswerte zu berechnen, ist das ausgegebene Ergebnis immer Null. Ich vermute, das Problem ist ein Unterlauf des pgfmath-Co-Domains und die mathematische Engine schneidet die kleinen Werte ab.

Dies ist ein Minimalbeispiel dessen, was ich in der Einleitung zu erklären versuchte:

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

Bildbeschreibung hier eingeben

Ich habe schon viel zu lange gebraucht, um so weit zu kommen, und es wäre sehr frustrierend für mich, hier aufzuhören und die ganze Berechnung in einer anderen Anwendung durchführen zu lassen.

Vielleicht hat ja jemand da draußen eine Lösung für mein Problem.

Ich möchte diesen Beitrag jedenfalls nutzen, um Danke zu sagen! Dies war bisher ein wunderbarer Ort, um Latex zu lernen, gute Arbeit, alle zusammen!

Antwort1

Update, um erneut auf numerische Instabilität zu bestehen

Bildbeschreibung hier eingeben

Hier ist die Protokollausgabe unter Verwendung von gamma=1.2, lambda=0.466und Lmin=4e-6, die die Werte aus dem ursprünglichen OP waren. Ähnliche, aber unterschiedliche Ergebnisse werden mit gamma=1.2, beobachtet 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

Hinweis: Ich habe konstant Kauf Wert gesetzt 1, um die Berechnungen mit zu überspringen Pi. Dies ändert das Ergebnis hier, da die Rundungsoperationen für Gleitkommazahlen nicht genau gleich sind.

Quellcode zum Generieren des oben genannten.

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

Ich habe es auch mit Maple getestet. Auch hier die Einstellung Kauf 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;

Die Ergebnisse sind vom gleichen Typ, weisen jedoch sowohl Übereinstimmungen als auch Unterschiede auf.

 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

Update, um eine faszinierende numerische Neugier/Instabilität zu kommentieren

Die erste Version des OP verlangte N1(1, 4e-6, 1.2, 0.466, 0.115), was weiter unten behandelt wird. Es stellt sich anscheinend heraus, dass \numbin diesem Fall Null ist. Aber je nach Gleitkommagenauigkeit kann es Null sein oder auch nicht. Dass es \numanur um 1e-5die Genauigkeit des Endergebnisses geht, kann durch kleine, aber nicht Nullen drastisch reduziert werden \numb.

Ich habe xintmit verglichen mapleund ähnliche Ergebnisse erhalten (unterscheiden sich nur in der letzten Ziffer) für 16, 20, 24Ziffern Genauigkeit (braucht Zeit, um Maple zu verwenden, weitere Tests sind unterwegs). Für Pihabe ich meine Tests in durchgeführt, xintbeginnend mit 94Dezimalzahlen und zuerst mit multipliziert, 1.0um auf die angegebenen zu reduzieren \xintDigits. Daher habe ich den folgenden Code mit ausgeführt

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

Auf der Ahornseite Piwird bis zum Ende als Symbol behandelt evalf.

So sehen die Ergebnisse auf der xintSeite mit immer höherer Float-Präzision aus:

8.038962683509860
8.0389626847662074875
8.03896268352242165100730
8.038962683509858157707745289
8.0389626835098594140570752438847
8.03896268350985817027123858823346261
8.038962683509858157707745288681429203705
8.0389626835098581577090016380113844070447859
8.03896268350985815770775785217472875573691848736

(dies gilt für die Lösung mit \numa+\numb). Beachten Sie, dass das Ergebnis mit 16Ziffernviel besserals das mit 20Ziffern!!!!!!! und es ist sogarganz besserals der für 24Ziffern! (aber nicht so gut wie 28Ziffern). Dies liegt an der Tatsache, dass 16sowohl xint als auch maple bei Ziffern \numbNull ergeben, aber ungefähr 3e-15bei 20Ziffern, was zu einem großen Fehler in der Summe führt, ebenso wie \numaungefähr 1e-5.

Mit 92der Dezimalstellen-Genauigkeit findet man \numbetwa 3e-51numerisch. Wenn der exakte Wert Null ist, bedeutet dies, dass die Ziffern des Ergebnisses nach etwa 46davon verfälscht werden...

Mit 92einer Genauigkeit von mehreren Ziffern findet \numbMaple

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

                          -50
    6392382213442481084 10

Und xinterhält

3.1622776601683793319988935444327185337195551393252168268575048527925944386392382213442481084e-51 Sie können sehen, dass es bis zum Ende übereinstimmt.;-)

aktualisierenwas für ein Idiot ich bin! Wie viele Jahre, bevor ich die Quadratwurzel von 10???? erkannt habe, ist zu beachten, dass das Obige im Wesentlichen die Quadratwurzel von 1e-101... ist. Der Grund scheint einfach genug, dass dies \numbeine Quadratwurzel einer Differenz ist, und irgendwie stellt sich heraus, dass diese Differenz, anstatt als Null gefunden zu werden, 1e-101auf einen Rundungsfehler in der letzten, 92. Ziffer jedes Terms zurückzuführen ist, der wahrscheinlich in der Größenordnung von liegt 1e-10!!! Ja, das sollte es für alle Ebenen Nder Gleitkommapräzision erklären. Ich schätze, manchmal ist die Differenz Null, manchmal ergibt sie 1e-(9+N). Zum Beispiel N=20kann man bei eine Differenz von erwarten 1e-29, also ungefähr 3e-15auf der Quadratwurzel, was istgenau was beobachtet wird. Seltsamerweise scheinen die Zahlen nie einen Unterschied zu ergeben, -1e-(9+N)der zu einem Fehler bei der Quadratwurzel führen würde.

Da die zurückgegebenen Werte mit zunehmender Genauigkeit abnehmen, kann ich vielleicht darauf vertrauen, dass der genaue Wert Null ist (ich habe die Algebra nicht durchgeführt). Wenn der genaue Wert wirklich Null ist, wird das Addieren oder Subtrahieren des obigen Werts zu etwas, das Null ist, 0.000010117182975...ihn nach etwa 46 signifikanten Ziffern verfälschen und die 92-stelligen Float-Auswertungen zerstören, um ihn zu erhalten ...

Sehr überraschend ! (aber lesen Sie den oben zitierten Block)

Dies sollte beim Vergleich mit anderen Mathematik-Engines berücksichtigt werden: Die Formel ist aufgrund einer möglichen katastrophalen Aufhebung bei einer Subtraktion numerisch instabil.


ursprüngliche Antwort

Hier ist ein Ansatz, der eine andere Mathematik-Engine verwendet. Sie kennt nur die Quadratwurzel, aber das reicht hier aus. Beachten Sie, dass im angegebenen Beispiel \numbgenau Null herauskommt.

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

In diesem Beispiel sind die beiden Lösungen gleich, da \numb... verschwindet.

Blockquote

Beachten Sie, dass die Lösungen erweiterbar berechnet werden. Das ist für einige (Narren ...) wichtig.

Wenn Sie mehr Präzision wünschen, beginnen Sie mit:

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

Antwort2

Sie könnten versuchen, diesen lualatexWeg zu gehen und dann die gesamte mathematische Präzision in zu haben lua, also pgfüberhaupt nicht. Das Folgende zeigt möglicherweise die falsche Antwort, aber das liegt nicht an den mathematischen Fähigkeiten von lua, sondern eher an einer ziemlich hastigen Übersetzung der erforderlichen Formel:

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

Bildbeschreibung hier eingeben

Antwort3

Update 1: pgfmath + fpu

Ich habe heute ein bisschen damit herumgespielt, XINTbin aber aufgrund des Mangels an mathematischen Funktionen zu meinem pgfmathAnsatz zurückgekehrt. Es gibt noch ein paar Formeln, die ich später einbetten muss, für die ich trigonometrische Funktionen usw. benötige, und soweit ich sehe, gibt es dafür keine Implementierung in xint. Mit Marks Hinweis zur Verwendung \usetikzlibrary{fpu}für höhere Genauigkeit habe ich es nach einigen Anpassungen endlich zum Laufen gebracht.

Das ist mein Code bisher:

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

aber ich bin mir hinsichtlich der Genauigkeit der Ergebnisse nicht sicher. Verglichen mit der jfbus-Lösung und meiner Ausgabe von wxMaxima ist die Quadratwurzel im Zähler jetzt nicht mehr Null, obwohl sie sehr klein ist (e-18). Auch wenn es ein sehr kleiner Unterschied ist, bin ich an der Gesamtgenauigkeit von pgfmaths interessiert. Denn ich habe vor, die gesamte Mathematik später in Latex zu erledigen, wenn ich kompiliere, und ich merke, dass ich danach jede Berechnung in Frage stelle.

Also, Leute, denkt ihr, dass es eine gute Idee ist, pgfmath für diese Art von Anwendung zu verwenden? Hat jemand etwas Ähnliches gemacht oder ist es einfach keine gute Idee, Mathematik einem Textverarbeitungsprogramm anzuvertrauen?

Übrigens habe ich jetzt \pgfmathsetmacrozum Speichern von Ergebnissen verwendet, die ich später brauche. Gibt es eine bessere Lösung oder ist das die übliche Vorgehensweise?


Update 2: LuaTeX + Luacode

pgfmathSo weit, so gut. Ich habe meinen Ansatz aufgrund seiner Ungenauigkeit aufgegeben und konzentriere mich jetzt auf Marks LuaTeX-Version.

Diese Lösung bietet mir eine gute Möglichkeit, die berechneten Lösungen in Formeln und Text einzubetten. Aber um dieses Zeug wirklich nützlich zu machen, muss ich es in pgfplotder Umgebung zum Laufen bringen. Hier ist ein Beispiel:

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

Bildbeschreibung hier eingeben

verwandte Informationen