├── LDDMM_Python
├── lddmm_python
│ ├── lib
│ │ ├── __init__.py
│ │ └── plotly
│ │ │ ├── version.py
│ │ │ ├── plotly
│ │ │ ├── chunked_requests
│ │ │ │ └── __init__.py
│ │ │ └── __init__.py
│ │ │ ├── matplotlylib
│ │ │ ├── mplexporter
│ │ │ │ ├── __init__.py
│ │ │ │ ├── renderers
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── vincent_renderer.py
│ │ │ │ │ └── fake_renderer.py
│ │ │ │ ├── _py3k_compat.py
│ │ │ │ └── tools.py
│ │ │ └── __init__.py
│ │ │ ├── widgets
│ │ │ └── __init__.py
│ │ │ ├── grid_objs
│ │ │ └── __init__.py
│ │ │ ├── offline
│ │ │ └── __init__.py
│ │ │ ├── graph_objs
│ │ │ └── __init__.py
│ │ │ ├── __init__.py
│ │ │ └── files.py
│ ├── modules
│ │ ├── math_utils
│ │ │ ├── __init__.py
│ │ │ ├── points_clouds.py
│ │ │ ├── kernels.py
│ │ │ └── real_fft.py
│ │ ├── __init__.py
│ │ ├── data_attachment
│ │ │ ├── __init__.py
│ │ │ └── currents.py
│ │ ├── models
│ │ │ ├── __init__.py
│ │ │ ├── frechet_mean.py
│ │ │ ├── hypertemplate_atlas.py
│ │ │ ├── free_atlas.py
│ │ │ └── free_1D_atlas.py
│ │ ├── io
│ │ │ ├── __init__.py
│ │ │ ├── show_code.py
│ │ │ ├── my_iplot.py
│ │ │ ├── level_lines.py
│ │ │ ├── anim3D.py
│ │ │ └── read_vtk.py
│ │ └── manifolds
│ │ │ ├── __init__.py
│ │ │ ├── theano_surfacescarrier.py
│ │ │ ├── theano_surfaces.py
│ │ │ ├── theano_curves.py
│ │ │ ├── torus.py
│ │ │ ├── theano_hamiltoniancarrier.py
│ │ │ └── theano_shapescarrier.py
│ └── __init__.py
└── demo
│ └── Notebooks
│ └── Feb2017_paper
│ └── data
│ ├── source.png
│ └── target.png
├── Pytorch
├── data
│ ├── amoeba_1.png
│ └── amoeba_2.png
├── __pycache__
│ ├── curve.cpython-35.pyc
│ ├── kernel.cpython-35.pyc
│ ├── shooting.cpython-35.pyc
│ └── data_attachment.cpython-35.pyc
├── kernel.py
├── shooting.py
├── curve.py
└── data_attachment.py
├── Simple_script
├── amoeba_1.png
├── amoeba_2.png
├── test_pytorch.py
└── pytorch_memory_overflow.py
├── matlab
├── Bin
│ ├── optim
│ │ ├── hanso (third party)
│ │ │ ├── .DS_Store
│ │ │ ├── isposreal.m
│ │ │ ├── isposint.m
│ │ │ ├── isnonnegint.m
│ │ │ ├── isnaninf.m
│ │ │ ├── hgprod.m
│ │ │ ├── getbundle.m
│ │ │ ├── gradsamp1run.m
│ │ │ ├── setx0.m
│ │ │ ├── postprocess.m
│ │ │ ├── setdefaults.m
│ │ │ ├── setdefaultshanso.m
│ │ │ └── gradsampfixed.m
│ │ ├── perform_bfgs.m
│ │ └── set_optim_option.m
│ ├── norms
│ │ ├── common
│ │ │ ├── area.m
│ │ │ ├── dcross.m
│ │ │ ├── darea.m
│ │ │ ├── fcatoms.m
│ │ │ └── pVectors.m
│ │ ├── shape
│ │ │ ├── wasserstein
│ │ │ │ ├── getoptions.m
│ │ │ │ ├── dsinkhorn_log_cuda.m
│ │ │ │ ├── sinkhorn_log_cuda.m
│ │ │ │ ├── cost_varifold.m
│ │ │ │ ├── fshape_wasserstein_distance.m
│ │ │ │ ├── dcost_varifold.m
│ │ │ │ ├── sinkhorn_log.m
│ │ │ │ └── dfshape_wasserstein_distance.m
│ │ │ ├── matchterm.m
│ │ │ ├── dmatchterm.m
│ │ │ └── chain_rule.m
│ │ ├── deformations
│ │ │ ├── scalarProductRkhsV.m
│ │ │ └── dnormRkhsV.m
│ │ └── compute_coefficents_normalization.m
│ ├── io
│ │ ├── disp_iteration_info.m
│ │ ├── dispstructure.m
│ │ ├── disp_info_dimension.m
│ │ ├── setoptions.m
│ │ ├── export_mom_vtk.m
│ │ ├── export_fshape_vtk.m
│ │ └── import_fshape_vtk.m
│ ├── models
│ │ ├── matching
│ │ │ ├── tan
│ │ │ │ ├── enr_match_tan.m
│ │ │ │ ├── fsmatch_tan.m
│ │ │ │ └── jnfmatch_tan.m
│ │ │ └── geom
│ │ │ │ ├── match_geom.m
│ │ │ │ └── jnfmatch_geom.m
│ │ └── atlas
│ │ │ └── tan_free
│ │ │ ├── enr_tan_free.m
│ │ │ └── denr_tan_free.m
│ ├── kernels
│ │ ├── matlab
│ │ │ ├── rho.m
│ │ │ └── radial_function_geom.m
│ │ └── cuda
│ │ │ ├── kernels_old.cx~
│ │ │ ├── kernels_old.cx
│ │ │ ├── makefile_cuda.sh~
│ │ │ └── makefile_cuda.sh
│ └── deformations
│ │ ├── set_defo_option.m
│ │ └── tangential
│ │ ├── backward_tan.m
│ │ ├── forward_tan.m
│ │ ├── dHr_tan.m
│ │ ├── shoot_and_flow_tan.m
│ │ └── ddHrtP_tan.m
├── Script
│ ├── hands
│ │ ├── data
│ │ │ ├── tribute_to_franquin.jpeg
│ │ │ ├── read_off.m
│ │ │ └── generate_fiber.m
│ │ └── script_hands_matching_tan_bundle_ot.m
│ ├── bundles
│ │ └── script_bundle_matching_ot.m
│ └── skulls
│ │ └── script_skulls_matching.m
├── README.txt~
└── README.txt
├── .gitignore
├── LICENSE
└── README.md
/LDDMM_Python/lddmm_python/lib/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['plotly']
2 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/version.py:
--------------------------------------------------------------------------------
1 | __version__ = '1.12.9'
2 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/math_utils/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['kernels']
2 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/plotly/chunked_requests/__init__.py:
--------------------------------------------------------------------------------
1 | from . chunked_request import Stream
--------------------------------------------------------------------------------
/Pytorch/data/amoeba_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/Pytorch/data/amoeba_1.png
--------------------------------------------------------------------------------
/Pytorch/data/amoeba_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/Pytorch/data/amoeba_2.png
--------------------------------------------------------------------------------
/Simple_script/amoeba_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/Simple_script/amoeba_1.png
--------------------------------------------------------------------------------
/Simple_script/amoeba_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/Simple_script/amoeba_2.png
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['data_attachment', 'io', 'manifolds', 'models', 'math_utils']
2 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/data_attachment/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['measures', 'currents', 'varifolds', 'normal_cycles']
2 |
--------------------------------------------------------------------------------
/Pytorch/__pycache__/curve.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/Pytorch/__pycache__/curve.cpython-35.pyc
--------------------------------------------------------------------------------
/Pytorch/__pycache__/kernel.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/Pytorch/__pycache__/kernel.cpython-35.pyc
--------------------------------------------------------------------------------
/Pytorch/__pycache__/shooting.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/Pytorch/__pycache__/shooting.cpython-35.pyc
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/matplotlylib/mplexporter/__init__.py:
--------------------------------------------------------------------------------
1 | from .renderers import Renderer
2 | from .exporter import Exporter
3 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/matlab/Bin/optim/hanso (third party)/.DS_Store
--------------------------------------------------------------------------------
/matlab/Script/hands/data/tribute_to_franquin.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/matlab/Script/hands/data/tribute_to_franquin.jpeg
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/models/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['atlas', 'frechet_mean', 'free_1D_atlas', 'free_atlas', 'hypertemplate_atlas', 'model']
2 |
--------------------------------------------------------------------------------
/Pytorch/__pycache__/data_attachment.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/Pytorch/__pycache__/data_attachment.cpython-35.pyc
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['lib', 'modules']
2 |
3 | import os, sys
4 | sys.path.append(os.path.join(os.path.dirname(__file__), "lib"))
5 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/widgets/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 |
3 | from plotly.widgets.graph_widget import GraphWidget
4 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/io/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['anim3D', 'interactive_riemannian_geometry', 'my_iplot', 'my_trisurf', 'read_vtk', 'show_code']
2 |
--------------------------------------------------------------------------------
/LDDMM_Python/demo/Notebooks/Feb2017_paper/data/source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/LDDMM_Python/demo/Notebooks/Feb2017_paper/data/source.png
--------------------------------------------------------------------------------
/LDDMM_Python/demo/Notebooks/Feb2017_paper/data/target.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeanfeydy/lddmm-ot/HEAD/LDDMM_Python/demo/Notebooks/Feb2017_paper/data/target.png
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/manifolds/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['landmarks', 'curves', 'thick_curves', 'riemannian_manifold', 'surface_of_revolution', 'torus', 'kendall_triangles', 'theano_curves']
2 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/grid_objs/__init__.py:
--------------------------------------------------------------------------------
1 | """"
2 | grid_objs
3 | =========
4 |
5 | """
6 | from __future__ import absolute_import
7 |
8 | from plotly.grid_objs.grid_objs import Grid, Column
9 |
--------------------------------------------------------------------------------
/matlab/README.txt~:
--------------------------------------------------------------------------------
1 | This is a software that computes
2 | registration of shapes using a OT fidelity.
3 |
4 | -----------
5 | Quick start
6 | -----------
7 |
8 | 1) compile the mex files in ./Bin/kernels/ with the makefile.sh
9 | 2) run the various examples in ./Script/
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Will ignore result files in the several examples :
2 | *results*
3 | *output*
4 | !/Pytorch/output/.gitkeep
5 | !/Simple_script/output/.gitkeep
6 |
7 | # Will ignore DS_Stores files
8 | .DS_Store
9 |
10 | # Will ignore .nfs files
11 | .nfs*
12 |
13 | #Will ignore vim swap
14 | *.swp
15 | #
16 | #Will ignore temp files
17 | *~
18 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/offline/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | offline
3 | ======
4 | This module provides offline functionality.
5 | """
6 | from . offline import (
7 | download_plotlyjs,
8 | enable_mpl_offline,
9 | init_notebook_mode,
10 | iplot,
11 | iplot_mpl,
12 | plot,
13 | plot_mpl,
14 | _plot_html
15 | )
16 |
--------------------------------------------------------------------------------
/matlab/README.txt:
--------------------------------------------------------------------------------
1 | This is a software that computes
2 | registration of shapes using a OT fidelity.
3 |
4 | Author : B. Charlier (2017)
5 |
6 | -----------
7 | Quick start
8 | -----------
9 |
10 | 1) compile the mex files in ./Bin/kernels/ with the makefile.sh
11 | 2) run the various examples in ./Script/
12 | 3) the results are saved in '.vtk' legacy format (may be vizualized with "paraview")
13 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/io/show_code.py:
--------------------------------------------------------------------------------
1 | import inspect
2 | from pygments import highlight
3 | from pygments.lexers import PythonLexer
4 | from pygments.formatters import HtmlFormatter, Terminal256Formatter
5 |
6 | def show_code(func):
7 | if type(func) is str :
8 | code = func
9 | else :
10 | code = inspect.getsourcelines(func)[0]
11 | code = ''.join(code)
12 | print(highlight(code, PythonLexer(), Terminal256Formatter()))
13 |
14 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/common/area.m:
--------------------------------------------------------------------------------
1 | function [res] = area(pts,tri)
2 | % compute the areas of a set of triangles
3 | %
4 | % Input:
5 | % pts : list of vertices (n x d matrix)
6 | % tri : list of edges (T x M matrix where M==2 for curve and M==3 for surface)
7 | %
8 | % Output
9 | % res : area of each cell (T x 1 column vector);
10 | % Author : B. Charlier (2017)
11 |
12 |
13 | m = 1 ./ factorial(size(tri,2)-1);
14 | res = sqrt(sum(pVectors(pts,tri) .^2,2)) .* m;
15 |
16 | end
17 |
18 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/graph_objs/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | graph_objs
3 | ==========
4 |
5 | This package imports definitions for all of Plotly's graph objects. For more
6 | information, run help(Obj) on any of the following objects defined here.
7 |
8 | The reason for the package graph_objs and the module graph_objs is to provide
9 | a clearer API for users.
10 |
11 | """
12 | from __future__ import absolute_import
13 |
14 | from plotly.graph_objs.graph_objs import * # this is protected with __all__
15 |
--------------------------------------------------------------------------------
/matlab/Bin/io/disp_iteration_info.m:
--------------------------------------------------------------------------------
1 | function disp_iteration_info(nb_iter_total,ENRnew,stopCond,stepsNew,list_of_variables)
2 | % Author : B. Charlier (2017)
3 |
4 | x=['steps sizes :'];
5 | for i = 1 : length(list_of_variables)
6 | x = [x ,' ',list_of_variables{i},' : %4.2e,'];
7 | end
8 |
9 | fprintf(['\nit. %3d : functional value : %4.2e, Stopping condition (MeandENR) : %4.2e \n ',x(1:end-1),'\n\n'],...
10 | nb_iter_total,ENRnew,stopCond(1),stepsNew{1},stepsNew{2}, stepsNew{3},stepsNew{4});
11 |
12 | end
13 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/matplotlylib/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | matplotlylib
3 | ============
4 |
5 | This module converts matplotlib figure objects into JSON structures which can
6 | be understood and visualized by Plotly.
7 |
8 | Most of the functionality should be accessed through the parent directory's
9 | 'tools' module or 'plotly' package.
10 |
11 | """
12 | from __future__ import absolute_import
13 |
14 | from plotly.matplotlylib.renderer import PlotlyRenderer
15 | from plotly.matplotlylib.mplexporter import Exporter
16 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/matplotlylib/mplexporter/renderers/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | Matplotlib Renderers
3 | ====================
4 | This submodule contains renderer objects which define renderer behavior used
5 | within the Exporter class. The base renderer class is :class:`Renderer`, an
6 | abstract base class
7 | """
8 |
9 | from .base import Renderer
10 | from .vega_renderer import VegaRenderer, fig_to_vega
11 | from .vincent_renderer import VincentRenderer, fig_to_vincent
12 | from .fake_renderer import FakeRenderer, FullFakeRenderer
13 |
--------------------------------------------------------------------------------
/matlab/Bin/models/matching/tan/enr_match_tan.m:
--------------------------------------------------------------------------------
1 | function [ENR,dENR] = enr_match_tan(variables_vec)
2 | % Simple wrapper function that can be called by Hanso bfgs.
3 | % Author : B. Charlier (2017)
4 |
5 | global deflag templatexc templatefc
6 |
7 | n = deflag(end) ;
8 | d = size(templatexc{1},2);
9 |
10 |
11 | mom_cell = {reshape(variables_vec(1:d*n),n,d)};
12 |
13 | ENR = enr_tan_free(templatexc,mom_cell);
14 |
15 |
16 | [~,dnom] = denr_tan_free(templatexc,mom_cell) ;
17 |
18 |
19 | dENR = [cell2mat(dnom )];
20 | dENR = dENR(:);
21 |
22 | end
23 |
24 |
25 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/common/dcross.m:
--------------------------------------------------------------------------------
1 | function [dG1,dG2,dG3,dD1,dD2,dD3] = dcross(G,D,H)
2 | % Differential of (. \wedge .) at points (G,D) and applied to H. In short : d_(G,D) (G\wedge D) (H)
3 | % Author : B. Charlier (2017)
4 |
5 | dG1 = ( -D(:,3) .* H(:,2) + D(:,2) .* H(:,3));
6 | dG2 = ( +D(:,3) .* H(:,1) - D(:,1) .* H(:,3));
7 | dG3 = ( -D(:,2) .* H(:,1) + D(:,1) .* H(:,2));
8 |
9 | dD1 = ( +G(:,3) .* H(:,2) - G(:,2) .* H(:,3));
10 | dD2 = ( -G(:,3) .* H(:,1) + G(:,1) .* H(:,3));
11 | dD3 = ( +G(:,2) .* H(:,1) - G(:,1) .* H(:,2));
12 |
13 | end
14 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/math_utils/points_clouds.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | def decimate_indices(q, r) :
4 | def rec(l) :
5 | if l == [] :
6 | return []
7 | else :
8 | new_index = l.pop()
9 | new_point = q[new_index]
10 | s = []
11 | for i in l :
12 | curr_point = q[i]
13 | if sum((curr_point - new_point)**2) > r**2 :
14 | s.append(i)
15 | m = rec(s)
16 | m.append(new_index)
17 | return m
18 |
19 | return rec([j for j in range(q.shape[0])])
20 |
21 | def decimate(q, r) :
22 | return np.array([q[i] for i in decimate_indices(q,r)])
23 |
24 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/matplotlylib/mplexporter/_py3k_compat.py:
--------------------------------------------------------------------------------
1 | """
2 | Simple fixes for Python 2/3 compatibility
3 | """
4 | import sys
5 | PY3K = sys.version_info[0] >= 3
6 |
7 |
8 | if PY3K:
9 | import builtins
10 | import functools
11 | reduce = functools.reduce
12 | zip = builtins.zip
13 | xrange = builtins.range
14 | map = builtins.map
15 | else:
16 | import __builtin__
17 | import itertools
18 | builtins = __builtin__
19 | reduce = __builtin__.reduce
20 | zip = itertools.izip
21 | xrange = __builtin__.xrange
22 | map = itertools.imap
23 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/plotly/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | plotly
3 | ======
4 |
5 | This module defines functionality that requires interaction between your
6 | local machine and Plotly. Almost all functionality used here will require a
7 | verifiable account (username/api-key pair) and a network connection.
8 |
9 | """
10 | from . plotly import (
11 | sign_in,
12 | update_plot_options,
13 | get_credentials,
14 | iplot,
15 | plot,
16 | iplot_mpl,
17 | plot_mpl,
18 | get_figure,
19 | Stream,
20 | image,
21 | grid_ops,
22 | meta_ops,
23 | file_ops,
24 | get_config
25 | )
26 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/wasserstein/getoptions.m:
--------------------------------------------------------------------------------
1 | function v = getoptions(options, name, v, mendatory)
2 | % getoptions - retrieve options parameter
3 | %
4 | % v = getoptions(options, 'entry', v0, mendatory);
5 | % is equivalent to the code:
6 | % if isfield(options, 'entry')
7 | % v = options.entry;
8 | % else
9 | % v = v0;
10 | % end
11 | % Author : B. Charlier (2017)
12 |
13 |
14 | if nargin<3
15 | error('Not enough arguments.');
16 | end
17 | if nargin<4
18 | mendatory = 0;
19 | end
20 |
21 | if isfield(options, name)
22 | v = eval(['options.' name ';']);
23 | elseif mendatory
24 | error(['You have to provide options.' name '.']);
25 | end
26 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/io/my_iplot.py:
--------------------------------------------------------------------------------
1 | from plotly.offline import iplot, _plot_html
2 | from IPython.display import HTML, display
3 | import ipywidgets as widgets
4 |
5 | def my_iplot(figure_or_data, show_link=False, link_text='Export to plot.ly',
6 | validate=True, image=None, filename='plot_image', image_width=800,
7 | image_height=600) :
8 | plot_html, plotdivid, width, height = _plot_html(
9 | figure_or_data, show_link, link_text, validate,
10 | '100%', 525, global_requirejs=True)
11 | #display(HTML(plot_html))
12 | wid = widgets.HTML(
13 | value=plot_html,
14 | placeholder='Some HTML',
15 | description='Some HTML',
16 | disabled=False
17 | )
18 |
19 | return (wid, plotdivid)
20 |
--------------------------------------------------------------------------------
/matlab/Bin/kernels/matlab/rho.m:
--------------------------------------------------------------------------------
1 | function r=rho(x,opt,sig)
2 | % r=RHO(x,opt,sig) implements the Gaussian kernel and its derivatives :
3 | %
4 | % rho(t)=exp(-t/lam^2);
5 | %
6 | % Computation of rho(x^2/2) (ie opt==0), rho'(x^2/2) (ie opt==1) and
7 | % rho"(x^2/2) (ie opt==2)
8 | %
9 | % Input :
10 | % x : a matrix
11 | % opt : a integer
12 | % sig : vector with kernel bandwidths
13 | %
14 | % Output :
15 | % r : matrix of the size of x
16 | % Author : B. Charlier (2017)
17 |
18 |
19 | r=zeros(size(x));
20 | for l=sig
21 |
22 | if opt==0
23 | r=r + exp(-x/l^2);
24 | elseif opt==1
25 | r=r -exp(-x/l^2)/l^2;
26 | elseif opt==2
27 | r=r +exp(-x/l^2)/l^4;
28 | end
29 | end
30 |
31 | end
32 |
--------------------------------------------------------------------------------
/matlab/Bin/io/dispstructure.m:
--------------------------------------------------------------------------------
1 | function mesg=dispstructure(structvar)
2 | % This function outputs a caracter array with nested structures. May be enhanced....
3 | % Author : B. Charlier (2017)
4 |
5 |
6 | mesg = [];
7 | structvar = orderfields(structvar);
8 |
9 |
10 | fields=fieldnames(structvar);
11 | for k=1:length(fields)
12 | if isstruct(eval(['structvar.' fields{k}]))
13 | str = orderfields(eval(['structvar.',fields{k}]));
14 | mesg = [mesg,[' ',fields{k},'.',char(10)],evalc(' disp( str )')];
15 | structvar = rmfield(structvar, fields{k});
16 | end
17 | end
18 |
19 |
20 | mesg_root = evalc('disp(structvar)');
21 |
22 | mesg = [mesg_root,mesg];
23 |
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/Pytorch/kernel.py:
--------------------------------------------------------------------------------
1 | # Import the relevant tools
2 | import numpy as np # standard array library
3 | import torch
4 |
5 | def _squared_distances(x, y) :
6 | "Returns the matrix of $\|x_i-y_j\|^2$."
7 | x_col = x.unsqueeze(1) # Theano : x.dimshuffle(0, 'x', 1)
8 | y_lin = y.unsqueeze(0) # Theano : y.dimshuffle('x', 0, 1)
9 | return torch.sum( (x_col - y_lin)**2 , 2 )
10 |
11 | def _k(x, y, s) :
12 | "Returns the matrix of k(x_i,y_j)."
13 | sq = _squared_distances(x, y) / (s**2)
14 | #return torch.exp( -sq )
15 | return torch.pow( 1. / ( 1. + sq ), .25 )
16 |
17 | def _cross_kernels(q, x, s) :
18 | "Returns the full k-correlation matrices between two point clouds q and x."
19 | K_qq = _k(q, q, s)
20 | K_qx = _k(q, x, s)
21 | K_xx = _k(x, x, s)
22 | return (K_qq, K_qx, K_xx)
23 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/math_utils/kernels.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import theano
3 | import theano.tensor as T
4 |
5 |
6 | def _squared_distances(x, y) :
7 | return (x ** 2).sum(1).reshape((x.shape[0], 1)) \
8 | + (y ** 2).sum(1).reshape((1, y.shape[0])) \
9 | - 2* x.dot(y.T)
10 |
11 | def _gaussian_kernel(x, y, s) :
12 | if type(s) is not list :
13 | s = [(1., s)]
14 | res = s[0][0] * T.exp(- _squared_distances(x,y) / (2 * s[0][1]**2) )
15 | for (coeff,sigm) in s[1:] :
16 | res = res + coeff * T.exp(- _squared_distances(x,y) / (2 * sigm**2) )
17 | return res
18 |
19 | def _gaussian_cross_kernels(q, x, s) :
20 | K_qq = _gaussian_kernel(q, q, s)
21 | K_qx = _gaussian_kernel(q, x, s)
22 | K_xx = _gaussian_kernel(x, x, s)
23 |
24 | return (K_qq, K_qx, K_xx)
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/matchterm.m:
--------------------------------------------------------------------------------
1 | function g= matchterm(fshape1,fshape2,objfun)
2 | % g= MATCHTERM(fshape1,fshape2,objfun) computes the distance between
3 | % fshape1 and fshape2 wrt various norms. Options
4 | % are given by the structure objfun.
5 | %
6 | %Input
7 | % fshape1 : fshape structure
8 | % fshape2 : fshape structure
9 | % objfun : structure containing the parameters :
10 | %Output
11 | % g = real number
12 | % Author : B. Charlier (2017)
13 |
14 |
15 | % Some checks
16 | if (size(fshape1.x,2) ~= size(fshape2.x,2)) || (size(fshape1.G,2) ~= size(fshape2.G,2))
17 | error('fshapes should be in the same space')
18 | end
19 |
20 | switch objfun.distance
21 |
22 | case 'wasserstein'
23 | G = @fshape_wasserstein_distance;
24 |
25 | end
26 |
27 |
28 | g = G(fshape1,fshape2,objfun);
29 |
30 | end
31 |
32 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/manifolds/theano_surfacescarrier.py:
--------------------------------------------------------------------------------
1 | # Import of the relevant tools
2 | import time
3 | import numpy as np
4 | import theano
5 | import theano.tensor as T
6 | from theano import pp, config
7 |
8 |
9 | from plotly.tools import FigureFactory as FF
10 | import plotly.graph_objs as go
11 |
12 | from ..io.read_vtk import ReadVTK
13 |
14 |
15 | from .theano_shapescarrier import TheanoShapesCarrier
16 | from .surfaces_manifold import SurfacesManifold
17 |
18 | class TheanoSurfacesCarrier(SurfacesManifold, TheanoShapesCarrier) :
19 | """
20 | Surface + HamiltonianDynamics with control points.
21 | """
22 | def __init__(self, *args, **kwargs) :
23 | """
24 | Creates a TheanoSurfaces manifold.
25 | Compilation takes place here.
26 | """
27 | TheanoShapesCarrier.__init__(self, *args, **kwargs)
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/wasserstein/dsinkhorn_log_cuda.m:
--------------------------------------------------------------------------------
1 | function [u,grad_x] = dsinkhorn_log_cuda(mu,nu,x,y,epsilon,options,d)
2 | % A wrapper function calling a cuda implementation of sinkhorn_log - stabilized
3 | % sinkhorn over log domain with acceleration. It computes the derivative
4 | % with respect to x.
5 | %
6 | % See : Sinkhorn_log and dfshapes_wasserstein_distance functions for details
7 | % Author : B. Charlier (2017)
8 |
9 |
10 | options.null = 0;
11 | rho = getoptions(options, 'rho', Inf);
12 |
13 | if rho==Inf
14 | %balanced
15 | lambda=1;
16 | else
17 | % unbalanced
18 | lambda = rho/(rho+epsilon);
19 | end
20 |
21 | % Sinkhorn
22 | u = zeros(size(mu));
23 | v = zeros(size(nu));
24 |
25 | [u,grad_x] = dsinkhornGpuConv(u',x,y,v',epsilon,lambda,mu',nu',options.weight_cost_varifold,int32(options.niter));
26 |
27 | u = u'; grad_x = grad_x';
28 |
29 | end
30 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/dmatchterm.m:
--------------------------------------------------------------------------------
1 | function [dxg]= dmatchterm(fshape1,fshape2,objfun)
2 | % g= DMATCHTERM(fshape1,fshape2,objfun) computes the distance between
3 | % fshape1 and fshape2 wrt various norms. Options
4 | % are given by the structure objfun.
5 | %
6 | %Input
7 | % fshape1 : a fshape structure
8 | % fshape2 : a fshape structure
9 | % objfun : structure containing the parameters
10 | %Output
11 | % dxg : derivative wrt x (matrix n x d)
12 | % dfg : derivative wrt f (vector n x 1)
13 | % Author : B. Charlier (2017)
14 |
15 | % Some checks
16 | if (size(fshape1.x,2) ~= size(fshape2.x,2)) || (size(fshape1.G,2) ~= size(fshape2.G,2))
17 | error('fshapes should be in the same space')
18 | end
19 |
20 |
21 | switch objfun.distance
22 | case 'wasserstein'
23 | DG = @dfshape_wasserstein_distance;
24 | end
25 |
26 |
27 |
28 | [dxg] = DG(fshape1,fshape2,objfun);
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/matlab/Bin/io/disp_info_dimension.m:
--------------------------------------------------------------------------------
1 | function msg = disp_info_dimension(data,template,silent)
2 | % print some informations about the dimension of the problem
3 | % Author : B. Charlier (2017)
4 |
5 | deflag = [0,cumsum(cellfun(@(y) size(y.x,1),template))];
6 | nlist = diff(deflag); % number of point in each shape
7 |
8 | [nb_obs,nb_match] = size(data);
9 | x = repmat(' %d,',1,nb_match);
10 | msg = [sprintf('\n----------- Dimensions of the problem -----------\n'),...
11 | sprintf('Data : %d observations containing %d fshape(s) each.',nb_obs,nb_match),...
12 | sprintf([' The mean number of points in each shape is : ',x(1+1:end-1),'.'],floor(mean(cellfun(@(y) size(y.x,1),data)))),...
13 | sprintf('\nMean Template : contains %d fshape(s). The number of points is : ',size(template,2)),...
14 | sprintf([x(1+1:end-1),'.'],nlist),...
15 | sprintf('\n')];
16 |
17 | if nargin ==2 || (silent == 0)
18 | disp(msg)
19 | end
20 |
21 | end
22 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/common/darea.m:
--------------------------------------------------------------------------------
1 | function [dArea] = darea(pts,tri)
2 | % compute the derivative of the areas of a set of triangles
3 | %
4 | % Input:
5 | % pts : nb_points x d matrix
6 | % tri : nb_tri x M matrix (M==2 for curve and M==3 for surface)
7 | %
8 | % Output
9 | % dArea : (M* nb_tri) x d matrix;
10 | % Author : B. Charlier (2017)
11 |
12 |
13 | [~,M] = size(tri);
14 | [~,d] = size(pts);
15 |
16 | N = pVectors(pts,tri);
17 | N = bsxfun(@rdivide,N,sqrt(sum(N.^2,2)));
18 |
19 | if (M==2) && (d<=3)
20 |
21 | dArea = [-N;N];
22 | elseif (M==3) && (d==3)
23 |
24 | E21 = (pts(tri(:,2),:) - pts(tri(:,1),:));
25 | E31 = (pts(tri(:,3),:) - pts(tri(:,1),:));
26 |
27 | [dG1,dG2,dG3,dD1,dD2,dD3] = dcross(E21,E31,N);
28 |
29 | dArea = .5* [[-dG1-dD1;+dG1 ;+dD1 ],...
30 | [-dG2-dD2;+dG2 ;+dD2 ],...
31 | [-dG3-dD3;+dG3 ;+dD3 ]];
32 | end
33 |
34 | end
35 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/wasserstein/sinkhorn_log_cuda.m:
--------------------------------------------------------------------------------
1 | function [u,v,Wprimal,Wdual,err] = sinkhorn_log_cuda(mu,nu,x,y,epsilon,options)
2 | % A wrapper function calling a cuda implementation of sinkhorn_log - stabilized sinkhorn over log domain without acceleration
3 | %
4 | % See : Sinkhorn_log function for details
5 | % Author : B. Charlier (2017)
6 |
7 |
8 | rho = getoptions(options, 'rho', Inf);
9 |
10 | % Sinkhorn
11 | u = zeros(size(mu));
12 | v = zeros(size(nu));
13 |
14 | if rho==Inf
15 | %balanced
16 | lambda=1;
17 | [u,v,Wdual] = sinkhornGpuConv(u',x,y,v',epsilon,lambda,mu',nu',options.weight_cost_varifold,int32(options.niter));
18 | else
19 | % unbalanced
20 | lambda = rho/(rho+epsilon);
21 | [u,v,Wdual] = sinkhornGpuConv_unbalanced(u',x,y,v',epsilon,lambda,rho,mu',nu',options.weight_cost_varifold,int32(options.niter));
22 | end
23 |
24 |
25 |
26 | Wprimal = [];
27 | err =0;
28 |
29 | u = u'; v = v';
30 |
31 | end
32 |
33 |
34 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | https://plot.ly/python/
3 |
4 | Plotly's Python API allows users to programmatically access Plotly's
5 | server resources.
6 |
7 | This package is organized as follows:
8 |
9 | Subpackages:
10 |
11 | - plotly: all functionality that requires access to Plotly's servers
12 |
13 | - graph_objs: objects for designing figures and visualizing data
14 |
15 | - matplotlylib: tools to convert matplotlib figures
16 |
17 | Modules:
18 |
19 | - tools: some helpful tools that do not require access to Plotly's servers
20 |
21 | - utils: functions that you probably won't need, but that subpackages use
22 |
23 | - version: holds the current API version
24 |
25 | - exceptions: defines our custom exception classes
26 |
27 | """
28 |
29 | from __future__ import absolute_import
30 |
31 | from plotly import (plotly, graph_objs, grid_objs, tools, utils, session,
32 | offline, colors)
33 | from plotly.version import __version__
34 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/manifolds/theano_surfaces.py:
--------------------------------------------------------------------------------
1 | # Import of the relevant tools
2 | import time
3 | import numpy as np
4 | import theano
5 | import theano.tensor as T
6 | from theano import pp, config
7 |
8 |
9 | from plotly.tools import FigureFactory as FF
10 | import plotly.graph_objs as go
11 |
12 | from ..io.read_vtk import ReadVTK
13 |
14 | # a TheanoCurves manifold will be created from a regular Curve,
15 | # with information about connectivity and number of points.
16 | # Basically, a TheanoCurves is an efficient implementation of
17 | # a shape orbit.
18 | from .theano_shapes import TheanoShapes
19 | from .surfaces_manifold import SurfacesManifold
20 |
21 | class TheanoSurfaces(SurfacesManifold, TheanoShapes) :
22 | """
23 | Surface + HamiltonianDynamics with dense momentum field.
24 | """
25 | def __init__(self, *args, **kwargs) :
26 | """
27 | Creates a TheanoSurfaces manifold.
28 | Compilation takes place here.
29 | """
30 | TheanoShapes.__init__(self, *args, **kwargs)
31 |
32 |
33 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/manifolds/theano_curves.py:
--------------------------------------------------------------------------------
1 | # Import of the relevant tools
2 | import time
3 | import numpy as np
4 | import theano
5 | import theano.tensor as T
6 | from theano import pp, config
7 |
8 |
9 | from plotly.tools import FigureFactory as FF
10 | import plotly.graph_objs as go
11 |
12 | from ..io.read_vtk import ReadVTK
13 |
14 | # a TheanoCurves manifold will be created from a regular Curve,
15 | # with information about connectivity and number of points.
16 | # Basically, a TheanoCurves is an efficient implementation of
17 | # a shape orbit.
18 | from .theano_shapes import TheanoShapes
19 | from .curves_manifold import CurvesManifold
20 |
21 | class TheanoCurves(CurvesManifold, TheanoShapes) :
22 | """
23 | Curve + HamiltonianDynamics with dense momentum field.
24 | """
25 | def __init__(self, *args, **kwargs) :
26 | """
27 | Creates a TheanoCurves manifold.
28 | Compilation takes place here.
29 | """
30 | TheanoShapes.__init__(self, *args, **kwargs)
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/matlab/Bin/deformations/set_defo_option.m:
--------------------------------------------------------------------------------
1 | function [ndefo,mesg] = set_defo_option(defo,list_of_variables)
2 | % This function check the defo structure and set default values if needed.
3 | % Author : B. Charlier (2017)
4 |
5 | is_algo_met =(sum(strcmp(list_of_variables(:),'pf')) >0);
6 |
7 | ndefo = defo;
8 |
9 | ndefo = setoptions(ndefo,'method','matlab',{'cuda','matlab','grid'});
10 |
11 | if (strcmp(defo.method,'grid')) && ( ~isfield(defo,'gridratio') || (defo.gridratio < 0) || (defo.gridratio >1) )
12 | ndefo.gridratio = .2;
13 | %fprintf('deformation : gridratio set to %f\n',ndefo.gridratio)
14 | end
15 |
16 | ndefo = setoptions(ndefo,'nb_euler_steps',10);
17 | ndefo = setoptions(ndefo,'kernel_size_mom');
18 |
19 | if is_algo_met
20 | ndefo = setoptions(ndefo,'weight_coef_pen_p',1);
21 | ndefo = setoptions(ndefo,'weight_coef_pen_pf',1);
22 | end
23 |
24 | % save message and display
25 | mesg = [sprintf('\n----------- Deformation parameters -----------\n' ),...
26 | evalc('disp(orderfields(ndefo))')];
27 | fprintf('%s',mesg);
28 |
29 | end
30 |
--------------------------------------------------------------------------------
/matlab/Bin/io/setoptions.m:
--------------------------------------------------------------------------------
1 | function v = setoptions(struct, fieldname, default_value, possible_value)
2 | % setoptions(struct, fieldname, default_value, possible_value) - given a struct,
3 | % check if the field 'fieldname' exists. If not it create the field with
4 | % the default value. If it exists and possible_value is
5 | % given, it checks that the existing value is in possible value.
6 | %
7 | % Input
8 | % struct : a structure
9 | % fieldname : a string with the fieldname
10 | % default_value : a default value
11 | % Output
12 | % struct : the checked structure.
13 | % Author : B. Charlier (2017)
14 |
15 | v = struct;
16 |
17 | if ~isfield(struct, fieldname) && (nargin ==2)
18 |
19 | error([fieldname,' is mandatory!'])
20 |
21 | elseif ~isfield(struct, fieldname) && (nargin > 2)
22 |
23 | v.(fieldname) = default_value;
24 |
25 | elseif nargin == 4 && ischar(default_value)
26 |
27 | if sum(strcmp(possible_value(:),v.(fieldname))) == 0
28 | error(['Possible values for ',fieldname,' is ',cell2mat(possible_value)])
29 | end
30 |
31 | end
32 |
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 jeanfeydy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/matlab/Script/hands/data/read_off.m:
--------------------------------------------------------------------------------
1 | function [vertex,face] = read_off(filename)
2 |
3 | % read_off - read data from OFF file.
4 | %
5 | % [vertex,face] = read_off(filename);
6 | %
7 | % 'vertex' is a 'nb.vert x 3' array specifying the position of the vertices.
8 | % 'face' is a 'nb.face x 3' array specifying the connectivity of the mesh.
9 |
10 |
11 | fid = fopen(filename,'r');
12 | if( fid==-1 )
13 | error('Can''t open the file.');
14 | return;
15 | end
16 |
17 | str = fgets(fid); % -1 if eof
18 | if ~strcmp(str(1:3), 'OFF')
19 | error('The file is not a valid OFF one.');
20 | end
21 |
22 | str = fgets(fid);
23 | [a,str] = strtok(str); nvert = str2num(a);
24 | [a,str] = strtok(str); nface = str2num(a);
25 |
26 |
27 |
28 | [A,cnt] = fscanf(fid,'%f %f %f', 3*nvert);
29 | if cnt~=3*nvert
30 | warning('Problem in reading vertices.');
31 | end
32 | A = reshape(A, 3, cnt/3);
33 | vertex = A;
34 | % read Face 1 1088 480 1022
35 | [A,cnt] = fscanf(fid,'%d %d %d %d\n', 4*nface);
36 | if cnt~=4*nface
37 | warning('Problem in reading faces.');
38 | end
39 | A = reshape(A, 4, cnt/4);
40 | face = A(2:4,:)+1;
41 |
42 |
43 | fclose(fid);
44 |
45 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/math_utils/real_fft.py:
--------------------------------------------------------------------------------
1 | import theano.tensor as T
2 | from theano.tensor.fft import rfft, irfft
3 | #from theano.gpuarray.fft import curfft as rfft
4 | #from theano.gpuarray.fft import cuirfft as irfft
5 | _rfft1d = rfft
6 | _irfft1d = irfft
7 |
8 | def _rfft2d(x) :
9 | """
10 | Outputs a tensor3 of size (im.shape//2+1)+(4,).
11 | At each location, 4 real fourier transforms which respectively encode
12 | Re.Re, Re.Im, Im.Re, Im.Im.
13 |
14 | This routine is provided for you to understand its inverse the _irfft2d routine...
15 | """
16 | # First, take the real FFT along dimension 1
17 | f_x = _rfft1d(x).dimshuffle(1,0,2) # dimshuffle in order to take the FFT along dim 0
18 | f_x_re = _rfft1d(f_x[:,:,0]).dimshuffle(1,0,2)
19 | f_x_im = _rfft1d(f_x[:,:,1]).dimshuffle(1,0,2)
20 | return T.concatenate([f_x_re, f_x_im], axis = 2)
21 |
22 | def _irfft2d(f_x) :
23 | """
24 | Inverse of the _rfft2d(x) routine.
25 | """
26 | f_x = f_x.dimshuffle(1,0,2)
27 | f_x_re = _irfft1d(f_x[:,:,0:2]).dimshuffle(1,0)
28 | f_x_im = _irfft1d(f_x[:,:,2:4]).dimshuffle(1,0)
29 | x = _irfft1d( T.stack([f_x_re, f_x_im], axis = 2) )
30 | return(x)
31 |
32 |
33 |
--------------------------------------------------------------------------------
/matlab/Bin/kernels/matlab/radial_function_geom.m:
--------------------------------------------------------------------------------
1 | function r=radial_function_geom(x,derivative_order,objfun)
2 | % r=RHO(x,opt,sig) implements the Gaussian kernel and its derivatives :
3 | %
4 | % rho(t)=exp(-t/lam^2);
5 | %
6 | % Computation of rho(x^2/2) (ie opt==0), rho'(x^2/2) (ie opt==1) and
7 | % rho"(x^2/2) (ie opt==2)
8 | %
9 | % Input :
10 | % x : a matrix
11 | % opt : a integer
12 | % sig : vector with kernel bandwidths
13 | %
14 | % Output :
15 | % r : matrix of the size of x
16 | % Author : B. Charlier (2017)
17 |
18 | r=zeros(size(x));
19 |
20 |
21 |
22 | switch lower(objfun.kernel_geom)
23 | case 'gaussian'
24 |
25 | for l=objfun.kernel_size_geom
26 | if derivative_order==0
27 | r=r + exp(-x/l^2);
28 | elseif derivative_order==1
29 | r=r -exp(-x/l^2)/l^2;
30 | end
31 | end
32 |
33 | case 'cauchy'
34 |
35 | for l=objfun.kernel_size_geom
36 | if derivative_order==0
37 | r=r + 1 ./ (1 + (x/l^2));
38 | elseif derivative_order==1
39 | r=r -1 ./ (l^2 * (1 + (x/l^2)) .^2);
40 | end
41 | end
42 |
43 |
44 | end
45 |
46 | end
47 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/manifolds/torus.py:
--------------------------------------------------------------------------------
1 | from pylab import *
2 | from .surface_of_revolution import SurfaceOfRevolution
3 |
4 | class Torus(SurfaceOfRevolution) :
5 | def __init__(self, a=2, b=1, vis_mode='3D') :
6 | """A Torus, seen as a Riemannian Manifold.
7 |
8 | Arguments :
9 | a -- radius of the donut
10 | b -- radius of its section
11 | vis_mode -- '2D', '3D' : mode for displaying results
12 | """
13 | R = lambda r : a + b * cos(r / b)
14 | Rp = lambda r : -sin(r / b)
15 | Rpp = lambda r : - cos(r / b) / b
16 | Z = lambda r : b * sin(r / b)
17 | Zp = lambda r : cos(r / b)
18 |
19 | D = array([[-b*pi,b*pi],
20 | [-pi, pi ]])
21 |
22 | SurfaceOfRevolution.__init__(self, R, Rp, Rpp, Z, Zp, D, vis_mode)
23 |
24 | self.a = a
25 | self.b = b
26 |
27 |
28 | """ Projection & Distances """
29 | def projection_onto(self, X) :
30 | """Orthogonal projection from R^3 to the torus."""
31 | x = X[:,0]
32 | y = X[:,1]
33 | z = X[:,2]
34 | Theta = angle(x + 1j * y)
35 | Pl = sqrt(x**2 + y**2) - self.a
36 | Xhi = angle( Pl + 1j * z)
37 | r = Xhi / self.b
38 | return vstack((r , Theta))
39 | def squared_distance_from(self, Xt) :
40 | """.5*(d(Xt, Torus)^2) from R^3 to the torus."""
41 | Q = self.projection_onto(Xt)
42 | X = self.I(q = Q)
43 | return .5*sum( (Xt - X)**2, 1)
44 |
45 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/isposreal.m:
--------------------------------------------------------------------------------
1 | function ipr = isposreal(x)
2 | % return true if x is a positive real scalar, false otherwise
3 | %
4 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
5 | % with a subject header containing the string "hanso".
6 | % Version 2.0, 2010, see GPL license info below.
7 |
8 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
10 | %% This program is free software: you can redistribute it and/or modify
11 | %% it under the terms of the GNU General Public License as published by
12 | %% the Free Software Foundation, either version 3 of the License, or
13 | %% (at your option) any later version.
14 | %%
15 | %% This program is distributed in the hope that it will be useful,
16 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | %% GNU General Public License for more details.
19 | %%
20 | %% You should have received a copy of the GNU General Public License
21 | %% along with this program. If not, see .
22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23 |
24 | if ~isscalar(x)
25 | ipr = 0;
26 | else % following is OK since x is scalar
27 | ipr = isreal(x) & x > 0;
28 | end
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/isposint.m:
--------------------------------------------------------------------------------
1 | function ipi = isposint(x)
2 | % return true if x is a positive integer, false otherwise
3 | %
4 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
5 | % with a subject header containing the string "hanso".
6 | % Version 2.0, 2010, see GPL license info below.
7 |
8 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
10 | %% This program is free software: you can redistribute it and/or modify
11 | %% it under the terms of the GNU General Public License as published by
12 | %% the Free Software Foundation, either version 3 of the License, or
13 | %% (at your option) any later version.
14 | %%
15 | %% This program is distributed in the hope that it will be useful,
16 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | %% GNU General Public License for more details.
19 | %%
20 | %% You should have received a copy of the GNU General Public License
21 | %% along with this program. If not, see .
22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23 |
24 | if ~isscalar(x)
25 | ipi = 0;
26 | else % following is OK since x is scalar
27 | ipi = isreal(x) & round(x) == x & x > 0;
28 | end
--------------------------------------------------------------------------------
/matlab/Bin/norms/deformations/scalarProductRkhsV.m:
--------------------------------------------------------------------------------
1 | function res=scalarProductRkhsV(p1,x,defo,p2)
2 | % res=SCALARPRODUCTRKHSV(p1,x,defo,p2) implements the scalar
3 | % product (p,K(x,x)p)/2 where the kernel size is given by
4 | % defo.kernel_size_mom. Several method are implemented (cuda, matlab...)
5 | %
6 | % scalarProductRkhsV(p1,x,defo) is equivalent to scalarProductRkhsV(p1,x,defo,p1)
7 | % that is returns the norm squared of p1.
8 | %
9 | % Inputs :
10 | % p1 : is a n x d matrix containing initial momenta
11 | % x : is a n x d matrix containing positions
12 | % defo : structure containing the parameters of deformations
13 | % p2 : is a n x d matrix containing initial momenta
14 | %
15 | % Output :
16 | % res : is a real number (scalar product)
17 | %
18 | % See also : dnormRkhsV
19 | % Author : B. Charlier (2017)
20 |
21 |
22 | if nargin == 3
23 | p2=p1;
24 | end
25 |
26 | [n,d] = size(x);
27 |
28 | switch defo.method
29 | case 'cuda'
30 |
31 | res=0;
32 | for sig=defo.kernel_size_mom
33 | res= res + sum(sum(GaussGpuConv(x',x',p2',sig)' .* p1));
34 | end
35 |
36 | otherwise
37 |
38 | % Calcul de A=exp(-|x_i -x_j|^2/(2*lam^2))
39 | S=zeros(n);
40 | for l=1:d
41 | S=S+(repmat(x(:,l),1,n)-repmat(x(:,l)',n,1)).^2;
42 | end
43 | res=trace(p1' * rho(S,0,defo.kernel_size_mom) * p2);
44 | end
45 |
46 |
47 | end
48 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/common/fcatoms.m:
--------------------------------------------------------------------------------
1 | function [X,Xi] = fcatoms(pts,tri)
2 | % [X,tf,Xi] = FCATOMS(pts,f,tri,signal_type) compute the dirac representation of meshes (1D or 2D)
3 | %
4 | % Input :
5 | % pts : matrix with vertices (one column per dimension, matrix nxd)
6 | % tri : connectivity matrix. if tri is of size (M x 2) this is a 1d current
7 | % (so each line of tri contains the two indexes of the points defining
8 | % an oriented segment), if tri is (M x 3) this to be considered
9 | % as a 2d current (so each line of tri contains the three indexes of
10 | % the points defining an oriented triangle).
11 | % f : column vector of functional values (n x1)
12 | % signal_type : optional string. If type_signal=='face', f is assumed to be
13 | % the values of the signal at the center of the faces else f is assumed to
14 | % be the values of the signal at the vertices (ie pts)
15 | %
16 | % Output
17 | % X : the matrix of the centers of the faces (M x d)
18 | % Xi: is the matric of p-vectors (tangent (1d current) or normal 2d current) (M x 2 or 3)
19 | % Author : B. Charlier (2017)
20 |
21 |
22 | [T,M]=size(tri);
23 | d = size(pts,2);
24 |
25 | %normals
26 | m = factorial(M-1);
27 | Xi = pVectors(pts,tri) / m; % normals or tangent vectors
28 |
29 | %centers
30 | if M==1
31 | X = pts;
32 | else
33 | X=sum(reshape(pts(tri(:),:)',d,T,M ),3)'/M; % center of the faces
34 | end
35 |
36 | end
37 |
38 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/isnonnegint.m:
--------------------------------------------------------------------------------
1 | function inni = isnonnegint(x)
2 | % return true if x is a nonnegative integer, false otherwise
3 | %
4 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
5 | % with a subject header containing the string "hanso".
6 | % Version 2.0, 2010, see GPL license info below.
7 |
8 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
10 | %% This program is free software: you can redistribute it and/or modify
11 | %% it under the terms of the GNU General Public License as published by
12 | %% the Free Software Foundation, either version 3 of the License, or
13 | %% (at your option) any later version.
14 | %%
15 | %% This program is distributed in the hope that it will be useful,
16 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | %% GNU General Public License for more details.
19 | %%
20 | %% You should have received a copy of the GNU General Public License
21 | %% along with this program. If not, see .
22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23 | if ~isscalar(x)
24 | inni = 0;
25 | else % following is OK since x is scalar
26 | inni = (isreal(x) & round(x) == x & x >= 0);
27 | end
28 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/isnaninf.m:
--------------------------------------------------------------------------------
1 | function ini = isnaninf(M)
2 | % returns the scalar 1 if ANY entry of M is nan or inf; 0 otherwise
3 | % note: isnan and isinf return matrices if M is a matrix, and
4 | % if treats [0 1] as false, not true.
5 | % ini = sum(sum(isnan(M))) > 0 | sum(sum(isinf(M))) > 0;
6 | ini = any(any(isnan(M))) | any(any(isinf(M)));
7 | %
8 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
9 | % with a subject header containing the string "hanso".
10 | % Version 2.0, 2010, see GPL license info below.
11 |
12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
14 | %% This program is free software: you can redistribute it and/or modify
15 | %% it under the terms of the GNU General Public License as published by
16 | %% the Free Software Foundation, either version 3 of the License, or
17 | %% (at your option) any later version.
18 | %%
19 | %% This program is distributed in the hope that it will be useful,
20 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
21 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 | %% GNU General Public License for more details.
23 | %%
24 | %% You should have received a copy of the GNU General Public License
25 | %% along with this program. If not, see .
26 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
27 |
28 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/perform_bfgs.m:
--------------------------------------------------------------------------------
1 | function [x,summary] = perform_bfgs(Grad, x, options)
2 |
3 | % perform_bfgs - wrapper to HANSO code
4 | %
5 | % [f, R, info] = perform_bfgs(Grad, f, options);
6 | %
7 | % Grad should return (value, gradient)
8 | % f is an initialization
9 | % options.niter is the number of iterations.
10 | % options.bfgs_memory is the memory for the hessian bookeeping.
11 | % R is filled using options.repport which takes as input (f,val).
12 | % Author : B. Charlier (2017)
13 |
14 |
15 | n = length(x);
16 | pars.nvar = n;
17 | pars.fgname = @(f,pars) eval([Grad,'(f)']);
18 |
19 | options.x0 = x;
20 |
21 | tstart = tic;
22 | [x, energy, ~, ~, iter, info, ~, ~, ~, fevalrec, xrec, ~] = bfgs(pars,options);
23 |
24 |
25 | info_exit = {'tolerance on smallest vector in convex hull of saved gradients met',...
26 | 'max number of iterations reached',...
27 | 'f reached target value',...
28 | 'norm(x) exceeded limit',...
29 | 'cpu time exceeded limit',...
30 | 'f is inf or nan at initial point',...
31 | 'direction not a descent direction due to rounding error',...
32 | 'line search bracketed minimizer but Wolfe conditions not satisfied',...
33 | 'line search did not bracket minimizer: f may be unbounded below'};
34 |
35 |
36 | summary.bfgs.list_of_energy = [fevalrec{1}(1),cellfun(@(x) x(end), fevalrec)];
37 | summary.bfgs.exit_flags=info_exit{info+1};
38 | summary.bfgs.nb_of_iterations=iter;
39 | summary.bfgs.computation_time = toc(tstart);
40 | summary.bfgs.xrec = xrec;
41 |
42 |
43 | end
44 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/common/pVectors.m:
--------------------------------------------------------------------------------
1 | function res = pVectors(pts,tri)
2 | % computes (a representation of) the p-vector (ie tangent vector for curve and normals for surfaces).
3 | %
4 | % Input:
5 | % pts: list of vertices (n x d matrix)
6 | % tri: list of edges (T x M matrix of indices)
7 | %
8 | % Output:
9 | % res: list of p-vectors (d x M matrix)
10 | % Author : B. Charlier (2017)
11 |
12 |
13 | M = size(tri,2);
14 | d = size(pts,2);
15 |
16 | if (M==2) % curves
17 |
18 | res=pts(tri(:,2),:)-pts(tri(:,1),:);
19 |
20 | elseif (M==3) && (d==3) % surfaces
21 |
22 | u=pts(tri(:,2),:)-pts(tri(:,1),:);
23 | v=pts(tri(:,3),:)-pts(tri(:,1),:);
24 |
25 | res =[u(:,2).*v(:,3)-u(:,3).*v(:,2),...
26 | u(:,3).*v(:,1)-u(:,1).*v(:,3),...
27 | u(:,1).*v(:,2)-u(:,2).*v(:,1)];
28 |
29 | elseif (M==1) % points
30 |
31 | res = repmat( 1./size(tri,1) ,size(tri,1),1) ;
32 |
33 | elseif (M==3) && (d==2)% simplexes
34 |
35 | u=pts(tri(:,2),:)-pts(tri(:,1),:);
36 | v=pts(tri(:,3),:)-pts(tri(:,1),:);
37 |
38 | res = u(:,1).*v(:,2) - u(:,2).*v(:,1);
39 |
40 | elseif (M==4) && (d==3)% simplexes
41 |
42 | u=pts(tri(:,2),:)-pts(tri(:,1),:);
43 | v=pts(tri(:,3),:)-pts(tri(:,1),:);
44 | w=pts(tri(:,4),:)-pts(tri(:,1),:);
45 |
46 | res = u(:,1).*v(:,2).*w(:,3) + v(:,1).*w(:,2).*u(:,3) + w(:,1).*u(:,2).*v(:,3)...
47 | - u(:,3).*v(:,2).*w(:,1) - v(:,3).*w(:,2).*u(:,1) - w(:,3).*u(:,2).*v(:,1); %det with Sarrus formula
48 |
49 | end
50 |
51 | end
52 |
--------------------------------------------------------------------------------
/matlab/Bin/io/export_mom_vtk.m:
--------------------------------------------------------------------------------
1 | function []=export_mom_vtk(pos,mom,fname,encod_type)
2 | % Author : B. Charlier (2017)
3 |
4 | if nargin ==3
5 | encod_type = 'ascii';
6 | end
7 |
8 | if size(pos,2)<=2
9 | pos = [pos,zeros(size(pos,1),3-size(pos,2))];
10 | end
11 |
12 | if size(mom,2)<=2
13 | mom = [mom,zeros(size(mom,1),3-size(mom,2))];
14 | end
15 |
16 |
17 | nb_points = size(mom,1);
18 |
19 | fid = fopen(fname, 'w');
20 |
21 |
22 | %-------------
23 | % header
24 | %-------------
25 |
26 | %ASCII file header
27 | fprintf(fid, '# vtk DataFile Version 3.0\n');
28 | fprintf(fid, 'VTK from fshapesTk\n');
29 | if strcmp(encod_type,'ascii')
30 | fprintf(fid, 'ASCII\n\n');
31 | else
32 | fprintf(fid, 'BINARY\n\n');
33 | end
34 |
35 | %-------------
36 | % Position
37 | %-------------
38 |
39 | %ASCII sub header
40 | fprintf(fid, 'DATASET STRUCTURED_GRID\n');
41 | fprintf(fid, ['DIMENSIONS ',num2str(nb_points),' 1 1\n']);
42 | %Record position
43 | fprintf(fid, ['POINTS ',num2str(nb_points),' float\n']);
44 | if strcmp(encod_type,'ascii')
45 | fprintf(fid,'%G %G %G\n',pos');
46 | else
47 | fwrite(fid,pos','float','b');
48 | end
49 |
50 | %-------------
51 | % vectors
52 | %-------------
53 |
54 | %ASCII sub header
55 | fprintf(fid, ['\nPOINT_DATA ',num2str(nb_points),'\n']);
56 | %Record vectors
57 | fprintf(fid, 'VECTORS momentum float\n');
58 | if strcmp(encod_type,'ascii')
59 | fprintf(fid,'%G %G %G\n',mom');
60 | else
61 | fwrite(fid, mom','float','b');
62 | end
63 |
64 | fclose(fid);
65 |
66 | fprintf('\nFile saved in %s',fname)
67 |
68 | end
69 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/deformations/dnormRkhsV.m:
--------------------------------------------------------------------------------
1 | function [dx,dp]=dnormRkhsV(x,p,defo)
2 | % [dx,dp]=DNORMrKHSV(x,p,defo) computes the gradient of (p,K(x,x)p)/2 wrt
3 | % x and p. The kernel size is given by defo.kernel_size_mom.
4 | % Several method are implemented (cuda, matlab...)
5 | %
6 | % Inputs :
7 | % x : is a n x d matrix containing positions
8 | % p : is a n x d matrix containing momentums
9 | % defo : structure containing the parameters of deformations
10 | %
11 | % Output :
12 | % dx : is a (n x d) column vector
13 | % dp : is a (n x d) column vector
14 | %
15 | % See also : scalarProductRkhsV
16 | % Author : B. Charlier (2017)
17 |
18 |
19 | [n,d] = size(x);
20 |
21 | switch defo.method
22 | case 'cuda'
23 |
24 | dx=zeros(n,d);
25 | dp=zeros(n,d);
26 | for t=size(defo.kernel_size_mom,2)
27 | dx = dx + GaussGpuGrad1Conv(p',x',x',p',defo.kernel_size_mom(t))';
28 | dp = dp + GaussGpuConv(x',x',p',defo.kernel_size_mom(t))';
29 | end
30 |
31 | otherwise
32 |
33 | % Calcul de A=exp(-|x_i -x_j|^2/(2*lam^2))
34 | dx=zeros(n,d);
35 | dp=zeros(n,d);
36 | S=zeros(n);
37 | pp=zeros(n);
38 | for l=1:d
39 | S=S+(repmat(x(:,l),1,n)-repmat(x(:,l)',n,1)).^2;
40 | pp=pp+p(:,l)*p(:,l)';
41 | end
42 | A=rho(S,0,defo.kernel_size_mom);
43 | B=2*rho(S,1,defo.kernel_size_mom).*pp;
44 |
45 | for r=1:d
46 | dx(:,r)=sum(B.*(repmat(x(:,r),1,n)-repmat(x(:,r)',n,1)),2);
47 | dp(:,r)=A*p(:,r);
48 | end
49 | end
50 | end
51 |
52 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/hgprod.m:
--------------------------------------------------------------------------------
1 | function r = hgprod(H0, g, S, Y)
2 | % compute the product required by the LM-BFGS method
3 | % see Nocedal and Wright
4 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
5 | % with a subject header containing the string "hanso" or "gradsamp".
6 | % Version 2.0, 2010, see GPL license info below.
7 |
8 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
10 | %% This program is free software: you can redistribute it and/or modify
11 | %% it under the terms of the GNU General Public License as published by
12 | %% the Free Software Foundation, either version 3 of the License, or
13 | %% (at your option) any later version.
14 | %%
15 | %% This program is distributed in the hope that it will be useful,
16 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | %% GNU General Public License for more details.
19 | %%
20 | %% You should have received a copy of the GNU General Public License
21 | %% along with this program. If not, see .
22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23 |
24 | N = size(S,2); % number of saved vector pairs (s,y)
25 | q = g;
26 | for i = N:-1:1
27 | s = S(:,i);
28 | y = Y(:,i);
29 | rho(i) = 1/(s'*y);
30 | alpha(i) = rho(i)*(s'*q);
31 | q = q - alpha(i)*y;
32 | end
33 | r = H0*q;
34 | for i=1:N
35 | s = S(:,i);
36 | y = Y(:,i);
37 | beta = rho(i)*(y'*r);
38 | r = r + (alpha(i)-beta)*s;
39 | end
40 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/models/frechet_mean.py:
--------------------------------------------------------------------------------
1 | from pylab import *
2 | from pprint import pprint
3 | import plotly.graph_objs as go
4 |
5 | from .model import Model
6 |
7 | class FrechetMean(Model):
8 | """Simple Frechet Mean - L2 or L1 depending on the cost function
9 | N.B.: this is a Frechet mean according to the "embedding" metric.
10 | To get an intrinsic Frechet mean, with geodesic distance,
11 | one needs to solve an atlas estimation problem."""
12 | def __init__(self, M, C, nobs, s, Q0 = array([0,0])) :
13 | Model.__init__(self, M, C, nobs, s)
14 | self.Q0 = Q0
15 |
16 | def training_step(self, Xt) :
17 | (C, dQ) = self.C(vstack((self.Q0,)*Xt.shape[1]).T, Xt) # Compute gradients
18 | dQ = - self.s * mean(dQ, 1) # Rescale and Aggregate
19 | self.Q0 = self.Q0 + dQ # Update
20 |
21 | # Display
22 | self.M.marker(self.Q0, marker = dict(size = 20, color='red'), name='Frechet Mean', visible=False)
23 | self.show_data_attachment(C) # 'Targets' + 'Distances'
24 |
25 | # We use a simple hide/show scheme for the plot updates
26 | frame = [dict(visible = False), dict(visible = True)]
27 | return (self.Q0,C,dQ, frame)
28 | def situation(self, Xt) :
29 | Q = vstack((self.Q0,)*Xt.shape[1]).T
30 | (C, dQ) = self.C(Q, Xt)
31 | return (Q,C,dQ)
32 | def get_frame(self, f) :
33 | # Three plotly traces per frame : 'Frechet Mean', 'Targets', 'Distances'
34 | list1 = str([ 1 + 3*self.current_frame, 2 + 3*self.current_frame, 3 + 3*self.current_frame])[1:-1]
35 | self.current_frame = f
36 | list2 = str([ 1 + 3*self.current_frame, 2 + 3*self.current_frame, 3 + 3*self.current_frame])[1:-1]
37 | return (self.frames[f] , [list1, list2])
38 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/files.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | # file structure
4 | PLOTLY_DIR = os.path.join(os.path.expanduser("~"), ".plotly")
5 | CREDENTIALS_FILE = os.path.join(PLOTLY_DIR, ".credentials")
6 | CONFIG_FILE = os.path.join(PLOTLY_DIR, ".config")
7 | GRAPH_REFERENCE_FILE = os.path.join(PLOTLY_DIR, ".graph_reference")
8 | TEST_DIR = os.path.join(os.path.expanduser("~"), ".test")
9 | TEST_FILE = os.path.join(PLOTLY_DIR, ".permission_test")
10 |
11 | # this sets both the DEFAULTS and the TYPES for these files
12 | FILE_CONTENT = {CREDENTIALS_FILE: {'username': '',
13 | 'api_key': '',
14 | 'proxy_username': '',
15 | 'proxy_password': '',
16 | 'stream_ids': []},
17 | CONFIG_FILE: {'plotly_domain': 'https://plot.ly',
18 | 'plotly_streaming_domain': 'stream.plot.ly',
19 | 'plotly_api_domain': 'https://api.plot.ly',
20 | 'plotly_ssl_verification': True,
21 | 'plotly_proxy_authorization': False,
22 | 'world_readable': True,
23 | 'sharing': 'public',
24 | 'auto_open': True}}
25 |
26 | try:
27 | os.mkdir(TEST_DIR)
28 | os.rmdir(TEST_DIR)
29 | if not os.path.exists(PLOTLY_DIR):
30 | os.mkdir(PLOTLY_DIR)
31 | f = open(TEST_FILE, 'w')
32 | f.write('testing\n')
33 | f.close()
34 | os.remove(TEST_FILE)
35 | _file_permissions = True
36 | except:
37 | _file_permissions = False
38 |
39 |
40 | def check_file_permissions():
41 | return _file_permissions
42 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/io/level_lines.py:
--------------------------------------------------------------------------------
1 | from numpy import *
2 | from skimage.measure import find_contours
3 | from scipy import misc
4 | from scipy.ndimage.filters import gaussian_filter
5 | from scipy.interpolate import interp1d
6 |
7 | from ..manifolds.curves import Curve
8 |
9 |
10 | def arclength_param(line) :
11 | vel = line[1:, :] - line[:-1, :]
12 | vel = sqrt(sum( vel ** 2, 1 ))
13 | return hstack( ( [0], cumsum( vel, 0 ) ) )
14 | def arclength(line) :
15 | return arclength_param(line)[-1]
16 |
17 | def resample(line, npoints) :
18 | s = arclength_param(line)
19 | f = interp1d(s, line, kind = 'linear', axis = 0, assume_sorted = True)
20 |
21 | t = linspace(0, s[-1], npoints)
22 | p = f(t)
23 |
24 | connec = vstack( (arange(0, len(p) - 1), arange(1, len(p)) ) ).T
25 | return (p, connec)
26 |
27 | def level_curves(fname, npoints, smoothing = 10, level = 0.5) :
28 | # Find the contour lines
29 | img = misc.imread(fname, flatten = True) # Grayscale
30 | img = img.T[:, ::-1]
31 | img = img / 255.
32 | img = gaussian_filter(img, smoothing, mode='nearest')
33 | lines = find_contours(img, level)
34 |
35 | # Compute the sampling ratio
36 | lengths = []
37 | for line in lines :
38 | lengths.append( arclength(line) )
39 | lengths = array(lengths)
40 | points_per_line = ceil( npoints * lengths / sum(lengths) )
41 |
42 | # Interpolate accordingly
43 | points = []
44 | connec = []
45 | index_offset = 0
46 | for ppl, line in zip(points_per_line, lines) :
47 | (p, c) = resample(line, ppl)
48 | points.append(p)
49 | connec.append(c + index_offset)
50 | index_offset += len(p)
51 |
52 | points = vstack(points)
53 | connec = vstack(connec)
54 | return Curve(points.ravel(), connec, 2) # Dimension 2 !
55 |
56 |
--------------------------------------------------------------------------------
/matlab/Bin/kernels/cuda/kernels_old.cx~:
--------------------------------------------------------------------------------
1 |
2 | ///////////////////////
3 | // Gaussian Kernel //
4 | ///////////////////////
5 |
6 |
7 | template < typename TYPE >
8 | __device__ TYPE KernelGauss(TYPE *u, TYPE *v, TYPE ooSigma2, int DIM){
9 |
10 | TYPE r2 = 0.0f;
11 | TYPE temp;
12 | // norm squared
13 | for(int k=0; k
26 | __device__ TYPE Kerneld1Gauss(TYPE *u, TYPE *v, TYPE ooSigma2, int l, int DIM){
27 |
28 | TYPE r2 = 0.0f;
29 | TYPE temp;
30 | // norm squared
31 | for(int k=0; k
49 | __device__ TYPE KernelGaussVar(TYPE *u, TYPE *v, TYPE ooSigma2, int DIM){
50 |
51 | TYPE temp;
52 |
53 | // norm(u) squared
54 | TYPE normu2 = 0.0f;
55 | for(int k=0; k
9 | __device__ TYPE KernelGauss(TYPE *u, TYPE *v, TYPE ooSigma2, int DIM){
10 |
11 | TYPE r2 = 0.0f;
12 | TYPE temp;
13 | // norm squared
14 | for(int k=0; k
27 | __device__ TYPE Kerneld1Gauss(TYPE *u, TYPE *v, TYPE ooSigma2, int l, int DIM){
28 |
29 | TYPE r2 = 0.0f;
30 | TYPE temp;
31 | // norm squared
32 | for(int k=0; k
50 | __device__ TYPE KernelGaussVar(TYPE *u, TYPE *v, TYPE ooSigma2, int DIM){
51 |
52 | TYPE temp;
53 |
54 | // norm(u) squared
55 | TYPE normu2 = 0.0f;
56 | for(int k=0; k'
52 | display(HTML(html))
53 |
--------------------------------------------------------------------------------
/Simple_script/test_pytorch.py:
--------------------------------------------------------------------------------
1 | # Import the relevant tools
2 | import time # to measure performance
3 | import numpy as np # standard array library
4 | import torch
5 | from torch.autograd import Variable
6 | import torch.optim as optim
7 |
8 |
9 | use_cuda = torch.cuda.is_available()
10 | dtype = torch.cuda.FloatTensor if use_cuda else torch.FloatTensor
11 |
12 |
13 |
14 | def _squared_distances(x, y) :
15 | "Returns the matrix of $\|x_i-y_j\|^2$."
16 | x_col = x.unsqueeze(1) #x.dimshuffle(0, 'x', 1)
17 | y_lin = y.unsqueeze(0) #y.dimshuffle('x', 0, 1)
18 | return torch.sum( (x_col - y_lin)**2 , 2 )
19 |
20 | def _k(x, y, s) :
21 | "Returns the matrix of k(x_i,y_j)."
22 | sq = _squared_distances(x, y) / (s**2)
23 | return torch.exp(-sq) #torch.pow( 1. / ( 1. + sq ), .25 )
24 |
25 | def _cross_kernels(q, x, s) :
26 | "Returns the full k-correlation matrices between two point clouds q and x."
27 | K_qq = _k(q, q, s)
28 | K_qx = _k(q, x, s)
29 | K_xx = _k(x, x, s)
30 | return (K_qq, K_qx, K_xx)
31 |
32 | def _Hqp(q, p, sigma) :
33 | "The hamiltonian, or kinetic energy of the shape q with momenta p."
34 | pKqp = _k(q, q, sigma) * (p @ p.t()) # Use a simple isotropic kernel
35 | return .5 * pKqp.sum() # $H(q,p) = \frac{1}{2} * sum_{i,j} k(x_i,x_j) p_i.p_j$
36 |
37 |
38 | # Part 2 : Geodesic shooting ====================================================================
39 | # The partial derivatives of the Hamiltonian are automatically computed !
40 | def _dq_Hqp(q,p,sigma) :
41 | return torch.autograd.grad(_Hqp(q,p,sigma), q, create_graph=True)[0]
42 | def _dp_Hqp(q,p,sigma) :
43 | return torch.autograd.grad(_Hqp(q,p,sigma), p, create_graph=True)[0]
44 |
45 |
46 | q0 = Variable(torch.from_numpy( Q0.points ).type(dtype), requires_grad=False)
47 | p0 = Variable(torch.from_numpy( 0.*Q0.points ).type(dtype), requires_grad=True )
48 | s = Variable(torch.from_numpy( 1.).type(dtype), requires_grad=False)
49 |
50 | _dp_Hqp(q,p,1.)
51 |
52 |
--------------------------------------------------------------------------------
/matlab/Bin/models/atlas/tan_free/enr_tan_free.m:
--------------------------------------------------------------------------------
1 | function [ENR,dist,penp] = enr_tan_free(templatex,momentums)
2 | % enr_tan_free(templatex,momentum) computes the energy functional
3 | % in the tangential and free framework.
4 | %
5 | % Input :
6 | % templatex : cell with the points position
7 | % momentums : cell with the momentums attached to each point
8 | %
9 | %Output :
10 | % ENR: energy (a number)
11 | % dist,penp : terms composing the energy
12 | % Author : B. Charlier (2017)
13 |
14 |
15 | global data objfunc defoc deflag templateG
16 |
17 | tstart =tic;
18 |
19 | %---------------
20 | % indiv. terms
21 | %---------------
22 |
23 | [nb_obs,nb_match] = size(data);
24 |
25 | enrg = zeros(nb_obs,1);
26 | enru = zeros(nb_obs,1);
27 |
28 | templatextotal = cell2mat(templatex');
29 |
30 | for sh_ind=1:nb_obs %parallel computations
31 |
32 | %sliced variable in parfor
33 | datac = data(sh_ind,:);
34 | momentumc = momentums{sh_ind};
35 |
36 | % compute the energy of the deformation
37 | enru(sh_ind) = objfunc{1}.weight_coef_pen_p *objfunc{1}.mC*scalarProductRkhsV(momentumc,templatextotal,defoc); % objfunc{1}.mC est commun!
38 |
39 | % shoot the template
40 | [shootingx,~]=forward_tan(templatextotal,momentumc,defoc);
41 |
42 | for l = 1:nb_match
43 |
44 | %load the deformed fshape number l (== final position)
45 | templatefinal= struct('x',shootingx{end}(deflag(l)+1:deflag(l+1),:),'G',templateG{l});
46 |
47 | %load current target
48 | targetc = struct('x',datac{l}.x,'G',datac{l}.G);
49 |
50 | enrg(sh_ind) = enrg(sh_ind) + objfunc{l}.weight_coef_dist * objfunc{l}.gC * matchterm(templatefinal,targetc,objfunc{l});
51 |
52 | end
53 | end
54 |
55 |
56 | %---------------
57 | % Energy term
58 | %---------------
59 |
60 | dist=sum(enrg);
61 | penp=sum(enru);
62 | ENR = penp + dist ;
63 |
64 | if nargout ==1
65 | fprintf('enr %4.2e: dist %4.2e, pen_p %4.2e, time %f\n', ENR, dist,penp,toc(tstart))
66 | end
67 |
68 | end
69 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/wasserstein/cost_varifold.m:
--------------------------------------------------------------------------------
1 | function res = cost_varifold(X,Y,weight)
2 | % This function compute the cost function used in the OT for discrete measure
3 | % composed with varifold Dirac mass.
4 | %
5 | % Input :
6 | % X is a discrete varifold measure : a d x 2n matrix where d is the dimension of
7 | % the ambient space and n is the number of points in the cloud. The first
8 | % n rows encode the position and en last n rows encode the orientation
9 | % Y : idem as X.
10 | %
11 | % Output :
12 | % res : a nx x ny matrix of positive real numbers.
13 | % Author : B. Charlier (2017)
14 |
15 |
16 | [d,nx] = size(X);%nx = nx/2;
17 | [~,ny] = size(Y);%ny = ny/2;
18 |
19 | d = d/2; %dimension ambient space
20 |
21 | %------------------%
22 | %-Cost on position-%
23 | %------------------%
24 |
25 | % C(x,y)=1/2*|x-y|^2
26 | nablaC1 = @(x,y)repmat(x,[1 1 size(y,2)]) - ...
27 | repmat(reshape(y,[size(y,1) 1 size(y,2)]),[1 size(x,2)]);
28 | C1 = @(x,y)squeeze( sum(nablaC1(x,y).^2)/2 );
29 |
30 |
31 | %---------------------%
32 | %-Cost on orientation-%
33 | %---------------------%
34 |
35 | normalsX = X(d+1:2*d,:)';
36 | normalsY = Y(d+1:2*d,:)';
37 |
38 | % Compute unit normals
39 | norm_normalsX = sqrt(sum(normalsX .^2,2));
40 | norm_normalsY = sqrt(sum(normalsY .^2,2));
41 |
42 | unit_normalsX = normalsX ./ repmat(norm_normalsX,1,size(normalsX,2));
43 | unit_normalsY = normalsY ./ repmat(norm_normalsY,1,size(normalsY,2));
44 |
45 | prs_unit_norm = zeros(nx,ny);
46 | for l=1:d
47 | prs_unit_norm = prs_unit_norm + (repmat(unit_normalsX(:,l),1,ny).*repmat(unit_normalsY(:,l)',nx,1));
48 | end
49 |
50 |
51 | % unoriented :
52 | %C2 = (2 - 2 * prs_unit_norm .^2);
53 |
54 | % oriented :
55 | C2 = (1 - prs_unit_norm) ;
56 |
57 | %--------%
58 | %-Result-%
59 | %--------%
60 |
61 | % canonical metric (c1 + c2)
62 | res = weight(1) * C1(X(1:d,:) ,Y(1:d,:) ) + weight(2) * C2;
63 |
64 | % Other pseudo metric tricks... (c1 + c1 * c2)
65 | %res = C1(X(1:d,:) ,Y(1:d,:) ) .* (1 + weight(2) * C2) ;
66 |
67 | end
68 |
--------------------------------------------------------------------------------
/matlab/Bin/deformations/tangential/forward_tan.m:
--------------------------------------------------------------------------------
1 | function [x_evol,p_evol]=forward_tan(x_init,p_init,defo,tf)
2 | % [x_evol,p_evol]=FORWARD(x_init,p_init,defo,final_time) compute
3 | % Forward integration of the Hamiltonian flow from initial coupled
4 | % configuration of points/momentums.
5 | %
6 | % Input :
7 | % x_init : initial coordinates of the points (position) in a (n x d) matrix.
8 | % p_init : initial momentums in a (n x d) matrix.
9 | % defo : structure containing the parameters of deformations (kernel_size_mom,method,nstep,...)
10 | % final_time : final time (optional, and fixed by default to 1)
11 | %
12 | % Output
13 | % x_evol : a cell list containing evolution path of positions ( points_evol{i} is a n x d matrix and i ranges from 1 to defo_options.nstep+1)
14 | % p_evol : a cell list containing evolution path of momentums ( nomentums_evol{i} is a n x d matrix and i ranges from 1 to defo_options.nstep+1)
15 | %
16 | % See also : backward_tan, dHr_tan, ddHrtP_tan
17 | % Author : B. Charlier (2017)
18 |
19 |
20 | if nargin == 3
21 | tf=1;
22 | end
23 |
24 | x_evol=cell(1,defo.nb_euler_steps+1);
25 | p_evol=cell(1,defo.nb_euler_steps+1);
26 |
27 | dt=tf/defo.nb_euler_steps;
28 |
29 | x_evol{1} =deal(x_init);
30 | p_evol{1} = deal(p_init);
31 |
32 | for i=1:defo.nb_euler_steps
33 |
34 | % Midpoint method
35 | [x2,p2]=fdh(x_evol{i},p_evol{i},defo,dt/2);
36 | [x3,p3]=fdh(x2,p2,defo,dt);
37 |
38 | x_evol{i+1} = x3 - x2 + x_evol{i};
39 | p_evol{i+1} = p3 - p2 + p_evol{i};
40 |
41 | end
42 |
43 | end
44 |
45 | function [nx,np]=fdh(x,p,defo,h)
46 | % This fonction implements an elementary Euler Step
47 | %
48 | % Inputs :
49 | % x: is a (n x d) matrix containing the points.
50 | % p: is a (n x d) matrix containing the momentums.
51 | % defo: is a structure of deformations.
52 | % h is the time step.
53 |
54 | % Outputs
55 | % nx : (n x d) matrix containing the new points.
56 | % np :(n x d) matrix containing the new the momentums.
57 |
58 | %here f = dHr
59 | [dp,dx]= dHr_tan(x,p,defo);
60 |
61 | nx=x+h*dx;
62 | np=p-h*dp;
63 |
64 | end
65 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/getbundle.m:
--------------------------------------------------------------------------------
1 | function [xbundle, gbundle] = getbundle(x, g, samprad, N, pars);
2 | % get bundle of N-1 gradients at points near x, in addition to g,
3 | % which is gradient at x and goes in first column
4 | % intended to be called by gradsampfixed
5 | %
6 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
7 | % with a subject header containing the string "hanso" or "gradsamp".
8 | % Version 2.0, 2010, see GPL license info below.
9 |
10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
12 | %% This program is free software: you can redistribute it and/or modify
13 | %% it under the terms of the GNU General Public License as published by
14 | %% the Free Software Foundation, either version 3 of the License, or
15 | %% (at your option) any later version.
16 | %%
17 | %% This program is distributed in the hope that it will be useful,
18 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | %% GNU General Public License for more details.
21 | %%
22 | %% You should have received a copy of the GNU General Public License
23 | %% along with this program. If not, see .
24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25 |
26 | m = length(x);
27 | xbundle(:,1) = x;
28 | gbundle(:,1) = g;
29 | for k = 2:N % note the 2
30 | xpert = x + samprad*(rand(m,1) - 0.5); % uniform distribution
31 | [f,grad] = feval(pars.fgname, xpert, pars);
32 | count = 0;
33 | while isnaninf(f) | isnaninf(grad) % in particular, disallow infinite function values
34 | xpert = (x + xpert)/2; % contract back until feasible
35 | [f,grad] = feval(pars.fgname, xpert, pars);
36 | count = count + 1;
37 | if count > 100 % should never happen, but just in case
38 | error('too many contractions needed to find finite f and grad values')
39 | end
40 | end; % discard function values
41 | xbundle(:,k) = xpert;
42 | gbundle(:,k) = grad;
43 | end
44 |
--------------------------------------------------------------------------------
/matlab/Script/skulls/script_skulls_matching.m:
--------------------------------------------------------------------------------
1 | % Matching of two curves : Skulls dataset
2 | % Author : B. Charlier (2017)
3 |
4 | clear all
5 | restoredefaultpath
6 | addpath(genpath('../../Bin'))
7 |
8 | %----------------%
9 | % Data %
10 | %----------------%
11 |
12 | %choose a target
13 | hom = 'australopithecus';
14 | hom = 'sapiens';
15 | hom = 'erectus';
16 |
17 | r =1; %the code should be scale invariant...
18 |
19 | target = import_fshape_vtk(['./Data/skull_',hom,'.vtk']);
20 | target.f = zeros(size(target.x,1),1);
21 | nu = sum(area(target.x,target.G));
22 | target.x = r* target.x /nu;
23 |
24 |
25 | template = import_fshape_vtk('./Data/template.vtk')
26 | template.f = zeros(size(template.x,1),1);
27 | mu = sum(area(template.x,template.G));
28 | template.x = r* template.x /mu;
29 |
30 |
31 | %------------------------------%
32 | % parameters %
33 | %------------------------------%
34 |
35 | comp_method = 'matlab';% possible values are 'cuda' or 'matlab'
36 |
37 | % Parameters for the deformations
38 | defo.kernel_size_mom = r*[.06,.03,.013]; % size of the kernel used to generate the deformations
39 | defo.nb_euler_steps =10; % nbr of steps in the (for||back)ward integration
40 | defo.method =comp_method; % possible values are 'cuda' or 'matlab'
41 |
42 | % Parameters for data attachment term
43 | objfun.weight_coef_dist = 10000; % weighting coeff in front of the fidelity term
44 | objfun.distance = 'wasserstein'; % OT fidelity
45 | objfun.wasserstein_distance.method=comp_method;
46 | objfun.wasserstein_distance.epsilon = .5*(r*.01/6)^2;
47 | objfun.wasserstein_distance.niter = 450;
48 | objfun.wasserstein_distance.tau = 0; % basic sinkhorn, no extrapolation (only matlab version)
49 | objfun.wasserstein_distance.rho = Inf; % balanced case
50 | objfun.wasserstein_distance.weight_cost_varifold = [1,0.001]; % weight on spatial and orientation distances
51 |
52 | % Parameters for optimization
53 | optim.method='bfgs'
54 | optim.bfgs.maxit=200;
55 |
56 | [momentums,summary]=match_geom(template,target,defo,objfun,optim);
57 |
58 | export_matching_tan(template,momentums,template.f,target,summary,['results/matching_',hom])
59 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/gradsamp1run.m:
--------------------------------------------------------------------------------
1 | function [x, f, g, dnorm, X, G, w] = gradsamp1run(x0, f0, g0, pars, options);
2 | % repeatedly run gradient sampling minimization, for various sampling radii
3 | % return info only from final sampling radius
4 | % intended to be called by gradsamp only
5 | %
6 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
7 | % with a subject header containing the string "hanso" or "gradsamp".
8 | % Version 2.0, 2010, see GPL license info below.
9 |
10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
12 | %% This program is free software: you can redistribute it and/or modify
13 | %% it under the terms of the GNU General Public License as published by
14 | %% the Free Software Foundation, either version 3 of the License, or
15 | %% (at your option) any later version.
16 | %%
17 | %% This program is distributed in the hope that it will be useful,
18 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | %% GNU General Public License for more details.
21 | %%
22 | %% You should have received a copy of the GNU General Public License
23 | %% along with this program. If not, see .
24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25 |
26 | samprad = options.samprad;
27 | cpufinish = cputime + options.cpumax;
28 | for choice = 1:length(samprad)
29 | options.cpumax = cpufinish - cputime; % time left
30 | [x, f, g, dnorm, X, G, w, quitall] = ...
31 | gradsampfixed(x0, f0, g0, samprad(choice), pars, options);
32 | % it's not always the case that x = X(:,1), for example when the max
33 | % number of iterations is exceeded: this is mentioned in the
34 | % comments for gradsamp
35 | if quitall % terminate early
36 | return
37 | end
38 | % get ready for next run, with lower sampling radius
39 | x0 = x; % start from where previous one finished,
40 | % because this is lowest function value so far
41 | f0 = f;
42 | g0 = g;
43 | end
44 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/matplotlylib/mplexporter/renderers/vincent_renderer.py:
--------------------------------------------------------------------------------
1 | import warnings
2 | from .base import Renderer
3 | from ..exporter import Exporter
4 |
5 |
6 | class VincentRenderer(Renderer):
7 | def open_figure(self, fig, props):
8 | self.chart = None
9 | self.figwidth = int(props['figwidth'] * props['dpi'])
10 | self.figheight = int(props['figheight'] * props['dpi'])
11 |
12 | def draw_line(self, data, coordinates, style, label, mplobj=None):
13 | import vincent # only import if VincentRenderer is used
14 | if coordinates != 'data':
15 | warnings.warn("Only data coordinates supported. Skipping this")
16 | linedata = {'x': data[:, 0],
17 | 'y': data[:, 1]}
18 | line = vincent.Line(linedata, iter_idx='x',
19 | width=self.figwidth, height=self.figheight)
20 |
21 | # TODO: respect the other style settings
22 | line.scales['color'].range = [style['color']]
23 |
24 | if self.chart is None:
25 | self.chart = line
26 | else:
27 | warnings.warn("Multiple plot elements not yet supported")
28 |
29 | def draw_markers(self, data, coordinates, style, label, mplobj=None):
30 | import vincent # only import if VincentRenderer is used
31 | if coordinates != 'data':
32 | warnings.warn("Only data coordinates supported. Skipping this")
33 | markerdata = {'x': data[:, 0],
34 | 'y': data[:, 1]}
35 | markers = vincent.Scatter(markerdata, iter_idx='x',
36 | width=self.figwidth, height=self.figheight)
37 |
38 | # TODO: respect the other style settings
39 | markers.scales['color'].range = [style['facecolor']]
40 |
41 | if self.chart is None:
42 | self.chart = markers
43 | else:
44 | warnings.warn("Multiple plot elements not yet supported")
45 |
46 |
47 | def fig_to_vincent(fig):
48 | """Convert a matplotlib figure to a vincent object"""
49 | renderer = VincentRenderer()
50 | exporter = Exporter(renderer)
51 | exporter.run(fig)
52 | return renderer.chart
53 |
--------------------------------------------------------------------------------
/matlab/Bin/models/matching/geom/match_geom.m:
--------------------------------------------------------------------------------
1 | function [momentums,summary]=match_geom(source,target,defo,objfun,optim)
2 | % [momentums,summary]=MATCH_GEOM(source,target,defo,objfun,optim) computes
3 | % a geometric matching of the shape source onto the shape target.
4 | %
5 | % Inputs:
6 | % source: a structure containing the source shape.
7 | % target : a structure containing the target shape.
8 | % defo: is a structure containing the parameters of the deformations.
9 | % objfun: is a structure containing the parameters of attachment term.
10 | % optim: is a structure containing the parameters of the optimization procedure (here gradient descent with adaptative step)
11 | %
12 | % Outputs:
13 | % momentums: a cell array with momentums
14 | % summary: is a structure containing various informations about the
15 | % gradient descent.
16 | %
17 | % See also : enr_geom, jnfmatch_geom
18 | % Author : B. Charlier (2017)
19 |
20 | global data
21 |
22 | %--------%
23 | % DATA %
24 | %--------%
25 |
26 |
27 | if ~iscell(target)
28 | data= {target};
29 | else
30 | data = target;
31 | end
32 |
33 | [nb_obs,nb_match] = size(data);
34 |
35 | if nb_obs >1
36 | error('target must contain only 1 observation')
37 | end
38 |
39 |
40 | for i = 1:nb_obs
41 | for l=1:nb_match
42 | if ~isfield(data{i,l},'f')
43 | data{i,l}.f = zeros(size(data{i,l}.x,1),1);
44 | end
45 | end
46 | end
47 |
48 | %----------%
49 | % TEMPLATE %
50 | %----------%
51 |
52 | if ~iscell(source)
53 | source= {source};
54 | end
55 |
56 | for l=1:nb_match
57 | if ~isfield(source{l},'f')
58 | source{l}.f = zeros(size(source{l}.x,1),1);
59 | end
60 | end
61 |
62 | fprintf('\n Performing a pure geometric matching \n')
63 |
64 | switch lower(optim.method)
65 | case 'bfgs'
66 | [momentums,summary]=jnfmatch_geom(source,[],defo,objfun,optim);
67 |
68 | case 'graddesc'
69 |
70 | % put the step size to 0
71 | optim.gradDesc.step_size_x = 0;
72 | optim.gradDesc.step_size_f = 0;
73 | optim.gradDesc.step_size_fr = 0;
74 |
75 | [~,momentums,~,summary]=jnfmean_tan_free(source,[],[],defo,objfun,optim);
76 |
77 | end
78 |
79 | end
80 |
81 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/wasserstein/fshape_wasserstein_distance.m:
--------------------------------------------------------------------------------
1 | function g= fshape_wasserstein_distance(fs1,fs2,objfun)
2 | % FSHAPE_KERNEL_DISTANCE(templatefinal,target,objfun) computes kernel based
3 | % distances between fshapes.
4 | %
5 | % \sum_i\sum_j K_signal(f_i-g_j)^2) K_geom(-norm(x_i-y_j)^2) K_tan(angle(V_i,W_j))
6 | %
7 | % Possible method are 'cuda' or 'matlab'.
8 | %
9 | % Inputs:
10 | % templatefinal : "fshape structure" containing the shooted template
11 | % target : "fshape structure" containing the target.
12 | % objfun : is a structure containing the data attachment term parameters (mandatory fields are : 'kernel_geom', 'kernel_signal' and 'kernel_grass' and the associated bandwidth)
13 | % Output
14 | % g : a real number.
15 | % Author : B. Charlier (2017)
16 |
17 | d=size(fs1.x,2);
18 | m=size(fs1.G,2)-1;
19 |
20 | % discretize the fshapes
21 | [center_faceX,normalsX]=fcatoms(fs1.x,fs1.G);
22 | [center_faceY,normalsY]=fcatoms(fs2.x,fs2.G);
23 |
24 | options = objfun.wasserstein_distance;
25 |
26 | if min(m, d-m) ==0 % for points clouds or simplexes dim or codim == 0 : some simplifications occurs
27 |
28 | x=center_faceX';
29 | y=center_faceY';
30 |
31 | mu = fs1.G;
32 | nu = fs2.G;
33 |
34 | %only needed for matlab version. See built-in function for cuda version.
35 | nablaC = @(x,y,~)repmat(x,[1 1 size(y,2)]) - ...
36 | repmat(reshape(y,[size(y,1) 1 size(y,2)]),[1 size(x,2)]);
37 | C = @(x,y,~)squeeze( sum(nablaC(x,y).^2)/2 );% C(x,y)=1/2*|x-y|^2
38 |
39 | elseif min(m,d-m) ==1 % for curves or surface dim or codim ==1;
40 |
41 | mu = area(fs1.x,fs1.G);
42 | nu = area(fs2.x,fs2.G);
43 |
44 | x=[center_faceX';normalsX'];
45 | y=[center_faceY';normalsY'];
46 |
47 | %only needed for matlab version. See built-in function for cuda version.
48 | C = @(X,Y) cost_varifold(X,Y,options.weight_cost_varifold);
49 |
50 | end
51 |
52 |
53 | switch lower(options.method)
54 | case 'matlab'
55 |
56 | [~,~,~,~,g,~] = sinkhorn_log(mu,nu,C(x,y),options.epsilon,options);
57 | g = g(end);
58 | case 'cuda'
59 |
60 | [~,~,~,g,~] = sinkhorn_log_cuda(mu,nu,x,y,options.epsilon,options);
61 |
62 | end
63 |
64 | end
65 |
--------------------------------------------------------------------------------
/matlab/Bin/models/matching/tan/fsmatch_tan.m:
--------------------------------------------------------------------------------
1 | function [momentums,summary]=fsmatch_tan(source,target,defo,objfun,optim)
2 | % [momentums,funres,List_energy]=FSMATCH_TAN(source,target,defo,objfun,optim)
3 | % performs a geometrico-functional matching of the fshape "source" to the
4 | % fshape "target" in the tangential framework.
5 | %
6 | % Note: This function is a wrapper function as it simply call the low-level function jnfmeanMultiShape with
7 | % some particular parameters.
8 | %
9 | % Inputs:
10 | % source: is a structure containing the source fshape
11 | % target: is a structure containing the target fshape
12 | % defo: is a structure containing the parameters of the deformations.
13 | % objfun: is a structure containing the parameters of attachment term.
14 | % optim: is a structure containing the parameters of the optimization procedure
15 | %
16 | % Outputs:
17 | % momentums: is a matrix containing the momentums (geometric deformation).
18 | % funres: is a vector with the functional residuals (functional deformation).
19 | % List_energy : is a matrix containing the values of the energy during
20 | % optimization process.
21 | %
22 | % See also: jnfmean_tan_free,fsatlas_tan_free,fsatlas_tan_HT
23 | % Author : B. Charlier (2017)
24 |
25 |
26 | global data
27 |
28 | %--------%
29 | % DATA %
30 | %--------%
31 |
32 |
33 | if ~iscell(target)
34 | data= {target};
35 | else
36 | data = target;
37 | end
38 |
39 | [nb_obs,nb_match] = size(data);
40 |
41 | if nb_obs >1
42 | error('target must contain only 1 observation')
43 | end
44 |
45 |
46 | for i = 1:nb_obs
47 | for l=1:nb_match
48 | if ~isfield(data{i,l},'f')
49 | data{i,l}.f = zeros(size(data{i,l}.x,1),1);
50 | end
51 | end
52 | end
53 |
54 | %----------%
55 | % TEMPLATE %
56 | %----------%
57 |
58 | if ~iscell(source)
59 | source= {source};
60 | end
61 |
62 | for l=1:nb_match
63 | if ~isfield(source{l},'f')
64 | source{l}.f = zeros(size(source{l}.x,1),1);
65 | end
66 | end
67 |
68 |
69 |
70 | %--------%
71 | % MATCH %
72 | %--------%
73 |
74 | switch lower(optim.method)
75 | case 'bfgs'
76 | fprintf('\n Performing a geometrico-functional matching \n')
77 | [momentums,summary]=jnfmatch_tan(source,[],[],defo,objfun,optim);
78 |
79 | end
80 |
81 | end
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/setx0.m:
--------------------------------------------------------------------------------
1 | function options = setx0(pars,options)
2 | % set columns of options.x0 randomly if not provided by user
3 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
4 | % with a subject header containing the string "hanso" or "bfgs".
5 | % Version 2.0, 2010, see GPL license info below.
6 |
7 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
9 | %% This program is free software: you can redistribute it and/or modify
10 | %% it under the terms of the GNU General Public License as published by
11 | %% the Free Software Foundation, either version 3 of the License, or
12 | %% (at your option) any later version.
13 | %%
14 | %% This program is distributed in the hope that it will be useful,
15 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | %% GNU General Public License for more details.
18 | %%
19 | %% You should have received a copy of the GNU General Public License
20 | %% along with this program. If not, see .
21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22 |
23 | nvar = pars.nvar;
24 | if ~isfield(options, 'x0')
25 | options.x0 = [];
26 | end
27 | if isempty(options.x0)
28 | if isfield(options, 'nstart')
29 | if ~isposint(options.nstart)
30 | error('setx0: input "options.nstart" must be a positive integer when "options.x0" is not provided')
31 | else
32 | options.x0 = randn(nvar, options.nstart);
33 | end
34 | else
35 | options.x0 = randn(nvar, 10);
36 | end
37 | else
38 | if size(options.x0,1) ~= nvar
39 | error('setx0: input "options.x0" must have "pars.nvar" rows')
40 | end
41 | if isfield(options, 'nstart')
42 | if ~isnonnegint(options.nstart)
43 | error('setx0: input "options.nstart" must be a nonnegative integer')
44 | elseif options.nstart < size(options.x0,2)
45 | error('setx0: "options.nstart" is less than number of columns of "options.x0"')
46 | else % augment vectors in options.x0 with randomly generated ones
47 | nrand = options.nstart - size(options.x0,2);
48 | options.x0 = [options.x0 randn(nvar, nrand)];
49 | end
50 | end % no else part, options.x0 is as provided
51 | end
--------------------------------------------------------------------------------
/matlab/Bin/io/export_fshape_vtk.m:
--------------------------------------------------------------------------------
1 | function [] = export_fshape_vtk(data,fname,signal_name,signal_type)
2 | % EXPORT_VTK(data,fname,funname) save a fshape structure into a .vtk file
3 | %
4 | %Input
5 | % data : struct with fields 'x','G' and 'f'. (the field 'f' may be optional)
6 | % fname : name of the output file
7 | % signal_name (optional) : name of the functional to be set in the.vtk file
8 | % type_signal : set to 'face' if the signal is defined at the center of
9 | % the face. In that case size(data.f,1) == size(data.G,1). Otherwise
10 | % the signal is assumed to be defined at each vertex.
11 | % Author : B. Charlier (2017)
12 |
13 |
14 | if nargin == 2 || isempty(signal_name)
15 | signal_name = 'signal';
16 | end
17 | if nargin <= 3
18 | if size(data.f,1) == size(data.x,1)
19 | signal_type = 'vertex';
20 | elseif size(data.f,1) == size(data.G,1)
21 | signal_type = 'face';
22 | end
23 | end
24 |
25 | if size(data.x,2)<=2
26 | data.x = [data.x,zeros(size(data.x,1),3-size(data.x,2))];
27 | end
28 |
29 |
30 |
31 | % open file
32 | fid = fopen(fname,'w');
33 |
34 | % header
35 | fprintf(fid,'# vtk DataFile Version 3.0\n');
36 | fprintf(fid,'vtk generated by fshapesTk\n');
37 |
38 | fprintf(fid,'%s\n','ASCII');
39 | fprintf(fid,'DATASET POLYDATA\n');
40 |
41 | %points
42 | fprintf(fid,'POINTS %u float\n', size(data.x,1));
43 |
44 | x = repmat('%G ',1,size(data.x,2)-1);
45 | fprintf(fid,[x,'%G\n'], data.x');
46 |
47 |
48 |
49 | %edges
50 | if size(data.G,2) == 3
51 | type = 'POLYGONS';
52 | elseif size(data.G,2) == 2
53 | type = 'LINES';
54 | elseif size(data.G,2) == 1
55 | type = 'VERTICES';
56 | elseif size(data.G,2) == 4
57 | type = 'POLYGONS';
58 | end
59 | fprintf(fid,['\n%s %u %u\n'], type,size(data.G,1),(size(data.G,2)+1).*size(data.G,1));
60 |
61 | x = [num2str(size(data.G,2)),' ',repmat('%u ',1,size(data.G,2)-1)];
62 | fprintf(fid,[x,'%u\n'], (data.G-1)');
63 |
64 |
65 | % functional
66 | if isfield(data,'f')
67 | if strcmpi(signal_type,'face')
68 | fprintf(fid,['\nCELL_DATA ','%u\n'],size(data.G,1)); % 5== triangle, 1 == vertex, 3 == lines,
69 | else
70 | fprintf(fid,['\nPOINT_DATA ','%u\n'],size(data.x,1)); % 5== triangle, 1 == vertex, 3 == lines,
71 |
72 | end
73 |
74 | fprintf(fid,['SCALARS ',signal_name,' FLOAT\nLOOKUP_TABLE default\n']);
75 | fprintf(fid,['%G\n'],data.f');
76 |
77 | end
78 | fclose(fid);
79 |
80 | %avoid unnecessary output
81 | if ~strcmpi(fname(end-17:end),'results_iter_c.vtk')
82 | fprintf('File saved in %s\n',fname)
83 | end
84 |
85 | end
86 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/wasserstein/dcost_varifold.m:
--------------------------------------------------------------------------------
1 | function res = dcost_varifold(x,y,weight)
2 | % This function compute the derivative wrt X of the cost function used in the OT for discrete measure
3 | % composed with varifold Dirac mass.
4 | %
5 | % Input :
6 | % X is a discrete varifold measure : a d x 2n matrix where d is the dimension of
7 | % the ambient space and n is the number of points in the cloud. The first
8 | % n rows encode the position and en last n rows encode the orientation
9 | % Y : idem as X.
10 | %
11 | % Output :
12 | % res : a (d x size(x,2) x size(y,2)) matrix);
13 | % Author : B. Charlier (2017)
14 |
15 |
16 | [d,nx] = size(x);%nx = nx/2;
17 | [~,ny] = size(y);%ny = ny/2;
18 |
19 | d = d/2; %dimension ambient space
20 |
21 | %------------------%
22 | %-Cost on position-%
23 | %------------------%
24 |
25 | % gradient with respect to x of C(x,y)=1/2*|x-y|^2
26 |
27 | nablaC1 = @(x,y)repmat(x,[1 1 size(y,2)]) - ...
28 | repmat(reshape(y,[size(y,1) 1 size(y,2)]),[1 size(x,2)]);
29 |
30 |
31 | %---------------------%
32 | %-Cost on orientation-%
33 | %---------------------%
34 |
35 | normalsX = x(d+1:2*d,:);
36 | normalsY = y(d+1:2*d,:);
37 |
38 | % Compute unit normals
39 | norm_normalsX = sqrt(sum(normalsX .^2,1));
40 | norm_normalsY = sqrt(sum(normalsY .^2,1));
41 |
42 | unit_normalsX = normalsX ./ repmat(norm_normalsX,d,1);
43 | unit_normalsY = normalsY ./ repmat(norm_normalsY,d,1);
44 |
45 | prs_unit_norm = zeros(nx,ny);
46 | for l=1:d
47 | prs_unit_norm = prs_unit_norm + (repmat(unit_normalsY(l,:),nx,1).*repmat(unit_normalsX(l,:)',1,ny));
48 | end
49 |
50 | dprs_unit_norm = ( -repmat(unit_normalsX,[1 1 ny]) .* repmat(reshape(prs_unit_norm,[1,nx,ny]),[d,1])...
51 | + repmat(reshape(unit_normalsY,[d 1 ny]),[1 nx])) ./ reshape(repmat(norm_normalsX,d,ny),[d,nx,ny]);
52 |
53 | %unoriented : gradient with respect to x of C(x,y)=2 * (1 - ^2)
54 | %nablaC2= -8 .* dprs_unit_norm .* repmat(reshape(prs_unit_norm,[1,nx,ny]),[d,1]);
55 |
56 |
57 | %oriented : gradient with respect to (1 - )
58 | nablaC2 = - dprs_unit_norm;
59 |
60 | %--------%
61 | %-Result-%
62 | %--------%
63 |
64 | % canonical metric (c1 + c2)
65 | res = [weight(1) * nablaC1(x(1:d,:),y(1:d,:));weight(2) * nablaC2];
66 |
67 |
68 | % Other pseudo metric tricks... (c1 + c1 * c2)
69 | %C1 = @(x,y)squeeze( sum(nablaC1(x,y).^2)/2 );
70 | %C2 = (2 - 2 * prs_unit_norm .^2);
71 | %res = [ nablaC1(x(1:d,:),y(1:d,:)) .* repmat(reshape( (1 + weight(2) * C2) , [1,nx,ny]),[d,1]) ;...
72 | % .5 *weight(2) * repmat(reshape( C1(x(1:d,:) ,y(1:d,:) ) , [1,nx,ny]),[d,1]).* nablaC2];
73 |
74 |
75 |
76 | end
77 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/postprocess.m:
--------------------------------------------------------------------------------
1 | function [loc, X, G, w] = postprocess(x, g, dnorm, X, G, w)
2 | % postprocessing of set of sampled or bundled gradients
3 | % if x is not one of the columns of X, prepend it to X and
4 | % g to G and recompute w and dnorm: this can only reduce dnorm
5 | % also set loc.dnorm to dnorm and loc.evaldist to the
6 | % max distance from x to columns of X
7 | % note: w is needed as input argument for the usual case that
8 | % w is not recomputed but is just passed back to output
9 | %
10 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
11 | % with a subject header containing the string "hanso".
12 | % Version 2.0, 2010, see GPL license info below.
13 |
14 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
16 | %% This program is free software: you can redistribute it and/or modify
17 | %% it under the terms of the GNU General Public License as published by
18 | %% the Free Software Foundation, either version 3 of the License, or
19 | %% (at your option) any later version.
20 | %%
21 | %% This program is distributed in the hope that it will be useful,
22 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | %% GNU General Public License for more details.
25 | %%
26 | %% You should have received a copy of the GNU General Public License
27 | %% along with this program. If not, see .
28 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29 |
30 | for j = 1:size(X,2)
31 | dist(j) = norm(x - X(:,j));
32 | end
33 | evaldist = max(dist); % for returning
34 | [mindist, indx] = min(dist); % for checking if x is a column of X
35 | if mindist == 0 & indx == 1
36 | % nothing to do
37 | elseif mindist == 0 & indx > 1
38 | % this should not happen in HANSO 2.0
39 | % swap x and g into first positions of X and G
40 | % might be necessary after local bundle, which is not used in HANSO 2.0
41 | X(:,[1 indx]) = X(:,[indx 1]);
42 | G(:,[1 indx]) = G(:,[indx 1]);
43 | w([1 indx]) = w([indx 1]);
44 | else
45 | % this cannot happen after BFGS, but it may happen after gradient
46 | % sampling, for example if max iterations exceeded: line search found a
47 | % lower point but quit before solving new QP
48 | % prepend x to X and g to G and recompute w
49 | X = [x X];
50 | G = [g G];
51 | [w,d] = qpspecial(G); % Anders Skajaa's QP code
52 | dnorm = norm(d);
53 | end
54 | loc.dnorm = dnorm;
55 | loc.evaldist = evaldist;
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/manifolds/theano_hamiltoniancarrier.py:
--------------------------------------------------------------------------------
1 | # Import of the relevant tools
2 | import time
3 | import numpy as np
4 | import theano
5 | import theano.tensor as T
6 | from theano import pp, config
7 |
8 |
9 | from plotly.tools import FigureFactory as FF
10 | import plotly.graph_objs as go
11 |
12 | from ..io.read_vtk import ReadVTK
13 | from ..data_attachment.measures import Measures
14 | from ..data_attachment.varifolds import Varifolds
15 | from ..math_utils.kernels import _squared_distances, _gaussian_kernel
16 |
17 |
18 | from .theano_hamiltonianclouds import TheanoHamiltonianClouds
19 |
20 | class TheanoHamiltonianCarrier(TheanoHamiltonianClouds) :
21 | """
22 | Superseeds the regular Hamiltonian cost, which is not computed wrt to
23 | the final state q1, but with respect to a carried "shape" s1.
24 | This is the class that shall be inherited by any "control points" manifold.
25 | """
26 | def __init__(self, **kwargs) :
27 |
28 | TheanoHamiltonianClouds.__init__(self, **kwargs)
29 |
30 |
31 | # Symbolic Hamiltonian functions ==========================================================================
32 |
33 | # Part 3 : Cost function and derivatives -------------------------------------------------------
34 | def _cost(self, q, p, s, *args) :
35 | cost_reg = self._Hqp(q,p)
36 | cost_att = self._data_attachment(self._HamiltonianShootingCarrying(q,p,s)[2], *args) # C(q_0, p_0, s_0) = A(s_1, x_t)
37 | return self.weight_regularization * cost_reg + self.weight_attachment * cost_att[0], cost_att[1]
38 |
39 | # The discrete backward scheme is automatically computed :
40 | def _dcost_q0(self, q,p, s, *args) : # Useful for template estimation
41 | return T.grad(self._cost(q,p,s, *args)[0], q) # The gradients wrt. q_0 is automatically computed
42 | def _dcost_p0(self, q,p,s, *args) : # Useful in a matching problem
43 | return T.grad(self._cost(q,p,s, *args)[0], p) # The gradients wrt. p_0 is automatically computed
44 |
45 | def _opt_shooting_cost(self, q0, p0, s0, *args) : # Wrapper
46 | cost_info = self._cost( q0, p0, s0, *args) # cost + additional information
47 | return [cost_info[0] , # Actual cost
48 | q0,#self._dcost_q0( q0, p0, s0, *args) ,
49 | self._dcost_p0( q0, p0, s0, *args) ,
50 | self._HamiltonianShootingCarrying(q0,p0,s0)[2],
51 | cost_info[1] ] # Additional information (transport plan, etc.)
52 |
53 | # Appendix : Collection of data attachment terms -----------------------------------------------
54 | def _data_attachment(self, s1, *args) :
55 | """Selects the appropriate data attachment routine, depending on self's attributes."""
56 | raise(NotImplementedError)
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/matlab/Bin/deformations/tangential/dHr_tan.m:
--------------------------------------------------------------------------------
1 | function [dxHr,dpHr] = dHr_tan(x,p,defo)
2 | % [dxHr,dpHr] = DHR(x,p,defo) computes the reduced Hamiltonian system. Several
3 | % method are implemented to speedup the compution (matlab, cuda and C). The method used is the one
4 | % given by defo.method
5 | %
6 | % Input :
7 | % x : state (n x d) matrix
8 | % p : costate (n x d) matrix
9 | % defo : structure containing the fields 'method' ('matlab', 'cuda' or 'grid') and 'kernel_size_mom' (kernel size)
10 | %
11 | % Output
12 | % dxHr : gradient of Hr wrt to x at point (x,p)
13 | % dpHr: gradient of Hr wrt to p at point (x,p)
14 | %
15 | % See also : forward_tan, backward_tan, ddHrtP_tan
16 | % Author : B. Charlier (2017)
17 |
18 |
19 | switch defo.method
20 | case 'cuda'
21 | DHR = @dHr_tan_cuda;
22 | case 'grid'
23 | DHR = @dHr_tan_grid;
24 | otherwise
25 | DHR = @dHr_tan_mat;
26 | end
27 |
28 | [dxHr,dpHr] = DHR(x,p,defo);
29 |
30 | end
31 |
32 | function [dxHr,dpHr] = dHr_tan_mat(x,p,defo)
33 | % Matlab version of the reduced Hamiltonian system.
34 | % Input :
35 | % x : state (n x d) matrix
36 | % p : costate (n x d) matrix
37 | % defo : structure containing the field and 'kernel_size_mom' (kernel size)
38 | %
39 | % Output
40 | % dxHr : gradient of Hr wrt to x at point (x,p)
41 | % dpHr: gradient of Hr wrt to p at point (x,p)
42 |
43 |
44 | [n,d]=size(x);
45 |
46 | % Calcul de A=exp(-|x_i -x_j|^2/(lam^2))
47 | S=zeros(n);
48 | for l=1:d
49 | S=S+(repmat(x(:,l),1,n)-repmat(x(:,l)',n,1)).^2;
50 | end
51 | A = rho(S,0,defo.kernel_size_mom);
52 | B = rho(S,1,defo.kernel_size_mom);
53 |
54 |
55 | dpHr=A*p;
56 |
57 |
58 | dxHr=zeros(n,d);
59 | for r=1:d
60 | % Computation of B=2*|x_i -x_j|*exp(-|x_i -x_j|^2/(lam^2))/(lam^2)
61 | Br=2*(repmat(x(:,r),1,n)-repmat(x(:,r)',n,1)).*B;
62 | dxHr(:,r)=dxHr(:,r)+ sum(p .* (Br*p) ,2);
63 | end
64 |
65 | end
66 |
67 | function [dxHr,dpHr] = dHr_tan_cuda(x,p,defo)
68 | % cuda version of the reduced Hamiltonian system.
69 | % Input :
70 | % x : state (n x d) matrix
71 | % p : costate (n x d) matrix
72 | % defo : structure containing the field 'kernel_size_mom' (kernel size)
73 | %
74 | % Output
75 | % dxHr : gradient of Hr wrt to x at point (x,p)
76 | % dpHr: gradient of Hr wrt to p at point (x,p)
77 |
78 |
79 | dxHr = zeros(size(x));
80 | dpHr = zeros(size(p));
81 |
82 | if isfield(defo,'precision') && strcmp(defo.precision,'double')
83 | conv = @GaussGpuConvDouble;
84 | gradconv= @GaussGpuGrad1ConvDouble;
85 | else
86 | conv = @GaussGpuConv;
87 | gradconv= @GaussGpuGrad1Conv;
88 |
89 | end
90 |
91 | for sig = defo.kernel_size_mom
92 | dxHr= dxHr + gradconv(p',x',x',p',sig)';
93 | dpHr = dpHr + conv(x',x',p',sig)';
94 | end
95 |
96 | end
97 |
--------------------------------------------------------------------------------
/Pytorch/shooting.py:
--------------------------------------------------------------------------------
1 | # Import the relevant tools
2 | import numpy as np # standard array library
3 | import torch
4 |
5 | # No need for a ~/.theanorc file anymore !
6 | use_cuda = torch.cuda.is_available()
7 | dtype = torch.cuda.FloatTensor if use_cuda else torch.FloatTensor
8 | dtypeint = torch.cuda.LongTensor if use_cuda else torch.LongTensor
9 |
10 | from kernel import _k
11 |
12 | # Pytorch is a fantastic deep learning library : it transforms symbolic python code
13 | # into highly optimized CPU/GPU binaries, which are called in the background seamlessly.
14 | # It can be thought of as a "heir" to the legacy Theano library (RIP :'-( ):
15 | # As you'll see, migrating a codebase from one to another is fairly simple !
16 | #
17 | # N.B. : On my Dell laptop, I have a GeForce GTX 960M with 640 Cuda cores and 2Gb of memory.
18 | #
19 | # We now show how to code a whole LDDMM pipeline into one (!!!) page of torch symbolic code.
20 |
21 | # Part 1 : cometric on the space of landmarks, kinetic energy on the phase space (Hamiltonian)===
22 |
23 | def _Hqp(q, p, sigma) :
24 | "The hamiltonian, or kinetic energy of the shape q with momenta p."
25 | pKqp = _k(q, q, sigma) * (p @ p.t()) # Use a simple isotropic kernel
26 | return .5 * pKqp.sum() # $H(q,p) = \frac{1}{2} * sum_{i,j} k(x_i,x_j) p_i.p_j$
27 |
28 | # Part 2 : Geodesic shooting ====================================================================
29 | # The partial derivatives of the Hamiltonian are automatically computed !
30 | def _dq_Hqp(q,p,sigma) :
31 | return torch.autograd.grad(_Hqp(q,p,sigma), q, create_graph=True)[0]
32 | def _dp_Hqp(q,p,sigma) :
33 | return torch.autograd.grad(_Hqp(q,p,sigma), p, create_graph=True)[0]
34 |
35 | def _hamiltonian_step(q,p, sigma) :
36 | "Simplistic euler scheme step with dt = .1."
37 | return [q + .1 * _dp_Hqp(q,p,sigma) , # See eq.
38 | p - .1 * _dq_Hqp(q,p,sigma) ]
39 |
40 | def _HamiltonianShooting(q, p, sigma) :
41 | "Shoots to time 1 a k-geodesic starting (at time 0) from q with momentum p."
42 | for t in range(10) :
43 | q,p = _hamiltonian_step(q, p, sigma) # Let's hardcode the "dt = .1"
44 | return [q,p] # and only return the final state + momentum
45 |
46 | # Part 2bis : Geodesic shooting + deformation of the ambient space, for visualization ===========
47 | def _HamiltonianCarrying(q, p, g, s) :
48 | """
49 | Similar to _HamiltonianShooting, but also conveys information about the deformation of
50 | an arbitrary point cloud 'grid' in the ambient space.
51 | """
52 | for t in range(10) : # Let's hardcode the "dt = .1"
53 | q,p,g = [q + .1 * _dp_Hqp(q,p, s),
54 | p - .1 * _dq_Hqp(q,p, s),
55 | g + .1 * _k(g, q, s) @ p]
56 | return q,p,g # return the final state + momentum + grid
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/lib/plotly/matplotlylib/mplexporter/renderers/fake_renderer.py:
--------------------------------------------------------------------------------
1 | from .base import Renderer
2 |
3 |
4 | class FakeRenderer(Renderer):
5 | """
6 | Fake Renderer
7 |
8 | This is a fake renderer which simply outputs a text tree representing the
9 | elements found in the plot(s). This is used in the unit tests for the
10 | package.
11 |
12 | Below are the methods your renderer must implement. You are free to do
13 | anything you wish within the renderer (i.e. build an XML or JSON
14 | representation, call an external API, etc.) Here the renderer just
15 | builds a simple string representation for testing purposes.
16 | """
17 | def __init__(self):
18 | self.output = ""
19 |
20 | def open_figure(self, fig, props):
21 | self.output += "opening figure\n"
22 |
23 | def close_figure(self, fig):
24 | self.output += "closing figure\n"
25 |
26 | def open_axes(self, ax, props):
27 | self.output += " opening axes\n"
28 |
29 | def close_axes(self, ax):
30 | self.output += " closing axes\n"
31 |
32 | def open_legend(self, legend, props):
33 | self.output += " opening legend\n"
34 |
35 | def close_legend(self, legend):
36 | self.output += " closing legend\n"
37 |
38 | def draw_text(self, text, position, coordinates, style,
39 | text_type=None, mplobj=None):
40 | self.output += " draw text '{0}' {1}\n".format(text, text_type)
41 |
42 | def draw_path(self, data, coordinates, pathcodes, style,
43 | offset=None, offset_coordinates="data", mplobj=None):
44 | self.output += " draw path with {0} vertices\n".format(data.shape[0])
45 |
46 | def draw_image(self, imdata, extent, coordinates, style, mplobj=None):
47 | self.output += " draw image of size {0}\n".format(len(imdata))
48 |
49 |
50 | class FullFakeRenderer(FakeRenderer):
51 | """
52 | Renderer with the full complement of methods.
53 |
54 | When the following are left undefined, they will be implemented via
55 | other methods in the class. They can be defined explicitly for
56 | more efficient or specialized use within the renderer implementation.
57 | """
58 | def draw_line(self, data, coordinates, style, label, mplobj=None):
59 | self.output += " draw line with {0} points\n".format(data.shape[0])
60 |
61 | def draw_markers(self, data, coordinates, style, label, mplobj=None):
62 | self.output += " draw {0} markers\n".format(data.shape[0])
63 |
64 | def draw_path_collection(self, paths, path_coordinates, path_transforms,
65 | offsets, offset_coordinates, offset_order,
66 | styles, mplobj=None):
67 | self.output += (" draw path collection "
68 | "with {0} offsets\n".format(offsets.shape[0]))
69 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/setdefaults.m:
--------------------------------------------------------------------------------
1 | function options = setdefaults(pars,options)
2 | % call: options = setdefaults(pars,options)
3 | % check that fields of pars and options are set correctly and
4 | % set basic default values for options that are common to various
5 | % optimization methods, including bfgs and gradsamp
6 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
7 | % with a subject header containing the string "hanso" or "bfgs".
8 | % Version 2.0, 2010, see GPL license info below.
9 |
10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
12 | %% This program is free software: you can redistribute it and/or modify
13 | %% it under the terms of the GNU General Public License as published by
14 | %% the Free Software Foundation, either version 3 of the License, or
15 | %% (at your option) any later version.
16 | %%
17 | %% This program is distributed in the hope that it will be useful,
18 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | %% GNU General Public License for more details.
21 | %%
22 | %% You should have received a copy of the GNU General Public License
23 | %% along with this program. If not, see .
24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25 | if nargin < 2
26 | options = [];
27 | end
28 | if ~isfield(pars, 'nvar')
29 | error('setdefaults: input "pars" must have a field "nvar" (number of variables)')
30 | elseif ~isposint(pars.nvar)
31 | error('setdefaults: input "pars.nvar" (number of variables) must be a positive integer')
32 | end
33 | if ~isfield(pars, 'fgname')
34 | error('setdefaults: input "pars" must have a field "fgname" (name of m-file computing function and gradient)')
35 | end
36 | if isfield(options, 'maxit')
37 | if ~isnonnegint(options.maxit)
38 | error('setdefaults: input "options.maxit" must be a nonnegative integer')
39 | end
40 | else
41 | options.maxit = 1000;
42 | end
43 | if isfield(options, 'normtol')
44 | if ~isposreal(options.normtol)
45 | error('setdefaults: input "options.normtol" must be a positive real scalar')
46 | end
47 | else
48 | options.normtol = 1.0e-6;
49 | end
50 | if isfield(options, 'fvalquit')
51 | if ~isreal(options.fvalquit)|~isscalar(options.fvalquit)
52 | error('setdefaults: input "options.fvalquit" must be a real scalar')
53 | end
54 | else
55 | options.fvalquit = -inf;
56 | end
57 | if isfield(options, 'xnormquit')
58 | if ~isreal(options.xnormquit)|~isscalar(options.xnormquit)
59 | error('setdefaults: input "options.fvalquit" must be a real scalar')
60 | end
61 | else
62 | options.xnormquit = inf;
63 | end
64 | if ~isfield(options, 'cpumax')
65 | options.cpumax = inf;
66 | end
67 | if ~isfield(options, 'prtlevel')
68 | options.prtlevel = 1;
69 | end
--------------------------------------------------------------------------------
/matlab/Script/hands/data/generate_fiber.m:
--------------------------------------------------------------------------------
1 | function Xall = generate_fiber(X0,l,curvature,n,v,noise)
2 | % generate n curves of length l from the starting points X0
3 | % with the given mean curvature and in the global direction v
4 | % (parametres code en dur : nb_gaussienne et sigma
5 | % qui influencent la nature du bruit)
6 |
7 | if 0 % script
8 | l=15; n=20; X0=zeros(3,10); v=[1;1;2];
9 | curvature=1/l; noise=.5;
10 | Xall=generate_fiber(X0,l,curvature,n,v,noise);
11 | figure; hold on;
12 | for i=1:size(X0,2)
13 | plot3(Xall(1,:,i),Xall(2,:,i),Xall(3,:,i));
14 | end
15 | hold off;
16 |
17 | X0=rand(3,10); % source unique juste pour visualiser
18 | Xall=generate_fiber(X0,l,curvature,n,v,noise);
19 | figure; hold on;
20 | for i=1:size(X0,2)
21 | plot3(Xall(1,:,i),Xall(2,:,i),Xall(3,:,i));
22 | end
23 | hold off;
24 |
25 | l =0.7;noise=.2; n=50;
26 | X0=repmat([0;-.2;0],1,n)+ randn(3,n)*.01; curvature=0.5/l; v=[.1;.1;2];
27 | Xall=generate_fiber(X0,l,curvature,n,v,noise);
28 | % Xall = Xall/10;
29 | figure(1); hold on;
30 | trisurf(t,p(:,1),p(:,2),p(:,3))
31 | for i=1:size(X0,2)
32 | plot3(Xall(1,:,i),Xall(2,:,i),Xall(3,:,i));
33 | end
34 | hold off;
35 | axis equal
36 | end
37 |
38 | d=size(X0,1);
39 | if d~=size(v,1)
40 | disp('Dimension of the direction vector does not match');
41 | end
42 |
43 | r=1/(curvature+eps);
44 | theta=l/r;
45 |
46 | th=3*pi/2+linspace(0,theta,n);
47 | X=zeros(3,n);
48 | X(1,:)=r*cos(th);
49 | X(2,:)=r*sin(th)+r;
50 |
51 | % Alignment on the direction v
52 | v=v/norm(v,2); ref=zeros(d,1);ref(1)=1;
53 | R=vrrotvec2mat(vrrotvec(ref,v));
54 | X=R*X;
55 |
56 | Xall=zeros(d,n,size(X0,2));
57 | % Generate the variations :
58 | for i=1:size(X0,2)
59 | nb_gaussienne=ceil(n/3); % parametre code en dur !
60 | sigma=(n/5)^2;
61 | noise_scale=max(noise,noise*max(max((dist(X0)))));
62 | fX=genereCourbe(n,noise_scale,nb_gaussienne,sigma);
63 | fY=genereCourbe(n,noise_scale,nb_gaussienne,sigma);
64 | fZ=genereCourbe(n,noise_scale,nb_gaussienne,sigma);
65 | fX=log(linspace(1,exp(1),n)).*fX; % cancel noise at X0
66 | fY=log(linspace(1,exp(1),n)).*fY; % cancel noise at X0
67 | fZ=log(linspace(1,exp(1),n)).*fZ; % cancel noise at X0
68 | Xall(:,:,i)=repmat(X0(:,i),1,n)+X+[fX;fY;fZ];
69 | end
70 |
71 | if d==2
72 | Xall(3,:,:)=[];
73 | end
74 | end
75 |
76 |
77 | function fX = genereCourbe(n,a,ng,sigma)
78 | % generate a curve of n points
79 | % d'amplitude a, centr�e en 0
80 |
81 | g=@(x,c,sigma)exp(-(x-c)^2/sigma);
82 |
83 | c=linspace(0,1,ng)'+(2*rand(ng,1)-.5*ones(ng,1))/ng; % centres des gaussiennes
84 | h=2*rand(ng,1)-ones(ng,1); % amplitudes et signes
85 | X=linspace(0,1,n);
86 | fX=zeros(size(X));
87 | for i=1:ng
88 | fX=fX+arrayfun(@(x)h(i)*g(x,c(i),sigma),X);
89 | end
90 | fX=a*fX/(max(fX)-min(fX));
91 | fX=fX-mean(fX);
92 | end
93 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/data_attachment/currents.py:
--------------------------------------------------------------------------------
1 | from pylab import *
2 | from scipy.spatial.distance import pdist, squareform, cdist
3 |
4 |
5 | class Current :
6 | """
7 | Encodes a Current as a sum of weighted vector diracs.
8 | \omega(v) = \sum_i (Omega_i, v(x_i))
9 | """
10 | def __init__(self, points, normals) :
11 | assert (points.shape[1] == 2), "3D currents have not been implemented yet !"
12 | assert (points.shape == normals.shape), "A current is given by an array of coordinates + an array of directions"
13 | self.points = points
14 | self.normals = normals
15 | self.dimension = self.points.shape[1]
16 |
17 | class Currents :
18 | @staticmethod
19 | def kernel_matching(Q, Xt, s) :
20 | """
21 | Implementation of the kernel data attachment term :
22 |
23 | d(Q, Xt) = .5 * sum_{i,j} (v_i, v_j) k( | Q_i - Q_j | )
24 | - .5 * 2*sum_{i,j} (v_i, w_j) k( | Q_i - Xt_j | )
25 | + .5 * sum_{i,j} (w_i, w_j) k( | Xt_i - Xt_j | )
26 | where
27 | Q = sum_i (v_i, \dirac_{ Q_i}(.) )
28 | Xt = sum_j (w_j, \dirac_{Xt_j}(.) )
29 | and where k( d ) = exp( - d^2/(2*s^2) ) is a gaussian kernel
30 | with std = s.
31 |
32 | This can be seen as a ``linear'' matching tool between curves/surfaces :
33 | - unlike the "Measures" tool, it takes the orientation into account,
34 | - but it only does so in a linear way.
35 | Today, one may prefer to use Varifolds or Normal Cycles.
36 | """
37 | # We use a Gaussian kernel
38 | kernel = lambda x : exp(- x / (2* s ** 2)) # kernel is given |x|^2 as input
39 | kernelp = lambda x : - exp(- x / (2* s ** 2)) / (2* s ** 2)
40 | q = Q.points
41 | xt = Xt.points
42 | v = Q.normals
43 | w = Xt.normals
44 | q_dists = squareform(pdist( q, 'sqeuclidean'))
45 | cross_dists = cdist( q, xt, 'sqeuclidean')
46 | xt_dists = squareform(pdist(xt, 'sqeuclidean'))
47 |
48 | # Matrices of scalar products between normals ('G' stands for Grassmanian)
49 | Gvv = v @ v.T
50 | Gvw = v @ w.T
51 | Gww = w @ w.T
52 |
53 | # We're gonna need those two for later calculations
54 | ker_qq = kernel(q_dists)
55 | ker_qxt = kernel(cross_dists)
56 |
57 | K_qq = Gvv * ker_qq
58 | K_qxt = Gvw * ker_qxt
59 | K_xtxt = Gww * kernel(xt_dists)
60 | # Total data attachment term :
61 | C = .5 * ( sum(K_qq) - 2*sum(K_qxt) + sum(K_xtxt) )
62 |
63 | # Computation of the directional derivatives
64 | # with respect to the dirac positions
65 | Kp_qq = Gvv * kernelp(q_dists)
66 | Kp_qxt = Gvw * kernelp(cross_dists)
67 | dq = zeros(q.shape)
68 | for d in range(q.shape[1]) :
69 | qi_min_qj = atleast_2d(q[:,d]).T - atleast_2d( q[:,d])
70 | qi_min_xtj = atleast_2d(q[:,d]).T - atleast_2d(xt[:,d])
71 | dq[:,d] = ( sum( qi_min_qj * Kp_qq , 1) \
72 | - 2* sum( qi_min_xtj * Kp_qxt, 1) )
73 |
74 | # Computation of the directional derivatives
75 | # with respect to the normals v
76 | dv = zeros(v.shape)
77 | for d in range(v.shape[1]) :
78 | dv[:,d] = sum( v[:,d] * ker_qq , 1) \
79 | - sum( w[:,d] * ker_qxt, 1)
80 |
81 | dOmega = Current(dq, dv)
82 | return (C, dOmega)
83 |
--------------------------------------------------------------------------------
/matlab/Bin/kernels/cuda/makefile_cuda.sh~:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This small script shows how to compile the cuda mex files. It has been tested :
4 | # on a Debian Jessie/Sid and Ubuntu 14.04 systems with Cuda 5.5 to 7.5 (packaged version) and matlab R2013b and R2014a.
5 | # If cuda was manually installed make sure that path "CUDAROOT" to cuda libs is correct and that ld knows where
6 | # libcudart.so.* is located (modify or create a LD_LIBRARY_PATH variable). Please adapt all the other values to fit your configuration.
7 |
8 |
9 | #------------------------------------#
10 | # CHECK THESE PATHS #
11 | #------------------------------------#
12 |
13 |
14 | MATLABROOT="/usr/local/MATLAB/R2014a"
15 | CUDAROOT="/usr/local/cuda-7.5/lib64"
16 | MEXC="$MATLABROOT/bin/mex"
17 | CC="/usr/bin/gcc"
18 | NVCC="/usr/local/cuda-7.5/bin/nvcc"
19 |
20 | # CHECK THESE PARAMETERS (depends on your GPU):
21 | COMPUTECAPABILITY=35
22 | USE_DOUBLE=0
23 | NVCCOPT="--use_fast_math"
24 | BLOCKSIZE=192
25 |
26 | # NVCC
27 | NVCCFLAGS="-ccbin=$CC -arch=sm_$COMPUTECAPABILITY -Xcompiler -fPIC"
28 | MEXPATH="-I$MATLABROOT/extern/include"
29 |
30 | # C
31 | COPTIMFLAG="-O3"
32 | CLIB="-L$CUDAROOT -lcudart"
33 |
34 | INSTALL_DIR="../binaries"
35 |
36 | #clean
37 | rm -f *.o;
38 |
39 | #---------------------------------------#
40 | # fshapes distances #
41 | #---------------------------------------#
42 |
43 | #clean
44 | rm -f *.o;
45 |
46 | # Wasserstein distances (compiled with double)
47 |
48 | $NVCC -c -D "USE_DOUBLE_PRECISION=1" -D "CUDA_BLOCK_SIZE=$BLOCKSIZE" ./shapes_distances/wasserstein/sinkhornGpuConv.cu $NVCCFLAGS $MEXPATH -o sinkhornGpuConv.o;echo "sinkhornGpuConv.cu successfully compiled";
49 | $NVCC -c -D "USE_DOUBLE_PRECISION=1" -D "CUDA_BLOCK_SIZE=$BLOCKSIZE" ./shapes_distances/wasserstein/sinkhornGpuConv_unbalanced.cu $NVCCFLAGS $MEXPATH -o sinkhornGpuConv_unbalanced.o;echo "sinkhornGpuConv_unbalanced.cu successfully compiled";
50 | $NVCC -c -D "USE_DOUBLE_PRECISION=1" -D "CUDA_BLOCK_SIZE=$BLOCKSIZE" ./shapes_distances/wasserstein/dsinkhornGpuConv.cu $NVCCFLAGS $MEXPATH -o dsinkhornGpuConv.o;echo "dsinkhornGpuConv.cu successfully compiled";
51 |
52 | #mex complilation
53 | for i in `ls *.o`;do $MEXC GCC=$CC COPTIMFLAGS=$COPTIMFLAG $i $CLIB;done
54 |
55 | # install
56 | mkdir -p "$INSTALL_DIR/fshapes_distances/wasserstein"
57 |
58 | for i in `ls *.mexa64`;do
59 | mv $i "$INSTALL_DIR/fshapes_distances/wasserstein/";
60 | echo "$i successfully installed"
61 | done
62 |
63 | #---------------------------------------#
64 | # Kernels #
65 | #---------------------------------------#
66 |
67 | #nvcc compilation of every .cu files
68 | for i in `ls *.cu`;do $NVCC -D "USE_DOUBLE_PRECISION=$USE_DOUBLE" -D "CUDA_BLOCK_SIZE=$BLOCKSIZE" -c $i $NVCCFLAGS $MEXPATH $NVCCOPT;echo "$i successfully compiled";done
69 |
70 | #mex complilation
71 | for i in `ls *.o`;do $MEXC GCC=$CC COPTIMFLAGS=$COPTIMFLAG $i $CLIB;done
72 |
73 | #clean
74 | rm -f *.o;
75 |
76 | # install
77 | mkdir -p "$INSTALL_DIR"
78 |
79 | for i in `ls *.mexa64`;do
80 | mv $i "$INSTALL_DIR";
81 | echo "$i successfully installed"
82 | done
83 |
84 |
--------------------------------------------------------------------------------
/matlab/Bin/kernels/cuda/makefile_cuda.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This small script shows how to compile the cuda mex files. It has been tested :
4 | # on a Debian Jessie/Sid and Ubuntu 14.04 systems with Cuda 5.5 to 7.5 (packaged version) and matlab R2013b and R2014a.
5 | # If cuda was manually installed make sure that path "CUDAROOT" to cuda libs is correct and that ld knows where
6 | # libcudart.so.* is located (modify or create a LD_LIBRARY_PATH variable). Please adapt all the other values to fit your configuration.
7 | # Author : B. Charlier (2017)
8 |
9 |
10 | #------------------------------------#
11 | # CHECK THESE PATHS #
12 | #------------------------------------#
13 |
14 |
15 | MATLABROOT="/usr/local/MATLAB/R2014a"
16 | CUDAROOT="/usr/local/cuda-7.5/lib64"
17 | MEXC="$MATLABROOT/bin/mex"
18 | CC="/usr/bin/gcc"
19 | NVCC="nvcc"
20 |
21 | # CHECK THESE PARAMETERS (depends on your GPU):
22 | COMPUTECAPABILITY=35
23 | USE_DOUBLE=0
24 | NVCCOPT="--use_fast_math"
25 | BLOCKSIZE=192
26 |
27 | # NVCC
28 | NVCCFLAGS="-ccbin=$CC -arch=sm_$COMPUTECAPABILITY -Xcompiler -fPIC"
29 | MEXPATH="-I$MATLABROOT/extern/include"
30 |
31 | # C
32 | COPTIMFLAG="-O3"
33 | CLIB="-L$CUDAROOT -lcudart"
34 |
35 | INSTALL_DIR="../binaries"
36 |
37 | #clean
38 | rm -f *.o;
39 |
40 | #---------------------------------------#
41 | # fshapes distances #
42 | #---------------------------------------#
43 |
44 | #clean
45 | rm -f *.o;
46 |
47 | # Wasserstein distances (compiled with double)
48 |
49 | $NVCC -c -D "USE_DOUBLE_PRECISION=1" -D "CUDA_BLOCK_SIZE=$BLOCKSIZE" ./shapes_distances/wasserstein/sinkhornGpuConv.cu $NVCCFLAGS $MEXPATH -o sinkhornGpuConv.o;echo "sinkhornGpuConv.cu successfully compiled";
50 | $NVCC -c -D "USE_DOUBLE_PRECISION=1" -D "CUDA_BLOCK_SIZE=$BLOCKSIZE" ./shapes_distances/wasserstein/sinkhornGpuConv_unbalanced.cu $NVCCFLAGS $MEXPATH -o sinkhornGpuConv_unbalanced.o;echo "sinkhornGpuConv_unbalanced.cu successfully compiled";
51 | $NVCC -c -D "USE_DOUBLE_PRECISION=1" -D "CUDA_BLOCK_SIZE=$BLOCKSIZE" ./shapes_distances/wasserstein/dsinkhornGpuConv.cu $NVCCFLAGS $MEXPATH -o dsinkhornGpuConv.o;echo "dsinkhornGpuConv.cu successfully compiled";
52 |
53 | #mex complilation
54 | for i in `ls *.o`;do $MEXC GCC=$CC COPTIMFLAGS=$COPTIMFLAG $i $CLIB;done
55 |
56 | # install
57 | mkdir -p "$INSTALL_DIR/fshapes_distances/wasserstein"
58 |
59 | for i in `ls *.mexa64`;do
60 | mv $i "$INSTALL_DIR/fshapes_distances/wasserstein/";
61 | echo "$i successfully installed"
62 | done
63 |
64 | #---------------------------------------#
65 | # Kernels #
66 | #---------------------------------------#
67 |
68 | #nvcc compilation of every .cu files
69 | for i in `ls *.cu`;do $NVCC -D "USE_DOUBLE_PRECISION=$USE_DOUBLE" -D "CUDA_BLOCK_SIZE=$BLOCKSIZE" -c $i $NVCCFLAGS $MEXPATH $NVCCOPT;echo "$i successfully compiled";done
70 |
71 | #mex complilation
72 | for i in `ls *.o`;do $MEXC GCC=$CC COPTIMFLAGS=$COPTIMFLAG $i $CLIB;done
73 |
74 | #clean
75 | rm -f *.o;
76 |
77 | # install
78 | mkdir -p "$INSTALL_DIR"
79 |
80 | for i in `ls *.mexa64`;do
81 | mv $i "$INSTALL_DIR";
82 | echo "$i successfully installed"
83 | done
84 |
85 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/set_optim_option.m:
--------------------------------------------------------------------------------
1 | function [noptim,mesg] = set_optim_option(optim,objfun,list_of_variables,enr)
2 | % This function check the optim structure and set default values if needed.
3 | % Author : B. Charlier (2017)
4 |
5 |
6 | noptim = optim;
7 |
8 |
9 | noptim = setoptions(noptim,'method','gradDesc',{'gradDesc','bfgs'});
10 | noptim = setoptions(noptim,noptim.method,[]);
11 |
12 |
13 | switch lower(noptim.method)
14 | case 'graddesc'
15 | noptim.gradDesc = set_gradDesc_defaults(noptim.gradDesc,objfun,list_of_variables,enr);
16 |
17 | case 'bfgs'
18 | noptim.bfgs = set_bfgs_defaults(noptim.bfgs,list_of_variables,enr);
19 |
20 | end
21 |
22 |
23 | % save message and display
24 | mesg = [sprintf('\n----------- Optimization parameters -----------\n' ),...
25 | dispstructure(noptim)];
26 |
27 | fprintf('%s',mesg);
28 |
29 |
30 |
31 |
32 | end
33 |
34 | function opt = set_gradDesc_defaults(opt,objfun,list_of_variables,enr_name)
35 |
36 |
37 | opt = setoptions(opt,'step_increase',1.2);
38 | opt = setoptions(opt,'step_decrease',.5);
39 |
40 | opt = setoptions(opt,'kernel_size_signal_reg',0);
41 | opt = setoptions(opt,'kernel_size_geom_reg',0);
42 |
43 | switch objfun{1}.distance
44 | case 'kernel'
45 | opt = setoptions(opt,'max_nb_iter',50 * ones(1,size(objfun{1}.kernel_distance.kernel_size_signal,2)));
46 |
47 | nb_run = length(opt.max_nb_iter);
48 | nb_match = length(objfun);
49 |
50 | if ~isequal(cell2mat(cellfun(@(x) length(x.kernel_distance.kernel_size_signal),objfun,'UniformOutput',0)),nb_run*ones(1,nb_match)) ...
51 | || ~isequal(cell2mat(cellfun(@(x) length(x.kernel_distance.kernel_size_geom),objfun,'UniformOutput',0)),nb_run*ones(1,nb_match))...
52 | || ( (strcmp(objfun{1}.kernel_distance.kernel_grass,'gaussian_oriented')|| strcmp(objfun{1}.kernel_distance.kernel_grass,'gaussian_unoriented') ) && ~isequal(cell2mat(cellfun(@(x) length(x.kernel_distance.kernel_size_grass),objfun,'UniformOutput',0)),nb_run*ones(1,nb_match)))
53 | error('All kernel sizes objfun.sigmaXX and optim.max_nb_iter must have the same length');
54 | end
55 |
56 | case 'wasserstein'
57 | opt = setoptions(opt,'max_nb_iter',50 * ones(1,size(objfun{1}.wasserstein_distance.epsilon,2)));
58 |
59 | end
60 |
61 | opt = setoptions(opt,'save_template_evolution',0);
62 | opt = setoptions(opt,'min_step_size',1e-10);
63 | opt = setoptions(opt,'min_fun_decrease',1e-4);
64 |
65 | for i =1:length(list_of_variables)
66 | opt = setoptions(opt,['step_size_',list_of_variables{i}],'auto');
67 | end
68 |
69 | opt = setoptions(opt,'list_of_variables',list_of_variables);
70 | opt = setoptions(opt,'enr_name',enr_name);
71 | end
72 |
73 | function opt = set_bfgs_defaults(opt,list_of_variables,enr_name)
74 |
75 |
76 |
77 | opt = setoptions(opt, 'nvec', 20); % BFGS memory
78 | opt = setoptions(opt, 'maxit', 50);
79 | opt = setoptions(opt, 'prtlevel',2);
80 | opt = setoptions(opt, 'normtol', eps);
81 | opt = setoptions(opt, 'tol',eps);
82 | opt = setoptions(opt,'list_of_variables',list_of_variables);
83 | opt = setoptions(opt,'enr_name',enr_name);
84 |
85 |
86 | end
87 |
88 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/models/hypertemplate_atlas.py:
--------------------------------------------------------------------------------
1 | from pylab import *
2 |
3 | from .atlas import Atlas
4 |
5 | class HypertemplateAtlas(Atlas):
6 | """
7 | Atlas with a shooted mean Q0 and no dimensional constraint.
8 | Important note :
9 | in general, the shooting method associated to the
10 | HT -> Template geodesic (Hilbert Space V0) can be different
11 | from the one used to get models X from the template.
12 | Here, we won't bother to define an other metric,
13 | and will simply use the one given by self.M.
14 | """
15 | def __init__(self, *args, **kwargs):
16 | Atlas.__init__(self, *args, **kwargs)
17 | self.P0 = self.M.zero_momentum()
18 | self.QHT = self.Q0
19 | def template(self) :
20 | (Q0, _, _, _, _) = self.M.shoot(self.QHT, self.P0)
21 | return Q0
22 | def update(self, dP0, dP):
23 | # Parameters update :
24 | self.update_Q0(dP0)
25 | self.update_P(dP)
26 | def after_step_Q0(self, dP0) :
27 | # template update
28 | return self.P0 + dP0 # update of the template shooting parameter...
29 | def after_step_P(self, dP) :
30 | return [ p + dp for (p,dp) in zip(self.P, dP)] # No dimensional constraint
31 | def set_state(self, new_state) :
32 | self.P0 = new_state.Q0
33 | self.Q0 = self.template() # to get a new template
34 | self.P = new_state.P
35 | def template_cost(self, prec_QHT) :
36 | return .5* self.gamma_V0 * ( self.M.norm_p(self.QHT, self.P0, prec_QHT) **2) # Quadratic cost
37 |
38 | def normalize_and_regularize_template_updates(self, dQ0p, iteration) :
39 | dQ0 = self.M.sum_position(self.Q0, dQ0p)
40 |
41 | (Q0, Qt, Pt, _, prec_Qt) = self.M.shoot(self.QHT, self.P0)
42 | (dQHT, dP0) = self.M.backward_scheme(dQ0, self.M.zero_momentum(), Qt, Pt, prec_Qt)
43 | (dQHT_reg, dP0_reg) = self.d_regularization_term_HT(self.QHT, self.P0, prec_Qt[0])
44 | # we will actually discard dQHT_reg, as we suppose it is fixed.
45 | dP0 = self.gamma_V0 * dP0_reg + dP0
46 |
47 | norm_update = self.M.norm_p(self.QHT, dP0, prec_Qt[0]) # usual approx
48 | dP0 = self.normalize_template_updates([dP0], norm_update, iteration)[0]
49 | return dP0.ravel()
50 | def d_regularization_term_HT(self, q, p, prec_q) :
51 | """
52 | Differential of the term associated to gamma_V0 :
53 | .5 * (p0, Kqht p0)
54 | """
55 | dp = self.M.K(q, p, prec_q)
56 | dq = - self.M.upP(q,p, prec_q)
57 | return (dq, dp)
58 | def show_HT(self) :
59 | self.M.marker(self.QHT, marker = dict(size = 10, color='rgb(255,0,255)'), name='Hypertemplate', visible=False)
60 | (Q0, Qt, Pt, _, _) = self.M.shoot(self.QHT, self.P0)
61 | self.M.plot_traj(Qt, line = dict(width= 2, color='rgb(255,128,0)'), name='Template Shooting', visible=False)
62 | def get_frame(self, f) :
63 | # Six plotly traces per frame : 'Hypertemplate', 'Template Shooting', 'Frechet Mean', 'Shootings', 'Targets', 'Models'
64 | list1 = str([ 1 + 6*self.current_frame, 2 + 6*self.current_frame, 3 + 6*self.current_frame, 4 + 6*self.current_frame, 5 + 6*self.current_frame, 6 + 6*self.current_frame])[1:-1]
65 | self.current_frame = f
66 | list2 = str([ 1 + 6*self.current_frame, 2 + 6*self.current_frame, 3 + 6*self.current_frame, 4 + 6*self.current_frame, 5 + 6*self.current_frame, 6 + 6*self.current_frame])[1:-1]
67 | return (self.frames[f] , [list1, list2])
68 |
69 |
70 |
--------------------------------------------------------------------------------
/Pytorch/curve.py:
--------------------------------------------------------------------------------
1 | # Import the relevant tools
2 | import numpy as np # standard array library
3 | import torch
4 |
5 | # Display routines :
6 | import matplotlib.cm as cm
7 | import matplotlib.pyplot as plt
8 | import matplotlib.colors as colors
9 | from matplotlib.collections import LineCollection
10 | from pyvtk import VtkData # from '.vtk' to Curves objects
11 |
12 | from input_output import level_curves
13 |
14 | # Curve representations =========================================================================
15 |
16 | class Curve :
17 | "Encodes a 2D curve as an array of float coordinates + a connectivity list."
18 | def __init__(self, points, connectivity) :
19 | "points should be a n-by-2 float array, connectivity an nsegments-by-2 int array."
20 | self.points = points
21 | self.connectivity = connectivity
22 |
23 | def segments(self) :
24 | "Returns the list of segments the curve is made of."
25 | return np.array( [ [self.points[l[0]], self.points[l[1]]] for l in self.connectivity ] )
26 |
27 | def to_measure(self) :
28 | """
29 | Outputs the sum-of-diracs measure associated to the curve.
30 | Each segment from the connectivity matrix self.c
31 | is represented as a weighted dirac located at its center,
32 | with weight equal to the segment length.
33 | """
34 | segments = self.segments()
35 | centers = [ .5 * ( seg[0] + seg[1] ) for seg in segments ]
36 | lengths = [np.sqrt(np.sum( (seg[1] - seg[0])**2 )) for seg in segments ]
37 | return ( np.array(centers), np.array(lengths) )
38 |
39 | @staticmethod
40 | def _vertices_to_measure( q, connec ) :
41 | """
42 | Transforms a torch array 'q1' into a measure, assuming a connectivity matrix connec.
43 | It is the Torch equivalent of 'to_measure'.
44 | """
45 | a = q[connec[:,0]] ; b = q[connec[:,1]]
46 | # A curve is represented as a sum of diracs, one for each segment
47 | x = .5 * (a + b) # Mean
48 | mu = torch.sqrt( ((b-a)**2).sum(1) ) # Length
49 | return (x, mu)
50 |
51 | def plot(self, ax, color = 'rainbow', linewidth = 3) :
52 | "Simple display using a per-id color scheme."
53 | segs = self.segments()
54 |
55 | if color == 'rainbow' : # rainbow color scheme to see pointwise displacements
56 | ncycles = 5
57 | cNorm = colors.Normalize(vmin=0, vmax=(len(segs)-1)/ncycles)
58 | scalarMap = cm.ScalarMappable(norm=cNorm, cmap=plt.get_cmap('hsv') )
59 | seg_colors = [ scalarMap.to_rgba( i % ((len(segs)-1)/ncycles) )
60 | for i in range(len(segs)) ]
61 | else : # uniform color
62 | seg_colors = [ color for i in range(len(segs)) ]
63 |
64 | line_segments = LineCollection(segs, linewidths=(linewidth,),
65 | colors=seg_colors, linestyle='solid')
66 | ax.add_collection(line_segments)
67 |
68 | @staticmethod
69 | def from_file(fname) :
70 | if fname[-4:] == '.png' :
71 | (points, connec) = level_curves(fname)
72 | return Curve(points, connec)
73 | elif fname[-4:] == '.vtk' :
74 | data = VtkData(fname)
75 | points = np.array(data.structure.points)[:,0:2] # Discard "Z"
76 | connec = np.array(data.structure.polygons)
77 | return Curve((points + 150)/300, connec) # offset for the skull dataset...
78 |
79 |
80 |
--------------------------------------------------------------------------------
/matlab/Bin/io/import_fshape_vtk.m:
--------------------------------------------------------------------------------
1 | function fshape = import_fshape_vtk(filename)
2 | % IMPORT_VTK(filename) import a vtk file as a fshape structure.
3 | %
4 | %Input :
5 | % path : string path to file
6 | %Output :
7 | % fshape : struct('x',...,'G',...,'f',...)
8 | %
9 | % See also : import_fshape_ply, import_fshape_obj
10 | % Author : B. Charlier (2017)
11 |
12 | [fshape.x,fshape.G,fshape.f] = read_vtk(filename);
13 |
14 |
15 | end
16 |
17 | function [vertex,face,signal] = read_vtk(filename)
18 |
19 | % read_vtk - read data from VTK file. (Based on a work Mario Richtsfeld)
20 | %
21 | % [vertex,face] = read_vtk(filename, verbose);
22 | %
23 | % 'vertex' is a 'nb.vert x 3' array specifying the position of the vertices.
24 | % 'face' is a 'nb.face x 2' (POLYGONS) or 'nb.face x 2' (LINES) array specifying the connectivity of the mesh.
25 |
26 |
27 |
28 | fid = fopen(filename,'r');
29 |
30 | %---------------
31 | % read header
32 | %----------------
33 |
34 | if( fid==-1 )
35 | error('Can''t open the file.');
36 | end
37 |
38 | str = fgets(fid); % -1 if eof
39 | if ~strcmp(str(3:5), 'vtk')
40 | error('The file is not a valid VTK one.');
41 | end
42 |
43 | %jump 3 lines
44 | [~] = fgets(fid);
45 | [~] = fgets(fid);
46 | [~] = fgets(fid);
47 |
48 | %----------------
49 | % read vertices
50 | %----------------
51 |
52 | str = fgets(fid);
53 | info = sscanf(str,'%s %*s %*s', 6);
54 |
55 | if strcmp(info,'POINTS')
56 | nvert = sscanf(str,'%*s %d %*s', 1);
57 | [A,cnt] = fscanf(fid,'%G ', 3*nvert);
58 | if cnt~=3*nvert
59 | warning('Problem in reading vertices.');
60 | end
61 | A = reshape(A, 3, cnt/3);
62 | vertex = A';
63 | end
64 |
65 | %----------------
66 | % read polygons
67 | %----------------
68 |
69 | str = fgets(fid);
70 | info = sscanf(str,'%s %*s %*s');
71 |
72 | if strcmp(info,'POLYGONS') || strcmp(info,'LINES')
73 | nface = sscanf(str,'%*s %d %d', 2);
74 | [A,cnt] = fscanf(fid,'%d ', nface(2));
75 | if cnt~=nface(2)
76 | warning('Problem in reading faces.');
77 | end
78 | A = reshape(A, nface(2)/nface(1),nface(1));
79 | face = (A(2:end,:)+1)';
80 | else
81 | error('Problem in reading faces.')
82 | end
83 |
84 | %-------------------
85 | % read signal
86 | %-------------------
87 |
88 | try
89 | str = fgets(fid);
90 | info = sscanf(str,'%s %*s', 10);
91 |
92 | if strcmp(info,'POINT_DATA')
93 |
94 | nvertex = sscanf(str,'%*s %d', 1);
95 | [~] = fgets(fid);
96 | [~] = fgets(fid);
97 |
98 | [signal,cnt] = fscanf(fid,'%G', nvertex);
99 | if cnt~=nvertex
100 | error('Problem in reading signal.');
101 | end
102 | elseif strcmp(info,'CELL_DATA')
103 | nface = sscanf(str,'%*s %d', 1);
104 | [~] = fgets(fid);
105 | [~] = fgets(fid);
106 |
107 | [signal,cnt] = fscanf(fid,'%G', nface);
108 | if cnt~=nface
109 | error('Problem in reading signal.');
110 | end
111 | else
112 | error('Problem in reading signal.');
113 | end
114 | catch
115 | signal = zeros( [size(vertex,1) ,1] );
116 | end
117 |
118 |
119 | fclose(fid);
120 |
121 | end
122 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/models/free_atlas.py:
--------------------------------------------------------------------------------
1 | from pylab import *
2 |
3 | from .atlas import Atlas
4 | from ..manifolds.curves import Curve
5 |
6 | class FreeAtlas(Atlas):
7 | "Atlas with a Free mean Q0 and no dimensional constraint."
8 | def __init__(self, *args, **kwargs):
9 | Atlas.__init__(self, *args, **kwargs)
10 | def after_step_Q0(self, dQ0) :
11 | return self.Q0 + dQ0 # Free templates
12 | def after_step_P(self, dP) :
13 | return [ p + dp for (p,dp) in zip(self.P, dP)] # No dimensional constraint
14 | def template_cost(self, *args) :
15 | return 0 # Free template
16 | def normalize_and_regularize_template_updates(self, dQ0p, iteration) :
17 | dQ0p = self.normalize_template_updates(dQ0p, self.M.displacement_norm(dQ0p), iteration)
18 | dQ0 = self.M.sum_position(self.Q0, dQ0p)
19 |
20 | # This whole Free template stuff is more or less a hack,
21 | # as it is not a well defined problem (flat prior on an unbounded space),
22 | # so it's put here without too much care.
23 | if self.reg_template_gradient is not None :
24 | if self.reg_template_gradient[0] == 'gaussian' and type(self.reg_template_gradient[1]) is float :
25 | if self.reg_template_gradient[1] > 0 :
26 | if type(dQ0) is ndarray :
27 | None
28 | elif type(dQ0) is Curve :
29 | None
30 | else :
31 | print("I don't know how to regularize this type of gradient.")
32 | raise NotImplementedError
33 | else :
34 | print('This regularization type for the free template is not implemented : ', self.reg_template_gradient)
35 | raise NotImplementedError
36 |
37 | return dQ0
38 | def regularize_template_gradient(self, grad) :
39 | "Free template gradient regularization."
40 | if self.reg_template_gradient[0] == 'gaussian' and type(self.reg_template_gradient[1]) is float :
41 | if self.reg_template_gradient[1] > 0 :
42 | K = self.M.precompute_kernels(self.Q0)[0]
43 | if type(grad) is ndarray :
44 | grad_p = grad.reshape((self.M.npoints, self.M.dimension))
45 | return (K @ grad_p).ravel()
46 | elif type(grad) is Curve :
47 | C = self.Q0 # assume it's a curve
48 | M = C.to_measure()
49 |
50 | mutilde = zeros(C.array_shape()[0])
51 | for (i,s) in enumerate(C.connectivity) :
52 | mutilde[s[0]] += .5 * M.weights[i]
53 | mutilde[s[1]] += .5 * M.weights[i]
54 |
55 | K = K * (atleast_2d(K.dot(mutilde)).T * mutilde)
56 | grad.points = (K @ grad.to_array()).ravel()
57 | return grad
58 | else :
59 | print("I don't know how to regularize this type of gradient.")
60 | raise NotImplementedError
61 | else :
62 | print('This regularization type for the free template is not implemented : ', self.reg_template_gradient)
63 | raise NotImplementedError
64 |
65 | def show_HT(self) :
66 | None # nothing to show...
67 | def get_frame(self, f) :
68 | # Five plotly traces per frame : 'Frechet Mean', 'Shootings', 'Targets', 'Models', 'Transports'
69 | list1 = str([ 1 + 5*self.current_frame, 2 + 5*self.current_frame, 3 + 5*self.current_frame, 4 + 5*self.current_frame, 5 + 5*self.current_frame])[1:-1]
70 | self.current_frame = f
71 | list2 = str([ 1 + 5*self.current_frame, 2 + 5*self.current_frame, 3 + 5*self.current_frame, 4 + 5*self.current_frame, 5 + 5*self.current_frame])[1:-1]
72 | return (self.frames[f] , [list1, list2])
73 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/wasserstein/sinkhorn_log.m:
--------------------------------------------------------------------------------
1 | function [u,v,gamma,Wprimal,Wdual,err] = sinkhorn_log(mu,nu,c,epsilon,options)
2 | % sinkhorn_log - stabilized sinkhorn over log domain with acceleration
3 | %
4 | % [u,v,Wprimal,Wdual,err] = sinkhorn_log(mu,nu,c,epsilon,options);
5 | %
6 | % mu and nu are marginals.
7 | % c is cost
8 | % epsilon is regularization
9 | % coupling is
10 | % gamma = exp( (-c+u*ones(1,N(2))+ones(N(1),1)*v')/epsilon );
11 | %
12 | % options.niter is the number of iterations.
13 | % options.tau is an avering step.
14 | % - tau=0 is usual sinkhorn
15 | % - tau<0 produces extrapolation and can usually accelerate.
16 | %
17 | % options.rho controls the amount of mass variation. Large value of rho
18 | % impose strong constraint on mass conservation. rho=Inf (default)
19 | % corresponds to the usual OT (balanced setting).
20 | % Author : B. Charlier (2017)
21 |
22 |
23 | options.null = 0;
24 | niter = getoptions(options, 'niter', 1000);
25 | tau = getoptions(options, 'tau', -.5);
26 | rho = getoptions(options, 'rho', Inf);
27 | record_evol = getoptions(options, 'record_evol', 0);
28 |
29 |
30 | lambda = rho/(rho+epsilon);
31 | if rho==Inf
32 | lambda=1;
33 | end
34 |
35 | % Sinkhorn
36 | N = [size(mu,1) size(nu,1)];
37 | ave = @(tau, u,u1)tau*u+(1-tau)*u1;
38 | lse = @(A)logReg(sum(exp(A),2));
39 | M = @(u,v)(-c+ repmat(u,1,N(2)) + repmat(v',N(1), 1) )/epsilon;
40 |
41 | if record_evol %only if needed!
42 | err = zeros(niter,1);
43 | Wprimal = zeros(niter,1);
44 | Wdual = zeros(niter,1);
45 | end
46 |
47 | u = zeros(N(1),1);
48 | v = zeros(N(2),1);
49 |
50 |
51 | for i=1:niter
52 |
53 | u1 = u;
54 | u = ave(tau, u, ...
55 | lambda*epsilon*log(mu) - lambda*epsilon*lse( M(u,v) ) + lambda*u );
56 |
57 | v = ave(tau, v, ...
58 | lambda*epsilon*log(nu) - lambda*epsilon*lse( M(u,v)' ) + lambda*v );
59 |
60 | if record_evol %only if needed!
61 | % coupling
62 | gamma = exp(M(u,v));
63 | [Wprimal(i),Wdual(i),err(i)]= objfunction(u,u1,v,nu,mu,c,gamma,rho,epsilon);
64 | end
65 |
66 | end
67 |
68 | % prepare output
69 |
70 | if ~record_evol
71 | % coupling
72 | gamma = exp(M(u,v));
73 | [Wprimal,Wdual,err]= objfunction(u,u1,v,nu,mu,c,gamma,rho,epsilon);
74 |
75 | end
76 |
77 | end
78 |
79 |
80 |
81 | function [Wprimal,Wdual,err]= objfunction(u,u1,v,nu,mu,c,gamma,rho,epsilon)
82 |
83 | % kullback divergence
84 | H = @(p)-sum( p(:).*(logReg(p(:))-1) );
85 | KL = @(h,p)sum( h(:).*log( h(:)./p(:) ) - h(:)+p(:) );
86 | KLd = @(u,p)sum( p(:).*(exp(-u(:))-1) );
87 | dotp = @(x,y)sum(x(:).*y(:));
88 |
89 |
90 | if rho==Inf % marginal violation
91 |
92 | Wprimal = dotp(c,gamma) - epsilon*H(gamma);
93 | Wdual = dotp(u,mu) + dotp(v,nu) ...
94 | - epsilon*sum( gamma(:) );
95 | err = norm( sum(gamma,2)-mu );
96 |
97 | else % difference with previous iterate
98 |
99 | Wprimal = dotp(c,gamma) - epsilon*H(gamma) ...
100 | + rho*KL(sum(gamma,2),mu) ...
101 | + rho*KL(sum(gamma,1),nu);
102 | Wdual = -rho*KLd(u/rho,mu) - rho*KLd(v/rho,nu) ...
103 | - epsilon*sum( gamma(:) );
104 | err = norm(u(:)-u1(:), 1);
105 |
106 | end
107 |
108 | end
109 |
110 | function r = logReg(x)
111 | r = log(x+eps);
112 | end
113 |
--------------------------------------------------------------------------------
/matlab/Bin/models/matching/geom/jnfmatch_geom.m:
--------------------------------------------------------------------------------
1 | function [momentums,summary]=jnfmatch_geom(source,momentumsInit,defo,objfun,optim)
2 | % Jackknife Match shape. It computes a matching between shapes using a bfgs
3 | % optimization scheme.
4 | %
5 | % Inputs:
6 | % templateInit: is a cell array of fshapes containing the initial mean template.
7 | % momentumsInit : a cell array with momentums
8 | % funresInit : a cell array with functional residuals.
9 | % defo: is a structure containing the parameters of the deformations.
10 | % objfun: is a structure containing the parameters of attachment term.
11 | % optim: is a structure containing the parameters of the optimization procedure (here gradient descent with adaptative step)
12 | %
13 | % Outputs:
14 | % meantemplate : a cell array of fshapes containing the mean template
15 | % momentums: a cell array with momentums
16 | % funres: a cell array with functional residuals.
17 | % summary: is a structure containing various informations about the
18 | % gradient descent.
19 | %
20 | % See also : enr_tan_free, denr_tan_free, fsatlas_tan_free
21 | % Author : B. Charlier (2017)
22 |
23 |
24 | global data templateG objfunc defoc deflag templatexc templatefc
25 |
26 |
27 | %------%
28 | % Init %
29 | %------%
30 |
31 | % check data
32 | if isempty(data)
33 | error('Check that data is global variable.')
34 | end
35 | nb_obs = size(data,1); %number of observations
36 | nb_match = size(data,2); % number of shape in each observation
37 |
38 | % check template
39 | if ~iscell(source)
40 | source={source};
41 | end
42 | n = sum(cellfun(@(y) size(y.x,1),source)); %total number of points
43 | deflag = [0,cumsum(cellfun(@(y) size(y.x,1),source))];
44 | d = size(source{1}.x,2); % dimension of the ambient space
45 |
46 |
47 | templateG = cellfun(@(y) y.G,source,'uniformOutput',0);
48 | templatexc = cellfun(@(y) y.x,source,'uniformOutput',0);
49 | templatefc = cellfun(@(y) y.f,source,'uniformOutput',0);
50 |
51 | % print some informations
52 | disp_info_dimension(data,source);
53 |
54 |
55 | % check momentums
56 | if isempty(momentumsInit)
57 | momentums = zeros(d*n,1);
58 | end
59 |
60 | %-----------%
61 | % options %
62 | %-----------%
63 |
64 | list_of_variables = {'p'};
65 |
66 |
67 | % check functional residuals
68 | if ~iscell(objfun)
69 | objfun ={objfun};
70 | objfun = objfun(ones(1,size(data,2)));
71 | end
72 | objfun = set_objfun_option(objfun,source,data,list_of_variables);
73 | % compute normalization coefficients
74 | objfun = compute_coefficents_normalization(objfun,source,data);
75 |
76 | defoc = set_defo_option(defo,list_of_variables);
77 |
78 | optim = set_optim_option(optim,objfun,list_of_variables,'enr_geom');
79 |
80 | %-----------%
81 | % Call bfgs %
82 | %-----------%
83 |
84 | objfunc = objfun;
85 |
86 | tstart = tic;
87 |
88 | [momentums,summary] = perform_bfgs(optim.bfgs.enr_name,momentums,optim.bfgs);
89 |
90 | momentums = reshape(momentums,n,d);
91 |
92 | % disp informations
93 | telapsed = toc(tstart);
94 | fprintf('\nTotal number of iterations : %d in %g sec (%g sec per it)\n\n',summary.bfgs.nb_of_iterations,telapsed,telapsed/summary.bfgs.nb_of_iterations);
95 |
96 |
97 | % Summary information : save real parameters
98 | summary.parameters.defo = defoc;
99 | summary.parameters.objfun = objfun;
100 | summary.parameters.optim = optim;
101 |
102 | end
103 |
104 |
--------------------------------------------------------------------------------
/matlab/Bin/deformations/tangential/shoot_and_flow_tan.m:
--------------------------------------------------------------------------------
1 | function [points_evol,obj_evol,mom_evol] = shoot_and_flow_tan(points,mom,defo,obj)
2 | % [points_evol,obj_evol,mom_evol] = SHOOT_AND_FLOW(points_init,mom_init,defo,obj) computes the evolution of
3 | % obj under the deformation generated by the couple points/momentums via the Hamiltonian dynamics.
4 | %
5 | % Input :
6 | % points_init : initial coordinates of the points (position) in a (n x d) matrix.
7 | % mom_init : initial momentums in a (n x d) matrix.
8 | % defo : structure containing the parameters of deformations (kernel_size_mom,method,nstep,...)
9 | % obj : initial coordinate of the object to be flown (if not set, assume obj = x)
10 | %
11 | % Output
12 | % points_evol : a cell list containing evolution path of positions ( points_evol{i} is a n x d matrix and i ranges from 1 to defo_options.nstep+1)
13 | % obj_evol : a cell list containing evolution path of object ( obj_evol{i} is a n x d matrix and i ranges from 1 to defo_options.nstep+1)
14 | % mom_evol : a cell list containing evolution path of momentums ( p_evol{i} is a n x d matrix and i ranges from 1 to defo_options.nstep+1)
15 | % Author : B. Charlier (2017)
16 |
17 |
18 | [points_evol,mom_evol] = forward_tan(points,mom,defo);
19 |
20 | if nargin==4
21 | obj_evol = flow(obj,points_evol,mom_evol,defo);
22 | else
23 | obj_evol =points_evol;
24 | end
25 |
26 | end
27 |
28 |
29 | function [obj_evol] = flow(obj,x,p,defo)
30 | % computes the evolution of the obj under the flow generated by x/p.
31 |
32 | h = 1 ./ defo.nb_euler_steps;
33 |
34 | switch defo.method
35 | case 'cuda'
36 | eulerStep = @euler_cuda;
37 | case 'matlab'
38 | eulerStep = @euler_mat;
39 | case 'grid'
40 | eulerStep = @euler_grid;
41 | end
42 |
43 | obj_evol= cell(1,defo.nb_euler_steps +1);
44 | obj_evol{1} = obj;
45 |
46 | for i = 1:defo.nb_euler_steps
47 | % Midpoint method
48 | obj1 = eulerStep(x{i},p{i},obj_evol{i},defo,h/2);
49 | obj2 = eulerStep((x{i}+x{i+1})/2,(p{i} + p{i+1})/2,obj1,defo,h);
50 |
51 | obj_evol{i+1} = obj2 - obj1 + obj_evol{i};
52 | end
53 |
54 | end
55 |
56 | function [nobj] = euler_cuda(x,p,obj,defo,h)
57 | % This function implements an elementary Euler Step in cuda
58 | nobj = obj;
59 | for lam = defo.kernel_size_mom
60 | nobj = nobj + h * GaussGpuConv(obj',x',p',lam)';
61 | end
62 |
63 | end
64 |
65 | function [nobj] = euler_mat(x,p,obj,defo,h)
66 | % This function implements an elementary Euler Step in cuda
67 |
68 | [nx,d]=size(x);
69 | [ny,~]=size(obj);
70 |
71 | % Calcul de A=exp(-|x_i -x_j|^2/(lam^2))
72 | S=zeros(ny,nx);
73 | for l=1:d
74 | S=S+(repmat(obj(:,l),1,nx)-repmat(x(:,l)',ny,1)).^2;
75 | end
76 | A = rho(S,0,defo.kernel_size_mom);
77 |
78 | nobj = obj + h * A*p;
79 |
80 | end
81 |
82 | function [nobj] = euler_grid(x,p,obj,defo,h)
83 | % This function implements an elementary Euler Step in cuda
84 |
85 | %generate grid
86 | bbox.min = min([x;obj],[],1)';bbox.max= max([x;obj],[],1)';
87 | do_grad=0;do_gradgrad=0;
88 | if ~isfield(defo,'sourcegrid')
89 | newGrid =1;
90 | else
91 | newGrid = changegrid(bbox.min,bbox.max,defo.kernel_size_mom,defo.gridratio,defo.sourcegrid);
92 | end
93 |
94 | if newGrid
95 | sourcegrid = setgrid(bbox,defo.kernel_size_mom,defo.gridratio,do_grad,do_gradgrad);
96 | else
97 | sourcegrid =defo.sourcegrid;
98 | end
99 |
100 | nobj = obj;
101 | for t = 1:size(sourcegrid.pas,2)
102 | nobj = nobj + h* gridOptimNew(x',p',obj',sourcegrid.long(:,t)',sourcegrid.pas(:,t),sourcegrid.origine(:,t),sourcegrid.fft3k_d{t},0)';
103 | end
104 |
105 | end
106 |
--------------------------------------------------------------------------------
/Simple_script/pytorch_memory_overflow.py:
--------------------------------------------------------------------------------
1 | NPOINTS = 10000
2 |
3 | # Variable definitions, etc. for this minimal working example. ----------------------------------
4 | # You don't need to read this to understand the bottlneck.
5 | # Import the relevant tools
6 | import numpy as np # standard array library
7 | import torch
8 | from torch.autograd import Variable
9 |
10 | use_cuda = torch.cuda.is_available()
11 | dtype = torch.cuda.FloatTensor if use_cuda else torch.FloatTensor
12 |
13 | # Computation of the Kernel Matrix :
14 | def _squared_distances(x, y) :
15 | "Returns the matrix of |x_i-y_j|^2."
16 | x_col = x.unsqueeze(1) ; y_lin = y.unsqueeze(0)
17 | return torch.sum( (x_col - y_lin)**2 , 2 )
18 | def _k(x, y, s) :
19 | "Returns the matrix of k(x_i,y_j)."
20 | sq = _squared_distances(x, y) / (s**2)
21 | return torch.exp( -sq )
22 |
23 |
24 | t = np.linspace(0, 2*np.pi, NPOINTS)
25 | weights = np.ones( (NPOINTS,) ) /NPOINTS
26 |
27 | X = Variable(torch.from_numpy( np.vstack([np.cos(t), np.sin(t)]).T ).type(dtype), requires_grad=True )
28 | Y = Variable(torch.from_numpy( np.vstack([np.cos(t)+1, np.sin(t)]).T ).type(dtype), requires_grad=True )
29 | P = Variable(torch.from_numpy( weights ).type(dtype), requires_grad=False)
30 | Q = Variable(torch.from_numpy( weights ).type(dtype), requires_grad=False)
31 |
32 | # The meaningful part of the program, aka "The Sinkhorn Algorithm" ------------------------------
33 | # Iterating this simple "for" loop is an efficient way of finding the optimal scaling
34 | # factors A and B such that Gamma = diag(A)*K*diag(B) has :
35 | # - row-wise sums equal to P
36 | # - column-wise sums equal to Q
37 | # Since the publication of the milestone paper :
38 | # "Sinkhorn Distances: Lightspeed Computation of Optimal Transport", Marco Cuturi (2013),
39 | # who proposed to use this scheme to compute Optimal Transport plans (Monge-Kantorovitch theory),
40 | # this algorithm has generated a considerable interest in some applied maths and
41 | # image registration communities.
42 | #
43 | # This algorithm showcases the typical features of state-of-the-art methods in the field
44 | # of medical image registration (major conference on the topic : MICCAI) :
45 | #
46 | # - "small" datasets, but each image has a large memory footprint
47 | # (say, 256x256x256 images, or >50,000 triangles for a segmented brain surface).
48 | #
49 | # - "diffeomorphic" (that is, tearing-free) registration algorithms, which iterate a simple
50 | # linear algebra operation on the data.
51 | # Here, we iterate a matrix-vector product + pointwise division,
52 | # but other pipelines will flow a vector field through time [t, t+dt] using an ODE step
53 | # such as Euler (simplistic) or Runge-Kutta, etc.
54 | #
55 | # - output is a matching score, whose gradient shall be used to update the registration.
56 | #
57 |
58 | K = _k( X, Y, .5) # Gaussian Kernel matrix (Npoints-by-Npoints), regularization parameter = .5
59 | A = Variable(torch.ones( NPOINTS ).type(dtype), requires_grad = False)
60 | B = Variable(torch.ones( NPOINTS ).type(dtype), requires_grad = False)
61 |
62 | for it in range(1000) :
63 | A = P / (K @ B)
64 | B = Q / (K.t() @ A)
65 |
66 | Gamma = (A.unsqueeze(1) @ B.unsqueeze(0)) * K # Gamma_ij = a_i * b_j * k( x_i , y_j )
67 | Cost = torch.sum( Gamma * _squared_distances(X,Y) )
68 | # The above cost can be used as a distance measure between the unlabeled points clouds X and Y.
69 | print(Cost)
70 |
71 | # In practice, target Y is fixed and we're looking for the X-gradient of the Cost.
72 | dX = torch.autograd.grad( Cost , X )
73 | print(dX)
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/matlab/Bin/models/matching/tan/jnfmatch_tan.m:
--------------------------------------------------------------------------------
1 | function [momentums,summary]=jnfmatch_tan(templateInit,momentumsInit,funresInit,defo,objfun,optim)
2 | % Jackknife Mean fshape estimation in the 'tangential' and 'free' framework.
3 | % This is a gradient descent for cost function computed in enr_tan_free.
4 | %
5 | % Inputs:
6 | % templateInit: is a cell array of fshapes containing the initial mean template.
7 | % momentumsInit : a cell array with momentums
8 | % funresInit : a cell array with functional residuals.
9 | % defo: is a structure containing the parameters of the deformations.
10 | % objfun: is a structure containing the parameters of attachment term.
11 | % optim: is a structure containing the parameters of the optimization procedure (here gradient descent with adaptative step)
12 | %
13 | % Outputs:
14 | % meantemplate : a cell array of fshapes containing the mean template
15 | % momentums: a cell array with momentums
16 | % funres: a cell array with functional residuals.
17 | % summary: is a structure containing various informations about the
18 | % gradient descent.
19 | %
20 | % See also : enr_tan_free, denr_tan_free, fsatlas_tan_free
21 | % Author : B. Charlier (2017)
22 |
23 |
24 | global data templateG objfunc defoc deflag templatexc templatefc
25 |
26 | %------%
27 | % Init %
28 | %------%
29 |
30 | % check data
31 | if isempty(data)
32 | error('Check that data is global variable.')
33 | end
34 | nb_obs = size(data,1); %number of observations
35 | nb_match = size(data,2); % number of shape in each observation
36 |
37 | % check template
38 | if ~iscell(templateInit)
39 | templateInit={templateInit};
40 | end
41 |
42 | deflag = [0,cumsum(cellfun(@(y) size(y.x,1),templateInit))];
43 | n = deflag(end);
44 | d = size(templateInit{1}.x,2); % dimension of the ambient space
45 |
46 | templateG = cellfun(@(y) y.G,templateInit,'uniformOutput',0);
47 | templatexc = cellfun(@(y) y.x,templateInit,'uniformOutput',0);
48 | templatefc = cellfun(@(y) y.f,templateInit,'uniformOutput',0);
49 |
50 |
51 | % print some informations
52 | disp_info_dimension(data,templateInit);
53 |
54 | % check momentums
55 | if isempty(momentumsInit)
56 | momentums = zeros(d*n,1);
57 | else
58 | momentums = momentumsInit;
59 | end
60 |
61 |
62 | %-----------%
63 | % options %
64 | %-----------%
65 |
66 | list_of_variables = {'p','fr'};
67 |
68 | if ~iscell(objfun)
69 | objfun ={objfun};
70 | objfun = objfun(ones(1,size(data,2)));
71 | end
72 | objfun = set_objfun_option(objfun,templateInit,data,list_of_variables);
73 | % compute normalization coefficients
74 | objfun = compute_coefficents_normalization(objfun,templateInit,data);
75 |
76 | defoc = set_defo_option(defo,list_of_variables);
77 |
78 | optim = set_optim_option(optim,objfun,list_of_variables,'enr_match_tan');
79 |
80 |
81 | %------------------%
82 | % BFGS %
83 | %------------------%
84 |
85 | tstart = tic;
86 | objfunc = objfun;
87 |
88 | [mom,summary] = perform_bfgs(optim.bfgs.enr_name,momentums,optim.bfgs);
89 |
90 | momentums = reshape(mom(1:n*d),n,d);
91 |
92 |
93 | % disp informations
94 | telapsed = toc(tstart);
95 | fprintf('\nTotal number of iterations : %d in %g sec (%g sec per it)\n\n',summary.bfgs.nb_of_iterations,telapsed,telapsed/summary.bfgs.nb_of_iterations);
96 |
97 |
98 | % Prepare Output
99 | meantemplate = cell(1,nb_match);
100 | for l=1:nb_match
101 | meantemplate{1,l} = struct('x',templatexc{l},'f',templatefc{l},'G',templateG{l});
102 | end
103 |
104 | % Summary information : save real parameters
105 | summary.parameters.defo = defoc;
106 | summary.parameters.objfun = objfun;
107 | summary.parameters.optim = optim;
108 |
109 | end
110 |
111 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/setdefaultshanso.m:
--------------------------------------------------------------------------------
1 | function options = setdefaultshanso(pars, options)
2 | % set HANSO defaults that are not set by setdefaults
3 | % called only by hanso
4 | %
5 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
6 | % with a subject header containing the string "hanso".
7 | % Version 2.2, 2016, see GPL license info below.
8 |
9 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 | %% HANSO 2.2 Copyright (C) 2010 Michael Overton
11 | %% This program is free software: you can redistribute it and/or modify
12 | %% it under the terms of the GNU General Public License as published by
13 | %% the Free Software Foundation, either version 3 of the License, or
14 | %% (at your option) any later version.
15 | %%
16 | %% This program is distributed in the hope that it will be useful,
17 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | %% GNU General Public License for more details.
20 | %%
21 | %% You should have received a copy of the GNU General Public License
22 | %% along with this program. If not, see .
23 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24 |
25 | % this is also in setdefaults, but setdefaults_hanso is called first
26 | % so we need it here too, as pars.nvar is referenced below
27 | if ~isfield(pars, 'nvar')
28 | error('hanso: input "pars" must have a field "nvar" (number of variables)')
29 | elseif ~isposint(pars.nvar)
30 | error('hanso: input "pars.nvar" (number of variables) must be a positive integer')
31 | end
32 | nvar = pars.nvar;
33 | % the following isn't needed since it's in setdefaults, but may as well
34 | % include it so error message says "hanso"
35 | if ~isfield(pars, 'fgname')
36 | error('hanso: input "pars" must have a field "fgname" (name of m-file computing function and gradient)')
37 | end
38 | if ~isfield(options, 'normtol')
39 | options.normtol = 1e-4;
40 | elseif ~isposreal(options.normtol)
41 | error('hanso: input "options.normtol" must be a positive scalar')
42 | end
43 | if ~isfield(options, 'evaldist')
44 | options.evaldist = 1e-4;
45 | elseif ~isposreal(options.evaldist)
46 | error('hanso: input "options.evaldist" must be a positive scalar')
47 | end
48 | if ~isfield(options, 'samprad')
49 | % default is NO gradient sampling as of HANSO 2.2: too expensive
50 | options.samprad = []; % no gradient sampling
51 | else
52 | % check sampling radii are positive and decreasing
53 | if any(sort(options.samprad,'descend') ~= options.samprad) || any(options.samprad <= 0)
54 | error('options.samprad must have decreasing positive entries')
55 | end
56 | end
57 | % the following are from HANSO 1.0, 1.01
58 | % for backwards compatibility:
59 | if isfield(options, 'phasemaxit')
60 | if ~isfield(options, 'prtlevel') | options.prtlevel > 0
61 | fprintf('hanso: "options.phasemaxit" is no longer used in HANSO 2.0\n')
62 | fprintf(' setting "options.maxit" to "options.phasemaxit(1)"\n\n')
63 | end
64 | options.maxit = options.phasemaxit(1); % for BFGS (ignore the others)
65 | end
66 | if isfield(options, 'phasenum')
67 | if ~isfield(options, 'prtlevel') | options.prtlevel > 0
68 | fprintf('hanso: "options.phasenum" is no longer used in HANSO 2.0\n')
69 | fprintf(' number of BFGS starting points is either 10 or number of columns in "options.x0"\n')
70 | fprintf(' number of gradient sampling phases is 3, or 0 if pars.nvar > 100, or number of entries in options.gradsamp\n\n')
71 | end
72 | % ignore the number of phases specified and use defaults
73 | end
--------------------------------------------------------------------------------
/matlab/Bin/models/atlas/tan_free/denr_tan_free.m:
--------------------------------------------------------------------------------
1 | function [dx,dp] = denr_tan_free(templatex,momentum)
2 | %[dx,df,dp,dfunres] = DENR_TAN_FREE(templatex,momentums) computes the gradient
3 | % of the energy functional coded in enr_tan_free.
4 | %
5 | % Input :
6 | % templatex : cell with the points position
7 | % momentums : cell with the momentums attached to each point
8 | %
9 | % Output :
10 | % dx : gradient wrt x
11 | % dp : gradient wrt momentums
12 | % Author : B. Charlier (2017)
13 |
14 | global data objfunc defoc deflag templateG
15 |
16 | [nb_obs,nb_match] = size(data);
17 | nlist = diff(deflag); % number of point in each shape
18 |
19 | dx = cell(1,nb_match);
20 | dp = cell(nb_obs,1);
21 |
22 | templatextotal = cell2mat(templatex'); [n,d] = size(templatextotal);
23 |
24 | %---------------------------%
25 | % gradient of penalization %
26 | %---------------------------%
27 |
28 | for l= 1:nb_match
29 | dx{l} = zeros(size(templatex{1,l}));
30 | end
31 |
32 |
33 | dX = cell(nb_obs,1);
34 |
35 | for sh_ind=1:nb_obs %parallel computations
36 |
37 | %sliced variable in parfor
38 | datac = data(sh_ind,:);
39 | momentumc = momentum{sh_ind};
40 |
41 | %---------------------%
42 | % gradient dmatchterm %
43 | %---------------------%
44 |
45 | [shootingx,shootingmom]=forward_tan(templatextotal,momentum{sh_ind},defoc);
46 |
47 | dxfinalg= cell(1,nb_match);
48 | dfg= cell(1,nb_match);
49 | for l = 1:nb_match
50 | %load the shooted fshape (== final position)
51 | templatefinal= struct('x',shootingx{end}(deflag(l)+1:deflag(l+1),:),'f',zeros(size(shootingx{end}(deflag(l)+1:deflag(l+1),:),1),1),'G',templateG{l});
52 | %load current target
53 | targetc = struct('x',datac{l}.x,'G',datac{l}.G);
54 | % gradient of the data attachment term wrt the final position
55 | [dxfinalg{l}]=dmatchterm(templatefinal,targetc,objfunc{l});
56 | dxfinalg{l} = dxfinalg{l} .*objfunc{l}.weight_coef_dist ;
57 |
58 | %save template final
59 | export_fshape_vtk(templatefinal,['./',num2str(l),'-results_iter_c.vtk']);
60 | end
61 |
62 | %at the final position the derivative wrt the moment is 0
63 | dpfinalg=zeros(n,d);
64 | % integrate backward the adjoint system to get the gradient at init
65 | [dxg,dpg]=backward_tan(cell2mat(dxfinalg'),dpfinalg,struct('x',{shootingx},'mom',{shootingmom}),defoc);
66 |
67 | %----------------------------%
68 | % gradient of the prior part %
69 | %----------------------------%
70 |
71 | [dxu,dpu] = dnormRkhsV(templatextotal,momentumc,defoc);
72 |
73 | dXt = cell(1,nb_match);
74 |
75 | for l = 1:nb_match
76 |
77 | % Normalization in order to get a gradient scale invariant
78 | dxg(deflag(l)+1:deflag(l+1),:)=dxg(deflag(l)+1:deflag(l+1),:).*objfunc{l}.dgxC;
79 | dpg(deflag(l)+1:deflag(l+1),:)=dpg(deflag(l)+1:deflag(l+1),:).*objfunc{l}.dgxC;
80 | dfg{l}=dfg{l}.*objfunc{l}.dgfC;
81 |
82 | %-----------------------------------%
83 | % gradient of penalization (funres) %
84 | %-----------------------------------%
85 | dXt{l} = objfunc{1}.weight_coef_pen_p * dxu(deflag(l)+1:deflag(l+1),:) + dxg(deflag(l)+1:deflag(l+1),:);
86 |
87 | end
88 |
89 | dp{sh_ind} = objfunc{1}.weight_coef_pen_p *dpu +dpg;
90 | dX{sh_ind} = dXt;
91 |
92 | end
93 |
94 | for i= 1:nb_obs
95 |
96 | dx = cellfun(@(y,z) y+z,dx,dX{i},'uniformoutput',0);
97 |
98 | end
99 |
100 |
101 |
102 | for l=1:nb_match
103 |
104 | % Normalization of the gradient
105 | dx{l}=dx{l}*nlist(l);
106 |
107 |
108 | end
109 |
110 | dp= cellfun(@(y) y/n,dp,'UniformOutput',0);
111 |
112 | end
113 |
--------------------------------------------------------------------------------
/matlab/Bin/deformations/tangential/ddHrtP_tan.m:
--------------------------------------------------------------------------------
1 | function [dPx,dPp] = ddHrtP_tan(x,p,Px,Pp,defo)
2 | % [dPx,dPp] = DDhRTP(x,p,Px,Pp,defo) computes the adjoints Hamiltonian
3 | % system usingthe methods given in defo.method.
4 | %
5 | % Inputs :
6 | % x: is a (n x d) matrix containing the points.
7 | % p: is a (n x d) matrix containing the momentums.
8 | % Px : is a (n x d) matrix (adjoint variable of x).
9 | % Pp : is a (n x d) matrix (adjoint variable of p ).
10 | % defo : structure containing the deformations parameters
11 | %
12 | % Outputs
13 | % dPx : (n x d) matrix containing the update of Px.
14 | % dPp :(n x d) matrix containing the update of Pp.
15 | %
16 | % See also : forward_tan, backward_tan, dHr_tan
17 | % Author : B. Charlier (2017)
18 |
19 | switch defo.method
20 | case 'cuda'
21 | DFTP = @dftP_cuda;
22 | otherwise
23 | DFTP = @dftP_mat;
24 | end
25 |
26 | [dPx,dPp] = DFTP(x,p,Px,Pp,defo);
27 |
28 | end
29 |
30 |
31 |
32 | function [dPx,dPp]=dftP_cuda(x,p,Px,Pp,defo)
33 | % Basic Euler step for the tangential Hamiltonian flow \deltaX_H using cuda mex file.
34 | %
35 | % Inputs :
36 | % x: is a (n x d) matrix containing the points.
37 | % p: is a (n x d) matrix containing the momentums.
38 | % Px : is a (n x d) matrix (adjoint variable x).
39 | % Pp : is a (n x d) matrix (adjoint variable momentums ).
40 | % defo : structure containing the deformations parameters
41 | %
42 | % Outputs
43 | % dPx : (n x d) matrix containing the update of Px.
44 | % dPp :(n x d) matrix containing the update of Pp.
45 |
46 | dPp = zeros(size(Pp));
47 | dPx = zeros(size(Px));
48 |
49 | for lam = defo.kernel_size_mom
50 |
51 | dPx = dPx - GaussGpuGradConv(p',x',Px',lam)'+ dxxHrP2(Pp',x',p',lam)';
52 | dPp = dPp - GaussGpuConv(x',x',Px',lam)'+ dpxHrP2(Pp',x',p',lam)';
53 |
54 | end
55 |
56 | end
57 |
58 |
59 | function [dPx,dPp]=dftP_mat(x,p,Px,Pp,defo)
60 | %Compute the [dPx;dPp] = dft([x;p]) * [Px;Pp] exactly with matlab.
61 | %
62 | % Inputs :
63 | % x: is a (n x d) matrix containing the points.
64 | % p: is a (n x d) matrix containing the momentums.
65 | % Px : is a (n x d) matrix (adjoint variable x).
66 | % Pp : is a (n x d) matrix (adjoint variable momentums ).
67 | % defo : structure containing the deformations parameters
68 | %
69 | % Outputs
70 | % dPx : (n x d) matrix containing the update of Px.
71 | % dPp :(n x d) matrix containing the update of Pp.
72 |
73 |
74 | lam=defo.kernel_size_mom;
75 | [n,d]=size(x);
76 |
77 | dPp = zeros(size(Pp));
78 | dPx = zeros(size(Px));
79 |
80 | % Calcul de A=exp(-|x_i -x_j|^2/(lam^2))
81 | S=zeros(n);
82 | for l=1:d
83 | S=S+(repmat(x(:,l),1,n)-repmat(x(:,l)',n,1)).^2;
84 | end
85 | A=rho(S,0,lam);
86 | B=rho(S,1,lam);
87 | C=rho(S,2,lam);
88 |
89 | for r=1:d
90 | dPxr=zeros(n,1);
91 | dPpr=-A*Px(:,r); % [\partial_{p_i}\partial_{p_j} H_r ] * Px
92 | % Computation of Br
93 | Br=2*(repmat(x(:,r),1,n)-repmat(x(:,r)',n,1)).*B;
94 |
95 | for s=1:d
96 | Bs=2*(repmat(x(:,s),1,n)-repmat(x(:,s)',n,1)).*B;
97 | dPpr=dPpr+(Bs*p(:,r)).*Pp(:,s)-Bs*(p(:,r).*Pp(:,s));% ([Diag(\partial_{x_i}\partial_{p_i} H_r)] + [\partial_{x_i} \partial_{p_j} H_r])* Pp
98 |
99 | dPxr=dPxr-(p(:,s).*(Br*Px(:,s))+Px(:,s).*(Br*p(:,s)));
100 |
101 | Crs=4*(repmat(x(:,r),1,n)-repmat(x(:,r)',n,1))...
102 | .*(repmat(x(:,s),1,n)-repmat(x(:,s)',n,1)).*C;
103 | if s==r
104 | Crs=Crs+2*B;
105 | end
106 |
107 | for l=1:d
108 | dPxr=dPxr+p(:,l).*...
109 | ((Crs*p(:,l)).*Pp(:,s)-Crs*(p(:,l).*Pp(:,s)));
110 | end
111 | end
112 | dPx(:,r)=dPxr;
113 | dPp(:,r)=dPpr;
114 | end
115 |
116 |
117 | end
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/wasserstein/dfshape_wasserstein_distance.m:
--------------------------------------------------------------------------------
1 | function [dxg]= dfshape_wasserstein_distance(fs1,fs2,objfun)
2 | % DFSHAPE_KERNEL_DISTANCE(templatefinal,target,objfun) computes the derivatives of the kernel based
3 | % distances between fshapes.
4 | %
5 | % \sum_i\sum_j K_signal(f_i-g_j)^2) K_geom(-norm(x_i-y_j)^2) K_tan(angle(V_i,W_j))
6 | %
7 | % Possible method are 'cuda' or 'matlab'.
8 | %
9 | % Inputs:
10 | % templatefinal : "fshape structure" containing the shooted template
11 | % target : "fshape structure" containing the target.
12 | % objfun : is a structure containing the data attachment term parameters (mandatory fields are : 'kernel_geom', 'kernel_signal' and 'kernel_grass' and the associated bandwidth)
13 | % Output
14 | % dxg : a matrix of the size of templatefinal.x.
15 | % dfg : a matrix of the size of templatefinal.f.
16 | % Author : B. Charlier (2017)
17 |
18 |
19 |
20 | %------------------------%
21 | % Start the chain's rule %
22 | %------------------------%
23 |
24 | d_ambient_space=size(fs1.x,2);
25 | m=size(fs1.G,2)-1;
26 |
27 | % discretize the fshapes
28 | [center_faceX,normalsX]=fcatoms(fs1.x,fs1.G);
29 | [center_faceY,normalsY]=fcatoms(fs2.x,fs2.G);
30 |
31 | options = objfun.wasserstein_distance;
32 |
33 |
34 | if min(m, d_ambient_space-m) ==0 % for points clouds or simplexes dim or codim == 0 : some simplifications occurs
35 |
36 | x=center_faceX';
37 | y=center_faceY';
38 |
39 | mu = fs1.G;
40 | nu = fs2.G;
41 |
42 | %only needed for matlab version. See built-in function for cuda version.
43 | nablaC = @(x,y)repmat(x,[1 1 size(y,2)]) - ...
44 | repmat(reshape(y,[size(y,1) 1 size(y,2)]),[1 size(x,2)]);
45 | C = @(x,y)squeeze( sum(nablaC(x,y).^2)/2 );% C(x,y)=1/2*|x-y|^2
46 |
47 | elseif min(m,d_ambient_space-m) ==1 % for curves or surface dim or codim ==1;
48 |
49 | x=[center_faceX';normalsX'];
50 | y=[center_faceY';normalsY'];
51 |
52 | mu = area(fs1.x,fs1.G);
53 | nu = area(fs2.x,fs2.G);
54 |
55 | %only needed for matlab version. See built-in function for cuda version.
56 | C = @(X,Y) cost_varifold(X,Y,options.weight_cost_varifold);
57 | nablaC = @(X,Y) dcost_varifold(X,Y,options.weight_cost_varifold);
58 |
59 | end
60 |
61 |
62 | switch options.method
63 | case 'matlab'
64 |
65 | [u,~,gamma,~,~,~] = sinkhorn_log(mu,nu,C(x,y),options.epsilon,options);
66 |
67 | % gradient with respect to positions
68 | DXg = sum( nablaC(x,y) .*...
69 | repmat(reshape(gamma, [1,size(mu,1),size(nu,1)]), [size(x,1),1,1]), ...
70 | 3 );
71 | case 'cuda'
72 |
73 | [u,DXg] = dsinkhorn_log_cuda(mu,nu,x,y,options.epsilon,options,d_ambient_space);
74 | DXg = DXg';
75 |
76 | end
77 |
78 | % gradient with respect to the weights
79 | if options.rho==Inf% balanced
80 | Dmug = u;
81 | else% unbalanced
82 | Dmug = -options.rho*(exp(-u/options.rho)-1);
83 | end
84 |
85 | % gradient with respect to the normal and centerFace
86 | if min(m,d_ambient_space-m) == 0
87 |
88 | Dcenter_faceXg = DXg(1:d_ambient_space,:)';
89 | DnormalsXg = zeros(size(normalsX));
90 |
91 |
92 | elseif min(m,d_ambient_space-m) ==1
93 |
94 | norm_normalsX = sqrt(sum(normalsX .^2,2));
95 | unit_normalsX = normalsX ./ repmat(norm_normalsX,1,d_ambient_space);
96 |
97 | Dcenter_faceXg = DXg(1:d_ambient_space,:)';
98 | DnormalsXg = repmat(Dmug,1,d_ambient_space) .*unit_normalsX+ DXg(d_ambient_space+1:2*d_ambient_space,:)'/2;
99 |
100 |
101 | end
102 |
103 |
104 | %-------------------------%
105 | % End of the chain's rule %
106 | %-------------------------%
107 |
108 | [dxg]= chain_rule(fs1.x,fs1.G,Dcenter_faceXg,DnormalsXg);
109 |
110 |
111 | end
112 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/io/anim3D.py:
--------------------------------------------------------------------------------
1 | # We use a slightly hacked version of the plot.ly js/python library
2 | lddmm_python = __import__(__name__.split('.')[0])
3 | print(lddmm_python)
4 | import lddmm_python.lib.plotly as plotly
5 |
6 | import re
7 | from pylab import *
8 | from IPython.html.widgets import interact
9 | from IPython.display import HTML, display
10 | from pprint import pprint
11 | import json
12 |
13 | from plotly.tools import FigureFactory as FF
14 | from plotly import utils, graph_objs
15 |
16 | from .my_iplot import my_iplot
17 | from .read_vtk import ReadVTK
18 |
19 |
20 | class Anim3d :
21 | def __init__(self, filenames):
22 | self.frames = list(ReadVTK(f) for f in filenames)
23 | self.current_frame = list(range(len(self.frames)))
24 | print(self.current_frame)
25 | def get_frame(self, w) :
26 | points = array(self.frames[w][0])
27 | """update = dict(
28 | x = [points[:,2]],
29 | y = [points[:,0]],
30 | z = [points[:,1]]
31 | )"""
32 | update1 = dict(
33 | visible = False
34 | )
35 | update2 = dict(
36 | visible = True
37 | )
38 | list1 = str(self.current_frame)
39 | self.current_frame = [w]
40 | list2 = str(self.current_frame)
41 | return ([update1, update2], [list1, list2])
42 | def show(self, title):
43 | figs = []
44 | for ind_f in range(len(self.frames)) :
45 | (points, triangles, signals) = self.frames[ind_f]
46 | points = array(points)
47 | triangles = array(triangles)
48 | signals = array(signals)
49 | signals_per_triangle = list( (signals[triangles[i,0]] + signals[triangles[i,1]] + signals[triangles[i,2]]) / 3
50 | for i in range(triangles.shape[0]) )
51 | signals_per_triangle[0] += 0.001
52 | # Validate colormap
53 | my_colormap = FF._validate_colors("Portland", 'tuple')
54 | newdata = FF._trisurf(x=points[:,2], y=points[:,0], z=points[:,1],
55 | colormap=my_colormap,
56 | simplices=triangles,
57 | color_func = signals_per_triangle,
58 | plot_edges=False,
59 | edges_color = 'rgb(50, 50, 50)',
60 | show_colorbar = False,
61 | data_list = True)
62 | figs += newdata
63 | axis = dict(
64 | showbackground=True,
65 | backgroundcolor='rgb(230, 230, 230)',
66 | gridcolor='rgb(255, 255, 255)',
67 | zerolinecolor='rgb(255, 255, 255)'
68 | )
69 | xaxis = axis.copy()
70 | xaxis['range'] = [-0.08,0.09]
71 | yaxis = axis.copy()
72 | yaxis['range'] = [-0.11,0.05]
73 | zaxis = axis.copy()
74 | zaxis['range'] = [0.02,0.18]
75 | aspectratio=dict(x=1, y=1, z=1)
76 | layout = graph_objs.Layout(
77 | title=title,
78 | width='100%',
79 | height= 800,
80 | scene=graph_objs.Scene(
81 | xaxis=graph_objs.XAxis(xaxis),
82 | yaxis=graph_objs.YAxis(yaxis),
83 | zaxis=graph_objs.ZAxis(zaxis),
84 | aspectratio=dict(
85 | x=aspectratio['x'],
86 | y=aspectratio['y'],
87 | z=aspectratio['z']),
88 | )
89 | )
90 |
91 | return my_iplot(graph_objs.Figure( data = figs, layout=layout))
92 | def slider(self, div_id) :
93 | #div_id = self.show(*args, **kwargs)
94 |
95 | def change_frame(w) :
96 | (updates, indices) = self.get_frame(w-1)
97 | script = ''
98 | for i in range(len(updates)) :
99 | jupdate = json.dumps(updates[i], cls=utils.PlotlyJSONEncoder)
100 | #pprint(jupdate)
101 | script = script \
102 | + 'Plotly.restyle("{id}", {update}, [{index}]);'.format(
103 | id=div_id,
104 | update=jupdate, index = indices[i][1:-1])
105 | #print(script)
106 | update_str = (
107 | ''
108 | ''
113 | '').format(script=script)
114 | display(HTML(update_str))
115 | interact((lambda frame : change_frame(frame)), frame=(1,len(self.frames)))
116 |
117 |
118 |
--------------------------------------------------------------------------------
/matlab/Bin/norms/shape/chain_rule.m:
--------------------------------------------------------------------------------
1 | function [dxg2]=chain_rule(x,tri,DXg,DXig)
2 | %
3 | % Computation of the gradient with respect to x by distributing the previous gradients
4 | % on points of the initial shape. (Chain's rule). There is two versions of the same
5 | % code somewhat equivalent : one using matlab for loop (that is not so bad
6 | % due to JIT precompilation process) and one using built in matlab function
7 | % accumarray.
8 | %
9 | % Input:
10 | % x: list of vertices (n x d matrix)
11 | % G: list of edges (T x M matrix)
12 | % DXg: derivative wrt X (center of the cells: T x d matrix)
13 | % DXig: derivative wrt Xi (p-vectors: T x d matrix)
14 | % Dtfg: derivative wrt tf (signal at center of the cells: T x1 colunm vector)
15 | %
16 | % Output:
17 | % dxg: derivative wrt x (n x d matrix)
18 | % dfg: derivative wrt f (n x 1 colunm vector)
19 | % Author : B. Charlier (2017)
20 |
21 |
22 |
23 | [nx,d]=size(x);
24 | [~,M] = size(tri);
25 |
26 | if M==1 % point cloud case chain's rule stops here
27 |
28 | dxg2 = DXg;
29 | return
30 | end
31 |
32 |
33 |
34 | if (d==2)
35 | U2 = [accumarray(tri(:),repmat(DXg(:,1),M,1),[nx,1],[],0),...
36 | accumarray(tri(:),repmat(DXg(:,2),M,1),[nx,1],[],0)] / M;
37 | elseif (d==3)
38 | U2 = [accumarray(tri(:),repmat(DXg(:,1),M,1),[nx,1],[],0),...
39 | accumarray(tri(:),repmat(DXg(:,2),M,1),[nx,1],[],0),...
40 | accumarray(tri(:),repmat(DXg(:,3),M,1),[nx,1],[],0)] / M;
41 | end
42 |
43 |
44 | if (M==2) % curve case
45 | if (d==2)
46 | dxg2 = U2 + [accumarray(tri(:),[-DXig(:,1);DXig(:,1)] ,[nx,1],[],0),...
47 | accumarray(tri(:),[-DXig(:,2);DXig(:,2)] ,[nx,1],[],0) ];
48 | elseif (d==3)
49 | dxg2 = U2 + [accumarray(tri(:),[-DXig(:,1);DXig(:,1)] ,[nx,1],[],0),...
50 | accumarray(tri(:),[-DXig(:,2);DXig(:,2)] ,[nx,1],[],0),...
51 | accumarray(tri(:),[-DXig(:,3);DXig(:,3)] ,[nx,1],[],0) ];
52 | end
53 |
54 | elseif (M==3) && (d==3) % surface case
55 |
56 | Xa=x(tri(:,1),:);
57 | Xb=x(tri(:,2),:);
58 | Xc=x(tri(:,3),:);
59 |
60 |
61 | [dU1,dU2,dU3,dV1,dV2,dV3] = dcross((Xb-Xa),(Xc-Xa),DXig/2);
62 |
63 | dxg2 = U2 + [accumarray(tri(:),[-dU1-dV1;+dU1 ;+dV1 ],[nx,1],[],0),...
64 | accumarray(tri(:),[-dU2-dV2;+dU2 ;+dV2 ],[nx,1],[],0),...
65 | accumarray(tri(:),[-dU3-dV3;+dU3 ;+dV3 ],[nx,1],[],0)];
66 |
67 | elseif (M==4) && (d==3) % simplexes case
68 |
69 | Xa=x(tri(:,1),:);
70 | Xb=x(tri(:,2),:);
71 | Xc=x(tri(:,3),:);
72 | Xd=x(tri(:,4),:);
73 |
74 | u=(Xb-Xa);v=(Xc-Xa);w=(Xd-Xa);
75 |
76 | %[dU1,dU2,dU3,dV1,dV2,dV3,dW1,dW2,dW3] = dcrosss(u,v,w,H);
77 | H = DXig/6;
78 |
79 | dU1 = ( v(:,2) .* w(:,3) - v(:,3) .* w(:,2) ).* H;
80 | dU2 = ( v(:,3) .* w(:,1) - v(:,1) .* w(:,3) ).* H;
81 | dU3 = ( v(:,1) .* w(:,2) - v(:,2) .* w(:,1) ).* H;
82 |
83 | dV1 = ( w(:,2) .* u(:,3) - w(:,3) .* u(:,2) ).* H;
84 | dV2 = ( w(:,3) .* u(:,1) - w(:,1) .* u(:,3) ).* H;
85 | dV3 = ( w(:,1) .* u(:,2) - w(:,2) .* u(:,1) ).* H;
86 |
87 | dW1 = ( u(:,2) .* v(:,3) - u(:,3) .* v(:,2) ).* H;
88 | dW2 = ( u(:,3) .* v(:,1) - u(:,1) .* v(:,3) ).* H;
89 | dW3 = ( u(:,1) .* v(:,2) - u(:,2) .* v(:,1) ).* H;
90 |
91 |
92 |
93 | dxg2 = U2 + [accumarray(tri(:),[-dU1-dV1-dW1 ;+dU1 ;+dV1 ; dW1],[nx,1],[],0),...
94 | accumarray(tri(:),[-dU2-dV2-dW2 ;+dU2 ;+dV2 ; dW2],[nx,1],[],0),...
95 | accumarray(tri(:),[-dU3-dV3-dW3 ;+dU3 ;+dV3 ; dW3],[nx,1],[],0)];
96 |
97 |
98 |
99 | elseif (M==3) && (d==2) % simplexes case
100 |
101 | Xa=x(tri(:,1),:);
102 | Xb=x(tri(:,2),:);
103 | Xc=x(tri(:,3),:);
104 |
105 | U=(Xb-Xa);V=(Xc-Xa);
106 |
107 | H = DXig/2;
108 |
109 | dU1 = V(:,2) .* H;
110 | dU2 = -V(:,1) .* H;
111 |
112 | dV1 = -U(:,2) .* H ;
113 | dV2 = U(:,1) .* H;
114 |
115 | dxg2 = U2 + [accumarray(tri(:),[-dU1-dV1;+dU1 ;+dV1 ],[nx,1],[],0)...
116 | accumarray(tri(:),[-dU2-dV2;+dU2 ;+dV2 ],[nx,1],[],0)];
117 |
118 | end
119 |
120 | end
121 |
--------------------------------------------------------------------------------
/Pytorch/data_attachment.py:
--------------------------------------------------------------------------------
1 | # Import the relevant tools
2 | import time # to measure performance
3 | import numpy as np # standard array library
4 | import torch
5 | from torch.autograd import Variable
6 | import torch.optim as optim
7 |
8 | # No need for a ~/.theanorc file anymore !
9 | use_cuda = torch.cuda.is_available()
10 | dtype = torch.cuda.FloatTensor if use_cuda else torch.FloatTensor
11 | dtypeint = torch.cuda.LongTensor if use_cuda else torch.LongTensor
12 |
13 | from kernel import _k, _cross_kernels, _squared_distances
14 |
15 | # Part 3 : Data attachment ======================================================================
16 |
17 | def _kernel_matching(q1_x, q1_mu, xt_x, xt_mu, radius) :
18 | """
19 | Given two measures q1 and xt represented by locations/weights arrays,
20 | outputs a kernel-fidelity term and an empty 'info' array.
21 | """
22 | K_qq, K_qx, K_xx = _cross_kernels(q1_x, xt_x, radius)
23 | cost = .5 * ( torch.sum(K_qq * torch.ger(q1_mu,q1_mu)) \
24 | + torch.sum(K_xx * torch.ger(xt_mu,xt_mu)) \
25 | -2*torch.sum(K_qx * torch.ger(q1_mu,xt_mu)) )
26 |
27 | # Info = the 2D graph of the blurred distance function
28 | # Increase res if you want to get nice smooth pictures...
29 | res = 10 ; ticks = np.linspace( 0, 1, res + 1)[:-1] + 1/(2*res)
30 | X,Y = np.meshgrid( ticks, ticks )
31 | points = Variable(torch.from_numpy(np.vstack( (X.ravel(), Y.ravel()) ).T).type(dtype), requires_grad=False)
32 |
33 | info = _k( points, q1_x , radius ) @ q1_mu \
34 | - _k( points, xt_x , radius ) @ xt_mu
35 | return [cost , info.view( (res,res) ) ]
36 |
37 | def _ot_matching(q1_x, q1_mu, xt_x, xt_mu, radius) :
38 | """
39 | Given two measures q1 and xt represented by locations/weights arrays,
40 | outputs an optimal transport fidelity term and the transport plan.
41 | """
42 | # The Sinkhorn algorithm takes as input three Theano variables :
43 | c = _squared_distances(q1_x, xt_x) # Wasserstein cost function
44 | mu = q1_mu ; nu = xt_mu
45 |
46 | # Parameters of the Sinkhorn algorithm.
47 | epsilon = (.02)**2 # regularization parameter
48 | rho = (.5) **2 # unbalanced transport (See PhD Th. of Lenaic Chizat)
49 | niter = 10000 # max niter in the sinkhorn loop
50 | tau = -.8 # nesterov-like acceleration
51 |
52 | lam = rho / (rho + epsilon) # Update exponent
53 |
54 | # Elementary operations .....................................................................
55 | def ave(u,u1) :
56 | "Barycenter subroutine, used by kinetic acceleration through extrapolation."
57 | return tau * u + (1-tau) * u1
58 | def M(u,v) :
59 | "$M_{ij} = (-c_{ij} + u_i + v_j) / \epsilon$"
60 | return (-c + u.unsqueeze(1) + v.unsqueeze(0)) / epsilon
61 | lse = lambda A : torch.log(torch.exp(A).sum( 1 ) + 1e-6) # slight modif to prevent NaN
62 |
63 | # Actual Sinkhorn loop ......................................................................
64 | u,v,err = 0.*mu, 0.*nu, 0.
65 | actual_nits = 0
66 |
67 | for i in range(niter) :
68 | u1= u # useful to check the update
69 | u = ave( u, lam * ( epsilon * ( torch.log(mu) - lse(M(u,v)) ) + u ) )
70 | v = ave( v, lam * ( epsilon * ( torch.log(nu) - lse(M(u,v).t()) ) + v ) )
71 | err = (u - u1).abs().sum()
72 |
73 | actual_nits += 1
74 | if (err < 1e-4).data.cpu().numpy() :
75 | break
76 | U, V = u, v
77 | Gamma = torch.exp( M(U,V) ) # Eventual transport plan g = diag(a)*K*diag(b)
78 | cost = torch.sum( Gamma * c ) # Simplistic cost, chosen for readability in this tutorial
79 |
80 | print('Sinkhorn error after ' + str(actual_nits) + ' iterations : ' + str(err.data.cpu().numpy()))
81 | return [cost, Gamma]
82 |
83 |
84 | def _data_attachment(q1_measure, xt_measure, radius) :
85 | "Given two measures and a radius, returns a cost - as a Theano symbolic variable."
86 | if radius == 0 : # Convenient way to allow the choice of a method
87 | return _ot_matching(q1_measure[0], q1_measure[1],
88 | xt_measure[0], xt_measure[1],
89 | radius)
90 | else :
91 | return _kernel_matching(q1_measure[0], q1_measure[1],
92 | xt_measure[0], xt_measure[1],
93 | radius)
94 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/io/read_vtk.py:
--------------------------------------------------------------------------------
1 | import re
2 | from pylab import *
3 |
4 | def ReadVTK(filename, points = True, polygons = True, signals = True, thicknesses = True):
5 | """ Specification of VTK-files:
6 | http://www.vtk.org/VTK/img/file-formats.pdf - page 4 """
7 | f = open(filename)
8 | lines = f.readlines()
9 | f.close()
10 |
11 | verticeList = []
12 | polygonsList = []
13 | signalsList = []
14 |
15 | lineNr = 0
16 | #pattern_points = re.compile('([-+]?\d*\.\d+|\d+) ([-+]?\d*\.\d+|\d+) ([-+]?\d*\.\d+|\d+)')
17 | pattern_points_3perline = re.compile('([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+)')
18 | pattern_points_2perline = re.compile('([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+)')
19 | pattern_points = re.compile('([-+Ee\d\.]+) ([-+Ee\d\.]+) ([-+Ee\d\.]+)')
20 | pattern_polygons_3 = re.compile('([\d]+) ([\d]+) ([\d]+) ([\d]+)')
21 | pattern_polygons_2 = re.compile('([\d]+) ([\d]+) ([\d]+)')
22 | pattern_signal = re.compile('([-+E\d\.]+)')
23 |
24 | def handle_points(l) :
25 | m = pattern_points_3perline.match(l)
26 | if m != None:
27 | x1 = float(m.group(1))
28 | y1 = float(m.group(2))
29 | z1 = float(m.group(3))
30 | x2 = float(m.group(4))
31 | y2 = float(m.group(5))
32 | z2 = float(m.group(6))
33 | x3 = float(m.group(7))
34 | y3 = float(m.group(8))
35 | z3 = float(m.group(9))
36 | verticeList.append([x1,y1,z1])
37 | verticeList.append([x2,y2,z2])
38 | verticeList.append([x3,y3,z3])
39 | else :
40 | m = pattern_points_2perline.match(l)
41 | if m != None:
42 | x1 = float(m.group(1))
43 | y1 = float(m.group(2))
44 | z1 = float(m.group(3))
45 | x2 = float(m.group(4))
46 | y2 = float(m.group(5))
47 | z2 = float(m.group(6))
48 | verticeList.append([x1,y1,z1])
49 | verticeList.append([x2,y2,z2])
50 | else :
51 | m = pattern_points.match(l)
52 | if m != None:
53 | x = float(m.group(1))
54 | y = float(m.group(2))
55 | z = float(m.group(3))
56 | verticeList.append([x,y,z])
57 |
58 | def handle_polygons(l) :
59 | m = pattern_polygons_3.match(l)
60 | if m != None :
61 | nrOfPoints = m.group(1)
62 | vertice1 = int(m.group(2))
63 | vertice2 = int(m.group(3))
64 | vertice3 = int(m.group(4))
65 | polygonsList.append([vertice1, vertice2, vertice3])
66 | else :
67 | m = pattern_polygons_2.match(l)
68 | if m != None :
69 | nrOfPoints = m.group(1)
70 | vertice1 = int(m.group(2))
71 | vertice2 = int(m.group(3))
72 | polygonsList.append([vertice1, vertice2])
73 |
74 | def handle_signal(l) :
75 | m = pattern_signal.match(l)
76 | if m != None :
77 | signal = float(m.group(1))
78 | signalsList.append(signal)
79 |
80 | def handle_nothing(l) :
81 | None
82 |
83 | current_treatment = handle_nothing
84 | for line in lines :
85 | if "POINTS" in line :
86 | current_treatment = handle_points
87 | elif "POLYGONS" in line :
88 | current_treatment = handle_polygons
89 | elif "LINES" in line :
90 | current_treatment = handle_polygons
91 | elif "LOOKUP_TABLE" in line :
92 | current_treatment = handle_signal
93 | else :
94 | current_treatment(line)
95 |
96 | """
97 | while "POINTS" not in lines[lineNr]:
98 | lineNr += 1
99 | while "POLYGONS" not in lines[lineNr]:
100 | lineNr += 1
101 | m = pattern_points.match(lines[lineNr])
102 | if m != None:
103 | x = float(m.group(1))
104 | y = float(m.group(2))
105 | z = float(m.group(3))
106 | verticeList.append([x,y,z])
107 | while "LOOKUP_TABLE" not in lines[lineNr]:
108 | lineNr += 1
109 | m = pattern_polygons.match(lines[lineNr])
110 | if m != None :
111 | nrOfPoints = m.group(1)
112 | vertice1 = int(m.group(2))
113 | vertice2 = int(m.group(3))
114 | vertice3 = int(m.group(4))
115 | gewicht = 1.0
116 | polygonsList.append([vertice1, vertice2, vertice3])
117 | while lineNr < len(lines)-1:
118 | lineNr += 1
119 | m = pattern_signal.match(lines[lineNr])
120 | if m != None :
121 | signal = float(m.group(1))
122 | signalsList.append(signal)
123 | """
124 | return (verticeList, polygonsList, signalsList)
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/matlab/Script/hands/script_hands_matching_tan_bundle_ot.m:
--------------------------------------------------------------------------------
1 | % Matching of multi-shapes : hands and fibres bundle (http://visionair.ge.imati.cnr.it/ontologies/shapes/)
2 | % Author : B. Charlier (2017)
3 |
4 | PathToFshapesTk = '../..'
5 | addpath(genpath([PathToFshapesTk,'/Bin']))
6 | addpath(genpath([PathToFshapesTk,'/Script']))
7 |
8 |
9 | %------------------%
10 | % oliver's hand %
11 | %------------------%
12 |
13 | [p,t] = read_off('./data/764-Olivier_hand_-_Simplified_to_10kF/764_closed.off');
14 |
15 | p=p';t=t';
16 |
17 | l =0.7;noise=.2; n=50;nb_point_bundle=8;
18 | X0=repmat([0;-.2;0],1,n)+ randn(3,n)*.01; curvature=0.5/l; v=[1;.1;2];
19 | Xall=generate_fiber(X0,l,curvature,nb_point_bundle,v,noise);
20 |
21 | oliver_hand{1,1} = struct('x',p,'G',t,'f',zeros(size(p,1),1));
22 | curvex = [];
23 | curveG = [];
24 | pointx = [];
25 | for i = 1:size(Xall,3)
26 | curvex =[curvex ; Xall(:,:,i)'] ;
27 | n = size(Xall,2);
28 | nstart = ((i-1)*n);
29 | curveG = [curveG;[nstart+1:(nstart+n-1);(nstart+2):(nstart+n)]'];
30 | pointx =[pointx ; Xall(:,end,i)'];
31 | end
32 |
33 | oliver_hand{1,2} = struct('x',curvex,'G',curveG,'f',zeros(numel(Xall)/3,1) );
34 |
35 | %-----------------------%
36 | % Pierre's hand %
37 | %-----------------------%
38 |
39 |
40 | [pp,tp] = read_off('./data/736-Pierre_s_hand__decimated_version/736.off');
41 |
42 | pp=pp';
43 | pp(:,1) = - pp(:,1);
44 | tp=tp';
45 |
46 |
47 | l =0.5;noise=.1; n=53;nb_point_bundle=9;
48 | X0=repmat([0;-.2;0],1,n)+ randn(3,n)*.01; curvature=0.5/l; v=[-.1;.2;1];
49 | Xall=generate_fiber(X0,l,curvature,nb_point_bundle,v,noise);
50 |
51 | pierre_hand{1,1} = struct('x',pp,'G',tp,'f',zeros(size(pp,1),1));
52 | curvex = [];
53 | curveG = [];
54 | pointx = [];
55 | for i = 1:size(Xall,3)
56 | curvex =[curvex ; Xall(:,:,i)'] ;
57 | n = size(Xall,2);
58 | nstart = ((i-1)*n);
59 | curveG = [curveG;[nstart+1:(nstart+n-1);(nstart+2):(nstart+n)]'];
60 | pointx =[pointx ; Xall(:,end,i)'];
61 | end
62 |
63 | pierre_hand{1,2} = struct('x',curvex,'G',curveG,'f',zeros(numel(Xall)/3,1) );
64 |
65 | %------------------------------%
66 | % parameters %
67 | %------------------------------%
68 |
69 | comp_method = 'cuda';% possible values are 'cuda' or 'matlab'
70 |
71 | % Parameters for the deformations
72 | defo.kernel_size_mom = [.5, .2,.1]; % the kernel used to generate the deformations is a sum of 2 kernels
73 | defo.nb_euler_steps =15; % nbr of steps in the (for||back)ward integration
74 | defo.method =comp_method; % possible values are 'cuda' or 'matlab'
75 |
76 | % Parameters for the matchterm
77 | objfun{1}.normalize_objfun=1;
78 | % First part of the shape : hand's shape surface
79 | objfun{1}.weight_coef_dist = 6000; % weighting coeff in front of the data attachment term
80 | objfun{1}.distance = 'wasserstein';
81 | objfun{1}.wasserstein_distance.epsilon = .5*(.05)^2;
82 | objfun{1}.wasserstein_distance.niter = 200;
83 | objfun{1}.wasserstein_distance.tau = 0; % basic sinkhorn, no extrapolation
84 | objfun{1}.wasserstein_distance.rho = 10; % balanced case
85 | objfun{1}.wasserstein_distance.weight_cost_varifold = [6,1]; % weight on spatial and orientation distances
86 | objfun{1}.wasserstein_distance.method=comp_method; % possible values are 'cuda' or 'matlab'
87 |
88 | % second part of the shape : the fibres bundles
89 | objfun{2}.normalize_objfun=1;
90 | objfun{2}.weight_coef_dist = 10; % weighting coeff in front of the data attachment term
91 | objfun{2}.distance = 'wasserstein';
92 | objfun{2}.wasserstein_distance.epsilon = .5*(.05)^2;
93 | objfun{2}.wasserstein_distance.niter = 200;
94 | objfun{2}.wasserstein_distance.tau = 0; % basic sinkhorn, no extrapolation
95 | objfun{2}.wasserstein_distance.rho = 10; % balanced case
96 | objfun{2}.wasserstein_distance.weight_cost_varifold = [6,1]; % weight on spatial and orientation distances
97 | objfun{2}.wasserstein_distance.method=comp_method; % possible values are 'cuda' or 'matlab'
98 |
99 |
100 | optim.method = 'bfgs';
101 | optim.bfgs.maxit = 300;
102 |
103 | %----------%
104 | % output %
105 | %----------%
106 |
107 | [momentums,summary]=fsmatch_tan(pierre_hand,oliver_hand,defo,objfun,optim);
108 |
109 | % export in vtk files
110 | saveDir ='./results/matching_hands_and_bundles_ot/';
111 | export_matching_tan(pierre_hand,momentums,{zeros(size(pierre_hand{1}.f)), zeros(size(pierre_hand{2}.f))},oliver_hand,summary,saveDir)
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/models/free_1D_atlas.py:
--------------------------------------------------------------------------------
1 | from pylab import *
2 |
3 | from .free_atlas import FreeAtlas
4 |
5 | class Free1DAtlas(FreeAtlas) :
6 | """Atlas with a free mean Q0 and rank-1 constraint on P0"""
7 | def __init__(self, *args, **kwargs) :
8 | FreeAtlas.__init__(self, *args, **kwargs)
9 |
10 | # the direction, a single momentum; we choose to constrain its norm
11 | self.E = self.M.unit_p(self.Q0, array([1,0])) # arbitrary choice.
12 | self.L = zeros((self.nobs,1)) # coefficients, 1xnobs real-valued matrix
13 | self.P = self.L @ atleast_2d(self.E) # it is more pythonic to work with the "transposes"
14 |
15 | # true (default) if we use the kernel matrix K
16 | # at the template to compute the scalar
17 | # products between momentums; this is the
18 | # natural choice, but it can be costly in
19 | # practice for shape manifolds.
20 | #
21 | # False to use a simple L2 metric.
22 | self.intrinsic_scalar_product = False
23 |
24 | """Updates"""
25 | def update_P(self, dP) :
26 | # models update
27 | self.normalize_basis() # just in case the user is toying with the scalar product
28 | (scals, residuals) = self.decompose(dP)
29 | assert(self.L.shape == scals.shape)
30 | assert(self.E.shape == (residuals.shape[1],))
31 | self.L = self.L + scals
32 |
33 | # scals = scals ./ (abs(scals) + eps)
34 | # residuals = self.M.unit_p(self.Q0, residuals)
35 | self.E = self.E + mean(residuals, 0) # !!!
36 |
37 | self.normalize_basis() # Don't forget to stay in the Stiefel manifold !
38 | self.P = self.L @ atleast_2d(self.E)
39 |
40 | def normalize_basis(self) :
41 | # This is the simplest way to do it; in practice,
42 | # we may use more accurate methods :
43 | if self.intrinsic_scalar_product :
44 | self.E = self.M.unit_p(self.Q0, self.E)
45 | else :
46 | self.E = self.E / sqrt(self.E @ self.E) # just in case the user is toying with the scalar product
47 |
48 | def decompose(self, dP) :
49 | """
50 | Decomposes the update dP in a :
51 | - longitudinal part along self.E, given by the coeff. update 'scals'
52 | - orthogonal part, given by 'residuals'
53 | self.E is assumed to be an orthonormal family
54 | """
55 | if self.intrinsic_scalar_product :
56 | scals = self.M.K( self.Q0, dP ) @ self.E
57 | else :
58 | scals = dP @ self.E
59 | scals = atleast_2d(scals).T
60 | residuals = dP - scals @ atleast_2d(self.E) # normal component
61 | # rescaling depending on the distance from model to the template :
62 | residuals = residuals * (self.weights())
63 | # scals = scals ./ max(.2, abs(scals));
64 | # scals = .01 * scals ./ abs(scals);
65 | residuals = atleast_2d(residuals)
66 | return (scals, residuals)
67 |
68 | def weights(self) :
69 | """
70 | Returns the weight associated to each point in the steering of
71 | the direction self.E. Just like with Frechet means, the choice
72 | of this function will change the behaviour of our model, from
73 | 'angular median' to 'angular mean'.
74 | Note that the correct quadratic gradient-based formula is '1 / L'.
75 | """
76 | return sign(self.L) #1/(self.L + 0.00001)
77 | """
78 | def show_inner_model(self, Xt, ax) :
79 | [points, Q, C, dQ] = show_inner_model@HypertemplateAtlas(Mod, Xt, ax);
80 | [dQ0p, dP] = self.training_step(Xt, 1, true); % simulation = true : there won't be any update !
81 | [scals, residuals] = self.decompose(dP);
82 |
83 | longitudinals = self.E * scals;
84 | % For ease of explanation as a steering process :
85 | normals = residuals.* sign(repmat(self.L, [size(residuals, 1), 1]));
86 | if self.intrinsic_scalar_product
87 | dP = self.M.L2_repr_p(self.Q0, dP);
88 | longitudinals = self.M.L2_repr_p(self.Q0, longitudinals);
89 | normals = self.M.L2_repr_p(self.Q0, residuals);
90 | end
91 |
92 | basis = self.M.L2_repr_p(self.Q0, self.E);
93 | hold(ax, 'on');
94 | %plot(ax, self.L, self.L, '-x');
95 | quiver(ax, 0, 0, basis(2,:), basis(1, :), 0);
96 | quiver(ax, points(2,:), points(1,:), longitudinals(2,:), longitudinals(1,:), 1, 'y');
97 | quiver(ax, points(2,:), points(1,:), normals(2,:), normals(1,:), 1, 'g');
98 | %quiver(ax, points(2,:), points(1,:), dQ0p(2,:), dQ0p(1,:), 1, 'r');
99 | quiver(ax, points(2,:), points(1,:), dP(2,:), dP(1,:), 1, 'r');
100 | quiver(ax, 0, 0, mean(dQ0p(2,:)), mean(dQ0p(1,:)), 1, 'Color', [0,0,.5], 'Linewidth', 2);
101 | hold(ax, 'off');
102 |
103 | """
104 |
105 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **N.B.:** This repository is out of date. A reference implementation of Optimal Transport divergences for shape registration is now available on the [geomloss](https://github.com/jeanfeydy/geomloss) repository: [website](https://www.kernel-operations.io/geomloss), [pip package](https://pypi.org/project/geomloss/).
2 |
3 |
4 | # lddmm-ot
5 | MICCAI 2017 Paper - Optimal Transport for Diffeomorphic Registration
6 |
7 | Authors :
8 | Jean Feydy, Benjamin Charlier, F.-X. Vialard, Gabriel Peyré
9 |
10 | This repositery contains three independent implementations of the Optimal Transport
11 | data attachment term introduced in the paper :
12 |
13 | - A simplistic "one-script" theano+python implementation, located in the
14 | 'Simple_script/' folder. It implements curves matching with a simplistic
15 | 'curve length' measure embedding.
16 |
17 | - A fully-fledged theano+python toolbox, located in the "LDDMM_Python" folder.
18 | It implements embeddings in the varifold space for curves and surfaces,
19 | and was used for Figure 1 (Protozoa).
20 |
21 | - A fully-fledged Matlab toolbox, placed in the 'matlab/' directory.
22 |
23 | It also hosts a mini implementation in Pytorch, that we will strive to make as
24 | memory-efficient as possible. Hopefully, we can find a way to relieve the major
25 | bottleneck of autodiffs libraries, as of 2017.
26 |
27 | --------------------------------------------------------------------------------
28 | Instructions for the python implementations
29 | --------------------------------------------------------------------------------
30 | You will need to install the autodiff library Theano on top of Jupyter/IPython.
31 | N.B. : To use your Nvidia GPU, don't forget to put the appropriate settings in
32 | your .theanorc (http://www.deeplearning.net/software/theano/tutorial/using_gpu.html).
33 | For our experiments, it was simply :
34 |
35 | ```markdown
36 | [nvcc]
37 | flags=-D_FORCE_INLINES
38 |
39 |
40 | [global]
41 | device=cuda
42 | floatX=float32
43 | exception_verbosity=high
44 | ```
45 |
46 | (With an Nvidia GeForce GTX 960M)
47 |
48 | We advise the interested reader to get introduced to our implementations with
49 | the 'Simple_script/' toy demo.
50 |
51 | Then, to recompute the Figure 1, please :
52 | - go into the 'LDDMM_Python/' folder.
53 | - there, open a terminal and launch the 'jupyter notebook' command - provided by
54 | a fresh Anaconda install for instance.
55 | - Your web browser should open itself. Through the web interface, go into
56 | 'demo/Notebooks/Feb2017_paper/'.
57 | - Click on 'curves_matching.ipynb' to open the IPython/Jupyter Notebook.
58 | - Simply make a 'Cell/Run all'.
59 | - Once the computation is over, you can run the 'pvpython render.py'
60 | (provided by the software Paraview) to convert the .vtk into the appropriate
61 | .png images.
62 |
63 | The runs made to compute the presented images have been saved in
64 | 'run_1.html' and 'run_2.html' (the first one had crashed due to a garbage
65 | collection problem combined to the super-greedy theano scan, we discarded
66 | the error message to preserve anonymity).
67 | You may check energy descent and computation time here.
68 |
69 | N.B. : you may change the source and target by editing the
70 | 'demo/Notebooks/Feb2017_paper/data/source.png' and 'target.png' images.
71 |
72 | As of today, theano's implementation of the 'scan' or 'for loop' operation,
73 | is extremely memory-greedy : we can't use autodiff with
74 | ~1000 sinkhorn iterations with more than 200 points without a memory overflow.
75 | A future version of the toolbox will use the 'scan_checkpoints' routine
76 | (which allows one to set the speed/memory tradeoff), and eventualy allow us
77 | to test our method on Eulerian image registration.
78 |
79 |
80 | --------------------------------------------------------------------------------
81 | Instructions for the matlab toolbox
82 | --------------------------------------------------------------------------------
83 | -----------
84 | Quick start
85 | -----------
86 |
87 | A) Use with pure matlab code
88 | 1) simplyrun the various examples in ./Script/
89 |
90 | B) Use with cuda mex files (mandatory with surfaces)
91 | 1) compile the mex files in ./Bin/kernels/ with the makefile.sh
92 | 2) run the various examples in ./Script/
93 |
94 | You will be able to read the .vtk files with Paraview.
95 |
96 |
97 |
98 | Best regards,
99 |
100 | The authors.
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/LDDMM_Python/lddmm_python/modules/manifolds/theano_shapescarrier.py:
--------------------------------------------------------------------------------
1 | # Import of the relevant tools
2 | import time
3 | import numpy as np
4 | import theano
5 | import theano.tensor as T
6 | from theano import pp, config
7 |
8 |
9 | from plotly.tools import FigureFactory as FF
10 | import plotly.graph_objs as go
11 |
12 | from ..io.read_vtk import ReadVTK
13 | from ..data_attachment.measures import Measures
14 | from ..data_attachment.varifolds import Varifolds
15 | from ..math_utils.kernels import _squared_distances, _gaussian_kernel
16 |
17 |
18 | from .theano_hamiltoniancarrier import TheanoHamiltonianCarrier
19 | from .shapes_manifold import ShapesManifold
20 |
21 |
22 |
23 | class TheanoShapesCarrier(ShapesManifold, TheanoHamiltonianCarrier) :
24 | """
25 | Combines the control points framework with the data attachment + io methods
26 | of the ShapesManifold class.
27 | """
28 |
29 | def __init__(self, S0,
30 | kernel = ('gaussian', 1),
31 | data_attachment = ('measure-kernel', ('gaussian', 1)),
32 | weights = (0.01, 1), # gamma_V, gamma_W
33 | dt = 0.1,
34 | compatibility_compile = False,
35 | plot_interactive = False,
36 | plot_file = True,
37 | foldername = 'results/'
38 | ) :
39 | """
40 | Creates a TheanoCurves/Surfaces manifold.
41 | Compilation takes place here.
42 | """
43 |
44 | TheanoHamiltonianCarrier.__init__(self, kernel = kernel,
45 | weights = weights,
46 | dt = dt,
47 | plot_interactive = plot_interactive,
48 | plot_file = plot_file,
49 | foldername = foldername)
50 | ShapesManifold.__init__(self, S0,
51 | data_attachment)
52 |
53 |
54 | #===============================================================
55 | # Before compiling, we assign types to the teano variables
56 | q0 = T.matrix('q0')
57 | p0 = T.matrix('p0')
58 | s0 = T.matrix('s0')
59 | xt_x = T.matrix('xt_x')
60 | xt_mu = T.vector('xt_mu')
61 | xt_n = T.matrix('xt_n')
62 |
63 | # Compilation. Depending on settings specified in the ~/.theanorc file or explicitely given
64 | # at execution time, this will produce CPU or GPU code.
65 |
66 | if not compatibility_compile : # With theano, it's better to let the compilator handle the whole forward-backward pipeline
67 | print('Compiling the shooting_cost routine...')
68 | time1 = time.time()
69 |
70 | if self.embedding_type == 'measure' :
71 | self.opt_shooting_cost = theano.function([q0, p0, s0, xt_x, xt_mu], # input
72 | self._opt_shooting_cost(q0, p0, s0, xt_x, xt_mu), # output
73 | allow_input_downcast=True) # GPU = float32 only, whereas numpy uses
74 | # float64 : we allow silent conversion
75 | elif self.embedding_type == 'varifold' :
76 | self.opt_shooting_cost = theano.function([q0, p0, s0, xt_x, xt_mu, xt_n], # input
77 | self._opt_shooting_cost(q0, p0, s0, xt_x, xt_mu, xt_n), # output
78 | allow_input_downcast=True) # GPU = float32 only, whereas numpy uses
79 | # float64 : we allow silent conversion
80 |
81 |
82 | time2 = time.time()
83 | print('Compiled in : ', '{0:.2f}'.format(time2 - time1), 's')
84 |
85 | # The hamiltonian_trajectory routine, that shall be used in the visualization
86 | print('Compiling the hamiltonian_trajectory visualization routine...')
87 | time1 = time.time()
88 | self.hamiltonian_trajectory = theano.function([q0,p0,s0], # input
89 | self._HamiltonianTrajectoryCarrying(q0, p0, s0), # output
90 | allow_input_downcast=True) # GPU = float32 only, whereas numpy uses
91 | # float64 : we allow silent conversion
92 | time2 = time.time()
93 | print('Compiled in : ', '{0:.2f}'.format(time2 - time1), 's')
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/matlab/Bin/optim/hanso (third party)/gradsampfixed.m:
--------------------------------------------------------------------------------
1 | function [x, f, g, dnorm, X, G, w, quitall] = ...
2 | gradsampfixed(x0, f0, g0, samprad, pars, options)
3 | % gradient sampling minimization with fixed sampling radius
4 | % intended to be called by gradsamp1run only
5 | %
6 | % Send comments/bug reports to Michael Overton, overton@cs.nyu.edu,
7 | % with a subject header containing the string "hanso" or "gradsamp".
8 | % Version 2.0, 2010, see GPL license info below.
9 |
10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11 | %% HANSO 2.0 Copyright (C) 2010 Michael Overton
12 | %% This program is free software: you can redistribute it and/or modify
13 | %% it under the terms of the GNU General Public License as published by
14 | %% the Free Software Foundation, either version 3 of the License, or
15 | %% (at your option) any later version.
16 | %%
17 | %% This program is distributed in the hope that it will be useful,
18 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | %% GNU General Public License for more details.
21 | %%
22 | %% You should have received a copy of the GNU General Public License
23 | %% along with this program. If not, see .
24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25 |
26 | fgname = pars.fgname;
27 | prtlevel = options.prtlevel;
28 | if prtlevel > 0
29 | fprintf('gradsamp: sampling radius = %7.1e,',samprad);
30 | end
31 | if prtlevel > 1
32 | fprintf('\n')
33 | end
34 | x = x0;
35 | f = f0;
36 | g = g0;
37 | X = x;
38 | G = g;
39 | w = 1;
40 | quitall = 0;
41 | maxit = options.maxit;
42 | normtol = options.normtol;
43 | ngrad = options.ngrad;
44 | fvalquit = options.fvalquit;
45 | cpufinish = cputime + options.cpumax;
46 | dnorm = inf;
47 | for iter = 1:maxit
48 | % evaluate gradients at randomly generated points near x
49 | % first column of Xnew and Gnew are respectively x and g
50 | [Xnew, Gnew] = getbundle(x, g, samprad, ngrad, pars);
51 | % solve QP subproblem
52 | [wnew,dnew] = qpspecial(Gnew); % Anders Skajaa specialized QP solver
53 | dnew = -dnew; % this is a descent direction
54 | gtdnew = g'*dnew; % gradient value at current point
55 | dnormnew = norm(dnew);
56 | if dnormnew < dnorm % for returning, may not be the final one
57 | dnorm = dnormnew;
58 | X = Xnew;
59 | G = Gnew;
60 | w = wnew;
61 | end
62 | if dnormnew < normtol
63 | % since dnormnew is first to satisfy tolerance, it must equal dnorm
64 | if prtlevel > 0
65 | fprintf(' tolerance met at iter %d, f = %g, dnorm = %5.1e\n', ...
66 | iter, f, dnorm);
67 | end
68 | return
69 | elseif gtdnew >= 0 | isnan(gtdnew)
70 | if prtlevel > 0 % dnorm, not dnormnew, which may be bigger
71 | fprintf(' not descent direction, quit at iter %d, f = %g, dnorm = %5.1e\n', ...
72 | iter, f, dnorm);
73 | end
74 | return
75 | end
76 | % note that dnew is NOT normalized, but we set second Wolfe
77 | % parameter to 0 so that sign of derivative must change
78 | % and this is accomplished by expansion steps when necessary,
79 | % so it does not seem necessary to normalize d
80 | wolfe1 = 0;
81 | wolfe2 = 0;
82 | [alpha, x, f, g, fail] = ...
83 | linesch_ww(x, f, g, dnew, pars, wolfe1, wolfe2, fvalquit, prtlevel);
84 | if prtlevel > 1 % since this is printed every iteration we print dnormnew here
85 | fprintf(' iter %d: step = %5.1e, f = %g, dnorm = %5.1e\n',...
86 | iter, alpha, f, dnormnew)
87 | end
88 | if f < fvalquit
89 | if prtlevel > 0
90 | fprintf(' reached target objective, quit at iter %d \n', iter)
91 | end
92 | quitall = 1;
93 | return
94 | end
95 | % if fail == 1 % Wolfe conditions not both satisfied, DO NOT quit,
96 | % because this typically means gradient set not rich enough and we
97 | % should continue sampling
98 | if fail == -1 % function apparently unbounded below
99 | if prtlevel > 0
100 | fprintf(' f may be unbounded below, quit at iter %d, f = %g\n',...
101 | iter, f)
102 | end
103 | quitall = 1;
104 | return
105 | end
106 | if cputime > cpufinish
107 | if prtlevel > 0
108 | fprintf(' cpu time limit exceeded, quit at iter %d\n', iter)
109 | end
110 | quitall = 1;
111 | return
112 | end
113 | end
114 | if prtlevel > 0
115 | fprintf(' %d iters reached, f = %g, dnorm = %5.1e\n', maxit, f, dnorm);
116 | end
--------------------------------------------------------------------------------