How to symmetrise a dataset in [0,1]^d in a bijective way

54 Views Asked by At

Suppose i have a dataset in [0,1]^d, that i want to symetrise in the sense that the repartition function of the "symmetrised" data, F, should hold the following assertion :

For exemple if d=2, the repartition function should be symetric around the first bissectrix :

The transformation should be constructed from data. If you want some (trivariate) data to try working with, you can run the following R code (the package copula must be installed first) :

library(copula)
source(system.file("Rsource", "AC-Liouville.R", package="copula"))
U <- rLiouville(n=1000, alpha=c(1, 10,20), theta=0.6, Rdist="Gamma")
pairs(U)

Furthermore, i would like this transformation to be bijective, so that it could embbed a fit.

The main issue is the following : i have a fitting algorythme for symetric datasets and i want to extend it to non-symetric ones by the mean of this transformation, that i cant write properly...

Ideas ? Thank you :)

1

There are 1 best solutions below

2
G. Grothendieck On

We can symmetrize a function by taking the average over all permutations of its arguments. Although the question asked for a bijective transformation that can't be done since the projection loses information.

Here FunSym inputs a scalar valued function Fun and outputs a symmetrized function.

library(combinat)

FunSym <- function(Fun) {
  function(...) mean(unlist(permn(list(...), do.call, what = Fun)))
}

Fun <- function(x, y) x - y  # test function
FunS <- FunSym(Fun)  # FunS is Fun symmetrized
FunS(1,2) # run FunS for particular arguments
## [1] 0

If we knew that Fun had 2 arguments then we could write the simpler:

FunSym2 <- function(Fun) {
  function(x, y) (Fun(x,y) + Fun(y,x))/2
}

FunS2 <- FunSym2(Fun)  # FunS is Fun symmetrized
FunS2(1,2) # run FunS for particular arguments
## [1] 0

If Fun were vector valued we could modify FunSym like this:

FunSymV <- function(Fun) {
  function(...) rowMeans(simplify2array(permn(list(...), do.call, what = Fun)))
}

# test
FunSymV(Fun)(1:3, 4:6)
## [1] 0 0 0