Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2D Arrangement Documentation and Test Improvement [CAT] #70

Open
wants to merge 38 commits into
base: julia-1.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
886c195
planar_arrangement_1 documented
eOnofri04 Apr 17, 2019
c7a10a1
frag_edge documented
eOnofri04 Apr 18, 2019
80bc694
frag_edge_channel and intersect_edges Documented
eOnofri04 Apr 19, 2019
3b2606d
PIPELINE PART 1 Documented
eOnofri04 Apr 19, 2019
76941af
[CISkip] Update readme
eOnofri04 Apr 19, 2019
126a2c2
adding Tests for Planar_arrangement_1 Pipeline
eOnofri04 Apr 19, 2019
229183f
Merge branch 'julia-1.0' of github.com:eOnofri04/LinearAlgebraicRepre…
eOnofri04 Apr 19, 2019
aba60fd
Fixing notational error in test
eOnofri04 Apr 19, 2019
2b9d968
Update .travis.yml
eOnofri04 Apr 19, 2019
26f90d0
moving documentation from function to Docs
eOnofri04 Apr 19, 2019
c8a6de8
Fixing Docs Errors
eOnofri04 Apr 19, 2019
d7dd132
Fixing typo error
eOnofri04 Apr 19, 2019
d1e84ac
Minor style change in Docs
eOnofri04 Apr 20, 2019
6091918
biconnected_components Docs and Tests
eOnofri04 Apr 20, 2019
d9179d2
Minor Docs fixing
eOnofri04 Apr 20, 2019
101bd7c
Minor Docs fixing2
eOnofri04 Apr 20, 2019
da6f876
Prepearing Documentation for part 2
eOnofri04 Apr 20, 2019
9f24b42
Docs for TGW ongoing
eOnofri04 Apr 22, 2019
f88f92a
Proceding with TGW docs
eOnofri04 Apr 22, 2019
7e9f5c8
Udating Refernces and Docs
eOnofri04 Apr 22, 2019
f03fc41
get_external_cycle Documentation
eOnofri04 Apr 22, 2019
09b184c
Some Test + pre_containment_test Docs
eOnofri04 Apr 23, 2019
16b62b0
Documentation Add
eOnofri04 Apr 23, 2019
590ca85
Adding new Examples
eOnofri04 Apr 23, 2019
e2bc3f2
Adding new Test over Pipeline2
eOnofri04 Apr 23, 2019
048eb81
Updating Tests
eOnofri04 Apr 23, 2019
745e07a
Fixing Tests Error
eOnofri04 Apr 23, 2019
63d2c2e
Pre Submit
eOnofri04 Apr 23, 2019
38bfc32
Last Step
eOnofri04 Apr 23, 2019
738f824
Update .travis.yml
eOnofri04 Apr 23, 2019
b8a3e05
Fixing 2d example
eOnofri04 Apr 26, 2019
caa15fc
Update mapper.jl
eOnofri04 Jun 3, 2019
38b75a3
Update REQUIRE
eOnofri04 Jun 3, 2019
f020c31
Update .travis.yml
eOnofri04 Jun 3, 2019
ff6cc52
[ci skip] back1
eOnofri04 Jun 3, 2019
11b88bd
Update mapper.jl
eOnofri04 Jun 3, 2019
6ac6109
Update .travis.yml
eOnofri04 Jun 3, 2019
11d5a28
Merge pull request #5 from eOnofri04/eOnofri04-patch-1
eOnofri04 Jun 3, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ deploy:
keep-history: true
local-dir: docs/build
on:
branch: master
branch: julia-1.0
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,20 @@ add("LinearAlgebraicRepresentation")

## Documentation

Go to [the documentation page](https://cvdlab.github.io/LinearAlgebraicRepresentation.jl/)
Building EOnofri julia-1.0 [![Build Status](https://travis-ci.org/eOnofri04/LinearAlgebraicRepresentation.jl.svg?branch=master)](https://travis-ci.org/eOnofri04/LinearAlgebraicRepresentation.jl)

Go to [eonofri documentation page](https://eonofri04.github.io/LinearAlgebraicRepresentation.jl/)


Go to [cvdlab documentation page](https://cvdlab.github.io/LinearAlgebraicRepresentation.jl/)


## Authors
* [Giulio Martella](https://github.com/giuliom95)
* [Alberto Paoluzzi](https://github.com/apaoluzzi)
* [Francesco Furiani](https://github.com/furio)

## Additional Documenters
* [Elia Onofri](https://github.com/eonofri04)
* [Maria Teresa Graziano](https://github.com/marteresagh)
* [Luca Angelini]()
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ julia 1.0
NearestNeighbors
IntervalTrees
DataStructures
Triangle
Triangle
5 changes: 4 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ makedocs(
"Home" => "index.md",
"L.A.R. Intro" => "lar.md",
"Interface" => "interface.md",
"Arrangement" => "arrangement.md",
"Arrangement" => [
"Arrangement module" => "arrangement.md",
"Planar arrangement" => "planar_arrangement.md"
],
"Parametric primitives" => [
"Mapper" => "mapper.md",
"Assemblies" => "struct.md"
Expand Down
21 changes: 9 additions & 12 deletions docs/src/arrangement.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@ The **arrangement** is an algorithm which gets two general ``d``-dimensional cel
* ``\sigma_1 \cap \sigma_2 = \emptyset,\quad \forall`` couple of cells ``(\sigma_1, \sigma_2)``
* ``\bigcup_i\sigma_i = \mathbb{E}^d``

This operation can be seen as a boolean union of two cellular complexes. Here an exploded visualization of the final result of the arrangement algorithm ran on 2 cubes made by ``10\times10\times10`` smaller cubes.
This operation can be seen as a boolean union of two cellular complexes. Here an exploded visualization of the final result of the arrangement algorithm run on 2 cubes made by ``10\times10\times10`` smaller cubes.

![10 x 10 Cube](./images/cube10x10.jpg)
> **Figure 1:** Arrangement of ``2000=2\times10\times10\times10`` cubes

## API
## Organisation

Every function strictly relative to the arrangement has been collected in the `Lar.Arrangement` sub-module but the two main functions are accessible directly from the `LinearAlgebraicRepresentation` namespace.
Every function strictly relative to the arrangement has been collected in the `Lar.Arrangement` sub-module but the two main functions are accessible directly from the `LinearAlgebraicRepresentation` namespace. They are:
- [`Lar.planar_arrangement`]() that evaluates the arrangements in 2D spaces.
- [`Lar.spatial_arrangement`]() that evaluates the arrangements in 3D spaces.
!!! warning
`Lar.Arrangement` is the only place in `LinearAlgebraicRepresentation` where `Point` matrices store points per row and not per column as described in the documentation of `Lar.Points`

```@docs
Lar.spatial_arrangement
Lar.planar_arrangement
```

!!! note
Even if the arrangement algorithm is theoretically dimension independent, we implemented "only" the ``d=2`` and ``d=3`` version of it.

Expand Down Expand Up @@ -47,14 +44,14 @@ the spatial index: it is a mapping ``\mathcal{I}(\sigma)`` from a cell
where the ``box`` function provides the axis aligned bounding box (AABB) of a cell [fig. 2, c,
``\sigma`` in red and ``\mathcal{I}(\sigma)`` in blue]. The spatial arrangement
calculation is speeded up by storing the AABBs as dimensional wise intervals
into an interval tree \cite{interval_trees}.
into an interval tree ``\cite{interval_trees}``.
Now for each cell ``\sigma`` we transform ``\sigma \cup \mathcal{I}(\sigma)``
in a way that ``\sigma`` lays on the ``x_3=0`` plane [fig. 2, d] and we find the intersections
of the ``\mathcal{I}(\sigma)`` cells with ``x_3=0`` plane. So we have a "soup"
of 1-cells in ``\mathbb{E}^2`` [fig. 2, e], and we fragment each 1-cell
with every other cell obtaining a valid 1-skeleton [fig. 2, f].
From this data it is possible to build the 2-cells using the ALGORITHM 1
presented and explored by Paoluzzi et al. \cite{Paoluzzi}
presented and explored by Paoluzzi et al. ``\cite{Paoluzzi}``
[fig. 2, g, exploded]. The procedure to fragment 1-cells
on a plane and return a 2-complex is called *planar arrangement*. When the planar arrangement
is complete, fragmented ``\sigma`` can be transformed back to its original position
Expand Down Expand Up @@ -83,14 +80,14 @@ are to discard: the ones outside the area of ``\sigma`` and the ones
which are not part of a maximal biconnected component
(We can talk about biconnected components because we can consider the 1-skeleton as a graph:
0-cells are nodes, 1-cells are edges and the boundary operator is
a incidence matrix.).
a incidence matrix).
The result of this edge pruning outputs a
1-skeleton [fig. 3, c, exploded].

After this, 2-cells must be computed:
For each connected component we build a containment tree, which indicates
which component is spatially inside an other component.
Computing these relations lets us launch the ALGORITHM 1 \cite{Paoluzzi}
Computing these relations lets us launch the ALGORITHM 1 ``\cite{Paoluzzi}``
on each component and then combine the results to create 2-cells with non-intersecting
shells [fig. 3, d, 2-cells numbered in green; please note that
cell 2 has cell 1 as an hole].
Expand Down
Binary file added docs/src/images/2d-arrangement-pipeline.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
262 changes: 262 additions & 0 deletions docs/src/planar_arrangement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
# Arrangement of cellular complexes in two-dimensional spaces

The module Arangement provides two dimensional space arrangements via the following method (accesible from the `LinearAlgebraicRepresentation` namespace):

```@docs
Lar.planar_arrangement
```

In general we recall the notation we have used in source code:
- `V::Lar.Points` is the 1-cells (Vertices) complex by Columns.
- `W::Lar.Points` is the 1-cells (Vertices) complex by Rows.
- `EV::Lar.Cells` is the 2-cells (Edges) complex.
- `FV::Lar.Cells` is the 3-cells (Faces) complex.
- `copEV::Lar.ChainOp`: is the Chain Coboundary of the 2-cells.
- `copFE::Lar.ChainOp`: is the Chain Coboundary of the 3-cells.
- `bigPI::Array{Array{Int64,1},1}`: is the bounding box intersection array:
each row is associated to a 2-cell and contains the indices of the other 2-cells intersecting its bounding box.

!!! warning
Do remember that in `planar_arrangement` (`Lar.Arrangement` module) matrices store points per row and not per column as described in the documentation of `Lar.Points`.

## The Arrangement Algorithm

In this section we will provide a general overview of how the `planar_arrangement` is meant to work.

The algorithm is divided into the following pipeline:
- Fragmentation of the 2-Cells.
- Spatial Indexing.
- Pairwise 2-Cells Fragmentation.
- Vertices Identification.
- Biconnected Components Detection.
- 3-Cells Evaluation and Dangling 2-Cells Elimination via Topological Gift Wrapping (TGW) algorithm.
- Component graph evaluation (TGW offline part).
- Evalution of the external cicle.
- Containment graph evaluation.
- Pruning of the containment graph.
- Transitive ``R`` reduction of ``S`` and generation of forest of flat trees
- Decomposition Cleaning (if a boundary has been specified).
- Shell poset aggregation (TGW onloine part).

### Fragmentation of the 2-Cells

This part of the pipeline is covered by:
```@docs
Lar.Arrangement.planar_arrangement_1
```
A small set of optional parameters could be choosen in order to personalize the computation:
- `sigma::Lar.Chain`: if specified, the arrangement will delete from the output every edge outside this cell
(*by defaults* = empty cell, no boundary).
- `return_edge_map::Bool`: If set to true, the function will also return an `edge_map` that maps the input edges to
the corresponding output ones.
- `multiproc::Bool`: If set to true, execute the arrangement in parallel (*by default* = false, sequential).



Once the data have been aquired, a spatial indexing between the 2-cells is made up in order to speed up the computation.
```@docs
Lar.spaceindex
```



Then each single 2-cell is fragmented by intersecting it with the other 2-cells that shares the same bounding box.
This process is either done in a parralel or a sequtial way via:
```@docs
Lar.Arrangement.frag_edge_channel
Lar.Arrangement.frag_edge
```
if the parallel way is choosen (namely `frag_edge_channel` is used) then a few more parameters must be specified:
- `in_chan::Distributed.RemoteChannel{Channel{Int64}}`: an input channel made of the edges indices to be intersected;
the channel must also hold at the end an EoW (`-1`) indicator for each worker thread in use.
- `out_chan::Distributed.RemoteChannel{Channel{Int64}}`: a ready-to-use output channel.



In order to split the edge, at a lower level, each pair of possible intersecting 2-cells are compared via:
```@docs
Lar.Arrangement.intersect_edges
```



In the end, the 1-cells are identified if they are located spatially very close one to the other (_i.e_ ``\epsilon = 10^{-4}``).
Of course if two 2-cells share the same endpoints then they are also identified in a unique 2-cell.
```@docs
Lar.Arrangement.merge_vertices!
```
Here also two optional parameters could be specified:
- `edge_map::Array{Array{Int64,1},1}`: Mapping from a set of edges to the edges of the given cochain.
If it is given in input than a copy of it would be returned in output, with its values coherently rearranged with the vertices merging (*by default* = ``[[-1]]``).
- `err::Float64`: Range of the vertex identification (*by default* = ``1e-4``).



!!! note
Choosing a good value for `err` is a very important issue.
Note that the identification is sequentially made;
therefore the following situation could happend:
if three vertices are collinear and evenly spaciated, then
- if the second is identified in the third,
then the first and the third won't be identified;
- if the third is identified with the second,
then the first and the second will be identified;

This situation could be seen in the secon example given by the function documentation.



### Biconnected Components Detection.

This part of the pipeline is covered by
```@docs
Lar.Arrangement.biconnected_components
```
As a reader can see the components are evaluated regardless the model geometrical structure;
in fact the 1-cells are not considered during the computation. This means that the abstract
graph made by the edges is the only input needed by the function.



### 3-Cells Evaluation and Dangling 2-Cells Elimination.

This part of the pipeline is covered by
```@docs
Lar.Arrangement.planar_arrangement_2
```


First of all the components of the graph are evaluated via
```@docs
Lar.Arrangement.componentgraph
```


Then, if a special chain ``\sigma`` has been specified, the given decomposition is cleaned
from all the 2-cells (and consequently from alle the 1-cells) that are located ouside its boundary via
```@docs
Lar.Arrangement.cleandecomposition
```


Lastly the 2-cells are merged in order to retrieve the 3-cell of the complex.
By doing so, all the 2-cells that are not linked to any 3-cell (_i.e._ dangling edges)
are lost.
!!! note
Do note that the 1-cells are not pruned during this computation.
Therefore the vertices associated with dangling edges will still be there.

This last part of the computation is done via:
```@docs
Lar.Arrangement.cell_merging
```


#### Component graph evaluation
Component Graph evaluation relies on different functions that could be use separatelly in order to obtain different results.

First of all we use the following function on each biconnected component
in order to gain the faces of the complex:
```@docs
Lar.Arrangement.get_external_cycle
```



Then a containment graph is build in order to clarify if some biconnected component
relies in another biconnected component. To do so, the approach is similiar to what
we did with the 2-cells decomposition. We firstly build the bounding box of each
component and we check whether they are one inside the other via:
```@docs
Lar.Arrangement.pre_containment_test
```



Then we prune the resulting mapping using:
```@docs
Lar.Arrangement.prune_containment_graph
```
In order to do so we take each biconnected component ``\phi`` whose bounding box is inside
the bounding box of ``\psi`` (``\forall \psi``) and we check if a point of ``phi`` is or is not
on the possible ``\psi`` 3-cells.
Do note that it is sufficient checking one single point since we know in advance
that each couple of biconnected components is intersection free. Therefore if a single
point of ``\phi`` is inside a biconnected component ``\psi`` then ``\phi \subset \psi``.


However if three or more faces are nested one into the other, then the mapping
is redundant. We therefore eliminate this redundany by applying:
```@docs
Lar.Arrangement.transitive_reduction!
```

## Examples

Lastly we close this section by giving a small example of how Planar Arrangement Works.
Using `Plasm` we are able to visualize the step of the computation grafically.


```julia
using Plasm
using LinearAlgebraicRepresentation
Lar = LinearAlgebraicRepresentation;

# Data Reading
V = [
0.0 0.5 3.0 5.0 2.0 2.0 0.0 1.0 0.0 3.0;
1.0 1.0 1.0 1.0 2.0 0.0 3.0 1.5 0.0 1.5
];
EV = [[1, 4], [2, 3], [5, 6], [2, 5], [3, 6], [7, 10], [8, 10], [9, 10]];

## 1 - Input Reading
Plasm.view(Plasm.numbering(0.5)((V,[[[k] for k=1:size(V,2)], EV])));

# Planar Arrangement 1
W = convert(Lar.Points, V'); # Infering type for W = V'
copEV = Lar.coboundary_0(EV::Lar.Cells);
W1, copEV1 = Lar.planar_arrangement_1(W::Lar.Points, copEV::Lar.ChainOp);

## 2 - 2-cells fragmentation
EV1 = Lar.cop2lar(copEV1);
V1 = convert(Lar.Points, W1');
Plasm.view(Plasm.numbering(0.5)((V1,[[[k] for k=1:size(V1,2)], EV1])));

# Biconnected COmponent Evaluation
bicon_comps = Lar.Arrangement.biconnected_components(copEV1);

## 3 - Biconnected Components
hpcs = [ Plasm.lar2hpc(V1,[EV1[e] for e in comp]) for comp in bicon_comps ]
Plasm.view([
Plasm.color(Plasm.colorkey[(k%12)==0 ? 12 : k%12])(hpcs[k])
for k = 1 : (length(hpcs))
])

# computation of 2-cells and 2-boundary
W2, copEV2, copFE2 = Lar.planar_arrangement_2(W1, copEV1, bicon_comps)

## 4 - 3-cells identification & dangling 1-cells elimination
Plasm.view( Plasm.numbering1(0.5)((W2, copEV2, copFE2)) )


# 5 - Colorfull Representation
triangulated_faces = Lar.triangulate2D(W2, [copEV2, copFE2])
V2 = convert(Lar.Points, W2')
FVs2 = convert(Array{Lar.Cells}, triangulated_faces)
Plasm.viewcolor(V2::Lar.Points, FVs2::Array{Lar.Cells})

# polygonal face boundaries
EVs2 = Lar.FV2EVs(copEV2, copFE2)
EVs2 = convert(Array{Array{Array{Int64,1},1},1}, EVs2)
Plasm.viewcolor(V2::Lar.Points, EVs2::Array{Lar.Cells})

# 6 - Exploded Representation
model = V2,EVs2
Plasm.view(Plasm.lar_exploded(model)(1.2,1.2,1.2))
```

The described commands gives the following representation via Plasm. Here we have reunited all the images in order to clarify the example. It could be seen in (4) that the 1-cells are not removed via the Pipeline.
![Pipeline visualization](./images/2d-arrangement-pipeline.jpg)
> **Figure 1:** Pipeline visualization over a sample structure.

More examples could be find in the `test` and `examples` directory.
Loading