计算定积分的值?

计算定积分的值?

我正在尝试为 创建一个包LaTeX,如果可能的话,我需要在这个包中计算定积分的值。 是否有可能在 中执行此操作LaTeX?例如使用 pgf 包?

答案1

以下使用梯形法则或高斯-勒让德求积法定义完全可扩展(只是因为我可以)积分。宏\integrate理解以下键:

  • start积分的下界
  • end上限
  • var函数项中使用的变量(应该是单个 TeX 标记、任何字母或宏名称都可以\x,但它不应该是您想要以任何其他方式评估的函数的一部分,例如,x如果您的函数正在使用,您就不能使用exp
  • points您要评估的点数,值越高,需要的时间就越多,但可以提高结果的精度(但数字稳定性......)
  • round您希望结果四舍五入到的位数
  • method求积法,可能的值有trapezoidalquadrature(如果选择trapezoidalpoints至少应该是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}

Cocalc 中运行的输出是: 在此处输入图片描述

我在您的问题下的评论与 Sage 符号/数值积分以及 Cocalc 有链接。

相关内容