![Tikzmath 中的大数问题](https://linux22.com/image/466022/Tikzmath%20%E4%B8%AD%E7%9A%84%E5%A4%A7%E6%95%B0%E9%97%AE%E9%A2%98.png)
我有一个如下的 MWE。我构建了一个矩阵,其第一列为 1;第二列是 x 的每个分量的平方;第三列是 x 分量的立方,依此类推。我需要tikzmath
出于其他原因使用它。
当xi
较小(x<10
)时,工作得很好;然而,当xi
为负或 较大(x>100
)时,就会出现问题。
我无法处理大于 19 英尺的尺寸。继续,我将使用我能使用的最大值。```
\documentclass[tikz,border=5mm]{article}
\usepackage{tikz,pgfplots}
\usepackage{xfp}
\usepackage{fp}
\usetikzlibrary{fixedpointarithmetic}
\usetikzlibrary{math}
\begin{document}
\tikzmath{
\p=12;%número de pontos fornecidos
\q=4;%número de parâmetros a serem ajustados
\X{1}=-100;
\X{2}=110;
\X{3}=120;
\X{4}=130;
%
function phi1(\x){%Funções da base
\y = 1;
return \y;
};
function phi2(\x){%Funções da base
\y = \x;
return \y;
};
%
function phi3(\x){%Funções da base
\y = \x*\x;
return \y;
};
%
function phi4(\x){%Funções da base
\y = \x*\x*\x;
return \y;
};
%
function G(\x) {
\u = phi1(\x);
\v = phi2(\x);
\w = phi3(\x);
\z = phi4(\x);
return {\u,\v,\w,\z};
};
real \Matriz; int \i; int \j;
for \i in {1,...,4}{
for \j in {1,...,4}{
\Matriz{\i,\j}={G(\X{\i})}[\fpeval{\j-1}];
};
};
}
A matriz $A$ é dada por: \\
$
A=\left[
\begin{array}{cccc}
\Matriz{1,1}&\Matriz{1,2} & \Matriz{1,3} & \Matriz{1,4}\\
\Matriz{2,1}&\Matriz{2,2} & \Matriz{2,3} & \Matriz{2,4}\\
\Matriz{3,1}&\Matriz{3,2} & \Matriz{3,3} & \Matriz{3,4}\\
\Matriz{4,1}&\Matriz{4,2} & \Matriz{4,3} & \Matriz{4,4}\\
\end{array}
\right]
$
\end{document}
我试过这个库fixedarithmeticpoint
,但没解决。问题出在行上\Matriz{\i,\j}={G(\X{\i})}[\fpeval{\j-1}];
,但我不知道如何解决这个问题,以及为什么这种情况只发生在大数和负数上。
有人能帮助我吗?
答案1
用真实的“矩阵”存储来回答
\documentclass[border=5mm]{standalone}
\usepackage{xintexpr}
\begin{document}
% store once and for all data for access
\xintAssignArray{-100}{110}{120}{130}\to\X
% store all computations for doing them only once
% syntax for retreival: \Matriz{i,j} where i = line, j = column starting at 1
\makeatletter
\newcommand\Matriz[1]{\Matriz@#1;}
\def\Matriz@#1#2,#3#4;{\csname
% using \numexpr here to allow \Matriz{3,1+2} syntax
% although usefulness is somewhat doubtful, but this
% can however also be used with LaTeX \value{counter}, which
% may be more useful
Matriz\the\numexpr#1#2,\the\numexpr#3#4;\endcsname}
% line index, column index;
\xintFor#1 in {1, 2, 3, 4}\do{% #1 = line index
\xintFor#2 in {1, 2, 3, 4}\do{% #2 = column index
% use "column index minus 1" as exponent
% let us not forget parentheses in case #1 is negative
\expandafter\edef\csname Matriz#1,#2;\endcsname{\xinteval{(\X{#1})^(#2-1)}}%
}%
}
\makeatother
A matriz $A$ é dada por: \\
$
A=\left[
\begin{array}{cccc}
\Matriz{1,1}&\Matriz{1,2} & \Matriz{1,3} & \Matriz{1,4}\\
\Matriz{2,1}&\Matriz{2,2} & \Matriz{2,3} & \Matriz{2,4}\\
\Matriz{3,1}&\Matriz{3,2} & \Matriz{3,3} & \Matriz{3,4}\\
\Matriz{4,1}&\Matriz{4,2} & \Matriz{4,3} & \Matriz{4,4}
\end{array}
\right]
$
\end{document}
初步答复
(参见答案底部的正误表,特别是由于代码中缺少括号而导致第一行的符号)
您似乎需要超出 TeX 内置能力的计算(如果使用 TeX 功能进行定点评估,则大约高达 16383.99999)。如果剩余的精度超过总共 16 位,LaTeX 现在会提供开箱即用的功能xfp
。但对于整数幂, 1234^6
您需要超过 16 位的精度。
有些人已经扩展了 TeX 以支持任意精度计算,我知道 bigintcalc(仅限整数)、apnum 和 xint。以下是通过 xint 的方法:
\documentclass[border=5mm]{standalone}
\usepackage{xintexpr}
\begin{document}
\xintAssignArray{-100}{110}{120}{130}\to\X
\makeatletter
\newcommand\Matriz[1]{\Matriz@#1;}
% this stuff with #1#2 and #3#4 is only to allow space tokens
% in reasonable places in input,
% but I don't think they would matter (one would have to ask
% an xint knowledgeable user)
\def\Matriz@#1#2,#3#4;{\xinteval{\X{#1#2}^(#3#4)}}
\makeatother
A matriz $A$ é dada por: \\
$
A=\left[
\begin{array}{cccc}
\Matriz{1,1}&\Matriz{1,2} & \Matriz{1,3} & \Matriz{1,4}\\
\Matriz{2,1}&\Matriz{2,2} & \Matriz{2,3} & \Matriz{2,4}\\
\Matriz{3,1}&\Matriz{3,2} & \Matriz{3,3} & \Matriz{3,4}\\
\Matriz{4,1}&\Matriz{4,2} & \Matriz{4,3} & \Matriz{4,4}\\
\end{array}
\right]
$
\end{document}
但是,\Matriz
这里是一个宏,每次使用时都会重新评估。如果您真的想要一种永久结构,则必须编写一些额外的代码;这里仅用\X
作永久的 1 维数组。
另外,这个解决方案不必担心列的对齐,也许可以看看 siunitx 来了解这类事情。
(更新:我忘记在这个原始答案中将列索引减少 1,更严重的是,我忘记了括号以防数字为负数,所以请简单地替换\xinteval{\X{#1#2}^(#3#4)}
为\xinteval{(\X{#1#2})^(#3#4-1)}
)
答案2
由于tikzmath
TeX 容量限制,计算量有限。我建议使用 Asymptote 或 Python 进行计算(一块蛋糕); 然后嵌入到 LaTeX 文档中(它不是一块蛋糕,我必须进行更多测试,并且请评论给我建议,因为这件事对其他情况有帮助)。
1. 使用 Asymptote 进行计算
// Run on http://asymptote.ualberta.ca/
real[] x={-100,110,120,-130};
int n=x.length; write('n = ',x.length);
real G(int i, real t) {return t^i;};
// initialisation A as the identity
real[][] A=identity(n);
for(int i=0; i<n; ++i)
for(int j=0; j<n; ++j)
A[i][j]=G(j,x[i]);
write('Now the matrix A is given by: ');
write(A);