Algoritmi per la stampa di funzioni (adattive?)


21

Sto cercando algoritmi per disegnare grafici 2D standard per funzioni che possono o meno avere singolarità. Lo scopo è scrivere un "Mini-CAS", quindi non ho una conoscenza a priori dei tipi di funzioni, gli utenti vogliono rappresentare graficamente.

Questo problema è molto vecchio, quindi immagino che ci debbano essere alcuni algoritmi standard in letteratura. Per una volta non ho avuto molto successo nel trovare riferimenti tramite Google.

Ho trovato un algoritmo interessante, vale a dire questo da "YACAS - Libro degli algoritmi" chiamato " Tracciato adattativo delle funzioni".

Quindi in breve:

  • Esistono algoritmi standard?
  • Esiste una suite di test per funzioni note difficili da tracciare?
  • Quali sono gli articoli interessanti da leggere?

2
Forse la domanda sarebbe meglio compresa con "tracciamento delle funzioni" anziché "disegno grafico"? Inizialmente ho interpretato male il titolo (teoria dei grafi).
astrojuanlu,

@ Juanlu001 Grazie per il suggerimento. Ho cambiato il titolo.
soegaard,

Quando dici 2D, intendi tracciare una funzione a una variabile come , o sei anche interessato a una funzione a due variabili ( ) mostrata in 2D con ad esempio colori / sfumature diverse che rappresentano valori diversi? f ( x , y )f(x)f(x,y)
Szabolcs,

Bene, intendevo tracciare una funzione di una variabile. Tuttavia, mi piacerebbe anche conoscere gli algoritmi per scegliere quali punti valutare anche in un'impostazione a due variabili. Non mi interessa sapere di colori e sfumature.
soegaard

Per le funzioni 2D, vedi la mia domanda e risposta qui . Quello che ho fatto lì è stato piuttosto limitato e non funzionerà così bene per una funzione arbitraria. Inoltre, mancano alcuni passaggi essenziali nella descrizione senza i quali il metodo non converge correttamente: avevo bisogno di inserire un nuovo punto di campionamento nel mezzo di ciascun bordo della mesh che scomparirebbe al successivo ritriangolo. (seguito)
Szabolcs,

Risposte:


10

Ho implementato la routine di campionamento adattivo di Mathematica qui su GitHub (è un singolo file C, vai all'albero dei sorgenti per il file di intestazione). Ho trovato una descrizione della routine in un grande libro su Mathematica molto tempo fa, e sto usando le variazioni su questa implementazione da qualche tempo. Fondamentalmente fa un campione lineare approssimativo sul dominio di interesse, quindi torna indietro per affinare regioni di alta curvatura. È possibile che manchino alcune funzioni molto nitide, ma in pratica lo trovo estremamente raro. Questo file contiene anche la versione parallela.


1
Di che libro si tratta? È quello che ho collegato? Sai cosa cambia esattamente nella loro implementazione tra le versioni 5 e 6?
Szabolcs,

1
@Szabolcs: No, credo che fosse nella sezione 4.1.3 di questo libro . La descrizione applica una versione molto vecchia di Mathematica. Le versioni più recenti (forse a partire dalla v6) rilevano gli asintoti verticali e rimuovono le trame verticali spurie dai grafici. Le nuove versioni eseguono sicuramente sofisticate preelaborazioni simboliche per far fronte a discontinuità, regioni indefinite e tagli delle filiali.
Victor Liu,

La preelaborazione simbolica di cui stai parlando è chiamata "rilevazione di esclusione" nella documentazione. Può essere disattivato Exclusions -> Noneo nascondendo la struttura della funzione Plotdefinendola come f[x_?NumericQ] := .... Questo non è ciò a cui mi riferivo quando ho chiesto delle modifiche. Credo che ci siano state alcune modifiche all'algoritmo, come v5 e v6 campionati in punti diversi. In questo momento non posso testare su v5 anche se per confrontare di nuovo.
Szabolcs,

"La guida grafica di Mathematica" conteneva un'ottima discussione del problema. Mi è piaciuta soprattutto la descrizione delle brevi mancanze dell'algoritmo.
soegaard,

Non riesco più a trovare il file GitHub, è stato spostato?
Andrei,

12

Sapere come altri CAS fanno questo potrebbe aiutarti.

f(x)(x(t),y(t))f(x)

  1. Inizia con una griglia di punti regolarmente distanziata sul dominio di stampa. (In Mathematica, c'è un parametro per controllare quanti prendere, chiamato PlotPoints.)

  2. (x1,f(x1)),(x2,f(x2)),(x3,f(x3))x1+x22x2+x32

  3. Se non abbiamo ancora raggiunto il limite di iterazione (impostato MaxRecursionin Mathematica), ripetere dal passaggio 2.

Alcuni di questi sono discussi nel libro Mathematica in Action di Stan Wagon, che puoi vedere qui su Google Libri .

Ho implementato questo algoritmo prima di avere un migliore controllo su quante volte è stata valutata la mia costosa funzione di calcolo. Ecco il codice Mathematica per il passaggio 2:

nd[{points_, values_}] :=
Transpose@{(Drop[points, 1] + Drop[points, -1])/2,
Differences[values]/Differences[points]}

subdivide1d[result_, resolution_, maxAngle_: 10] :=
  Module[
    {deriv, angle, dangle, pos, nf},
    deriv = nd[result\[Transpose]];
    angle = ArcTan[#2] & @@@ deriv;
    dangle = Differences[angle];
    pos = Flatten@Position[dangle, d_ /; Abs[d] > maxAngle/180 Pi];
    pos = Union[pos, pos + 1];
    nf = Nearest[result[[All, 1]]];
    Select[deriv[[pos, 1]], Abs[# - First@nf[#]] > resolution &]
  ]

7

La pagina Web di MathWorld sui grafici delle funzioni contiene riferimenti a numerosi articoli che sembrano essere rilevanti per la rappresentazione adattativa delle funzioni. Citando la pagina:

Buone routine per tracciare grafici utilizzano algoritmi adattativi che tracciano più punti in regioni in cui la funzione varia più rapidamente (Wagon 1991, Math Works 1992, Heck 1993, Wickham-Jones 1994). Tupper (1996) ha sviluppato un algoritmo [...]

D'altra parte, su Google mi sono imbattuto in un documento

www.cs.uic.edu/~wilkinson/Publications/plotfunc.pdf

che spiega come scegliere correttamente il dominio e altre cose. Spero che ti siano utili.


1

Ho trovato questo argomento e ho pensato di condividere la pagina del problema degli sviluppatori per l'aggiunta di questo alla libreria Julia Plots.jl. Abbiamo provato un sacco di tecniche per vedere cosa avrebbe dato buoni risultati, a partire dalle note sull'implementazione di Mathematica. Aggiungendo un po 'di potatura, una piccola perturbazione per non iniziare esattamente agli endpoint dell'intervallo, un limite di ricorsione e uno stimatore di errore a doppia mesh erano tutti necessari per "farlo bene". Il thread punta anche al codice open source per l'implementazione. Quindi ci sono voluti un po 'di modifiche, ma l'aggiunta di quelle funzionalità lo ha reso piuttosto robusto (secondo i test, come mostrato nel thread).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.