Ho una funzione bidimensionale cui vorrei campionare i valori. La funzione è molto costosa da calcolare e ha una forma complessa, quindi ho bisogno di trovare un modo per ottenere il maggior numero di informazioni sulla sua forma usando il minor numero di punti campione.
Quali buoni metodi ci sono per farlo?
Quello che ho finora
Comincio da un insieme esistente di punti in cui ho già calcolato il valore della funzione (questo potrebbe essere un reticolo quadrato di punti o qualcos'altro).
Quindi computo una triangolazione Delaunay di questi punti.
Se due punti vicini nella triangolazione di Delaunay sono abbastanza lontani ( ) e il valore della funzione differisce sufficientemente in essi ( ), inserisco un nuovo punto a metà tra di loro. Lo faccio per ogni coppia di punti adiacente.> Δ f
Cosa c'è di sbagliato in questo metodo?
Bene, funziona relativamente bene, ma su funzioni simili a questa non è l'ideale perché i punti campione tendono a "saltare" sulla cresta e non si accorgono nemmeno che è lì.
Produce risultati come questo (se la risoluzione della griglia del punto iniziale è sufficientemente approssimativa):
Questo diagramma sopra mostra i punti in cui viene calcolato il valore della funzione (in realtà celle Voronoi attorno a loro).
Questo diagramma sopra mostra l'interpolazione lineare generata dagli stessi punti e la confronta con il metodo di campionamento incorporato di Mathematica (per circa la stessa risoluzione iniziale).
Come migliorarlo?
Penso che il problema principale qui sia che il mio metodo decida se aggiungere un punto di raffinamento o meno in base al gradiente.
Sarebbe meglio tenere conto della curvatura o almeno della seconda derivata quando si aggiungono punti di raffinamento.
Domanda
Qual è un modo molto semplice da implementare per tenere conto della seconda derivata o curvatura quando le posizioni dei miei punti non sono affatto vincolate? (Non ho necessariamente un reticolo quadrato di punti di partenza, questo dovrebbe idealmente essere generale.)
O quali altri modi semplici ci sono per calcolare la posizione dei punti di raffinamento in modo ottimale?
Lo implementerò in Mathematica, ma questa domanda riguarda principalmente il metodo. Per il bit "facile da implementare", conta comunque che sto usando Mathematica (ad esempio, è stato facile farlo finora perché ha un pacchetto per fare triangolazione Delaunay)
A quale problema pratico sto applicando questo
Sto calcolando un diagramma di fase. Ha una forma complessa. In una regione il suo valore è 0, in un'altra regione è tra 0 e 1. C'è un forte salto tra le due regioni (è discontinuo). Nella regione in cui la funzione è maggiore di zero ci sono sia alcune variazioni regolari che un paio di discontinuità.
Il valore della funzione viene calcolato sulla base di una simulazione Monte Carlo, quindi occasionalmente è prevedibile un valore di funzione errato o rumore (questo è molto raro, ma accade per un gran numero di punti, ad esempio quando lo stato stazionario non viene raggiunto a causa qualche fattore casuale)
L'ho già chiesto su Mathematica.SE ma non riesco a collegarlo perché è ancora in beta privata. Questa domanda qui riguarda il metodo, non l'implementazione.
Rispondi a @suki
È questo il tipo di divisione che suggerisci, ovvero mettere un nuovo punto nel mezzo dei triangoli?
La mia preoccupazione qui è che sembra richiedere una gestione speciale ai bordi della regione, altrimenti darà triangoli molto lunghi e molto sottili, come mostrato sopra. Hai corretto per questo?
AGGIORNARE
Un problema che appare sia con il metodo che descrivo sia con il suggerimento di @ suki di mettere la suddivisione in base ai triangoli e di inserire i punti di suddivisione all'interno del triangolo è che quando ci sono discontinuità (come nel mio problema), ricalcolare la triangolazione di Delaunay dopo un passaggio può fa sì che i triangoli cambino e forse compaiano alcuni triangoli grandi che hanno valori di funzione diversi nei tre vertici.
Ecco due esempi:
Il primo mostra il risultato finale quando si campiona intorno a una discontinuità lineare. Il secondo mostra la distribuzione del punto di campionamento per un caso simile.
Quali modi semplici ci sono per evitarlo? Attualmente sto semplicemente suddividendo quegli egdes che scompaiono dopo una retriangolazione, ma questo sembra un hack e deve essere fatto con cura come nel caso di maglie simmetriche (come una griglia quadrata) ci sono diverse triangolazioni Delaunay valide, quindi i bordi potrebbero cambiare casualmente dopo la retriangolazione.