我正在尝试为 创建一个包LaTeX
,如果可能的话,我需要在这个包中计算定积分的值。 是否有可能在 中执行此操作LaTeX
?例如使用 pgf 包?
答案1
以下使用梯形法则或高斯-勒让德求积法定义完全可扩展(只是因为我可以)积分。宏\integrate
理解以下键:
start
积分的下界end
上限var
函数项中使用的变量(应该是单个 TeX 标记、任何字母或宏名称都可以\x
,但它不应该是您想要以任何其他方式评估的函数的一部分,例如,x
如果您的函数正在使用,您就不能使用exp
)points
您要评估的点数,值越高,需要的时间就越多,但可以提高结果的精度(但数字稳定性......)round
您希望结果四舍五入到的位数method
求积法,可能的值有trapezoidal
和quadrature
(如果选择trapezoidal
键points
至少应该是2,如果选择quadrature
那么points
应该在区间[1,5]内)trapezoidal
(这是设置两者的快捷方式method
,如果你输入了一个值points
)quadrature
(这是设置两者的快捷方式method
,如果你输入了一个值points
)
这些键中的任何一个都可以在可选参数中设置\integrate
,或\integratesetup
作为强制参数设置。
\integrate
需要将要求值的函数项作为强制参数。您可以在此处使用 -module 可以理解的任何内容l3fp
expl3
(请查看文档xfp
以了解概述)。
\documentclass{article}
\usepackage{etl}
\usepackage{expkv-cs}
\ExplSyntaxOn
\msg_new:nnn { fsbmat } { unknown-method }
{ Unknown~ integration~ method~ #1 }
\msg_new:nnn { fsbmat } { points-range }
{ Points~ out~ of~ range,~ should~ be~ [1,5] }
\ekvcSplit \__fsbmat_integrate_kv:nn
{
var = x
,start = 0
,end = 1
,points = 25
,round = 3
,method = trapezoidal
}
{
\cs_if_exist_use:cTF { fsbmat_integrate_ #6 :Nnnnnn }
{ #1 {#2} {#3} {#4} {#5} }
{
\msg_expandable_error:nnn { fsbmat } { unknown-method } {#6}
0
\use_none:n % remove the function argument
}
}
\ekvcSecondaryKeys \__fsbmat_integrate_kv:nn
{
,nmeta~ trapezoidal = {method=trapezoidal}
,nmeta~ quadrature = {method=quadrature}
,meta~ trapezoidal = {method=trapezoidal,points={#1}}
,meta~ quadrature = {method=quadrature ,points={#1}}
}
\NewDocumentCommand \integratesetup { m }
{ \ekvcChange \__fsbmat_integrate_kv:nn {#1} }
\NewExpandableDocumentCommand\integrate { O{} m }
{ \__fsbmat_integrate_kv:nn {#1} {#2} }
\cs_generate_variant:Nn \fp_eval:n { e }
\cs_generate_variant:Nn \etl_token_replace_all_deep:nNn { nNe }
\cs_new:Npn \fsbmat_integrate_trapezoidal:Nnnnnn #1#2#3#4#5#6
{
% #1: variable
% #2: start
% #3: end
% #4: points
% #5: round
% #6: function
\fp_eval:e
{
\exp_last_unbraced:Ne
\__fsbmat_integrate_trapezoidal:nnNnnnn
{
{ \fp_eval:n { ( #3 - #2 ) / ( #4 - 1 ) } }
{ \int_eval:n { #4 - 2 } }
}
#1 {#2} {#3} {#5} {#6}
}
}
\cs_new:Npn \fsbmat_evaluate:nNn #1#2#3
{ \fp_eval:e { \etl_token_replace_all_deep:nNn {#3} #2 { (#1) } } }
\cs_new:Npn \__fsbmat_integrate_trapezoidal:nnNnnnn #1#2#3#4#5#6#7
{
round
(
#1 *
(
0.5 *
(
\fsbmat_evaluate:nNn {#4} #3 {#7}
+ \fsbmat_evaluate:nNn {#5} #3 {#7}
)
\exp_last_unbraced:Ne \__fsbmat_integrate_trapezoidal_loop:nnnNnn
{
{1}
{ \fp_eval:n { #4 + #1 } }
}
{#2} #3 {#7} {#1}
)
,#6
)
}
\cs_new:Npn \__fsbmat_integrate_trapezoidal_loop:nnnNnn #1#2#3#4#5#6
{
\int_compare:nNnF {#1} > {#3}
{
+ \fsbmat_evaluate:nNn {#2} #4 {#5}
\exp_last_unbraced:Ne \__fsbmat_integrate_trapezoidal_loop:nnnNnn
{
{ \int_eval:n { #1 + 1 } }
{ \fp_eval:n { #2 + #6 } }
}
{#3} #4 {#5} {#6}
}
}
\cs_new_eq:NN \evaluatefunction \fsbmat_evaluate:nNn
\cs_new:Npn \fsbmat_integrate_quadrature:Nnnnnn #1#2#3#4#5#6
{
% #1: variable
% #2: start
% #3: end
% #4: points
% #5: round
% #6: function
\fp_eval:e
{
\bool_lazy_or:nnTF
{ \int_compare_p:nNn {#4} < 1 }
{ \int_compare_p:nNn {#4} > 5 }
{
\msg_expandable_error:nn { fsbmat } { points-range }
0
}
{
round
(
\bool_lazy_and:nnTF
{ \fp_compare_p:nNn {#2} = {-1} }
{ \fp_compare_p:nNn {#3} = {1} }
{
\__fsbmat_integrate_quadrature_aux:vNn
{ c__fsbmat_integrate_quadrature_points_ #4 _tl }
#1 {#6}
}
{
(#3 - #2) / 2 * (
\__fsbmat_integrate_quadrature_aux:vNe
{ c__fsbmat_integrate_quadrature_points_ #4 _tl }
#1
{
\etl_token_replace_all_deep:nNe {#6} #1
{
(
\fp_eval:n { (#3 - #2) / 2 } * \exp_not:N #1
+ \fp_eval:n { (#3 + #2) / 2 }
)
}
}
)
}
,#5
)
}
}
}
\cs_new:Npn \__fsbmat_integrate_quadrature_aux:nNn #1#2#3
{ \__fsbmat_integrate_quadrature_point:NnnnN #2 {#3} #1 }
\cs_generate_variant:Nn \__fsbmat_integrate_quadrature_aux:nNn { v, vNe }
\cs_new:Npn \__fsbmat_integrate_quadrature_point:NnnnN #1#2#3#4#5
{
+ (#4) * (\fsbmat_evaluate:nNn {#3} #1 {#2})
#5 #1 {#2}
}
% points and weights according to
% https://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_quadrature
\tl_const:cx { c__fsbmat_integrate_quadrature_points_1_tl }
{ {0} {2} \exp_not:N \use_none:nn }
\tl_const:cx { c__fsbmat_integrate_quadrature_points_2_tl }
{
{ -\fp_eval:n { 1/sqrt(3) } } {1}
\exp_not:N \__fsbmat_integrate_quadrature_point:NnnnN
{ \fp_eval:n { 1/sqrt(3) } } {1}
\exp_not:N \use_none:nn
}
\tl_const:cx { c__fsbmat_integrate_quadrature_points_3_tl }
{
{ -\fp_eval:n { sqrt(3/5) } } { \fp_eval:n { 5/9 } }
\exp_not:N \__fsbmat_integrate_quadrature_point:NnnnN
{0} { \fp_eval:n { 8/9 } }
\exp_not:N \__fsbmat_integrate_quadrature_point:NnnnN
{ \fp_eval:n { sqrt(3/5) } } { \fp_eval:n { 5/9 } }
\exp_not:N \use_none:nn
}
\tl_const:cx { c__fsbmat_integrate_quadrature_points_4_tl }
{
{ -\fp_eval:n { sqrt(3/7 + 2/7*sqrt(6/5)) } }
{ \fp_eval:n { (18-sqrt(30))/36 } }
\exp_not:N \__fsbmat_integrate_quadrature_point:NnnnN
{ -\fp_eval:n { sqrt(3/7 - 2/7*sqrt(6/5)) } }
{ \fp_eval:n { (18+sqrt(30))/36 } }
\exp_not:N \__fsbmat_integrate_quadrature_point:NnnnN
{ \fp_eval:n { sqrt(3/7 - 2/7*sqrt(6/5)) } }
{ \fp_eval:n { (18+sqrt(30))/36 } }
\exp_not:N \__fsbmat_integrate_quadrature_point:NnnnN
{ \fp_eval:n { sqrt(3/7 + 2/7*sqrt(6/5)) } }
{ \fp_eval:n { (18-sqrt(30))/36 } }
\exp_not:N \use_none:nn
}
\tl_const:cx { c__fsbmat_integrate_quadrature_points_5_tl }
{
{ -\fp_eval:n { 1/3 * sqrt(5 + 2*sqrt(10/7)) } }
{ \fp_eval:n { (322 - 13*sqrt(70)) / 900 } }
\exp_not:N \__fsbmat_integrate_quadrature_point:NnnnN
{ -\fp_eval:n { 1/3 * sqrt(5 - 2*sqrt(10/7)) } }
{ \fp_eval:n { (322 + 13*sqrt(70)) / 900 } }
\exp_not:N \__fsbmat_integrate_quadrature_point:NnnnN
{0}
{ \fp_eval:n { 128/225 } }
\exp_not:N \__fsbmat_integrate_quadrature_point:NnnnN
{ \fp_eval:n { 1/3 * sqrt(5 - 2*sqrt(10/7)) } }
{ \fp_eval:n { (322 + 13*sqrt(70)) / 900 } }
\exp_not:N \__fsbmat_integrate_quadrature_point:NnnnN
{ \fp_eval:n { 1/3 * sqrt(5 + 2*sqrt(10/7)) } }
{ \fp_eval:n { (322 - 13*sqrt(70)) / 900 } }
\exp_not:N \use_none:nn
}
\ExplSyntaxOff
\begin{document}
A simple example
\[
\int_0^1 x\,\mathrm{d}x = \integrate[points=2]{x}
= \integrate[quadrature=1]{x}
\]
and something more difficult
\[
\int_1^5 \frac{1}{\exp{x}}\,\mathrm{d}x
\approx \integrate[var=\x,start=1,end=5,round=10,quadrature=5]{1/exp(\x)}
\approx \integrate[var=\x,start=1,end=5,round=10]{1/exp(\x)}
\]
\end{document}
印刷:
请注意,这可能会变得非常数值不稳定(取决于您想要评估的函数),例如,尝试计算@Fran 显示的积分(通过将其分成几部分以提高准确性,对于大值不会发生太大变化):
\fpeval
{
\integrate[start=0.001,end=10,points=501]{1/((1+x)*sqrt(x))}
+ \integrate[start=29.98,end=10000,points=500]{1/((1+x)*sqrt(x))}
}
得到的结果为 2.98(有点不对,不是吗?),再调整一下数值,并再次分割第一个区间,你可以将其改进为
\fpeval
{
\integrate[start=1e-5,end=1,points=501]{1/((1+x)*sqrt(x))}
+ \integrate[start=1.018,end=10,points=500]{1/((1+x)*sqrt(x))}
+ \integrate[start=29.98,end=10000,points=500]{1/((1+x)*sqrt(x))}
}
得到 3.12。但是,进一步降低第一个间隔的下限会由于数值不稳定而导致结果恶化。
答案2
不知道如何仅使用 LaTeX 来做到这一点,但在以下帮助下knitr
似乎很容易:
\documentclass[twocolumn]{article}
\usepackage{physics}
\begin{document}
\[\int_{0}^{\infty}\frac{1}{(1+x)\sqrt{x}} \dd{x}\]
<<echo=F>>=
integrand <- function(x) {1/((x+1)*sqrt(x))}
a <- integrate(integrand, lower = 0, upper = Inf)
@
The result is roughly \Sexpr{round(a$value,2)}
(more exactly \Sexpr{a$value}) with an absolute
error of \Sexpr{signif(a$abs.error,2)}.
\end{document}
答案3
仅使用 LaTeX 确定积分值不太可能奏效,除非您能够对到达的积分施加一些限制(例如,被积函数始终是次数小于 n 的多项式)。一般来说,LaTeX 在处理复杂计算时会遇到问题。允许sagetex
您访问贤者 CAS以及 Python 编程语言,因此它可以轻松解决积分问题。CAS 不是 LaTeX 的一部分,因此无法从中创建包。以下是示例代码:
\documentclass{article}
\usepackage{sagetex,amsmath}
\begin{document}
The sagetex package gives you access to the Sage CAS along with the Python
programming language.
\begin{sagesilent}
from sage.symbolic.integration.integral import indefinite_integral
f=x/3
g(x)= 1/((x+1)*sqrt(x))
\end{sagesilent}
Using Sage we can calculate integrals that can be solved using symbolic integration. For example: \[\int_{0}^{1}\frac{x}{3} dx = \sage{f.integral(x)}\biggr\rvert_{0}^{1}=\sage{f.integral(x, 0, 1)}\].
Sage can calculate integrals numerically as well. For example:
\[\int_{0}^{\infty}\frac{dx}{(x+1)\sqrt(x)} \approx \sage{numerical_integral(g, 0, +Infinity)[0]}\]
The error estimate for the answer is $\sage{numerical_integral(g, 0, +Infinity)[1]}$.
\end{document}
我在您的问题下的评论与 Sage 符号/数值积分以及 Cocalc 有链接。