Somatórios de cálculo em látex

Oct 19 2020

Alguém pode me ajudar, por favor? Preciso calcular a soma 1 + 1/2 + 1/3 + ... 1 / n (n fornecido) usando apenas comandos de látex. Não tenho ideia de como posso fazer isso. Muito Obrigado.

Respostas

4 frougon Oct 19 2020 at 21:11

Para melhor precisão, sugiro realizar este cálculo usando em l3fpvez de pgfmath. Proponho duas funções, \mySetToSume \mySetToSumAlt. Ambos aceitam os mesmos argumentos e calculam a soma usando l3fp. A diferença está em como eles escrevem o resultado arredondado em seu primeiro argumento:

  • \mySetToSum arredonda a soma computada de acordo com o número de casas decimais dado em seu terceiro argumento, então descarta os zeros finais, se houver;

  • \mySetToSumAlt faz o mesmo, mas mantém zeros à direita.

\documentclass{article}
\usepackage{amsmath}            % only for the sample text with \dotsb
\usepackage{xparse}             % not necessary with recent LaTeX (Oct. 2020)
\usepackage{xfp}                % only for \fpeval (demo code)
\usepackage{pgfmath}            % for printing the result with a fixed number
                                % of decimal places (used in \mySetToSumAlt)
\ExplSyntaxOn

\cs_new_protected:Npn \angelo_set_to_sum:Nn #1#2
  {
    \fp_zero_new:N #1
    \int_step_inline:nn {#2} { \fp_add:Nn #1 { 1/##1 } }
  }

\fp_new:N \l__angelo_result_fp

% Document-level interface
% #1: control sequence that will receive the result
% #2: value of n
% #3: round the result to this number of decimal places
\NewDocumentCommand \mySetToSum { m m m }
  {
    % Compute the sum with l3fp; put the result in \l__angelo_result_fp.
    \angelo_set_to_sum:Nn \l__angelo_result_fp {#2}
    % Set #1 to the result after rounding.
    \tl_set:Nx #1 { \fp_eval:n { round(\l__angelo_result_fp, #3) } }
  }

% Same macro, but uses \pgfmathprintnumberto in order to always write the
% specified number of decimal places, even if this means printing trailing
% zeros.
\NewDocumentCommand \mySetToSumAlt { m m m }
  {
    \angelo_set_to_sum:Nn \l__angelo_result_fp {#2}
    % Set #1 to the result after rounding.
    \pgfmathprintnumberto[fixed~zerofill, precision={#3}]
      { \fp_eval:n { \l__angelo_result_fp } } {#1}
  }
\ExplSyntaxOff

\begin{document}

% Use n = 60 and round to 6 decimal places.
\mySetToSum{\result}{60}{6}%
% Ditto, but keep trailing zeros, if any.
\mySetToSumAlt{\resultWithTrailingZeros}{60}{6}%
\[ 1 + \frac{1}{2} + \frac{1}{3} + \dotsb + \frac{1}{60}
   \approx \resultWithTrailingZeros \approx \result \]
Approximation of the Euler–Mascheroni constant:
\[ 1 + \frac{1}{2} + \frac{1}{3} + \dotsb + \frac{1}{60} - \ln(60) \approx
    \fpeval{round(\result - ln(60), 6)} \]
%
% Now use n = 100
\mySetToSum{\result}{100}{6}%
\[ 1 + \frac{1}{2} + \frac{1}{3} + \dotsb + \frac{1}{100} - \ln(100) \approx
    \fpeval{round(\result - ln(100), 6)} \]
%
% Now use n = 200
\mySetToSum{\result}{200}{6}%
\[ 1 + \frac{1}{2} + \frac{1}{3} + \dotsb + \frac{1}{200} - \ln(200) \approx
    \fpeval{round(\result - ln(200), 6)} \]
%
% Now use n = 1000
\mySetToSum{\result}{1000}{6}%
\[ 1 + \frac{1}{2} + \frac{1}{3} + \dotsb + \frac{1}{1000} - \ln(1000) \approx
    \fpeval{round(\result - ln(1000), 6)} \]
According to Wikipedia, the value of this constant is close to $0.57722$.

\end{document}

4 Mico Oct 19 2020 at 22:21

Aqui está uma solução baseada em LuaLaTeX.

% !TEX TS-program = lualatex
\documentclass{article}
\directlua{%
  function harmonic ( n )
     local h=0
     for i=1,n do h=h+1/i end
     return h
  end
} 
%% LaTeX macro to access the Lua function:
\newcommand\harmonic[1]{\directlua{tex.sprint(harmonic(#1))}}
\newcommand\difference[1]{\directlua{tex.sprint(harmonic(#1)-math.log(#1))}}

\begin{document}

The value of the tenth harmonic number is \harmonic{10}.

\medskip
\begin{tabular}{@{} rll @{}}
\hline
$n$ & harmonic($n$) & harmonic($n$)${}-\ln(n)$\\
\hline
1 & \harmonic{1}   & \difference{1}    \\
10 & \harmonic{10}  & \difference{10}   \\
100 & \harmonic{100} & \difference{100}  \\
1000 & \harmonic{1e3} & \difference{1e3}  \\
10000 & \harmonic{1e4} & \difference{1e4}  \\
100000 & \harmonic{1e5} & \difference{1e5}  \\
1000000 & \harmonic{1e6} & \difference{1e6}  \\
10000000 & \harmonic{1e7} & \difference{1e7}  \\
100000000 & \harmonic{1e8} & \difference{1e8}  \\
\hline
\end{tabular}

\medskip
Euler-Mascheroni constant${}\approx 0.5772156649$.
         
\end{document}
3 egreg Oct 19 2020 at 23:55

Basicamente, não há como obter cálculos rápidos apenas com métodos TeX, devido aos recursos aritméticos muito limitados.

A solução a seguir armazena os valores das somas harmônicas até 5000, portanto, eles estão disponíveis em tempo linear. Acima de 5000, o tempo de cálculo torna-se muito longo.

\documentclass{article}
\usepackage{booktabs}
%\usepackage{xparse} % not necessary with LaTeX 2020-10-01 or later
\usepackage{xfp} % for \fpeval

\ExplSyntaxOn
% store the values of H_n in an array (up to 5000)
\fparray_new:Nn \g_aliano_harmonic_fparray { 5000 }
% initialize
\fparray_gset:Nnn \g_aliano_harmonic_fparray { 1 } { 1 }
% at each step add the reciprocal of the next number
\int_step_inline:nn { 5000-1 }
 {
  \fparray_gset:Nnn \g_aliano_harmonic_fparray { #1+1 }
   {
    \fparray_item:Nn \g_aliano_harmonic_fparray { #1 } + 1/(#1+1)
   }
 }
% this retrieves the value, rounding it to 5 decimal digits
\NewExpandableDocumentCommand{\harmonic}{m}
 {
  \fp_eval:n { round(\fparray_item:Nn \g_aliano_harmonic_fparray { #1 },5) }
 }
\ExplSyntaxOff

\begin{document}

\begin{tabular}{@{}rll@{}}
\toprule
\multicolumn{1}{@{}c}{$n$} &
\multicolumn{1}{c}{$H_n$} &
\multicolumn{1}{c@{}}{$H_n-\log n$} \\
\midrule
1    & \harmonic{1}    & \fpeval{round(\harmonic{1}-ln(1),5)} \\
10   & \harmonic{10}   & \fpeval{round(\harmonic{10}-ln(10),5)} \\
100  & \harmonic{100}  & \fpeval{round(\harmonic{100}-ln(100),5)}\\
1000 & \harmonic{1000} & \fpeval{round(\harmonic{1000}-ln(1000),5)}\\
5000 & \harmonic{5000} & \fpeval{round(\harmonic{5000}-ln(5000),5)}\\
\bottomrule
\end{tabular}

\end{document}

Se você precisar de mais termos, usar LuaTeX parece a única alternativa rápida. Talvez isso também possa ser feito com PythonTeX de maneira suficientemente rápida.