Background
I want to sample values from an isosurface, calculated with the marching squares algorithm from the misc3d
package in R
. In essence, the problem is as follows: I have a simulation that takes three parameters and outputs a single value. I want to reverse the process: I would like to input the outcome and obtain possible combinations of parameters.
Approach
I have used the marching squares algorithm in the computeCountour3d
function from the misc3d
package. As I understood it correctly, it outputs a data frame in which every three rows represent the vertices of a triangular plane. In this plane, all the parameter combinations should lead to the same output (=level), right?
library(tidyverse)
library(misc3d)
# Create a dataset (the mean() is used for simplicity)
data <- expand_grid(x = seq(1, 51, 10), y = seq(0, -2, -0.5), z = seq(0, -3, -1)) %>%
rowwise() %>% mutate(value = mean(c(x, y, z)))
data
#> x y z value
#> 1 1 0 0 0.333
#> 2 1 0 -1 0
#> 3 1 0 -2 -0.333
#> 4 1 0 -3 -0.667
#> 5 1 -0.5 0 0.167
#> 6 1 -0.5 -1 -0.167
# Turn dataframe into an 3d array
value <- data$value
data <- data[order( data$x, data$y, data$z),]
dimensions <- c(length(unique(data$x)), length(unique(data$y)), length(unique(data$z)))
v <- array(data = value, dim=dimensions)
# Create subarrays that map indices back
# to the original data
vX <- array( data=data$x, dim=dimensions )
vY <- array( data=data$y, dim=dimensions )
vZ <- array( data=data$z, dim=dimensions )
# Calculate isosurface, with level = 3
isosurface <-computeContour3d(vol = v,
maxvol = max(v),
level = 3) %>%
as.data.frame() %>%
rowwise() %>%
# Map the indices of the output the original x,y,z values
mutate(x = vX[V1, V2, V3],
y = vY[V1, V2, V3],
z = vZ[V1, V2, V3]) %>%
ungroup()
isosurface
#> V1 V2 V3 x y z
#> 1 3 1.2 2 11 -0.5 -3
#> 2 3 1 1.95 1 -2 -1
#> 3 2.8 1 2 11 -1 0
#> # … with 180 more rows
Question
How do you translate this dataframe of vertices to a set of parameter values that lead to a similar output? Are there functions to do so?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…