How to test the exchangeability of data? I have implemented a constraint-based random number generator producing 3 columns with the constraint that each row sums to 1:
0.4 0.3 0.3
0.5 0.2 0.3
0.5 0.3 0.2
0.6 0.1 0.3
0.6 0.3 0.1
0.8 0.1 0.1
0.6 0.2 0.2
0.3 0.4 0.3
0.2 0.5 0.3
0.3 0.5 0.2
0.1 0.6 0.3
0.3 0.6 0.1
0.1 0.8 0.1
0.2 0.6 0.2
0.3 0.3 0.4
0.2 0.3 0.5
0.3 0.2 0.5
0.1 0.3 0.6
0.3 0.1 0.6
0.1 0.1 0.8
0.2 0.2 0.6

I would like to test whether these three columns $X$, $Y$, and $Z$ are exchangeable: that is, are the multivariate distributions of $(X,Y,Z)$ and all its permutations, such as $(Y,X,Z)$ and $(Z,X,Y)$, the same?
E.g., if column 1 can be $0.4$ followed by a $0.3$ in column 2 and $0.3$ in column 3, then is there also an equal chance for column 2 to be $0.4$ and columns 1 and 2 to be $0.3$?
 A: Not a complete answer, but here are two quick checks. Both need to be fullfilled in order to have the columns exchangeable. That is, if you see that there are differences then the 3 columns cannot be exchanged:
First check is of course whether the 3 columns have the same univariate distributions. 
Second check: Generate enough samples and produce a ternary histogram, i.e. count how often each combination of numbers appears and plot that e.g. color coded into a ternary diagram. If the diagram isn't symmetric with respect to the 3 columns (3-fold rotation $C_3$ around 0.5,0.5,0.5 and also  3 $\sigma$ mirror-symmetry) then the distributions cannot be the same. 
Here are two examples:
This one has obviously not the same distribution for each colunm:
 
Whereas this one has:

Note: I produced the second set of random numbers by shuffling the rows within each column of the first version of random numbers.

Here's the R code:
require ("plyr")
require ("ggtern")

## make up some data
df <- data.frame (x = rnorm (5000, mean=.4, sd = .3)^2,
                  y = rnorm (5000, mean=.4, sd = .3)^2)

df <- round (df*10) / 10
df$z <- 1 - rowSums (df)
df <- df [df$z >= 0,]

## first quick check
summary (df) 

## 3d histogram
hist3d <- ddply(df,.(x,y,z),nrow)
ggtern (hist3d, aes (x = x, y = y, z = z, col = V1)) + 
   geom_point (size = 10) + 
   scale_color_gradientn (colours = c (low = "darkred", mid = "red", high = "yellow"))

## shuffling within each row (could be done faster by matrix indexing)
df <- t (apply (df, 1, sample))
df <- as.data.frame (df)
colnames (df) <- c ("x", "y", "z")

