Eu tenho uma função bidimensional cujos valores eu gostaria de provar. A função é muito cara de calcular e tem uma forma complexa, portanto, preciso encontrar uma maneira de obter o máximo de informações sobre sua forma usando o menor número de pontos de amostra.
Que bons métodos existem para fazer isso?
O que eu tenho até agora
Começo com um conjunto de pontos existente em que já calculei o valor da função (isso poderia ser uma estrutura quadrada de pontos ou outra coisa).
Então eu calculo uma triangulação de Delaunay desses pontos.
Se dois pontos vizinhos na triangulação de Delaunay são distantes o suficiente ( ) e o valor da função difere suficientemente neles ( > Δ f ), insiro um novo ponto no meio deles. Eu faço isso para cada par de pontos vizinho.
O que há de errado com esse método?
Bem, funciona relativamente bem, mas em funções semelhantes a essa não é ideal porque os pontos de amostra tendem a "pular" a cordilheira e nem percebem que está lá.
Produz resultados como este (se a resolução da grade de pontos inicial for suficientemente aproximada):
Este gráfico acima mostra os pontos onde o valor da função é calculado (na verdade, as células Voronoi ao seu redor).
Este gráfico acima mostra a interpolação linear gerada a partir dos mesmos pontos e a compara ao método de amostragem embutido do Mathematica (para aproximadamente a mesma resolução inicial).
Como melhorá-lo?
Penso que a questão principal aqui é que meu método decide se deve adicionar um ponto de refinamento ou não com base no gradiente.
Seria melhor levar em consideração a curvatura ou pelo menos a segunda derivada ao adicionar pontos de refinamento.
Questão
O que é uma maneira muito simples de implementar para levar em consideração a segunda derivada ou curvatura quando os locais dos meus pontos não estão restritos? (Eu não tenho necessariamente uma estrutura quadrada de pontos de partida, isso idealmente deve ser geral.)
Ou que outras maneiras simples existem para calcular a posição dos pontos de refinamento da maneira ideal?
Vou implementar isso no Mathematica, mas essa pergunta é principalmente sobre o método. Para o bit "fácil de implementar", é importante contar que eu estou usando o Mathematica (isto é, isso foi fácil de fazer até agora porque tem um pacote para fazer a triangulação de Delaunay)
Que problema prático eu estou aplicando isso a
Estou calculando um diagrama de fases. Tem uma forma complexa. Em uma região, seu valor é 0, em outra região, está entre 0 e 1. Há um salto acentuado entre as duas regiões (é descontínuo). Na região onde a função é maior que zero, existem variações suaves e algumas descontinuidades.
O valor da função é calculado com base em uma simulação de Monte Carlo; portanto, ocasionalmente, é esperado um valor ou ruído incorreto da função (isso é muito raro, mas ocorre um grande número de pontos, por exemplo, quando o estado estacionário não é atingido devido algum fator aleatório)
Já perguntei isso no Mathematica.SE, mas não consigo vinculá-lo porque ele ainda está na versão beta privada. Esta pergunta aqui é sobre o método, não a implementação.
Responder para @suki
Esse é o tipo de divisão que você sugere, ou seja, colocando um novo ponto no meio dos triângulos?
Minha preocupação aqui é que parece exigir um tratamento especial nas bordas da região, caso contrário, resultará em triângulos muito longos e muito finos, como mostrado acima. Você corrigiu isso?
ATUALIZAR
Um problema que aparece tanto no método que descrevo quanto na sugestão de @ suki de subdividir com base em triângulos e colocar os pontos de subdivisão dentro do triângulo é que, quando há descontinuidades (como no meu problema), recalcular a triangulação de Delaunay após uma etapa pode faça com que os triângulos mudem e talvez alguns grandes triângulos apareçam com diferentes valores de função nos três vértices.
Aqui estão dois exemplos:
O primeiro mostra o resultado final ao amostrar em torno de uma descontinuidade direta. O segundo mostra a distribuição do ponto de amostragem para um caso semelhante.
Que maneiras simples existem para evitar isso? Atualmente, estou simplesmente subdividindo os egdes que desaparecem após uma retriangulação, mas isso parece um hack e precisa ser feito com cuidado, pois no caso de malhas simétricas (como uma grade quadrada) existem várias triangulações válidas de Delaunay, portanto as bordas podem mudar aleatoriamente após retriangulação.