@@ -10,6 +10,8 @@ Becaues the runtime of the GOGMA algorithm is O(n^2), and that of the TIV-GOGMA
1010## Construct Isotropic Gaussian Mixture Models (GMMs) for alignment
1111
1212``` julia
13+ julia> using GaussianMixtureAlignment; GMA = GaussianMixtureAlignment;
14+
1315julia> # These are very simple point sets that can be perfectly aligned
1416
1517julia> xpts = [[0. ,0. ,0. ], [3. ,0. ,0. ,], [0. ,4. ,0. ]];
@@ -32,56 +34,130 @@ julia> overlap(gmmx, gmmy)
32341.1908057504684806
3335```
3436
35- ## Align Isotropic GMMs with TIV- GOGMA
37+ ## Align Isotropic GMMs with GOGMA
3638
3739``` julia
38- julia> res = tiv_gogma_align (gmmx, gmmy);
40+ julia> res = gogma_align (gmmx, gmmy; nextblockfun = GMA . randomblock, maxsplits = 10000 );
3941
4042julia> # upper and lower bounds of alignmnet objective function at search termination
4143
4244julia> res. upperbound, res. lowerbound
43- (- 3.2512906351736524 , - 3.348917632693506 )
45+ (- 3.251290635173653 , - 5.528700740172087 )
4446
4547julia> # rotation component of the best transformation
4648
4749julia> res. tform. linear
48503 × 3 AngleAxis{Float64} with indices SOneTo (3 )× SOneTo (3 )(2.0944 , - 0.57735 , 0.57735 , - 0.57735 ):
49- 1.63136e-10 1.90925e-10 1.0
50- - 1.0 2.24997e-10 1.63136e-10
51- - 2.24997e-10 - 1.0 1.90925e-10
51+ - 1.38948e-11 - 2.5226e-11 1.0
52+ - 1.0 9.12343e-11 - 1.38948e-11
53+ - 9.12343e-11 - 1.0 - 2.52261e-11
5254
5355julia> # translation component of the best transformation
5456
5557julia> res. tform. translation
56583 - element StaticArrays. SVector{3 , Float64} with indices SOneTo (3 ):
57- 1.0
58- 1.0
59- 1.0
60-
61- julia> # repeat alignment with stricter tolerance
62-
63- julia> res. upperbound, res. lowerbound
64- (- 3.2512906351736524 , - 3.2522904816062654 )
65-
66- julia> # The result has not changed, but there is a tighter lower bound
59+ 1.0000000000115654
60+ 1.000000000557716
61+ 0.9999999997059433
6762
68- julia> # Compute the overlap between the GMMs after alignment
63+ julia> # Compute the overlap between the GMMs after alignment (equal to res.upperbound)
6964
7065julia> overlap (res. tform (gmmx), gmmy)
71- 3.2512906351736524
66+ 3.251290635173653
7267```
7368
7469## Plot Isotropic GMMs
7570``` julia
71+ julia> using GLMakie
72+
7673julia> # Draw the unaligned GMMs
7774
78- julia> plotdrawing ( drawIsotropicGMMs ([ gmmx,gmmy]) )
75+ julia> gmmdisplay ( gmmx,gmmy)
7976```
8077<img src =" ./assets/image/example.png " width =" 400 " />
8178
8279``` julia
8380julia> # Draw the aligned GMMs
8481
85- julia> plotdrawing ( drawIsotropicGMMs ([ res. tform (gmmx),gmmy]) )
82+ julia> gmmdisplay ( res. tform (gmmx), gmmy)
8683```
8784<img src =" ./assets/image/example_aligned.png " width =" 400 " />
85+
86+ ## Align GMMs with different types of interacting features
87+
88+ ``` julia
89+ julia> # four points defining a tetrahedron
90+
91+ julia> tetrahedron = [
92+ [0. ,0. ,1. ],
93+ [sqrt (8 / 9 ), 0. , - 1 / 3 ],
94+ [- sqrt (2 / 9 ),sqrt (2 / 3 ),- 1 / 3 ],
95+ [- sqrt (2 / 9 ),- sqrt (2 / 3 ),- 1 / 3 ]
96+ ];
97+
98+ julia> # each feature type is given its own IsotropicGMM
99+
100+ julia> chargedGMM = IsotropicGMM ([IsotropicGaussian (tetrahedron[1 ], 1.0 , 1.0 )]);
101+
102+ julia> stericGMM = IsotropicGMM ([IsotropicGaussian (p, 0.5 , 1.0 ) for p in tetrahedron]);
103+
104+ julia> mgmmx = IsotropicMultiGMM (Dict (
105+ :positive => chargedGMM,
106+ :steric => stericGMM
107+ ))
108+ IsotropicMultiGMM{3 , Float64, Symbol} with 2 labeled IsotropicGMM{3 , Float64} models made up of a total of 5 IsotropicGMM{3 , Float64} distributions.
109+
110+ julia> mgmmy = IsotropicMultiGMM (Dict (
111+ :negative => chargedGMM,
112+ :steric => stericGMM
113+ ))
114+ IsotropicMultiGMM{3 , Float64, Symbol} with 2 labeled IsotropicGMM{3 , Float64} models made up of a total of 5 IsotropicGMM{3 , Float64} distributions.
115+
116+ julia> # define interactions between each type of feature
117+
118+ julia> interactions = Dict (
119+ :positive => Dict (
120+ :positive => - 1.0 ,
121+ :negative => 1.0 ,
122+ ),
123+ :negative => Dict (
124+ :positive => 1.0 ,
125+ :negative => - 1.0 ,
126+ ),
127+ :steric => Dict (
128+ :steric => - 1.0 ,
129+ ),
130+ );
131+
132+ julia> # apply a random rigid transformation to one of the models
133+
134+ julia> using CoordinateTransformations; randtform = AffineMap ((rand (), rand (), rand (), rand (), rand (), rand ()));
135+
136+ julia> mgmmx = randtform (mgmmx);
137+
138+ julia> # compute alignment between the two MultiIsotropicGMMs
139+
140+ julia> res = gogma_align (mgmmx, mgmmy; interactions= interactions, nextblockfun= GMA. randomblock, maxsplits= 10000 );
141+ ```
142+ ## Plot MultiGMMs
143+
144+ ```
145+ julia> # Draw the unaligned GMMs
146+
147+ julia> gmmdisplay(mgmmx)
148+ ```
149+ <img src =" ./assets/image/multi_example_x.png " width =" 400 " />
150+
151+ ```
152+ julia> gmmdisplay(mgmmy)
153+ ```
154+ <img src =" ./assets/image/multi_example_x.png " width =" 400 " />
155+
156+ ``` julia
157+ julia> # Draw the aligned GMMs. Note that the "steric" features (green) repulse one another.
158+
159+ julia> gmmdisplay (res. tform (mgmmx), mgmmy)
160+ ```
161+ <img src =" ./assets/image/multi_example_aligned.png " width =" 400 " />
162+
163+ ## Align GMMs with different types of interacting features
0 commit comments