Definizione di un comando per le derivate

  • Creatore
    Topic
  • #40173
    Up
    0
    Down
    ::


    Ciao a tutti,

    in una classe che sto scrivendo è da molto tempo che ho definito
    i comandi (copiandoli non ricordo da dove):
    `\providecommand*{\der}[3][]{\frac{d^{#1}#2}{d #3^{#1}}}
    \providecommand*{\pder}[3][]{\frac{\partial^{#1}#2}{\partial #3^{#1}}}
    `

    Solo ora mi sono accorto che le mie definizioni introducono a numeratore uno spazio in più, molto brutto da vedere secondo me.
    Il problema è chiaramente dovuto al fatto che manca l’esponente.
    `\documentclass{minimal}
    \providecommand*{\der}[3][]{\frac{d^{#1}#2}{d #3^{#1}}}
    \providecommand*{\pder}[3][]{\frac{\partial^{#1}#2}{\partial #3^{#1}}}
    \begin{document}
    \[
    \der{f}{t}\quad\frac{df}{dt}\quad\pder{f}{t}\quad\frac{\partial f}{\partial t}
    \]
    \end{document}`

    Ora l’idea è quella di controllare se l’argomento opzionale è vuoto o meno.
    Leggendo la sezione 3.5 degli “Appunti di programmazione in LaTeX e TeX” di Enrico
    mi sono un po’ perso e alla fine non ho capito nel mio caso cosa mi conviene usare.
    Per ora ho fatto così:
    `\makeatletter
    \providecommand*{\der}[3][]{\frac{d\if#1\@empty ^{#1}\else\relax\fi#2}{d #3\if#1\@empty ^{#1}\else\relax\fi}}
    \providecommand*{\pder}[3][]{\frac{\partial\if#1\@empty ^{#1}\else\relax\fi#2}{\partial #3\if#1\@empty ^{#1}\else\relax\fi}}
    \makeatother`
    e sembra tutto funzionare.

    Vorrei sapere se questo codice può creare dei pasticci, soprattutto considerando che magari una persona può mettere anche roba strana a esponente, non solo numeri.

    Grazie mille.
    Ciao ciao.
    Fra

Visualizzazione 3 filoni di risposte
  • Autore
    Risposte
    • #40174
      Up
      0
      Down
      ::

      Ciao a tutti,

      in una classe che sto scrivendo è da molto tempo che ho definito
      i comandi (copiandoli non ricordo da dove):
      `\providecommand*{\der}[3][]{\frac{d^{#1}#2}{d #3^{#1}}}
      \providecommand*{\pder}[3][]{\frac{\partial^{#1}#2}{\partial #3^{#1}}}
      `

      Solo ora mi sono accorto che le mie definizioni introducono a numeratore uno spazio in più, molto brutto da vedere secondo me.
      Il problema è chiaramente dovuto al fatto che manca l’esponente.
      `\documentclass{minimal}
      \providecommand*{\der}[3][]{\frac{d^{#1}#2}{d #3^{#1}}}
      \providecommand*{\pder}[3][]{\frac{\partial^{#1}#2}{\partial #3^{#1}}}
      \begin{document}
      \[
      \der{f}{t}\quad\frac{df}{dt}\quad\pder{f}{t}\quad\frac{\partial f}{\partial t}
      \]
      \end{document}`

      Ora l’idea è quella di controllare se l’argomento opzionale è vuoto o meno.
      Leggendo la sezione 3.5 degli “Appunti di programmazione in LaTeX e TeX” di Enrico
      mi sono un po’ perso e alla fine non ho capito nel mio caso cosa mi conviene usare.
      Per ora ho fatto così:
      `\makeatletter
      \providecommand*{\der}[3][]{\frac{d\if#1\@empty ^{#1}\else\relax\fi#2}{d #3\if#1\@empty ^{#1}\else\relax\fi}}
      \providecommand*{\pder}[3][]{\frac{\partial\if#1\@empty ^{#1}\else\relax\fi#2}{\partial #3\if#1\@empty ^{#1}\else\relax\fi}}
      \makeatother`
      e sembra tutto funzionare.

      Vorrei sapere se questo codice può creare dei pasticci, soprattutto considerando che magari una persona può mettere anche roba strana a esponente, non solo numeri.

      Altroché se può creare pasticci. Suppongo che tu non abbia davvero provato, perché \der[2]{f}{x} e \der{f}{x} danno esattamente lo stesso risultato. 😯

      Vediamo perché. Quando chiami \der[2]{f}{x}, hai #1=2, #2=f, #3=x, quindi la lista di token del numeratore è
      `d\if2\@empty ^{2}\else\relax\fi f`
      Il condizionale \if espande ciò che segue fino a trovare due token non espandibili che, in questo caso sono “2” e “^”; quindi il testo per la parte `vero’ è “{2}” quello per la parte `falso’ è “\relax”. Viene scelto `falso’ perché “2” e “^” sono token diversi.

      Se invece chiami \der{f}{x}, la lista di token nel numeratore è
      `d\if\@empty ^{}\else\relax\fi f`
      che risulta falso perché il confronto è fatto tra “^” e “{“. Il condizionale \if è una brutta bestia. 🙂

      Se sei certo che nell’argomento opzionale i tuoi utenti non mettano comandi espandibili che facciano cose strane, il modo più semplice è di riscrivere il condizionale come
      `\if?#1?\else^{#1}\fi`
      Se #1 è vuoto, il test risulta vero perché ? è uguale a ?. Se #1 non è vuoto, il primo token che lo forma non sarà “?” (nessuno mette ? a esponente, direi). Quindi il test risulta falso e tutto ciò che compare fino a \else viene ignorato. Al posto di ? si può mettere qualsiasi token non espandibile (anche \relax, se vuoi, oppure uno totalmente fuori posto come &).

      Se invece temi che a esponente possano andare cose pericolose come \sqrt{2} o costruzioni bizzarre, il modo più veloce è
      `\newcommand*{\der}[3][]{\def\@temp{#1}
      \frac{d\ifx\@temp\@empty\else^{#1}\fi #2}{d#3 \ifx\@temp\@empty\else^{#1}\fi}}`
      Non mi pare che quella costruzione risulti fra quelle esposte nell’Introduzione. O mi sbaglio? 😉

      Ciao
      Enrico

    • #40175
      Up
      0
      Down
      ::

      Suppongo che tu non abbia davvero provato, perché \der[2]{f}{x} e \der{f}{x} danno esattamente lo stesso risultato.

      Ammetto le mie colpe 🙁 Domani ho la consegna della tesi di dottorato e non sono molto lucido…

      Il condizionale \if è una brutta bestia.

      Ho notato! Avevo preferito quello perché mi sono detto “È un comando basilare di TeX, funzionerà in maniera velocissima. Oltretutto devo solo verificare che un parametro è vuoto!”
      Solo che poi ho pasticciato prendendo un pezzo di qua e un pezzo di là.
      E infatti quella costruzione non è da nessuna parte 🙁

      `\if?#1?\else^{#1}\fi`

      Era così semplice!
      Era scritto chiaramente nell’Introduzione, così come l’altro
      esempio per i comandi espandibili. Scusa la distrazione 🙁
      Vabbè almeno ora ho capito (almeno credo) quella sezione.

      Grazie infinite.
      Ciao ciao.
      Fra

    • #40176
      Up
      0
      Down
      ::

      Suppongo che tu non abbia davvero provato, perché \der[2]{f}{x} e \der{f}{x} danno esattamente lo stesso risultato.

      Ammetto le mie colpe 🙁 Domani ho la consegna della tesi di dottorato e non sono molto lucido…

      Scusa validissima! In bocca al lupo!

      Il condizionale \if è una brutta bestia.

      Ho notato! Avevo preferito quello perché mi sono detto “È un comando basilare di TeX, funzionerà in maniera velocissima. Oltretutto devo solo verificare che un parametro è vuoto!”
      Solo che poi ho pasticciato prendendo un pezzo di qua e un pezzo di là.
      E infatti quella costruzione non è da nessuna parte 🙁

      È infatti un comando molto utile, purché si sappia come funziona; e il funzionamento è poco intuitivo, ma così si possono ottenere effetti molto vari.

      `\if?#1?\else^{#1}\fi`

      Era così semplice!
      Era scritto chiaramente nell’Introduzione, così come l’altro
      esempio per i comandi espandibili. Scusa la distrazione 🙁
      Vabbè almeno ora ho capito (almeno credo) quella sezione.

      Be’, semplice forse no. 🙂 Quello che va tenuto presente è che i condizionali \if, \ifcat e \ifx confrontano due token (in modo diverso) e che #1 in una definizione può rappresentare una lista di numerosi token. Quindi anche \ifx#1\@empty non è sufficiente.

      Esiste anche un altro metodo, trovato dal solito Heiko Oberdiek:
      `\expandafter\ifx\expandafter\relax\detokenize{#1}\relax
      <#1 è vuoto>%
      \else
      <#1 non è vuoto>%
      \fi`
      L’espansione del comando \detokenize (che è una delle estensioni e-TeX) è la lista di token data come argomento al comando, ma come caratteri di categoria 12 (è una generalizzazione di \string); se #1 non è vuoto, \ifx confronta \relax con il primo carattere prodotto da \detokenize che ovviamente non può essere \relax. Succede allora come con \if!#1!, tutto ciò che segue fino a \else è ignorato. Se invece #1 è vuoto, \ifx confronta \relax con \relax e il test è vero!

      Per esempio, l’espansione di \detokenize{\abc\def} è la successione di caratteri di categoria 12 \abc\def; lo stesso effetto si potrebbe ottenere con una macro ricorsiva che mette sempre dopo di sé \string fino a quando incontra una “sentinella”, ma certo una primitiva è più efficiente.

      Devo ricordarmi di aggiungerlo all’Introduzione.

      Ciao
      Enrico

    • #40177
      Up
      0
      Down
      ::

      In bocca al lupo!

      Crepi il lupo!
      Menomale che alla Sapienza le tesi di dottorato si consegnano solo
      in formato elettronico! Così ho tempo per fare altre correzioni 😀

      Esiste anche un altro metodo, trovato dal solito Heiko Oberdiek:

      Wow!

      Grazie di tutto Enrico!
      Ciao ciao.
      Fra

Visualizzazione 3 filoni di risposte
  • Devi essere connesso per rispondere a questo topic.

Go to top