---
title: Metric unfolding with "munfold"
output: rmarkdown::html_vignette
vignette: >
  % \VignetteIndexEntry{Metric unfolding with "munfold"}
  % \VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
bibliography: munfold.bib
---

```{r,echo=FALSE,message=FALSE}
knitr::opts_chunk$set(comment=NA,
               fig.align="center",
               results="markup")
```

The following code demonstrates the use of `unfold()` with artificial data.

We first create some artificial data of which we know the correct configuration.
`a1` and `a2` are the coordinates of a first group of points, which form a
circle (with some very small perturbations added). 
`b1` and `b2` are the coordinates of a second group of points, which form a square.
```{r}
r <- seq(from=0,to=2*pi,length=24)
a1 <- cos(r)*4 + 0.00001*rnorm(r)
a2 <- sin(r)*4 + 0.00001*rnorm(r)
b1 <- c(.5,-.5,-.5,.5)*3 + 5
b2 <- c(.5,.5,-.5,-.5)*3 + 1
```
Im the next step, we compute the squred distamces between the two groups of points.
```{r}
D1 <- outer(b1,a1,"-")
D2 <- outer(b2,a2,"-")
Dsq <- D1^2+D2^2
```
Now we call `unfold()`:
```{r}
library(munfold)
Dsq.uf<-unfold(Dsq,squared=TRUE)
Dsq.uf
```

The printout indicates that `unfold()` prefers a two-dimensional solution, which
fits the observed squared distances perfectly. 

The output does not tell us, who well we can recreate the original
configuration, so let's do some plotting.

With `biplot()` we get an illustration of the reconstructed configuration.
Second, let's plot the reconstructed locations of the two groups of points.
To enhance the geometric configuration of the points, we require a
points-and-line plot by using the argument `type="b"`
```{r}
biplot(Dsq.uf,type="b")
```

Now let's compare this with the original configuration, where we need to make
sure that all of the original points appear in the plot.

```{r}
A <- cbind(a1,a2)
B <- cbind(b1,b2)
orig <- rbind(A,B)
xlim <- ylim <- range(orig)#*1.5

plot(A,type="b",pch=1,asp=1,
    xlim=xlim,ylim=ylim,
    xlab="Dimension 1",ylab="Dimension 2")
lines(B,type="b",pch=3,lty=2)
abline(h=0,v=0,lty=3)
```

This looks pretty similar, but a comparison will be easier if we put both plots
side by side:

```{r}
oldpar <- par(mfrow=c(1,2))
plot(A,type="b",pch=1,
    xlim=xlim,ylim=ylim,
    xlab="Dimension 1",ylab="Dimension 2",main=expression("Original data"),asp=1)
lines(B,type="b",pch=3,lty=2)
abline(h=0,v=0,lty=3)

biplot(Dsq.uf,type="b",
    xlim=xlim,ylim=ylim,
    main=expression(paste(italic(unfold)," solution")),asp=1)
par(oldpar)
```

Curiously, Schönemann's algorithm fails with a perfect circle:

```{r}
r <- seq(from=0,to=2*pi,length=24)
a1_0 <- cos(r)*4 # NB: no random noise added here
a2_0 <- sin(r)*4
b1_0 <- c(.5,-.5,-.5,.5)*3 + 5
b2_0 <- c(.5,.5,-.5,-.5)*3 + 1
D1_0 <- outer(b1_0,a1_0,"-")
D2_0 <- outer(b2_0,a2_0,"-")
Dsq0 <- D1_0^2+D2_0^2
Dsq.uf0 <- unfold(Dsq0,squared=TRUE)
Dsq.uf0
```
The stress level indicates an imperfect fit, while the configuration within
groups seems to be okay, the overall configuration is wrong:

```{r}
biplot(Dsq.uf0,type="b")
```


However, the iterative conjugate gradient method seems to work:

```{r}
Dsq.uf0.cg<-unfold(Dsq,squared=TRUE,method="CG")
Dsq.uf0.cg
```
We get a non-convergence warning, but the stress level is much lower and the
reconstructed configuration looks okay:
```{r}
biplot(Dsq.uf0.cg,type="b")
```

Less surprisingly, it is important to correctly indicate whether the input for
`unfold()` consists of squared distances or un-squared distances. 

Here we provide squared distances, but indicate that the distances are not
squared. 
```{r}
Dsq.uf1 <- unfold(Dsq,squared=FALSE)
Dsq.uf1
```

We get an additional spurious dimension and the reconstruction of the points is distorted:

```{r}
biplot(Dsq.uf1,type="b")
```

Here we provide non-squared distances, but indicate that the distances *are*
squared. 
```{r}
Dsq.uf2 <- unfold(sqrt(Dsq),squared=TRUE)
Dsq.uf2
```

Again we end up with a spurious additional dimension and a distorted
configuration of the points:

```{r}
biplot(Dsq.uf2,type="b")
```
