Criando uma tabela automatizada de sinais

Criando uma tabela automatizada de sinais

Ao resolver algumas desigualdades no contexto do curso de álgebra-pré-cálculo, às vezes é útil esboçar o comportamento dos fatores envolvidos usando uma tabela. Tudo fica claro com um exemplo - digamos que queremos resolver:

inequação

a tabela associada é:

mesa

Se na desigualdade houver um fator da forma, 1/(x-a)às vezes é indicado na tabela usando uma linha dupla ||abaixo de a. Vamos chamar essas restrições.

Ao ensinar cálculo, existem algumas tabelas semelhantes para lidar com o sinal das derivadas, concavidade, pontos críticos e assim por diante.

O que eu quero é:

  • um novo tipo de ambiente de tabela que toma como argumentos os números onde os fatores mudam de sinal (-3, 0, 1).
  • uma forma de indicar que tal número é uma restrição.
  • as duas primeiras linhas do exemplo devem ser digitadas como:

    \begin{signtable}{-3}{0}{1}
      x & -  & - & + & + \\
    \end{signtable}`
    

Então posto isso porque acho que existem muitas maneiras possíveis de resolver isso e quero conhecê-las.

Eu me pergunto se isso pode ser feito melhor com o TikZ.

Até agora, o código do exemplo é:

\documentclass{article}
\usepackage{array}

\begin{document}
\begin{array}{*{5}{c|}@{}c@{}}
\multicolumn{6}{@{}c@{}}{
\begin{array}{*{10}{@{}l@{}}}
\phantom{x(x-1)(x+3} & -\infty & \hspace*{5pt} & -3 & \phantom{-} & 0 & \phantom{+}\hspace*{3pt} & 1 & \phantom{+} & +\infty
\end{array}
}\\
\cline{1-5}
x                     &  - & - & + & + &\\
\cline{1-5}
x-1                   &  - & - & - & + &\\
\cline{1-5}
x+3                   &  - & + & + & + &\\
\cline{1-5}
x(x-1)(x+3)           &  - & + & - & + &
\end{array}
\end{document}

Responder1

Antes de investir muito tempo na criação de um novo pacote eu recomendo que você dê uma olhada nos pacotes tableaux, tablor e tkz-tab. Os exemplos de código são legíveis, porém toda a documentação dos três pacotes está em francês. Executei com sucesso alguns dos exemplos nestes manuais como demonstrações para meus alunos da aula de LateX. Usarhttp://www.texdoc.net/para obter a documentação de cada um deles rapidamente.

Responder2

Achei que era uma boa ideia e que poderia ser divertido, então tentei. Pretendo usar isso sozinho, então foge dos detalhes da questão, mas mantendo a questão em mente, cheguei bem perto.

  • Sintaxe:\SignTable{comma separated factors}{comma separated zeros}
  • A variável deve serz
  • aceita quaisquer funções reconhecidas por l3fp. Usei alguns abaixo, mais podem ser encontrados na documentação. A sintaxe é importante, use símbolos de colchetes e multiplicação adequados quando apropriado. Exceção: funções como sin z, ln ze exp z.
  • Isso só pode ser confiável se os valores usados ​​forem zeros/descontinuidades da função e todos forem contabilizados em qualquer intervalo de seu interesse. Se você escolher apenas um monte de números aleatórios, erros poderão ser introduzidos. Tenho quase certeza de que pode ser confiável de qualquer maneira, passei muito tempo resolvendo as coisas.
  • Tenha cuidado ao usar uma função como ln xe testar valores negativos
  • Para centralizar os números críticos nas colunas, fiz algo hackeado (tenho certeza de que pode-se argumentar que toda a minha parede de código é hackeado!), Isso dificultou o uso de regras verticais e fez com que parecessem ok (além das booktabsregras /vertical regras de interação Portanto, não há regras verticais.
  • Para marcar "restrições" usei \fboxoutras coisas que poderiam ser tentadas.

\SignTable{sin z,z+6,2^z,z^3,1/(z+4)}{-6,-4,0,\pi}produz o seguinte (e sim, ignorei alguns zeros sin z:)

insira a descrição da imagem aqui

Muralha do Código

\documentclass{article}
\usepackage{xparse}
\usepackage{booktabs}
\usepackage{array}
\usepackage{mathtools}
\ExplSyntaxOn

% table rows
\tl_new:N \l_ft_rows_tl
% actual function
\tl_new:N \g_the_funct_tl
% table setup, first and last rows require special handling
\tl_new:N \g_ft_first_row_tl
\tl_new:N \l_ft_col_set_tl
\tl_new:N \l_last_row_tl
% holds points of discontinuity, if any
\seq_new:N \g_asys_seq
% set of (loosely) "critical points"
\seq_new:N \g_ft_pts_seq
% pts at which to evaluate function to determine sign
\seq_new:N \g_ft_eval_pts_seq
% holds the factors that are input
\seq_new:N \g_ft_functs_seq

% arg 1 is comma separated list of factors
% arg2 is set of "critical points"
\NewDocumentCommand { \SignTable } { m m }
    {
        % function names should be fairly self explanatory
        \ft_def_functs:n {#1}
        \ft_set_vals:n {#2}
        \seq_map_function:NN \g_ft_functs_seq \ft_eval_funct_rows:n
            % this looks for entered values that give infinite results and marks them.
        \seq_map_function:NN \g_ft_functs_seq \ft_find_asys:n
        \ft_last_row:
        \ft_set_cols:
        \ft_first_row:
        % space the table a bit more openly
        \renewcommand{\arraystretch}{1.5}
        % \l_ft_col_set_tl contains column spec
        \exp_args:Nnx\begin{array}{\tl_use:N \l_ft_col_set_tl}
        \tl_use:N \g_ft_first_row_tl
    \toprule
    \tl_use:N \l_ft_rows_tl
        \bottomrule
        \tl_use:N \l_last_row_tl
    \end{array}
    }

% grab factors from arg
\cs_new:Npn \ft_def_functs:n #1
    {
        \seq_gset_split:Nnn \g_ft_functs_seq { , } {#1}
    }

% just average consecutive critical numbers for test points
\cs_new:Npn \ft_set_vals:n #1
    {
        \seq_gset_split:Nnn \g_ft_pts_seq { , } {#1}
        \seq_set_eq:NN \l_tmpa_seq \g_ft_pts_seq
        \group_begin:
            \seq_get_left:NN \g_ft_pts_seq \l_tmpa_fp
            \seq_put_left:Nx \g_ft_pts_seq {\fp_eval:n {\l_tmpa_fp-1}}
            \seq_get_right:NN \l_tmpa_seq \l_tmpa_fp
            \seq_put_right:Nx \l_tmpa_seq {\fp_eval:n {\l_tmpa_fp+1}}
            \seq_mapthread_function:NNN \l_tmpa_seq \g_ft_pts_seq \ft_avg:nn
        \group_end:
    }
% helper function for the above
\cs_new:Npn \ft_avg:nn #1#2
    {
        \seq_gput_right:Nx \g_ft_eval_pts_seq {\fp_eval:n {#1/2+#2/2}}
    }

% receives a factor, does some formatting, plugs in some numbers, test sign,
% print appropriate sign.  
\cs_new:Npn \ft_eval_funct_rows:n #1
    {
        \tl_set:Nn \l_tmpa_tl {#1}
        \tl_gput_right:Nx \g_the_funct_tl {(\tl_use:N \l_tmpa_tl)*}
        \tl_remove_all:Nn \l_tmpa_tl {*}
        \tl_put_right:NV \l_ft_rows_tl \l_tmpa_tl 
        \seq_map_inline:Nn \g_ft_eval_pts_seq
            {
                \tl_set:Nn \l_tmpa_tl {#1}
                \tl_replace_all:Nnn \l_tmpa_tl {z} {(##1)}
                \fp_compare:nNnTF {\fp_eval:n {\l_tmpa_tl}}< {0}
                    {\tl_put_right:Nn \l_ft_rows_tl {&&-}}
                    {\tl_put_right:Nn \l_ft_rows_tl {&&+}}
            }
        \tl_put_right:Nn \l_ft_rows_tl {&\\}
    }

% receives a factor, plugs in critical points to see if any give infinite result
% if yes, add point to asys sequence.
\cs_new:Npn \ft_find_asys:n #1
    {
        \group_begin:
        \fp_trap:nn {invalid_operation}{none}
        \seq_map_inline:Nn \g_ft_pts_seq
            {
                \tl_set:Nn \l_tmpa_tl {#1}
                \tl_replace_all:Nnn \l_tmpa_tl {z} {(##1)}
                \fp_compare:nNnT {\fp_eval:n {\l_tmpa_tl}}={inf}
                {\seq_gput_right:Nn \g_asys_seq {##1}}
            }
        \group_end:
    }

\cs_new:Npn \ft_last_row:
    {
        % remove an extra mult operator, this is ugly
        \tl_put_right:Nn \l_last_row_tl {f(z)}
        \tl_reverse:N \g_the_funct_tl
        \tl_set:Nx \g_the_funct_tl {\tl_tail:N \g_the_funct_tl}
        \tl_reverse:N \g_the_funct_tl
        % if you want the function to appear rather than f(z)
        % uncomment the below and comment the first line above.
        %\group_begin:
            %\tl_remove_all:Nn \g_the_funct_tl {*}
            %\tl_gput_right:NV \l_last_row_tl \g_the_funct_tl
        %\group_end:
        \seq_map_inline:Nn \g_ft_eval_pts_seq
            {
                \tl_set_eq:NN \l_tmpa_tl \g_the_funct_tl
                \tl_replace_all:Nnn \l_tmpa_tl {z} {(##1)}
                \fp_compare:nNnTF {\fp_eval:n {\l_tmpa_tl}}< {0}
                    {\tl_put_right:Nn \l_last_row_tl {&&-}}
                    {\tl_put_right:Nn \l_last_row_tl {&&+}}
            }
        \tl_put_right:Nn \l_last_row_tl {&}
    }

% alternating centered and centered with zero width.
\cs_new:Npn \ft_set_cols:
    {
        \prg_replicate:nn{2+\seq_count:N \g_ft_pts_seq}{\tl_put_right:Nn \l_ft_col_set_tl {cm{0pt}}}
    }

% to center the critical points on the column separators, all I could think of was to make the 
% headings have zero size and center them on columns of zero width
\cs_new:Npn \ft_first_row:
    {
        \tl_put_right:Nn \g_ft_first_row_tl {&$\mathclap{\underset{\phantom{\downarrow}}{-\infty}}$&}
        \seq_map_inline:Nn \g_ft_pts_seq
            {
                \tl_put_right:Nn \g_ft_first_row_tl {&$\mathclap{\underset{\downarrow}{\is_asy:n {##1}}}$&}
            }
        \tl_put_right:Nn \g_ft_first_row_tl {&$\mathclap{\underset{\phantom{\downarrow}}{\infty}}$\\}
    }

% do something to the points of discontinuity
% change this to whatever works
\cs_new:Npn \is_asy:n #1
    {
        \seq_if_in:NnTF \g_asys_seq {#1}
            {\fboxsep=1pt \fbox{$#1$}}
            {#1}
    }

\ExplSyntaxOff
\begin{document}

\[
\SignTable{sin z,z+6,2^z, z^3,1/(z+4)}{-6,-4,0,\pi}
\]

\end{document}

informação relacionada