calcolare prodotto scalare con l’ausilio di pgfmath

  • Creatore
    Topic
  • #58489
    Up
    0
    Down
    ::


    Ciao a tutti,

    quello che vorrei riuscire a fare è calcolare un prodotto scalare tra due vettori.
    Di seguito il codice:
    `
    \documentclass{article}
    \usepackage{tikz}

    \def\vectorDot(#1,#2,#3)(#4,#5,#6)#7{%
    \pgfmathparse{#1*#4+#2*#5+#3*#6}%
    \expandafter\let\csname#7\endcsname=\pgfmathresult%
    }

    \begin{document}
    \def\A{1,1,1}
    \def\B{1,2,3}

    \vectorDot(1,1,1)(1,1,1){dotAB} % funziona
    %\vectorDot(\A)(\B){dotAB} % non funziona

    \dotAB
    \end{document}
    `

    come potete vedere il caso in cui io definisco il vettore A prima con il comando \def per poi inserirlo nel comando che compie il prodotto non funziona.

    Immagino perché il comando \A venga è visto dal comando \vectorDot solamente come l’input #1 e non come #1,#2,#3.

    Si può ovviare a questo?

    Saluti

    Michele

Visualizzazione 6 filoni di risposte
  • Autore
    Risposte
    • #58490
      OldClaudio
      Partecipante
        Up
        0
        Down
        ::


        Si può fare, ma devi giocare pesante con i comandi “primitivi” di TeX; vedo due possibili soluzioni:

        1) definire \vectorDot con due soli argomenti, ciascuno dei quali contenga tre numeri searati da virgole; poi una macro che gestisce argomenti delimitati da virgole, separa ogni argomento nelle sue tre componenti; per le macro ad argomenti delimitati oltre al TeXbook, puoi vedere il mio articolo su ArsTecnica o anche il tutorial di Enrico introtex.pdf.

        2) usare una macro di interfaccia che espanda il suo contenuto; anche qui ci vuole il TeXbook oppure il tutorial di Enrico.

      • #58491
        Up
        0
        Down
        ::

        Ciao a tutti,

        quello che vorrei riuscire a fare è calcolare un prodotto scalare tra due vettori.
        Di seguito il codice:
        `
        \documentclass{article}
        \usepackage{tikz}

        \def\vectorDot(#1,#2,#3)(#4,#5,#6)#7{%
        \pgfmathparse{#1*#4+#2*#5+#3*#6}%
        \expandafter\let\csname#7\endcsname=\pgfmathresult%
        }

        \begin{document}
        \def\A{1,1,1}
        \def\B{1,2,3}

        \vectorDot(1,1,1)(1,1,1){dotAB} % funziona
        %\vectorDot(\A)(\B){dotAB} % non funziona

        \dotAB
        \end{document}
        `

        come potete vedere il caso in cui io definisco il vettore A prima con il comando \def per poi inserirlo nel comando che compie il prodotto non funziona.

        Immagino perché il comando \A venga è visto dal comando \vectorDot solamente come l’input #1 e non come #1,#2,#3.

        Si può ovviare a questo?

        Saluti

        Michele

        \A non è una lista di token della forma richiesta, lo è la sua espansione.
        `\def\vectorDot(#1)(#2){\begingroup
        \edef\x{\endgroup\noexpand\vectorDotI(#1)(#2)}\x}
        \def\vectorDotI(#1,#2,#3)(#4,#5,#6)#7{%
        \pgfmathparse{#1*#4+#2*#5+#3*#6}%
        \expandafter\let\csname#7\endcsname\pgfmathresult
        }`
        Ciao
        Enrico

      • #58492
        Up
        0
        Down
        ::


        è quello che sto tentando di fare, vi farò sapere se ce la faccio…

      • #58493
        Up
        0
        Down
        ::


        Cavoli, non mi ero accorto di aver risposto nello stesso istante in cui a risposto egreg9

        \A non è una lista di token della forma richiesta, lo è la sua espansione.
        Enrico

        Vorrei capire meglio la soluzione che ha dato Gregorio. Per questo avrei delle domandine:

          1. Il fatto che nel mio codice mettessi \A significava che 1,1,1 era visto come un unico token?
          2. La soluzione è quindi fare espandere \A(cioè creare una lista ed un numero di token) prima di \vectorDotI(e per questo l’uso combinato di \edef ed \noexpand)?
          3. Passando al commando \vectorDotI, facendo rifarimento al codice da te suggerito e definendo prima \A e \B come faccio io, quando lo uso è come se scrivessi il codice di seguito?
          `\begingroup\endgroup\vectorDotI(1,1,1)(1,1,1)`
          4. Se si, \begingroup\endgroup serve per espandere solamente (#1)(#2) senza qualcosa precedente?

        Spero che le domande siano pertinenti e corrette.

        Saluti

      • #58494
        OldClaudio
        Partecipante
          Up
          0
          Down
          ::


          Come al solito Enrico ti ha dato la soluzione perfetta che realizza la soluzione 2) che ti avevo suggerito.
          La risposta alle prime tre domande è “sì”.
          La risposta alla quarta domande dovrebbe essere più articolata (spiegazione dettagliata nel mio articolo su ArsTeXnica: Le graffe: queste sconosciute): il giochetto di aprire un gruppo, definire una macro che nel suo corpo contiene il comando di chiusura del gruppo, e poi eseguire la macro, serve per non lasciare tracce della macro stessa nela memoria del programma di composizione, pur eseguendo quello che la macro dice di volere fare.

          Quindi la macro \x contiene lo sviluppo del suo argomento, tranne ciò che è prefissato con \noexpand; in particolare vengono sviluppati, se sono sviluppabili, i due argomenti; se hai passato \A e \B come li hai definiti, lo sviluppo consiste nel sostituire quelle due macro con la loro definizione. se passi a \vectorDot solo le terne numeriche di coordinate separate dalle loro virgole, queste non sono macro e non richiedono nessuno sviluppo e vengono usate tali e quali., quando \x va in esecuzione, per prima cosa chiude il gruppo,e quindi viene “dimenticata” la sua definizione, definizione però che è già in esecuzione, quindi viene eseguito il calcolo sulle trene di cooridnate comunque siano state propinate a \vectorDot.

          Enrico può spiegarti meglio il giochetto; lui ha una capacità descrittiva del codice molto migliore, ma la sostanza è quella.

        • #58495
          Up
          0
          Down
          ::

          Enrico può spiegarti meglio il giochetto; lui ha una capacità descrittiva del codice molto migliore, ma la sostanza è quella.

          Direi che la spiegazione è completa e accurata.

          Ciao
          Enrico

        • #58496
          Up
          0
          Down
          ::


          grazie mille per la chiarissima risposta!!

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

      Go to top