├── .gitignore ├── LICENSE ├── README.md ├── doc └── source │ ├── _jekyll │ ├── _config.yml │ ├── _includes │ │ ├── after_footer.html │ │ ├── breadcrumbs.html │ │ ├── footer.html │ │ └── head.html │ ├── _layouts │ │ ├── default.html │ │ └── page.html │ ├── css │ │ ├── bootstrap.css │ │ ├── bootstrap.min.css │ │ ├── site.css │ │ └── syntax.css │ ├── font-awesome-4.1.0 │ │ ├── css │ │ │ ├── font-awesome.css │ │ │ └── font-awesome.min.css │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ └── fontawesome-webfont.woff │ │ ├── less │ │ │ ├── bordered-pulled.less │ │ │ ├── core.less │ │ │ ├── fixed-width.less │ │ │ ├── font-awesome.less │ │ │ ├── icons.less │ │ │ ├── larger.less │ │ │ ├── list.less │ │ │ ├── mixins.less │ │ │ ├── path.less │ │ │ ├── rotated-flipped.less │ │ │ ├── spinning.less │ │ │ ├── stacked.less │ │ │ └── variables.less │ │ └── scss │ │ │ ├── _bordered-pulled.scss │ │ │ ├── _core.scss │ │ │ ├── _fixed-width.scss │ │ │ ├── _icons.scss │ │ │ ├── _larger.scss │ │ │ ├── _list.scss │ │ │ ├── _mixins.scss │ │ │ ├── _path.scss │ │ │ ├── _rotated-flipped.scss │ │ │ ├── _spinning.scss │ │ │ ├── _stacked.scss │ │ │ ├── _variables.scss │ │ │ └── font-awesome.scss │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ └── js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ ├── contact_me.js │ │ ├── jqBootstrapValidation.js │ │ ├── jquery.js │ │ └── site.js │ ├── _xsl │ └── mxdom2jekyll.xsl │ ├── api │ └── img │ │ ├── ecdfactory_01.png │ │ ├── gammafactory_01.png │ │ ├── mixturefactory_01.png │ │ ├── mixturefactory_02.png │ │ ├── mvn2factory_01.png │ │ ├── mvnfactory_01.png │ │ └── vmffactory_01.png │ ├── caching.m │ ├── data_input.m │ ├── developer_guide.m │ ├── distribution_parameters.m │ ├── estimation_options.m │ ├── estimation_statistics_structure.m │ ├── helptoc.xml │ ├── img │ └── user_guide_01.png │ ├── index.html │ └── user_guide.m ├── examples ├── data2d.mat ├── data_iris.mat ├── data_sm.mat ├── example1.m ├── example2.m ├── example3.m ├── example4.m └── mixspheregen.m ├── info.xml ├── install_mixest.m ├── mixest ├── auxiliary │ ├── checking │ │ ├── check_grad.m │ │ ├── check_kl.m │ │ ├── obj2vec.m │ │ ├── objlen.m │ │ └── vec2obj.m │ ├── estimation │ │ ├── mxe_adjustoptions.m │ │ ├── mxe_costgrad.m │ │ ├── mxe_crossvalidation.m │ │ ├── mxe_ecostgrad.m │ │ ├── mxe_egradbatch.m │ │ ├── mxe_getplotdata.m │ │ ├── mxe_getsolverhandle.m │ │ ├── mxe_gradbatch.m │ │ ├── mxe_inneroptions.m │ │ ├── mxe_mergeinfo.m │ │ ├── mxe_minibatch.m │ │ ├── mxe_options.m │ │ ├── mxe_plot.m │ │ ├── mxe_plotavg.m │ │ ├── mxe_stoppingcriterion.m │ │ └── mxe_visualization.m │ ├── manopt_manifolds │ │ ├── euclidean │ │ │ └── triufactory.m │ │ ├── linesearch │ │ │ ├── linesearch_wolfe.m │ │ │ ├── linesearch_wolfe_euc.m │ │ │ ├── linesearch_wolfe_old.m │ │ │ └── polyinterp.m │ │ ├── mxe_addsharedmanifold.m │ │ ├── mxe_powermanifold.m │ │ ├── mxe_product2manifold.m │ │ ├── mxe_productmanifold.m │ │ ├── positivedefinite │ │ │ ├── hpdfactory.m │ │ │ ├── positive2factory.m │ │ │ ├── positivefactory.m │ │ │ ├── spdfactory.m │ │ │ ├── spdfactorytmp.m │ │ │ ├── spdffactory.m │ │ │ ├── sqrtm_fast.m │ │ │ ├── sqrtm_triu_complex.c │ │ │ ├── sqrtm_triu_negative.c │ │ │ └── sqrtm_triu_real.c │ │ ├── simplex │ │ │ ├── productsimplexfactory.m │ │ │ ├── simplexKfactory.m │ │ │ └── simplexfactory.m │ │ └── sphere │ │ │ └── sphere2factory.m │ ├── manopt_solvers │ │ ├── getEuclideanCostGrad.m │ │ ├── lbfgs │ │ │ ├── desc_dir_cal.m │ │ │ ├── lbfgs.m │ │ │ └── lbfgs_update.m │ │ └── sgd │ │ │ ├── sgd.m │ │ │ └── sgd_old.m │ └── private_tools │ │ ├── mxe_htmltable.m │ │ ├── mxe_publishdocs.m │ │ ├── mxe_readdata.m │ │ ├── mxe_readweight.m │ │ ├── mxe_scaleparam.m │ │ ├── mxe_setfields.m │ │ └── mxe_sumparam.m ├── distributions │ ├── ag │ │ ├── Integral_Method.m │ │ ├── ag_estimatedefault.m │ │ └── agfactory.m │ ├── common │ │ ├── doc_distribution_common.m │ │ ├── mxe_AICc.m │ │ ├── mxe_BIC.m │ │ └── mxe_addsharedfields.m │ ├── ecd │ │ ├── ecd_eg_estimatedefault.m │ │ ├── ecd_estimatedefault.m │ │ └── ecdfactory.m │ ├── factorial │ │ ├── factorialfactory.m │ │ └── factorialmogfactory.m │ ├── gamma │ │ ├── gamma_estimatedefault.m │ │ └── gammafactory.m │ ├── gaussianize │ │ └── gaussianizationfactory.m │ ├── mixture │ │ ├── meg_estimatedefault.m │ │ ├── mixture_estimatedefault.m │ │ ├── mixture_mergecandidates.m │ │ ├── mixture_mergeinit.m │ │ ├── mixture_splitcandidates.m │ │ ├── mixture_splitinit.m │ │ ├── mixture_visualize.m │ │ ├── mixturefactory.m │ │ ├── mixturefactory_mashal.m │ │ ├── mixturefactory_new.m │ │ ├── moe_estimatedefault.m │ │ └── moefactory.m │ ├── mnl │ │ └── mnlfactory.m │ ├── mvn │ │ ├── cmvn2factory.m │ │ ├── cmvnfactory.m │ │ ├── mvn2_estimatedefault.m │ │ ├── mvn2cholfactory.m │ │ ├── mvn2factory.m │ │ ├── mvn2factorytmp.m │ │ ├── mvn2factorytmp2.m │ │ ├── mvn2icholfactory.m │ │ ├── mvn_estimatedefault.m │ │ ├── mvn_selfmerge.m │ │ ├── mvn_selfsplit.m │ │ ├── mvn_visualize.m │ │ ├── mvnfactory.m │ │ └── mvnicholfactory.m │ └── vmf │ │ ├── vmf_estimatedefault.m │ │ ├── vmf_visualize.m │ │ └── vmffactory.m ├── estimation │ ├── mxe_estimate.m │ └── split_and_merge │ │ ├── cem.m │ │ ├── smem.m │ │ ├── smile.m │ │ ├── totalmerge.m │ │ ├── totalsplit.m │ │ └── totalsplitopt.m └── gates │ ├── softmax_estimateMstep.m │ └── softmaxfactory.m ├── paper ├── paper.bib └── paper.md ├── tests ├── highlevel │ ├── spiral.mat │ ├── test_cem_spiral.m │ ├── test_crossvalidation.m │ ├── test_custom_splitinit.m │ ├── test_ecd.m │ ├── test_factorial.m │ ├── test_functions.m │ ├── test_minibatch.m │ ├── test_mixture.m │ ├── test_mnl.m │ ├── test_mvn.m │ ├── test_plotting.m │ ├── test_previnfo.m │ ├── test_simplex.m │ ├── test_smem.m │ ├── test_smile.m │ └── test_totalsplit.m ├── test_gammafactory.m ├── test_mixturefactory.m ├── test_mvnfactory.m ├── test_mxe_crossvalidation.m ├── test_mxe_mergeinfo.m ├── test_mxe_minibatch.m ├── test_mxe_options.m ├── test_mxe_plot.m ├── test_mxe_plotavg.m └── test_mxe_readdata.m └── thirdparty ├── lightspeed ├── README.txt ├── license.txt └── logsumexp.m ├── manopt ├── CLA.txt ├── COPYING.txt ├── CREDITS.txt ├── LICENSE.txt ├── README.txt ├── checkinstall │ └── basicexample.m ├── examples │ ├── dominant_invariant_subspace.m │ ├── generalized_procrustes.m │ ├── low_rank_matrix_completion.m │ ├── maxcut.m │ ├── maxcut_octave.m │ ├── packing_on_the_sphere.m │ ├── positive_definite_karcher_mean.m │ ├── sparse_pca.m │ └── truncated_svd.m ├── importmanopt.m ├── manopt │ ├── manifolds │ │ ├── complexcircle │ │ │ └── complexcirclefactory.m │ │ ├── euclidean │ │ │ ├── euclideanfactory.m │ │ │ └── symmetricfactory.m │ │ ├── fixedrank │ │ │ ├── fixedrankMNquotientfactory.m │ │ │ ├── fixedrankembeddedfactory.m │ │ │ ├── fixedrankfactory_2factors.m │ │ │ ├── fixedrankfactory_2factors_preconditioned.m │ │ │ ├── fixedrankfactory_2factors_subspace_projection.m │ │ │ ├── fixedrankfactory_3factors.m │ │ │ └── fixedrankfactory_3factors_preconditioned.m │ │ ├── grassmann │ │ │ └── grassmannfactory.m │ │ ├── oblique │ │ │ └── obliquefactory.m │ │ ├── rotations │ │ │ ├── randrot.m │ │ │ ├── randskew.m │ │ │ └── rotationsfactory.m │ │ ├── sphere │ │ │ ├── spherecomplexfactory.m │ │ │ └── spherefactory.m │ │ ├── stiefel │ │ │ └── stiefelfactory.m │ │ └── symfixedrank │ │ │ ├── elliptopefactory.m │ │ │ ├── spectrahedronfactory.m │ │ │ ├── symfixedrankYYfactory.m │ │ │ └── sympositivedefinitefactory.m │ ├── privatetools │ │ ├── applyStatsfun.m │ │ ├── canGetCost.m │ │ ├── canGetDirectionalDerivative.m │ │ ├── canGetEuclideanGradient.m │ │ ├── canGetGradient.m │ │ ├── canGetHessian.m │ │ ├── canGetLinesearch.m │ │ ├── canGetPrecon.m │ │ ├── getApproxHessian.m │ │ ├── getCost.m │ │ ├── getCostGrad.m │ │ ├── getDirectionalDerivative.m │ │ ├── getEuclideanGradient.m │ │ ├── getGlobalDefaults.m │ │ ├── getGradient.m │ │ ├── getHessian.m │ │ ├── getHessianFD.m │ │ ├── getLinesearch.m │ │ ├── getPrecon.m │ │ ├── getStore.m │ │ ├── hashmd5.m │ │ ├── mergeOptions.m │ │ ├── purgeStoredb.m │ │ ├── setStore.m │ │ └── stoppingcriterion.m │ ├── solvers │ │ ├── conjugategradient │ │ │ └── conjugategradient.m │ │ ├── linesearch │ │ │ ├── linesearch.m │ │ │ ├── linesearch_adaptive.m │ │ │ └── linesearch_hint.m │ │ ├── neldermead │ │ │ ├── centroid.m │ │ │ └── neldermead.m │ │ ├── pso │ │ │ └── pso.m │ │ ├── steepestdescent │ │ │ └── steepestdescent.m │ │ └── trustregions │ │ │ ├── license for original GenRTR code.txt │ │ │ ├── tCG.m │ │ │ └── trustregions.m │ └── tools │ │ ├── checkdiff.m │ │ ├── checkgradient.m │ │ ├── checkhessian.m │ │ ├── diagsum.m │ │ ├── hessianspectrum.m │ │ ├── identify_linear_piece.m │ │ ├── multiprod.m │ │ ├── multiprodmultitransp_license.txt │ │ ├── multiscale.m │ │ ├── multiskew.m │ │ ├── multisym.m │ │ ├── multitrace.m │ │ ├── multitransp.m │ │ ├── plotprofile.m │ │ ├── powermanifold.m │ │ └── productmanifold.m └── manopt_version.m ├── matlab-xunit-master ├── README.md ├── license.txt └── src │ ├── +xunit │ └── +utils │ │ ├── Contents.m │ │ ├── arrayToString.m │ │ ├── compareFloats.m │ │ ├── comparisonMessage.m │ │ ├── containsRegexp.m │ │ ├── generateDoc.m │ │ ├── isAlmostEqual.m │ │ ├── isSetUpString.m │ │ ├── isTearDownString.m │ │ ├── isTestCaseSubclass.m │ │ ├── isTestString.m │ │ ├── parseFloatAssertInputs.m │ │ └── stringToCellArray.m │ ├── CommandWindowTestRunDisplay.m │ ├── FunctionHandleTestCase.m │ ├── TestCase.m │ ├── TestCaseInDir.m │ ├── TestCaseWithAddPath.m │ ├── TestComponent.m │ ├── TestComponentInDir.m │ ├── TestRunDisplay.m │ ├── TestRunLogger.m │ ├── TestRunMonitor.m │ ├── TestSuite.m │ ├── TestSuiteInDir.m │ ├── VerboseTestRunDisplay.m │ ├── XMLTestRunLogger.m │ ├── assertElementsAlmostEqual.m │ ├── assertEqual.m │ ├── assertExceptionThrown.m │ ├── assertFalse.m │ ├── assertFilesEqual.m │ ├── assertTrue.m │ ├── assertVectorsAlmostEqual.m │ ├── initTestSuite.m │ ├── runxunit.m │ ├── xml_read.m │ └── xml_write.m ├── randraw ├── license.txt └── randraw.m └── vmfmatlab ├── emsamp.m ├── house.m ├── logbesseli.m ├── mixinit.m ├── movmf.m ├── testmle.m ├── unitrand.m └── vsamp.m /.gitignore: -------------------------------------------------------------------------------- 1 | ##--------------------------------------------------- 2 | ## Remove autosaves generated by the Matlab editor 3 | ## We have git for backups! 4 | ##--------------------------------------------------- 5 | 6 | # Windows default autosave extension 7 | *.asv 8 | 9 | # OSX / *nix default autosave extension 10 | *.m~ 11 | .DS_Store 12 | 13 | # Compiled MEX binaries (all platforms) 14 | *.mex* 15 | 16 | # Simulink Code Generation 17 | slprj/ 18 | 19 | # Search databases (created by builddocsearchdb) 20 | helpsearch/ 21 | 22 | 23 | # files only included in release versions 24 | doc/public/ 25 | Contents.m 26 | 27 | 28 | # published html except for manually-created ones 29 | *.html 30 | !doc/source/*.html 31 | !doc/source/api/*.html 32 | !doc/source/examples/*.html 33 | !doc/source/_jekyll/_layouts/*.html 34 | !doc/source/_jekyll/_includes/*.html 35 | 36 | # published graphics except for manually-created ones 37 | *.png 38 | !doc/source/img/*.png 39 | !doc/source/api/img/*.png 40 | !doc/source/examples/img/*.png 41 | 42 | # other special files 43 | doc/source/_jekyll/helptoc.xml -------------------------------------------------------------------------------- /doc/source/_jekyll/_config.yml: -------------------------------------------------------------------------------- 1 | # Site settings 2 | title: MixEst 3 | description: > 4 | MixEst - The Mixture-Model Estimation Toolbox 5 | 6 | # Build settings 7 | destination: ../../public 8 | markdown: kramdown 9 | highlighter: rouge #false # temporarily added because of pygments.rb issue on Windows 10 | -------------------------------------------------------------------------------- /doc/source/_jekyll/_includes/after_footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /doc/source/_jekyll/_includes/breadcrumbs.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/source/_jekyll/_includes/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /doc/source/_jekyll/_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% if page.title %}{{ page.title }} | {% endif %}{{ site.title }} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | -------------------------------------------------------------------------------- /doc/source/_jekyll/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include head.html %} 5 | 6 | 7 | 8 |
9 | 10 | {{ content }} 11 | 12 | {% include footer.html %} 13 | 14 |
15 | 16 | {% include after_footer.html %} 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /doc/source/_jekyll/_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 |
7 |

{{ page.title }}{% if page.subtitle %} {{ page.subtitle }}{% endif %} 8 |

9 | 10 | {% include breadcrumbs.html %} 11 | 12 |
13 |
14 | 15 | 16 | 17 |
18 |
19 | 20 | {{ content }} 21 | 22 |
23 |
24 | 25 | 26 |
27 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/_jekyll/font-awesome-4.1.0/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/_jekyll/font-awesome-4.1.0/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/_jekyll/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/_jekyll/font-awesome-4.1.0/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .@{fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "spinning.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: -@fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon-rotate(@degrees, @rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); 6 | -webkit-transform: rotate(@degrees); 7 | -moz-transform: rotate(@degrees); 8 | -ms-transform: rotate(@degrees); 9 | -o-transform: rotate(@degrees); 10 | transform: rotate(@degrees); 11 | } 12 | 13 | .fa-icon-flip(@horiz, @vert, @rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1); 15 | -webkit-transform: scale(@horiz, @vert); 16 | -moz-transform: scale(@horiz, @vert); 17 | -ms-transform: scale(@horiz, @vert); 18 | -o-transform: scale(@horiz, @vert); 19 | transform: scale(@horiz, @vert); 20 | } 21 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}')"; 7 | src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype')", 8 | ~"url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff')", 9 | ~"url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype')", 10 | ~"url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg')"; 11 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/spinning.less: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @keyframes spin { 24 | 0% { 25 | -webkit-transform: rotate(0deg); 26 | transform: rotate(0deg); 27 | } 28 | 100% { 29 | -webkit-transform: rotate(359deg); 30 | transform: rotate(359deg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon-rotate($degrees, $rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 6 | -webkit-transform: rotate($degrees); 7 | -moz-transform: rotate($degrees); 8 | -ms-transform: rotate($degrees); 9 | -o-transform: rotate($degrees); 10 | transform: rotate($degrees); 11 | } 12 | 13 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 15 | -webkit-transform: scale($horiz, $vert); 16 | -moz-transform: scale($horiz, $vert); 17 | -ms-transform: scale($horiz, $vert); 18 | -o-transform: scale($horiz, $vert); 19 | transform: scale($horiz, $vert); 20 | } 21 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 9 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 10 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 11 | //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/_spinning.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @keyframes spin { 24 | 0% { 25 | -webkit-transform: rotate(0deg); 26 | transform: rotate(0deg); 27 | } 28 | 100% { 29 | -webkit-transform: rotate(359deg); 30 | transform: rotate(359deg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /doc/source/_jekyll/font-awesome-4.1.0/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "spinning"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /doc/source/_jekyll/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/_jekyll/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /doc/source/_jekyll/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/_jekyll/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /doc/source/_jekyll/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/_jekyll/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /doc/source/_jekyll/js/site.js: -------------------------------------------------------------------------------- 1 | // activate scrollspy and affix for sidenav 2 | $('body').scrollspy({ target: '#sidenav' }); 3 | $('#sidenav').affix({ 4 | offset: { 5 | top: 165 6 | } 7 | }) 8 | 9 | // smooth scrolling 10 | $('a[href*=#]:not([href=#])').click(function() { 11 | if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) { 12 | var target = $(this.hash); 13 | target = target.length ? target : $('[name=' + this.hash.slice(1) +']'); 14 | if (target.length) { 15 | $('html,body').animate({ 16 | scrollTop: target.offset().top 17 | }, 800); 18 | return false; 19 | } 20 | } 21 | }); 22 | 23 | // Back to top 24 | $(document).ready(function(){ 25 | $('body').append('
'); 26 | $(window).scroll(function () { 27 | if ($(this).scrollTop() != 0) { 28 | $('#toTop').fadeIn(); 29 | } else { 30 | $('#toTop').fadeOut(); 31 | } 32 | }); 33 | $('#toTop').click(function(){ 34 | $("html, body").animate({ scrollTop: 0 }, 600); 35 | return false; 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /doc/source/api/img/ecdfactory_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/api/img/ecdfactory_01.png -------------------------------------------------------------------------------- /doc/source/api/img/gammafactory_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/api/img/gammafactory_01.png -------------------------------------------------------------------------------- /doc/source/api/img/mixturefactory_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/api/img/mixturefactory_01.png -------------------------------------------------------------------------------- /doc/source/api/img/mixturefactory_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/api/img/mixturefactory_02.png -------------------------------------------------------------------------------- /doc/source/api/img/mvn2factory_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/api/img/mvn2factory_01.png -------------------------------------------------------------------------------- /doc/source/api/img/mvnfactory_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/api/img/mvnfactory_01.png -------------------------------------------------------------------------------- /doc/source/api/img/vmffactory_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/api/img/vmffactory_01.png -------------------------------------------------------------------------------- /doc/source/caching.m: -------------------------------------------------------------------------------- 1 | %% Caching Intermediate Results 2 | 3 | %% 4 | % Some distribution functions allow for a special input and output named 5 | % |store|. This is a structure wherein the function can store the 6 | % intermediate calculation results that it has done for a set of inputs, as 7 | % its fields. These results might speed up things when calling another 8 | % function of the distribution with the same set of inputs. For instance, 9 | % the usual syntax for the |ll| function which calculates log-likelihoods 10 | % is: 11 | % 12 | % ll = D.ll(theta, data) 13 | % 14 | % But this function also admits the following syntax: 15 | % 16 | % [ll, store] = D.ll(theta, data, store) 17 | % 18 | % where, either |store| is optional. If we also need the gradient of the 19 | % log-likelihood (|llgrad|) for the same |theta| and |data|, we can use the 20 | % |store| output from the |ll| function as an input to the |llgrad| 21 | % function to prevent |llgrad| from re-calculating the intermediate values 22 | % which are shared in the two functions: 23 | % 24 | % [ll, store] = D.ll(theta, data); 25 | % dll = D.llgrad(theta, data, store); 26 | % 27 | % Please note that you should only share the |store| while working with the 28 | % same distribution and inputs (|theta| and |data|). When these are 29 | % changed, a new store structure should be used, or you will get wrong 30 | % results. 31 | % 32 | -------------------------------------------------------------------------------- /doc/source/data_input.m: -------------------------------------------------------------------------------- 1 | %% Data Input Argument to Functions 2 | % In MixEst, all the functions taking a |data| input argument, can accept 3 | % the data in one of the following forms: 4 | % 5 | 6 | %% Data Matrix 7 | % In matrix form, the data is arranged in an n-by-N matrix where |n| is 8 | % the dimensions of the data space and |N| is the number of data points 9 | % (i.e. each column of the matrix represents a single observation). 10 | % 11 | % *Example* 12 | % 13 | % % create a distribution and random parameters 14 | % D = mvnfactory(2); 15 | % theta = D.randparam(); 16 | % % generate 1000 random 2-dimensional data points 17 | % data = randn(2, 1000); 18 | % % pass the data to the ll function 19 | % ll = D.ll(theta, data) 20 | % 21 | % *Note:* In MATLAB versions R2011b and above, instead of the data matrix, 22 | % you can give a |matlab.io.MatFile| object referring to a MAT-file 23 | % containing a variable named |data| with specifications as pointed out 24 | % above. 25 | % 26 | 27 | %% Data Structure 28 | % Using the structure form, you can pass along with the data matrix, the 29 | % indices of a subset of data points and/or a weighting vector on the data 30 | % points whenever applicable. In this form, |data| is a structure with the 31 | % following fields (All fields except |data| are optional): 32 | % 33 | % * *|data|* (|n-by-N|) The data matrix as described in the previous 34 | % section. 35 | % * *|index|* (|1-by-L|) Data indexing vector for selecting a subset of 36 | % data (Only numeric indexing is supported. Logical indexing is not 37 | % supported). 38 | % * *|weight|* (|1-by-N|, or |1-by-L| if indexing is used) Data weighting 39 | % vector containing values between zero and one to be multiplied by each 40 | % data point. 41 | % 42 | % where |n| is the dimensions of the data space, |N| is the total number of 43 | % data points, and |L| is the number of points in the indexed subset of 44 | % data. 45 | % 46 | % *Example 1* 47 | % 48 | % % create a distribution and random parameters 49 | % D = mvnfactory(2); 50 | % theta = D.randparam(); 51 | % % generate 1000 random 2-dimensional data points 52 | % data = randn(2, 1000); 53 | % % use only the 100th up to 200th points from the data 54 | % index = 100:200; 55 | % % generate random weights for the selected data 56 | % weight = rand(1, 101); % 101 is the number of elements in index 57 | % % build the data structure 58 | % data = struct('data', data, 'index', index, 'weight', weight); 59 | % % pass the data to the ll function 60 | % ll = D.ll(theta, data) 61 | % 62 | % *Example 2* 63 | % 64 | % D = mvnfactory(2); 65 | % theta = D.randparam(); 66 | % ll = D.ll(theta, struct('data', randn(2,1000), 'weight', rand(1,1000))) 67 | % -------------------------------------------------------------------------------- /doc/source/distribution_parameters.m: -------------------------------------------------------------------------------- 1 | %% Distribution Parameters Structure 2 | % Since by design, we keep the distribution parameters apart from the 3 | % distribution structure, many functions of the distributions require a 4 | % parameter structure |theta| to be passed in, or output this parameter 5 | % structure. In what follows we describe this structure in detail (well, 6 | % there is not that much detail, actually). 7 | % 8 | 9 | %% Structure Description 10 | % |theta| is a structure with field names corresponding to parameter names 11 | % defined in the respective distribution, and values equal to the desired 12 | % parameter values. 13 | % 14 | % *Example* 15 | % 16 | % The parameters for a multi-variate normal distribution are |mu| for the 17 | % mean, and |sigma| for the covariance matrix. So we can construct a 18 | % parameter structure for this distribution like this: 19 | % 20 | % theta = struct('mu', [1; 2], 'sigma', [2 1; 3 4]); 21 | % 22 | % or equivalently like this: 23 | % 24 | % theta.mu = [1; 2]; 25 | % theta.sigma = [2 1; 3 4]; 26 | % 27 | % Then we can pass |theta| to the distribution functions. For example: 28 | % 29 | % D = mvnfactory(2); 30 | % h = D.entropy(theta) 31 | % 32 | % h = 33 | % 3.8108 34 | % 35 | 36 | %% Relation with Manopt Manifolds 37 | % MixEst distribution parameter structures (|theta|) are actually points on 38 | % some specific manifold representing the compound geometry of valid values 39 | % for all of the parameters of the distribution. The manifold is created 40 | % using the |productmanifold| function from the to build a product of the manifolds corresponding to each 42 | % parameter, and therefore you can work with the value of each parameter 43 | % using a field in |theta|. 44 | % 45 | % The Manopt manifold of parameters for a distribution structure |D| can be 46 | % accessed using |D.M|. 47 | % 48 | -------------------------------------------------------------------------------- /doc/source/estimation_statistics_structure.m: -------------------------------------------------------------------------------- 1 | %% Estimation Statistics Structure 2 | 3 | %% 4 | % Every iterative estimation function in MixEst, returns some information 5 | % about its progress at each iteration. This information is output as the 6 | % structure array |info| from the estimation function: 7 | % 8 | % [theta, D, info, options] = estimation_function(...) 9 | % 10 | % Each element in |info| is a structure with fields corresponding to each 11 | % logged info. For instance |info(1).iter| contains zero (since the 12 | % iterations are numbered starting at zero) and |info(end).iter| contains 13 | % the last iteration number. You may also use the |[info.cost]| syntax to 14 | % get all the logged costs for all iterations as a vector. The following 15 | % example plots the cost by iterations: 16 | % 17 | % plot([info.iter], [info.cost]) 18 | % 19 | % You can find information about the fields present in |info| output for 20 | % each estimation function in its documentation. When a Manopt solver is 21 | % used in the estimation, the |info| returned by the Manopt solver is 22 | % returned directly. 23 | % -------------------------------------------------------------------------------- /doc/source/helptoc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MixEst Toolbox 5 | User Guide 6 | 7 | API Reference 8 | 9 | Examples 10 | 11 | Developer Guide 12 | 13 | Online Web Site 14 | 15 | 16 | -------------------------------------------------------------------------------- /doc/source/img/user_guide_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/img/user_guide_01.png -------------------------------------------------------------------------------- /doc/source/user_guide.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/doc/source/user_guide.m -------------------------------------------------------------------------------- /examples/data2d.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/examples/data2d.mat -------------------------------------------------------------------------------- /examples/data_iris.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/examples/data_iris.mat -------------------------------------------------------------------------------- /examples/data_sm.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/examples/data_sm.mat -------------------------------------------------------------------------------- /examples/example1.m: -------------------------------------------------------------------------------- 1 | %% Example 1 2 | 3 | %% 4 | % This example visualizes the estimation process of a mixture of three 5 | % Gaussians on sample 2-D data. 6 | % 7 | 8 | function example1 9 | 10 | clc 11 | clear 12 | close all 13 | 14 | load data2d 15 | 16 | num = 3; 17 | D = mixturefactory(mvn2factory(2), num); 18 | 19 | 20 | % graphical visualization 21 | figure('Units', 'normalized', 'OuterPosition', [0 0 1 1]) 22 | options.visualization.axes = subplot(2,2,[1 3]); 23 | options.visualization.mixture.colorize = true; 24 | % options.visualization.dataPlotType = 'scatter'; 25 | options.visualization.stopOnClose = true; 26 | 27 | % plotting 28 | options.plotCost.axes = subplot(2,2,2); 29 | options.plotGradNorm.axes = subplot(2,2,4); 30 | 31 | % main options 32 | options.verbosity = 2; 33 | options.solver = 'sgd'; 34 | options.sgd.stepsize = 1; 35 | batchnum = size(data,2)/(2*5); 36 | it = 20; 37 | options.sgd.batchnum = batchnum; 38 | options.sgd.base = 10^(-3/batchnum/it); 39 | % options.crossVal = true; 40 | % options.crossVal.tolIter = 100; 41 | % options.tolCostDiff = -Inf; 42 | options.penalize = true; 43 | % options.minibatch.iter = 5; 44 | % options.minibatch.discardHistory = false; 45 | % options.minibatch.size = 300; 46 | % options.regularize = true; 47 | 48 | % perform estimation 49 | D.estimate(data, options) 50 | -------------------------------------------------------------------------------- /examples/example2.m: -------------------------------------------------------------------------------- 1 | %% Example 2 2 | 3 | %% 4 | % This example uses a mixture of multinomial logistic experts to classify 5 | % Fisher's iris data. 6 | % 7 | 8 | function example2 9 | 10 | clc 11 | clear 12 | %close all 13 | 14 | load data_iris 15 | 16 | % random permute the iris data 17 | index = randperm(150); 18 | % load rndprm150 19 | data = data(:, index); 20 | 21 | % Use 120 data for training 22 | data_train = data(:, 1:120); 23 | data_test = data(:, 121:150); 24 | datadim = size(data_train,1) - 1; 25 | num = max(data(end,:),[], 2); 26 | 27 | % create a mixture of multivariate logit 28 | nummix = 3; % number of components in gate 29 | E = mnlfactory(datadim, num); % expert 30 | G = softmaxfactory(nummix, datadim); % gate 31 | D = moefactory(G, E); 32 | %D = E; 33 | % figure('units', 'normalized', 'outerposition', [0 0 1 1]) 34 | 35 | % plotting options 36 | options.plotcost = true; 37 | 38 | 39 | % main options 40 | options.verbosity = 2; 41 | options.solver = 'lbfgs'; 42 | options.tolcostdiff = 1e-6; 43 | %options.crossval = true; 44 | options.minibatch.size = 10; 45 | options.maxiter = 200; 46 | options.minibatch.discardhistory = false; 47 | options.crossval.toliter = 100; 48 | 49 | % perform estimation 50 | theta = D.estimate(data_train, options); 51 | 52 | % perform prediction 53 | data_pred = D.predict(theta, data_test); 54 | label = data_test(end,:) 55 | data_pred 56 | disp(['percentage of correct classification : ' ... 57 | num2str(sum((label-data_pred)==0) * 100 /30)]); -------------------------------------------------------------------------------- /examples/example3.m: -------------------------------------------------------------------------------- 1 | %% Example 3 2 | 3 | %% 4 | % This example visualizes the estimation process of a mixture of von 5 | % Mises-Fisher distributions on sample data. 6 | % 7 | 8 | function example3 9 | 10 | clc 11 | clear 12 | close all 13 | 14 | num = 5; 15 | D = mixturefactory(vmffactory(3), num); 16 | 17 | theta = D.randparam(); 18 | for k = 1 : num 19 | theta.D{k}.kappa = theta.D{k}.kappa*10 +10; 20 | end 21 | 22 | data = D.sample(theta, 5000); 23 | 24 | figure('units', 'normalized', 'outerposition', [0 0 1 1]) 25 | 26 | % graphical visualization 27 | options.visualization.axes = subplot(2,2,[1 3]); 28 | options.visualization.mixture.colorize = true; 29 | % options.visualization.dataplottype = 'scatter'; 30 | 31 | 32 | % % graphical visualization init 33 | % viz = subplot(2,2,[1 3]); 34 | % plot3(viz, data(1, :), data(2, :), data(3, :), '.', ... 35 | % 'MarkerSize', 4, 'Marker', '.'); 36 | % options.stopfun = @(D, theta, info, last) stopfun(D, theta, data, viz); 37 | 38 | 39 | % plotting options 40 | options.plotcost.axes = subplot(2,2,2); 41 | options.plotgradnorm.axes = subplot(2,2,4); 42 | 43 | % main options 44 | options.verbosity = 2; 45 | options.solver = 'default'; 46 | % options.crossval = true; 47 | % options.cvtoliter = 100; 48 | options.tolcostdiff = 1e-5; 49 | %options.penalize = true; 50 | %options.minibatchiter = 5; 51 | %options.minibatchdiscardhistory = false; 52 | %options.minibatchsize = 300; 53 | options.regularize = true; 54 | % perform estimation 55 | D.estimate(data, options); 56 | 57 | 58 | function stopnow = stopfun(D, theta, data, viz) 59 | % update the graphical visualization 60 | colors = hsv(D.num()); % {[ 0 0 1], [0 1 0], [1 0 0]}; 61 | weights = D.weighting(theta, data); 62 | [notused, ind] = max(weights,[],1); 63 | hold(viz, 'off'); 64 | for k = 1 : D.num() 65 | mu = theta.D{k}.mu; 66 | plot3(viz, data(1,ind==k), data(2,ind==k), data(3,ind==k), '.', ... 67 | 'MarkerSize', 4, 'Color', colors(k,:), 'Marker', '.'); 68 | %set(h, 'MarkerSize', 4, 'Color', colors{k}, 'Marker', '.'); 69 | h = line([0 mu(1)], [0 mu(2)], [0 mu(3)], 'Parent', viz, ... 70 | 'LineWidth', 2, 'Color', colors(k,:)); 71 | %set(h, 'LineWidth', 2, 'Color', colors{k}, 'Parent', viz); 72 | if k == 1 73 | hold(viz, 'on'); 74 | end 75 | end 76 | drawnow 77 | pause(0.3) 78 | stopnow = false; -------------------------------------------------------------------------------- /examples/example4.m: -------------------------------------------------------------------------------- 1 | %% Example 4 2 | 3 | %% 4 | % This example visualizes the estimation process of a modified version of 5 | % the Competitive EM (CEM) algorithm (Zhang et al., 2004) on sample 2-D 6 | % data. 7 | % 8 | 9 | function example4 10 | 11 | clc 12 | clear 13 | close all 14 | 15 | f = load('data_sm'); 16 | data = f.data; 17 | 18 | % visualization and plotting options 19 | figure('Units', 'normalized', 'OuterPosition', [0 0 1 1]) 20 | options.visualization.axes = subplot(2,2,[1 3]); 21 | options.plotCost.axes = subplot(2,2,2); 22 | options.plotGradNorm.axes = subplot(2,2,4); 23 | options.visualization.mixture.colorize = true; 24 | options.visualization.stopOnClose = true; 25 | 26 | % common estimation options 27 | options.verbosity = 1; 28 | options.solver = 'lbfgs'; 29 | options.tolCostDiff = 1e-3; 30 | 31 | % % split-and-merge options 32 | % options.sm.splitCriterion = 'kl'; 33 | % options.sm.mergeCriterion = 'kl'; 34 | % options.sm.splitInit = 'default'; 35 | % options.sm.mergeInit = 'default'; 36 | % options.sm.numInit = 1; 37 | % options.sm.numMin = 1; 38 | % options.sm.numMax = 15; 39 | % options.sm.mergeMaxCands = 5; 40 | % options.sm.splitMaxCands = 5; 41 | % options.sm.maxFail = 2; 42 | % options.sm.ComponentD = mvnfactory2(2); 43 | 44 | 45 | % run 46 | splitTmerge(data, 7, options) 47 | -------------------------------------------------------------------------------- /info.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | - 6 | MixEst 7 | toolbox 8 | 9 | doc/public/ 10 | $toolbox/matlab/icons/bookicon.gif 11 | 12 | -------------------------------------------------------------------------------- /install_mixest.m: -------------------------------------------------------------------------------- 1 | function install_mixest 2 | 3 | fprintf('Installing the MixEst toolbox...\n'); 4 | 5 | % Find required paths 6 | this_file = mfilename('fullpath'); % get this file's path and name (without .m) 7 | toolbox_root_path = fileparts(this_file); 8 | 9 | % Add MixEst folders to search path 10 | fprintf('Adding MixEst folders to search path...\n'); 11 | addpath(toolbox_root_path) 12 | addpath(genpath(fullfile(toolbox_root_path, 'mixest'))) 13 | addpath(genpath(fullfile(toolbox_root_path, 'thirdparty'))) 14 | fprintf('[Done]\n') 15 | 16 | % Compile mex files 17 | fprintf('Compiling mex files...\n'); 18 | mex_dir = fullfile(toolbox_root_path, 'mixest', 'auxiliary', 'manopt_manifolds', 'positivedefinite'); 19 | mex('-outdir', mex_dir, fullfile(mex_dir, 'sqrtm_triu_real.c')); 20 | mex('-outdir', mex_dir, fullfile(mex_dir, 'sqrtm_triu_complex.c')); 21 | fprintf('[Done]\n') 22 | 23 | fprintf('\nMixEst has been successfully installed.\n'); 24 | fprintf('You can use "Set Path" -> "Save" from MATLAB menus to save the added paths permanently.\n\n'); 25 | 26 | % build search database for the documentation 27 | fprintf('Building search database for the documentation (Optional Step)...\n') 28 | builddocsearchdb(fullfile(toolbox_root_path, 'doc', 'public')) 29 | fprintf('[Done]\n') 30 | 31 | fprintf('\nAll Done!\n\n') 32 | -------------------------------------------------------------------------------- /mixest/auxiliary/checking/check_grad.m: -------------------------------------------------------------------------------- 1 | %% |check_grad| 2 | % *Note:* This is a private function. 3 | % 4 | % Checking gradient derivation of log-likelihood 5 | % 6 | % *Syntax* 7 | % 8 | % check_grad(D, theta, data) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function check_grad(D, theta, data) 22 | 23 | if nargin < 3 24 | nrd = 10000; 25 | data = D.sample(theta, nrd); 26 | else 27 | data = mxe_readdata(data); 28 | nrd = data.size; 29 | data = data.data; 30 | end 31 | 32 | disp(['Numerical Checking using ' num2str(nrd) ' datapoints']); 33 | 34 | % First checking the entropy derivation 35 | disp(' '); 36 | disp('+++ Checking Gradient -> grad(theta) +++'); 37 | x0 = obj2vec(theta); 38 | gnum = finidiff(x0, @(x)fun(D, theta, x, data)); 39 | [f, gth] = fun(D, theta, x0, data); 40 | 41 | disp([' Numerical Gradient: ' num2str(gnum)]); 42 | disp([' Theoretical Gradient: ' num2str(gth')]); 43 | disp([' Maximum Difference: ',num2str(max(abs(gnum-gth')))]); 44 | 45 | 46 | function g = finidiff(x, fun) 47 | 48 | f = fun(x); 49 | len = length(x); 50 | delf = zeros(1,len); 51 | mu = 1e-6*(1+norm(x))/len; 52 | for k = 1:len 53 | e_k = zeros(len,1); 54 | e_k(k) = 1; 55 | delf(k) = fun(x + mu*e_k); 56 | end 57 | g = (delf-f)/mu; 58 | 59 | 60 | function [y, dy] = fun(D, theta, x, data) 61 | 62 | px = vec2obj(theta, x); 63 | if nargout>1 64 | [y, store] = D.ll(px, data); 65 | dd = D.llgrad(px, data, store); 66 | dy = obj2vec(dd); 67 | else 68 | y = D.ll(px, data); 69 | end -------------------------------------------------------------------------------- /mixest/auxiliary/checking/check_kl.m: -------------------------------------------------------------------------------- 1 | %% |check_kl| 2 | % *Note:* This is a private function. 3 | % 4 | % Checking kl-divergence derivation 5 | % 6 | % *Syntax* 7 | % 8 | % check_kl(D, p1, p2) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function check_kl(D, p1, p2) 22 | 23 | if nargin < 3 24 | p2 = D.randparam(); 25 | end 26 | if nargin < 2 27 | p1 = D.randparam(); 28 | end 29 | nrd = 200000; 30 | disp(['Numerical Checking using ' num2str(nrd) ' datapoints']); 31 | data = D.sample(p1, nrd); 32 | 33 | % First checking the entropy derivation 34 | disp(' '); 35 | disp('+++ Checking Entropy -> entropy(theta1) +++'); 36 | disp([' Numerical Entropy:' num2str(-D.ll(p1,data)/nrd)]); 37 | disp([' Theoretical Entropy:' num2str(D.entropy(p1))]); 38 | 39 | % Now checking kl-divergence derivation 40 | disp(' '); 41 | disp('+++ Checking KL-divergence -> kl(theta1||theta2) +++'); 42 | disp([' Numerical KL:' num2str((D.ll(p1,data)-D.ll(p2,data))/nrd)]); 43 | disp([' Theoretical KL:' num2str(D.kl(p1,p2))]); -------------------------------------------------------------------------------- /mixest/auxiliary/checking/obj2vec.m: -------------------------------------------------------------------------------- 1 | %% |obj2vec| 2 | % *Note:* This is a private function. 3 | % 4 | % Convert the object into a vector 5 | % 6 | % *Syntax* 7 | % 8 | % vecOut = obj2vec(obj) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function vecOut = obj2vec(obj) 22 | 23 | if isobject(obj) 24 | vecOut = obj.obj2vec(); 25 | elseif iscell(obj) 26 | L=objlen(obj); 27 | vecOut=zeros(L,1); 28 | beginIt=0; 29 | for k=1:length(obj) 30 | l=objlen(obj{k}); 31 | if l>0 32 | vecOut( beginIt+1:beginIt+l)=obj2vec(obj{k}); 33 | end 34 | beginIt=beginIt+l; 35 | end 36 | elseif isstruct(obj) 37 | st=fieldnames(obj); 38 | L=objlen(obj); 39 | vecOut=zeros(L,1); 40 | beginIt=0; 41 | for k=1:length(st) 42 | l=objlen(obj.(st{k})); 43 | if l>0 44 | vecOut(beginIt+1:beginIt+l)=obj2vec( obj.(st{k}) ); 45 | end 46 | beginIt=beginIt+l; 47 | end 48 | elseif isnumeric(obj) 49 | vecOut=obj(:); 50 | else ischar(obj) 51 | vecOut=[]; 52 | end -------------------------------------------------------------------------------- /mixest/auxiliary/checking/objlen.m: -------------------------------------------------------------------------------- 1 | %% |objlen| 2 | % *Note:* This is a private function. 3 | % 4 | % Calculate the number of numerical elements in obj 5 | % 6 | % *Syntax* 7 | % 8 | % l = objlen(obj) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function l = objlen(obj) 22 | 23 | if isobject(obj) 24 | l = obj.objlen(); 25 | elseif iscell(obj) 26 | l=0; 27 | for k=1:length(obj) 28 | l=l+objlen(obj{k}); 29 | end 30 | elseif isstruct(obj) 31 | st=fieldnames(obj); 32 | l=0; 33 | for k=1:length(st) 34 | l=l+objlen(obj.(st{k})); 35 | end 36 | elseif isnumeric(obj) 37 | l=numel(obj); 38 | elseif ischar(obj) 39 | l=0; 40 | end -------------------------------------------------------------------------------- /mixest/auxiliary/checking/vec2obj.m: -------------------------------------------------------------------------------- 1 | %% |vec2obj| 2 | % *Note:* This is a private function. 3 | % 4 | % Convert the vector |vec| into an object like the sample object |obj| 5 | % 6 | % *Syntax* 7 | % 8 | % obj = vec2obj(obj, vec) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function obj = vec2obj(obj, vec) 22 | 23 | if isobject(obj) 24 | obj = obj.vec2obj(vec); 25 | elseif iscell(obj) 26 | beginIt = 0; 27 | for k = 1:length(obj) 28 | l = objlen(obj{k}); 29 | if l > 0 30 | obj{k} = vec2obj( obj{k}, vec(beginIt+1:beginIt+l) ); 31 | end 32 | beginIt = beginIt + l; 33 | end 34 | elseif isstruct(obj) 35 | st = fieldnames(obj); 36 | beginIt = 0; 37 | for k = 1:length(st) 38 | l = objlen(obj.(st{k})); 39 | if l > 0 40 | obj.(st{k}) = vec2obj( obj.(st{k}), vec(beginIt+1:beginIt+l) ); 41 | end 42 | beginIt = beginIt + l; 43 | end 44 | elseif isnumeric(obj) 45 | obj = reshape(vec, size(obj)); 46 | end -------------------------------------------------------------------------------- /mixest/auxiliary/estimation/mxe_adjustoptions.m: -------------------------------------------------------------------------------- 1 | %% |mxe_adjustoptions| 2 | % *Note:* This is a private function. 3 | % 4 | % Makes the required adjustments to |options| fields like |maxiter| when 5 | % using |options.previnfo| to continue from a previous estimation. 6 | % 7 | % *Syntax* 8 | % 9 | % options = mxe_adjustoptions(options, stats) 10 | % 11 | 12 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 13 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 14 | % 15 | % Contributors: 16 | % Reshad Hosseini 17 | % Mohamadreza Mash'al 18 | % 19 | % Change log: 20 | % 21 | 22 | function options = mxe_adjustoptions(options, stats) 23 | % stats is normally options.previnfo(end) 24 | 25 | options.miniter = options.miniter + stats.iter; 26 | options.maxiter = options.maxiter + stats.iter; 27 | if isfield(stats, 'time') 28 | options.maxtime = options.maxtime + stats.time; 29 | end 30 | if isfield(stats, 'costevals') 31 | options.maxcostevals = options.maxcostevals + stats.costevals; 32 | end 33 | 34 | end -------------------------------------------------------------------------------- /mixest/auxiliary/estimation/mxe_egradbatch.m: -------------------------------------------------------------------------------- 1 | %% |mxe_costgrad| 2 | % *Note:* This is a private function. 3 | % 4 | % Returns the Riemannian gradient of cost (negative log-likelihood) 5 | % with respect to distribution parameters calculated on data, considering 6 | % penalization, etc. Used in gradient-based estimation functions. 7 | % 8 | % Since it is for SGD no databatchsize is necessary 9 | % 10 | % 11 | % *Syntax* 12 | % 13 | % grad = mxe_gradbatch(D, theta, data, options) 14 | % 15 | 16 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 17 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 18 | % 19 | % Contributors: 20 | % Reshad Hosseini 21 | % Mohamadreza Mash'al 22 | % 23 | % Change log: 24 | % 25 | 26 | function egrad = mxe_egradbatch(D, theta, data, batch_index, options) 27 | % Note: options are NOT optional here. Following fields are required: 28 | % 29 | % * penalize 30 | % * penalizerTheta (must contain valid penalizer parameters if penalize is true) 31 | % * dataPatchSize 32 | % 33 | 34 | if nargin < 5 35 | options.sgd.batchnum = 1; 36 | batch_index = 1; 37 | end 38 | % We don't use Manopt stores because it reduces performance due to 39 | % calculating the gradient in line-search. 40 | data = mxe_readdata(data, false); 41 | idx = data.index; 42 | datamat = data.data; 43 | data_size = length(idx); 44 | 45 | if options.penalize 46 | % Calculating the penalizer gradient 47 | egradPen = D.penalizergrad(theta, options.penalizertheta); 48 | end 49 | 50 | egrad = D.llgrad(theta, datamat(:, idx(batch_index))); 51 | egrad = D.scaleparam(-1/length(batch_index), egrad); 52 | if options.penalize 53 | egradPen = D.scaleparam(-1/data_size, egradPen); 54 | egrad = D.sumparam(egrad, egradPen); 55 | end 56 | 57 | end 58 | -------------------------------------------------------------------------------- /mixest/auxiliary/estimation/mxe_getplotdata.m: -------------------------------------------------------------------------------- 1 | %% |mxe_getplotdata| 2 | % *Note:* This is a private function. 3 | % 4 | % Extract plot data from info 5 | % 6 | % *Syntax* 7 | % 8 | % [ploty, plotx] = mxe_getplotdata(fieldname, plot_options, info, last) 9 | % [ploty, plotx] = mxe_getplotdata(fieldname, plot_options, info, last, previter, allinfo, allinfolast) 10 | % 11 | 12 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 13 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 14 | % 15 | % Contributors: 16 | % Reshad Hosseini 17 | % Mohamadreza Mash'al 18 | % 19 | % Change log: 20 | % 21 | 22 | function [ploty, plotx] = mxe_getplotdata(fieldname, plot_options, info, last, previter, allinfo, allinfolast) 23 | 24 | if nargin < 5 25 | 26 | 27 | if plot_options.itercount <= last 28 | % available info is enough 29 | plotx = [info(last-plot_options.itercount+1 : last).iter]; 30 | ploty = [info(last-plot_options.itercount+1 : last).(fieldname)]; 31 | else 32 | % available info is less than iterCount 33 | plotx = [info(1:last).iter]; 34 | ploty = [info(1:last).(fieldname)]; 35 | end 36 | 37 | 38 | else 39 | 40 | 41 | iterCount = plot_options.itercount; 42 | if iterCount == Inf 43 | % iterCount==Inf => plot all info 44 | if previter > 0 45 | plotx = [allinfo.iter, info(2:last).iter]; 46 | ploty = [allinfo.(fieldname), info(2:last).(fieldname)]; 47 | else 48 | plotx = [info(1:last).iter]; 49 | ploty = [info(1:last).(fieldname)]; 50 | end 51 | elseif iterCount 0 57 | % we need info from previous runs 58 | startidx = max(allinfolast - (iterCount - last), 1); 59 | plotx = [allinfo(startidx:allinfolast).iter, info(2:last).iter]; 60 | ploty = [allinfo(startidx:allinfolast).(fieldname), info(2:last).(fieldname)]; 61 | else 62 | % available info is less than iterCount 63 | plotx = [info(1:last).iter]; 64 | ploty = [info(1:last).(fieldname)]; 65 | end 66 | 67 | 68 | end 69 | 70 | 71 | % averaged plotting 72 | if plot_options.avgiter > 1 73 | [plotx, ploty] = mxe_plotavg(plotx, ploty, plot_options.avgiter); 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /mixest/auxiliary/estimation/mxe_getsolverhandle.m: -------------------------------------------------------------------------------- 1 | %% |mxe_getsolverhandle| 2 | % *Note:* This is a private function. 3 | % 4 | % Returns function handle to a manopt solver given its name 5 | % 6 | % *Syntax* 7 | % 8 | % h = mxe_getsolverhandle(solverName) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function h = mxe_getsolverhandle(solverName) 22 | 23 | switch lower(solverName) 24 | case {'cg', 'conjugategradient'} 25 | h = @conjugategradient; 26 | case 'lbfgs' 27 | h = @lbfgs; 28 | case {'tr', 'trustregions'} 29 | h = @trustregions; 30 | case {'sd', 'gd', 'steepestdescent', 'gradientdescent'} 31 | h = @steepestdescent; 32 | case {'sgd', 'stochasticgradientdescent'} 33 | h = @sgd; 34 | %TODO 35 | otherwise 36 | error('Solver "%s" not defined in mxe_getsolverhandle.', solverName) 37 | end 38 | end 39 | 40 | -------------------------------------------------------------------------------- /mixest/auxiliary/estimation/mxe_gradbatch.m: -------------------------------------------------------------------------------- 1 | %% |mxe_costgrad| 2 | % *Note:* This is a private function. 3 | % 4 | % Returns the Riemannian gradient of cost (negative log-likelihood) 5 | % with respect to distribution parameters calculated on data, considering 6 | % penalization, etc. Used in gradient-based estimation functions. 7 | % 8 | % Since it is for SGD no databatchsize is necessary 9 | % 10 | % 11 | % *Syntax* 12 | % 13 | % grad = mxe_gradbatch(D, theta, data, options) 14 | % 15 | 16 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 17 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 18 | % 19 | % Contributors: 20 | % Reshad Hosseini 21 | % Mohamadreza Mash'al 22 | % 23 | % Change log: 24 | % 25 | 26 | function grad = mxe_gradbatch(D, theta, data, batch_index, options) 27 | % Note: options are NOT optional here. Following fields are required: 28 | % 29 | % * penalize 30 | % * penalizerTheta (must contain valid penalizer parameters if penalize is true) 31 | % * dataPatchSize 32 | % 33 | 34 | if nargin < 5 35 | options.sgd.batchnum = 1; 36 | batch_index = 1; 37 | end 38 | % We don't use Manopt stores because it reduces performance due to 39 | % calculating the gradient in line-search. 40 | data = mxe_readdata(data, false); 41 | idx = data.index; 42 | datamat = data.data; 43 | data_size = length(idx); 44 | 45 | if options.penalize 46 | % Calculating the penalizer gradient 47 | egradPen = D.penalizergrad(theta, options.penalizertheta); 48 | end 49 | 50 | egrad = D.llgrad(theta, datamat(:, idx(batch_index))); 51 | egrad = D.scaleparam(-1/length(batch_index), egrad); 52 | if options.penalize 53 | egradPen = D.scaleparam(-1/data_size, egradPen); 54 | egrad = D.sumparam(egrad, egradPen); 55 | end 56 | 57 | grad = D.M.egrad2rgrad(theta, egrad); 58 | 59 | end 60 | -------------------------------------------------------------------------------- /mixest/auxiliary/estimation/mxe_inneroptions.m: -------------------------------------------------------------------------------- 1 | %% |mxe_inneroptions| 2 | % *Note:* This is a private function. 3 | % 4 | % Read options for inner estimations 5 | % 6 | % *Syntax* 7 | % 8 | % inner_options = mxe_inneroptions(options, inner_defaults, subfield) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function inner_options = mxe_inneroptions(options, inner_defaults, subfield) 22 | % |options|: full options, possibly containing options.inner fields given by the user 23 | % |inner_defaults| (optional): specific defaults for the inner options 24 | % |subfield| (optional): specific sub-field of options.inner, used to address specific inner estimation functions between various functions 25 | % 26 | % The estimation functions that call other estimation functions inside, 27 | % should use this function to get the options for the inner estimation 28 | % functions. They can give specific defaults using the |inner_defaults| 29 | % argument and also they may give |subfield|, defining a specific name 30 | % distinguishing the inner estimation from any other inner estimations, in 31 | % order to enable the user to change the options for that specific inner 32 | % estimation by |options.inner.(subfield).(option)|. 33 | % 34 | % The priorities for setting the output options are as follows: 35 | % 1. |options.inner| (if set by the user) 36 | % 2. |inner_defaults| 37 | % 3. |options| (outer options) 38 | 39 | 40 | if isfield(options, 'inner') 41 | user_options = options.inner; 42 | options = rmfield(options, 'inner'); 43 | 44 | if nargin>2 && isfield(user_options, subfield) 45 | user_options = user_options.(subfield); 46 | end 47 | else 48 | user_options = []; 49 | end 50 | 51 | if nargin > 1 52 | options = mxe_setfields(options, inner_defaults); 53 | end 54 | 55 | inner_options = mxe_setfields(options, user_options); 56 | 57 | end -------------------------------------------------------------------------------- /mixest/auxiliary/estimation/mxe_mergeinfo.m: -------------------------------------------------------------------------------- 1 | %% |mxe_mergeinfo| 2 | % *Note:* This is a private function. 3 | % 4 | % Merge info structure arrays, considering memory pre-allocation 5 | % 6 | % *Syntax* 7 | % 8 | % [info, last] = mxe_mergeinfo(info, last, newinfo) 9 | % [info, last] = mxe_mergeinfo(info, last, newinfo, maxiter) 10 | % [info, last] = mxe_mergeinfo(info, last, newinfo, maxiter, field_names_differ) 11 | % 12 | 13 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 14 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 15 | % 16 | % Contributors: 17 | % Reshad Hosseini 18 | % Mohamadreza Mash'al 19 | % 20 | % Change log: 21 | % 22 | 23 | function [info, last] = mxe_mergeinfo(info, last, newinfo, maxiter, field_names_differ) 24 | % maxiter: max size for info 25 | % field_names_differ: flag to use the hard way 26 | 27 | % if info is empty, return the newinfo 28 | if isempty(info) 29 | info = newinfo; 30 | last = numel(newinfo); 31 | return 32 | end 33 | 34 | % if newinfo is empty, return the info untouched 35 | if isempty(newinfo) 36 | return 37 | end 38 | 39 | if nargin < 5 40 | field_names_differ = false; 41 | end 42 | if nargin < 4 43 | maxiter = Inf; 44 | end 45 | 46 | % update allinfo and pre-allocate if necessary 47 | allinfosize = numel(info); 48 | infosize = numel(newinfo)-1; 49 | tobelast = last + infosize; 50 | if tobelast > allinfosize 51 | allinfosize = min(tobelast+10000, maxiter+1); 52 | info(allinfosize).iter = []; 53 | end 54 | 55 | if ~field_names_differ 56 | % perform the merge 57 | info(last+1 : tobelast) = newinfo(2:end); 58 | last = tobelast; 59 | return 60 | end 61 | 62 | % manage different field names 63 | fn_info = fieldnames(info); 64 | fn_newinfo = fieldnames(newinfo); 65 | 66 | % find field names in newinfo that are not in info 67 | idx_newinfo = find(~ismember(fn_newinfo, fn_info)); 68 | % add them to info 69 | for m = idx_newinfo 70 | info(1).(fn_newinfo{m}) = []; 71 | end 72 | 73 | % find field names in info that are not in newinfo 74 | idx_info = find(~ismember(fn_info, fn_newinfo)); 75 | % add them to newinfo 76 | for m = idx_info 77 | newinfo(1).(fn_info{m}) = []; 78 | end 79 | 80 | % we need to make the struct fields in the same order 81 | info = orderfields(info); 82 | newinfo = orderfields(newinfo); 83 | 84 | % perform the merge 85 | info(last+1 : tobelast) = newinfo(2:end); 86 | last = tobelast; 87 | end 88 | -------------------------------------------------------------------------------- /mixest/auxiliary/estimation/mxe_minibatch.m: -------------------------------------------------------------------------------- 1 | %% |mxe_minibatch| 2 | % *Note:* This is a private function. 3 | % 4 | % Returns a structure used for mini batch optimization 5 | % 6 | % *Syntax* 7 | % 8 | % [mb, idxMBTrain] = mxe_minibatch(idxAllTrain, options) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function [mb, idxMBTrain] = mxe_minibatch(idxAllTrain, options) 22 | 23 | minibatchsize = options.minibatch.size; 24 | minibatchoverlap = options.minibatch.overlap; 25 | 26 | nAllTrain = numel(idxAllTrain); 27 | idxMiniBatch = 1:min(minibatchsize, nAllTrain); 28 | idxMBTrain = idxAllTrain(idxMiniBatch); 29 | 30 | mb.next = @next; 31 | function idxMBTrain = next() 32 | 33 | if nAllTrain <= minibatchsize 34 | idxMiniBatch = 1:nAllTrain; 35 | else 36 | 37 | idxMiniBatchEnd = mod(idxMiniBatch(end) - minibatchoverlap - 1, nAllTrain) + 1; 38 | if idxMiniBatchEnd >= nAllTrain 39 | idxMiniBatch = 1:minibatchsize; 40 | else 41 | nAvailable = nAllTrain - idxMiniBatchEnd; 42 | if nAvailable >= minibatchsize 43 | idxMiniBatch = idxMiniBatchEnd + 1 : idxMiniBatchEnd + minibatchsize; 44 | else 45 | idxMiniBatch = [idxMiniBatchEnd + 1 : idxMiniBatchEnd + nAvailable, ... 46 | 1 : minibatchsize - nAvailable]; 47 | end 48 | end 49 | 50 | end 51 | idxMBTrain = idxAllTrain(idxMiniBatch); 52 | end 53 | end -------------------------------------------------------------------------------- /mixest/auxiliary/estimation/mxe_plotavg.m: -------------------------------------------------------------------------------- 1 | %% |mxe_plotavg| 2 | % *Note:* This is a private function. 3 | % 4 | % Function used in averaged plotting 5 | % 6 | % *Syntax* 7 | % 8 | % [plotx, ploty] = mxe_plotavg(plotx, ploty, avgiter) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function [plotx, ploty] = mxe_plotavg(plotx, ploty, avgiter) 22 | 23 | % make the number of elements of plot data a multiple of 24 | % plotavg, by removing extra elements from its start. 25 | n = numel(plotx); 26 | m = mod(n, avgiter); 27 | if m > 0 28 | n = n - m; 29 | plotx = plotx(:, end-n+1:end); 30 | ploty = ploty(:, end-n+1:end); 31 | end 32 | 33 | % average every avgiter iterations 34 | temp = reshape(ploty, avgiter, []); 35 | ploty = mean(temp, 1); 36 | 37 | % update plotx also 38 | idx = avgiter : avgiter : n; 39 | plotx = plotx(:, idx); 40 | end -------------------------------------------------------------------------------- /mixest/auxiliary/manopt_manifolds/euclidean/triufactory.m: -------------------------------------------------------------------------------- 1 | function M = triufactory(m, n) 2 | % Returns a manifold struct over m-by-n lower-triangular matrices. 3 | % 4 | % function M = triufactory(m, n) 5 | % 6 | % Returns M, a structure describing the Euclidean space of lower-triangular 7 | % m-by-n matrices equipped with the standard Frobenius distance and 8 | % associated trace inner product as a manifold for Manopt. 9 | 10 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 11 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 12 | % 13 | % Original author: Reshad Hosseini, Aug, 08, 2015 14 | 15 | 16 | if ~exist('n', 'var') || isempty(n) 17 | n = 1; 18 | end 19 | 20 | M.name = @() sprintf('Euclidean space R^(%dx%d)', m, n); 21 | 22 | M.dim = @() m*n; 23 | 24 | M.inner = @(x, d1, d2) d1(:).'*d2(:); 25 | 26 | M.norm = @(x, d) norm(d, 'fro'); 27 | 28 | M.dist = @(x, y) norm(x-y, 'fro'); 29 | 30 | M.typicaldist = @() sqrt(m*n); 31 | 32 | M.proj = @(x, d) triu(d); 33 | 34 | M.egrad2rgrad = @(x, g) triu(g); 35 | 36 | M.ehess2rhess = @(x, eg, eh, d) eh; 37 | 38 | M.tangent = M.proj; 39 | 40 | M.exp = @exp; 41 | function y = exp(x, d, t) 42 | if nargin == 3 43 | y = x + t*d; 44 | else 45 | y = x + d; 46 | end 47 | y = triu(y); 48 | end 49 | 50 | M.retr = M.exp; 51 | 52 | M.log = @(x, y) triu(y-x); 53 | 54 | M.hash = @(x) ['z' hashmd5(x(:))]; 55 | 56 | M.rand = @() triu(randn(m, n)); 57 | 58 | M.randvec = @randvec; 59 | function u = randvec(x) %#ok 60 | u = triu(randn(m, n)); 61 | u = u / norm(u, 'fro'); 62 | end 63 | 64 | M.lincomb = @lincomb; 65 | function v = lincomb(x, a1, d1, a2, d2) %#ok 66 | if nargin == 3 67 | v = a1*d1; 68 | elseif nargin == 5 69 | v = a1*d1 + a2*d2; 70 | else 71 | error('Bad usage of euclidean.lincomb'); 72 | end 73 | end 74 | 75 | M.zerovec = @(x) zeros(m, n); 76 | 77 | M.transp = @(x1, x2, d) d; 78 | 79 | M.pairmean = @(x1, x2) triu(.5*(x1+x2)); 80 | 81 | M.vec = @(x, u_mat) u_mat(:); 82 | M.mat = @(x, u_vec) reshape(u_vec, [m, n]); 83 | M.vecmatareisometries = @() true; 84 | 85 | end 86 | -------------------------------------------------------------------------------- /mixest/auxiliary/manopt_manifolds/positivedefinite/sqrtm_fast.m: -------------------------------------------------------------------------------- 1 | %% |sqrtm_fast| 2 | % Calculate matrix square root using Schur decomposition 3 | % 4 | % *Syntax* 5 | % 6 | % As = sqrtm_fast(A) 7 | % 8 | 9 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 10 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 11 | % 12 | % Original author: Reshad Hosseini 13 | % 14 | % Change log: 15 | % 16 | 17 | function As=sqrtm_fast(A) 18 | 19 | % ToDO:For Hermitian positive definite there is a faster version based on 20 | % Chapter 6 of "Functions of Matrices" by N. J. Higham 21 | % 22 | if any(isinf(A(:))) || any(isnan(A(:))) 23 | As = eye(size(A)); 24 | return 25 | end 26 | 27 | [U,T]=schur(A,'complex'); 28 | if isequal(T,diag(diag(T))) 29 | % case of symmetric or hermitian input 30 | Ts = diag(sqrt(diag(T))); 31 | elseif isreal(T) && all(diag(T)>0) 32 | % case of non-symmetric or non-hermitial positive definite input 33 | Ts = sqrtm_triu_real(T); 34 | elseif isreal(T) 35 | % case of real input 36 | Ts = sqrtm_triu_negative(T); 37 | else 38 | Ts = sqrtm_triu_complex(T); 39 | end 40 | As = U * Ts * U'; 41 | if isreal(A) 42 | if all(imag(As) == 0) 43 | As = real(As); 44 | end 45 | end -------------------------------------------------------------------------------- /mixest/auxiliary/manopt_manifolds/positivedefinite/sqrtm_triu_real.c: -------------------------------------------------------------------------------- 1 | /* Function for calculating the square root of upper triangular matrix 2 | * when matrix is real with positive diagonals 3 | * Written by Reshad Hosseini*/ 4 | #include "mex.h" 5 | #include //needed for sqrt 6 | //#include //needed for memcpy 7 | 8 | void mexFunction(int nlhs, mxArray *plhs[], 9 | int nrhs, const mxArray *prhs[]) { 10 | int m, n, i, j, k; 11 | double *Tr, *Sr; 12 | double num, denum, s; 13 | 14 | if(nrhs != 1 || nlhs > 1) 15 | mexErrMsgTxt("Usage: Ts = sqrtm_triu(T)"); 16 | 17 | /* prhs[0] is first argument. 18 | * mxGetPr returns double* (data, col-major) 19 | * mxGetM returns int (rows) 20 | * mxGetN returns int (cols) 21 | */ 22 | /* m = rows(T) */ 23 | m = mxGetM(prhs[0]); 24 | n = mxGetN(prhs[0]); 25 | if(m != n) mexErrMsgTxt("matrix must be square"); 26 | 27 | //if(mxIsSparse(prhs[1])) { 28 | // mexErrMsgTxt("Can not handle sparse matrices yet."); 29 | //} 30 | 31 | if(mxGetNumberOfDimensions(prhs[0]) != 2) { 32 | mexErrMsgTxt("Arguments must be matrices."); 33 | } 34 | 35 | Tr = mxGetPr(prhs[0]); 36 | 37 | /* Set the output pointer to the output matrix. */ 38 | plhs[0] = mxCreateDoubleMatrix(m, n, mxREAL); 39 | 40 | /* Create a C pointer to a copy of the output matrix. */ 41 | Sr = mxGetPr(plhs[0]); 42 | 43 | /* copy T into Ts to speed up memory access */ 44 | //memcpy(Ts, T, m*n*sizeof(double)); 45 | for(j=0;j=0;i--) { 47 | *(Sr + i + m*j) = *(Tr + i + m*j); 48 | } 49 | } 50 | 51 | /* Upper triangular */ 52 | for(j=0;j=0;i--) { 58 | s = 0; 59 | for(k=i+1;k' ... 26 | '
' ... 27 | '' ... 28 | '' ... 29 | '' ... 30 | ]; 31 | 32 | % table header 33 | names = fieldnames(S); 34 | for i = 1 : numel(names) 35 | html = [html sprintf('', strrep(names{i},'_',' ') )]; %#ok 36 | end 37 | 38 | html = [html ... 39 | '' ... 40 | '' ... 41 | '' ... 42 | ]; 43 | 44 | % table rows 45 | for n = 1 : numel(S) 46 | html = [html '']; %#ok 47 | for i = 1 : numel(names) 48 | html = [html sprintf('', value2str( S(n).(names{i}) ) )]; %#ok 49 | end 50 | html = [html '']; %#ok 51 | end 52 | 53 | html = [html ... 54 | '' ... 55 | '
%s
%s
' ... 56 | '
' ... 57 | '' ... 58 | ]; 59 | end 60 | 61 | function str = value2str(value) 62 | 63 | str = value; 64 | if isnumeric(value) 65 | if isempty(value) 66 | str = '[]'; 67 | else 68 | str = num2str(value); 69 | end 70 | elseif islogical(value) 71 | if str 72 | str = 'true'; 73 | else 74 | str = 'false'; 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /mixest/auxiliary/private_tools/mxe_readweight.m: -------------------------------------------------------------------------------- 1 | %% |mxe_readweight| 2 | % *Note:* This is a private function. 3 | % 4 | % Read only the data weights from the given data argument 5 | % 6 | % *Syntax* 7 | % 8 | % weight = mxe_readweight(data) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function weight = mxe_readweight(data) 22 | 23 | weight = []; 24 | if isstruct(data) 25 | if isfield(data, 'weight') 26 | weight = data.weight; 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /mixest/auxiliary/private_tools/mxe_scaleparam.m: -------------------------------------------------------------------------------- 1 | %% |mxe_scaleparam| 2 | % *Note:* This is a private function. 3 | % 4 | % Scaling the parameters 5 | % 6 | % *Syntax* 7 | % 8 | % param = mxe_scaleparams(scale, param1) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function param = mxe_scaleparam(scale, param1) 22 | param = param1; 23 | if isobject(param1) 24 | param = param1.sumparam(scale, param1); 25 | elseif iscell(param1) 26 | for k=1:length(param1) 27 | param{k} = mxe_sumparam(scale, param1{k}); 28 | end 29 | elseif isstruct(param1) 30 | st=fieldnames(param1); 31 | for k=1:length(st) 32 | param.(st{k}) = mxe_sumparam(scale, param1.(st{k})); 33 | end 34 | elseif isnumeric(param1) 35 | param = scale * param1; 36 | else ischar(obj) 37 | param = param1; 38 | end -------------------------------------------------------------------------------- /mixest/auxiliary/private_tools/mxe_setfields.m: -------------------------------------------------------------------------------- 1 | %% |mxe_setfields| 2 | % *Note:* This is a private function. 3 | % 4 | % Sets options structure recursively, converting the names to lower case 5 | % 6 | % *Syntax* 7 | % 8 | % options = mxe_setfields(options, given_options) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function options = mxe_setfields(options, given_options) 22 | % sets the given fields from given_options in options. 23 | % struct-type options are handled recursively. 24 | % given field names are converted to lower case. 25 | 26 | if isempty(given_options) 27 | return 28 | end 29 | 30 | % MATLAB R14: Assigning Nonstructure Variables As Structures Displays Warning 31 | if ~isstruct(options) 32 | options = struct; 33 | end 34 | 35 | given_fields = fieldnames(given_options); 36 | for n = 1:numel(given_fields) 37 | fn = given_fields{n}; 38 | lfn = lower(fn); 39 | 40 | issuboption = isstruct(given_options.(fn)); 41 | if issuboption && numel(given_options.(fn)) > 1 % for info structs passed as options (previnfo) 42 | issuboption = false; 43 | end 44 | if issuboption && isfield(given_options.(fn), 'name') % for distribution structs passed as options (we shouldn't make their field names lower case) 45 | issuboption = false; 46 | end 47 | 48 | if issuboption 49 | if ~isfield(options, lfn) 50 | options.(lfn) = struct; 51 | end 52 | options.(lfn) = mxe_setfields(options.(lfn), given_options.(fn)); 53 | else 54 | options.(lfn) = given_options.(fn); 55 | end 56 | end 57 | end 58 | 59 | -------------------------------------------------------------------------------- /mixest/auxiliary/private_tools/mxe_sumparam.m: -------------------------------------------------------------------------------- 1 | %% |mxe_sumparam| 2 | % *Note:* This is a private function. 3 | % 4 | % Adding two parameters 5 | % 6 | % *Syntax* 7 | % 8 | % param = mxe_addparams(param1, param2) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function param = mxe_sumparam(param1, param2) 22 | param = param1; 23 | if isobject(param1) 24 | param = param1.sumparam(param1, param2); 25 | elseif iscell(param1) 26 | for k=1:length(param1) 27 | param{k} = mxe_sumparam(param1{k}, param2{k}); 28 | end 29 | elseif isstruct(param1) 30 | st=fieldnames(param1); 31 | for k=1:length(st) 32 | param.(st{k}) = mxe_sumparam(param1.(st{k}), param2.(st{k})); 33 | end 34 | elseif isnumeric(param1) 35 | param = param1 + param2; 36 | else ischar(obj) 37 | param = param1; 38 | end -------------------------------------------------------------------------------- /mixest/distributions/ag/Integral_Method.m: -------------------------------------------------------------------------------- 1 | function A = Integral_Method(mat, Tol) 2 | %% 3 | % Calculating the expected logarithm of weighted sum of chi-square 4 | % distribution (A = E[ \log \sum d_i N_i^2]) with the integral method 5 | % 6 | % Written by: Pourya H. Zadeh 7 | 8 | % eigs should be a column vector 9 | [r, c] = size(mat); 10 | if r == c 11 | eigs = eig(mat); 12 | else 13 | eigs = mat; 14 | end 15 | 16 | if size(eigs,2) > 1 17 | eigs = eigs.'; 18 | end 19 | 20 | if nargin == 1 21 | Tol = 1e-13; 22 | end 23 | 24 | eigs = sort(eigs); 25 | d = length(eigs); 26 | 27 | fun = @(x) inint(x, eigs, d); 28 | cons = quadgk(fun,0,Inf,'RelTol',0,'AbsTol',Tol); 29 | A = psi(d/2)+log(2*sum(eigs)/d)+cons; 30 | end 31 | 32 | function y = inint(x, d, n) 33 | %% Function for value inside integral 34 | % x should have one row and others should have one column 35 | im = 1; 36 | for j = 1:n 37 | im = im .* ((1+2*d(j).*x).^(-1/2)); 38 | end 39 | 40 | y = (1./x).*(((1+(2*x*sum(d)/n)).^(-n/2))-im); 41 | end -------------------------------------------------------------------------------- /mixest/distributions/common/doc_distribution_common.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/mixest/distributions/common/doc_distribution_common.m -------------------------------------------------------------------------------- /mixest/distributions/common/mxe_AICc.m: -------------------------------------------------------------------------------- 1 | %% |mxe_AICc| 2 | % *Note:* This is a private function. 3 | % 4 | % Calculate AICc 5 | % 6 | % *Syntax* 7 | % 8 | % aicc = mxe_AICc(D, data) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function aicc = mxe_AICc(D, data) 22 | 23 | data = mxe_readdata(data); 24 | 25 | n = D.dim(); 26 | N = data.size; 27 | aicc = N/(N-n-1)*n; 28 | end 29 | -------------------------------------------------------------------------------- /mixest/distributions/common/mxe_BIC.m: -------------------------------------------------------------------------------- 1 | %% |mxe_BIC| 2 | % *Note:* This is a private function. 3 | % 4 | % Calculate BICc 5 | % 6 | % *Syntax* 7 | % 8 | % bic = mxe_BIC(D, data) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function bic = mxe_BIC(D, data) 22 | % 23 | % bic=icBIC(theta,dat) 24 | % 25 | % The function calculates (negative)BIC information criteria for the model 26 | % 27 | % Inputs: 28 | % theta : theta is mcgsm distribution class 29 | % Data: A NISDET class variable for Data 30 | % 31 | % Outputs: 32 | % aic: the total criteria value 33 | 34 | data = mxe_readdata(data); 35 | 36 | n = D.dim(); 37 | N = data.size; 38 | bic = -n/2*log(N); 39 | end 40 | -------------------------------------------------------------------------------- /mixest/distributions/common/mxe_addsharedfields.m: -------------------------------------------------------------------------------- 1 | %% |mxe_addsharedfields| 2 | % *Note:* This is a private function. 3 | % 4 | % Add shared fields to distribution structures 5 | % 6 | % *Syntax* 7 | % 8 | % D = mxe_addsharedfields(D) 9 | % 10 | 11 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 12 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 13 | % 14 | % Contributors: 15 | % Reshad Hosseini 16 | % Mohamadreza Mash'al 17 | % 18 | % Change log: 19 | % 20 | 21 | function D = mxe_addsharedfields(D, notshared) 22 | % Note: fields added here should be documented in doc_distribution_common.m 23 | % and referenced in every distribution factory 24 | 25 | if nargin < 2 26 | notshared = struct; 27 | end 28 | 29 | % |estimate| 30 | D.estimate = @estimate; 31 | function [varargout] = estimate(varargin) 32 | [varargout{1:nargout}] = mxe_estimate(D, varargin{:}); 33 | end 34 | 35 | % |randparam| 36 | D.randparam = @() D.M.rand(); % generate random parameters 37 | 38 | % basic operations on Riemannian gradients 39 | D.sumgrad = @sumgrad; 40 | function rgrad = sumgrad(rgrad1, rgrad2, theta) 41 | if nargin < 3 42 | theta = []; 43 | end 44 | rgrad = D.M.lincomb(theta, 1, rgrad1, 1, rgrad2); 45 | end 46 | 47 | D.scalegrad = @scalegrad; 48 | function rgrad = scalegrad(scalar, rgrad, theta) 49 | if nargin < 3 50 | theta = []; 51 | end 52 | rgrad = D.M.lincomb(theta, scalar, rgrad); 53 | end 54 | 55 | % Check is sumparam and scale param is there 56 | if ~isfield(D, 'sumparam') 57 | D.sumparam = @mxe_sumparam; 58 | end 59 | if ~isfield(D, 'scaleparam') 60 | D.scaleparam = @mxe_scaleparam; 61 | end 62 | 63 | % Check if ll was implemented 64 | if ~isfield(D, 'll') 65 | D.ll = @ll; 66 | end 67 | 68 | function [ll, store] = ll(theta, data, store) 69 | 70 | if nargin < 3 71 | store = struct; 72 | end 73 | 74 | [llvec, store] = D.llvec(theta, data, store); 75 | ll = sum(llvec); 76 | end 77 | 78 | % Information Criteria 79 | D.AICc = @(data) mxe_AICc(D, data); 80 | D.BIC = @(data) mxe_BIC(D, data); 81 | 82 | % |pdf| 83 | if ~isfield(notshared, 'pdf') 84 | D.pdf = @pdf; 85 | end 86 | function y = pdf(theta, data) 87 | y = exp( D.llvec(theta, data) ); 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /mixest/distributions/gamma/gamma_estimatedefault.m: -------------------------------------------------------------------------------- 1 | %% |gamma_estimatedefault| 2 | % *Note:* This is a private function. 3 | % 4 | % Default estimation function for the gamma distribution 5 | % 6 | 7 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 8 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 9 | % 10 | % Contributors: 11 | % Reshad Hosseini 12 | % Mohamadreza Mash'al 13 | % 14 | % Change log: 15 | % 16 | 17 | function [theta, D, info, options] = gamma_estimatedefault(D, data, options) 18 | 19 | data = mxe_readdata(data); 20 | weight = data.weight; 21 | datamat = data.data; 22 | 23 | if nargin < 3 24 | options = mxe_options(); 25 | else 26 | options = mxe_options(options); 27 | end 28 | 29 | if isempty(options.theta0) 30 | theta = D.randparam(); 31 | else 32 | theta = options.theta0; 33 | end 34 | theta = D.fullparam(theta); 35 | 36 | % Below is the parameters needed for the estimation (sufficient statistics) 37 | if isempty(weight) 38 | n = data.size; 39 | par1 = sum( datamat, 2 ) / n; 40 | par2 = sum(log(datamat), 2) /n; 41 | else 42 | n = sum(weight); 43 | par1 = sum(weight .* datamat , 2 ) / n; 44 | par2 = sum(weight .* log(datamat) , 2) /n; 45 | end 46 | 47 | aa = theta.a; 48 | 49 | iterin = 0; 50 | while 1 51 | iterin = iterin + 1; 52 | if iterin > 100 53 | error('Difficulties with estimating the gamma distribution'); 54 | end 55 | if aa < eps 56 | aa = eps; 57 | end 58 | anew = (1/aa + (par2 - log(par1) + log(aa) - psi(0,aa)) / ... 59 | (aa * aa * (1/aa - psi(1,aa)))) ^ -1; 60 | err = abs(anew - aa); 61 | if err < options.minstepsize 62 | aa = anew; 63 | break 64 | end 65 | aa = anew; 66 | end 67 | theta.a = aa; 68 | theta.b = par1 / aa; 69 | 70 | if nargout > 2 71 | info = []; 72 | end 73 | -------------------------------------------------------------------------------- /mixest/distributions/mixture/mixture_mergecandidates.m: -------------------------------------------------------------------------------- 1 | %% |mixture_mergecandidates| 2 | % *Note:* This is a private function. 3 | % 4 | % Sort mixture components for merging, based on given merge method 5 | % 6 | 7 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 8 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 9 | % 10 | % Contributors: 11 | % Reshad Hosseini 12 | % Mohamadreza Mash'al 13 | % 14 | % Change log: 15 | % 16 | 17 | function [idx1, idx2] = mixture_mergecandidates(D, theta, data, options, n) 18 | 19 | num = D.num(); 20 | max_count = num*(num-1)/2; 21 | 22 | if nargin<4 || ~isfield(options, 'sm') 23 | options = mxe_options(); 24 | end 25 | if ~ischar(options.sm.mergecriterion) 26 | error('mixture.mergecandidates: Invalid options.mergecriterion') 27 | end 28 | if nargin < 5 29 | n = max_count; 30 | end 31 | 32 | switch options.sm.mergecriterion 33 | 34 | case 'kl' 35 | % Find using symmetric kl-divergence 36 | mat = -Inf(num); 37 | for k1 = 1 : num-1 38 | for k2 = k1+1 : num 39 | D1 = D.component(k1); 40 | D2 = D.component(k2); 41 | mat(k1,k2) = -(D1.kl(theta.D{k1}, theta.D{k2})+... 42 | D2.kl(theta.D{k2}, theta.D{k1})) / 2; 43 | end 44 | end 45 | 46 | case 'overlap' 47 | % Find using posterior inner product (distribution overlaps) 48 | mat = post_inner_prod(D, theta, data, options.datapatchsize); 49 | 50 | case 'rand' 51 | % Random Merge 52 | mat = triu(rand(num), 1); 53 | 54 | otherwise 55 | error('mergecandidates: Merge criterion ''%s'' not recognized', options.sm.mergecriterion) 56 | end 57 | 58 | n = min(n, max_count); 59 | [unused, idx] = sort(mat(:), 'descend'); %#ok 60 | idx = idx(1:n); % Note: here, we're removing the zero elements also 61 | [idx1, idx2] = ind2sub([num,num], idx); 62 | end 63 | 64 | function innerprod = post_inner_prod(D, theta, data, datapatchsize) 65 | % This function implements posterior inner product 66 | 67 | h = D.weighting(theta, data, struct, datapatchsize); 68 | 69 | num = D.num(); 70 | innerprod = zeros(num); 71 | for k1 = 1 : num-1 72 | for k2 = k1+1 : num 73 | innerprod(k1,k2) = h(k1,:) * h(k2,:)'/... 74 | sqrt((h(k1,:) * h(k1,:)')*(h(k2,:) * h(k2,:)')); 75 | end 76 | end 77 | end 78 | 79 | -------------------------------------------------------------------------------- /mixest/distributions/mixture/mixturefactory.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/mixest/distributions/mixture/mixturefactory.m -------------------------------------------------------------------------------- /mixest/distributions/mixture/mixturefactory_new.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/mixest/distributions/mixture/mixturefactory_new.m -------------------------------------------------------------------------------- /mixest/distributions/mvn/mvn2_estimatedefault.m: -------------------------------------------------------------------------------- 1 | %% |mvn2_estimatedefault| 2 | % *Note:* This is a private function. 3 | % 4 | % Default estimation function for the multi-variate normal distribution 5 | % 6 | 7 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 8 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 9 | % 10 | % Contributors: 11 | % Reshad Hosseini 12 | % Mohamadreza Mash'al 13 | % 14 | % Change log: 15 | % 16 | 17 | function [theta, D, info, options] = mvn2_estimatedefault(D, data, options) 18 | 19 | data = mxe_readdata(data); 20 | weight = data.weight; 21 | N = data.size; 22 | data = data.data; 23 | data = [data; ones(1,N)]; 24 | 25 | if isempty(weight) 26 | weight = ones(1, N); 27 | end 28 | if nargin > 2 && options.penalize 29 | nu = options.penalizertheta.nu; 30 | invLambda = options.penalizertheta.invLambda; 31 | d = size(data,1); 32 | end 33 | n = sum(weight); 34 | 35 | 36 | theta.sigmat = bsxfun(@times, data, weight) * data' / n; 37 | 38 | if nargin > 2 && options.penalize 39 | theta.sigmat = (invLambda + theta.sigmat *n) / (nu+n+d+1); 40 | end 41 | if nargout > 2 42 | info = []; 43 | end 44 | -------------------------------------------------------------------------------- /mixest/distributions/mvn/mvn_estimatedefault.m: -------------------------------------------------------------------------------- 1 | %% |mvn_estimatedefault| 2 | % *Note:* This is a private function. 3 | % 4 | % Default estimation function for the multi-variate normal distribution 5 | % 6 | 7 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 8 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 9 | % 10 | % Contributors: 11 | % Reshad Hosseini 12 | % Mohamadreza Mash'al 13 | % 14 | % Change log: 15 | % 16 | 17 | function [theta, D, info, options] = mvn_estimatedefault(D, data, options) 18 | 19 | data = mxe_readdata(data); 20 | weight = data.weight; 21 | N = data.size; 22 | data = data.data; 23 | 24 | if isempty(weight) 25 | weight = ones(1, N); 26 | end 27 | if nargin > 2 && options.penalize 28 | kappa = options.penalizertheta.kappa; 29 | nu = options.penalizertheta.nu; 30 | mu = options.penalizertheta.mu; 31 | invLambda = options.penalizertheta.invLambda; 32 | d = size(data,1); 33 | end 34 | n = sum(weight); 35 | 36 | theta.mu = sum(bsxfun(@times, data, weight),2)/n; 37 | 38 | data = bsxfun(@minus, data, theta.mu); 39 | 40 | theta.sigma = bsxfun(@times, data, weight) * data' / n; 41 | 42 | if nargin > 2 && options.penalize 43 | mat = (kappa*n)/(kappa+n) * ((theta.mu-mu) * (theta.mu-mu).'); 44 | theta.sigma = (invLambda + mat + theta.sigma *n) / (nu+n+d+2); 45 | theta.mu = (n * theta.mu + kappa * mu) / (n+kappa); 46 | end 47 | if nargout > 2 48 | info = []; 49 | end 50 | -------------------------------------------------------------------------------- /mixest/distributions/mvn/mvn_selfmerge.m: -------------------------------------------------------------------------------- 1 | %% |mvn_selfmerge| 2 | % *Note:* This is a private function. 3 | % 4 | % Calculate the initial parameter values for a merged distribution to be 5 | % substituted for two distributions. Each parameter should be requested by 6 | % a separate call with an optional specific method. 7 | % 8 | 9 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 10 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 11 | % 12 | % Contributors: 13 | % Reshad Hosseini 14 | % Mohamadreza Mash'al 15 | % 16 | % Change log: 17 | % 18 | 19 | function [value, store, mixture_store] = ... 20 | mvn_selfmerge(D, theta1, theta2, param_name, w1, w2, method, data, store, ... 21 | mixture_D, mixture_theta, idx1, idx2, mixture_store) %#ok 22 | 23 | if nargin < 6 24 | method = 'default'; 25 | end 26 | if nargin < 8 27 | store = struct; 28 | end 29 | 30 | switch param_name 31 | 32 | case 'mu' 33 | %% 34 | switch method 35 | case 'default' 36 | if isfield(store, 'selfmerge_theta') 37 | theta = store.selfmerge_theta; 38 | else 39 | theta = D.sumparam(D.scaleparam(w1/(w1+w2),theta1), D.scaleparam(w2/(w1+w2),theta2)); 40 | store.selfmerge_theta = theta; 41 | end 42 | value = theta.mu; 43 | 44 | otherwise 45 | error('mvn.selfmerge: Method ''%s'' not recognized for parameter ''%s''', method, param_name) 46 | end 47 | 48 | 49 | 50 | case 'sigma' 51 | %% 52 | switch method 53 | case 'default' 54 | if isfield(store, 'selfmerge_theta') 55 | theta = store.selfmerge_theta; 56 | else 57 | theta = D.sumparam(D.scaleparam(w1/(w1+w2),theta1), D.scaleparam(w2/(w1+w2),theta2)); 58 | store.selfmerge_theta = theta; 59 | end 60 | value = theta.sigma; 61 | 62 | otherwise 63 | error('mvn.selfmerge: Method ''%s'' not recognized for parameter ''%s''', method, param_name) 64 | end 65 | 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /mixest/distributions/mvn/mvn_selfsplit.m: -------------------------------------------------------------------------------- 1 | %% |mvn_selfsplit| 2 | % *Note:* This is a private function. 3 | % 4 | % Calculate the initial parameter values for two splitted distributions to 5 | % be substituted for the current distribution. Each parameter should be 6 | % requested by a separate call with an optional specific method. 7 | % 8 | 9 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 10 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 11 | % 12 | % Contributors: 13 | % Reshad Hosseini 14 | % Mohamadreza Mash'al 15 | % 16 | % Change log: 17 | % 18 | 19 | function [value1, value2, store, mixture_store] = ... 20 | mvn_selfsplit(D, theta, param_name, method, data, store, ... 21 | mixture_D, mixture_theta, idx, mixture_store) %#ok 22 | 23 | if nargin < 4 24 | method = 'default'; 25 | end 26 | if nargin < 6 27 | store = struct; 28 | end 29 | 30 | switch param_name 31 | 32 | case 'mu' 33 | %% 34 | switch method 35 | case 'default' 36 | [V,D] = eig(theta.sigma); 37 | lambda_max = abs(D(end,end)); 38 | v_max = V(:,end); 39 | mu_add = (sqrt(lambda_max)/2) * v_max; 40 | value1 = theta.mu + mu_add; 41 | value2 = theta.mu - mu_add; 42 | 43 | otherwise 44 | error('mvn.selfsplit: Method ''%s'' not recognized for parameter ''%s''', method, param_name) 45 | end 46 | 47 | 48 | 49 | case 'sigma' 50 | %% 51 | switch method 52 | case 'default' 53 | value1 = theta.sigma / 2; 54 | value2 = value1; 55 | 56 | otherwise 57 | error('mvn.selfsplit: Method ''%s'' not recognized for parameter ''%s''', method, param_name) 58 | end 59 | 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /mixest/distributions/vmf/vmf_estimatedefault.m: -------------------------------------------------------------------------------- 1 | %% |vmf_estimatedefault| 2 | % *Note:* This is a private function. 3 | % 4 | % Default estimation function for the von Mises-Fisher distribution 5 | % 6 | 7 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 8 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 9 | % 10 | % Contributors: 11 | % Reshad Hosseini 12 | % Mohamadreza Mash'al 13 | % 14 | % Change log: 15 | % 16 | 17 | function [theta, D, info, options] = vmf_estimatedefault(D, data, options) 18 | 19 | data = mxe_readdata(data); 20 | weight = data.weight; 21 | N = data.size; 22 | dim = data.dim; 23 | data = data.data; 24 | 25 | if isempty(weight) 26 | weight = ones(1, N); 27 | end 28 | 29 | n = sum(weight); 30 | 31 | mu = sum(bsxfun(@times, weight, data), 2); 32 | norm_mu = norm(mu); 33 | theta.mu = mu / norm_mu; 34 | 35 | rbar = norm_mu/n; 36 | 37 | theta.kappa = (rbar*dim - rbar^3)/(1-rbar^2); 38 | 39 | if nargout > 2 40 | info = []; 41 | end 42 | -------------------------------------------------------------------------------- /mixest/distributions/vmf/vmf_visualize.m: -------------------------------------------------------------------------------- 1 | %% |mvn_visualize| 2 | % *Note:* This is a private function. 3 | % 4 | % von Mises-Fisher distribution visualization 5 | % 6 | 7 | % Copyright 2015 Reshad Hosseini and Mohamadreza Mash'al 8 | % This file is part of MixEst: visionlab.ut.ac.ir/mixest 9 | % 10 | % Contributors: 11 | % Reshad Hosseini 12 | % Mohamadreza Mash'al 13 | % 14 | % Change log: 15 | % 16 | 17 | function handle_array = vmf_visualize(D, theta, vis_options) 18 | 19 | datadim = D.datadim(); 20 | if ~(datadim==3) 21 | error('Only 3-D visualization is supported') 22 | end 23 | 24 | default_options = struct( ... 25 | 'axes', 0, ... 26 | 'color', [0 0 1], ... 27 | 'label', '', ... 28 | 'fixed', false ... 29 | ); 30 | 31 | if nargin < 3 32 | vo = default_options; 33 | else 34 | vo = mxe_setfields(default_options, vis_options); 35 | end 36 | if ~( ishandle(vo.axes) && strcmp(get(vo.axes,'type'),'axes') ) 37 | figure 38 | vo.axes = gca; 39 | end 40 | ax = vo.axes; 41 | 42 | handle_array = []; 43 | 44 | mu = theta.mu; 45 | 46 | h = line([0 mu(1)], [0 mu(2)], [0 mu(3)], 'Parent', ax, ... 47 | 'LineWidth', 2, 'Color', vo.color); 48 | handle_array = [handle_array; h]; 49 | 50 | 51 | if ~isempty(vo.label) 52 | h = text(mu(1), mu(2), mu(3), vo.label, 'Parent', ax); 53 | set(h, ... 54 | 'FontWeight','bold', ... 55 | 'FontSize',24, ... 56 | 'FontUnits','normalized', ... 57 | 'FontName','FixedWidth', ... 58 | ... 'BackgroundColor','w', ... 59 | 'HorizontalAlignment','center'); 60 | handle_array = [handle_array; h]; 61 | end 62 | 63 | end 64 | 65 | -------------------------------------------------------------------------------- /mixest/estimation/split_and_merge/cem.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/mixest/estimation/split_and_merge/cem.m -------------------------------------------------------------------------------- /mixest/estimation/split_and_merge/smem.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/mixest/estimation/split_and_merge/smem.m -------------------------------------------------------------------------------- /mixest/estimation/split_and_merge/smile.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/mixest/estimation/split_and_merge/smile.m -------------------------------------------------------------------------------- /mixest/estimation/split_and_merge/totalmerge.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/mixest/estimation/split_and_merge/totalmerge.m -------------------------------------------------------------------------------- /mixest/estimation/split_and_merge/totalsplit.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/mixest/estimation/split_and_merge/totalsplit.m -------------------------------------------------------------------------------- /mixest/estimation/split_and_merge/totalsplitopt.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/mixest/estimation/split_and_merge/totalsplitopt.m -------------------------------------------------------------------------------- /tests/highlevel/spiral.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/tests/highlevel/spiral.mat -------------------------------------------------------------------------------- /tests/highlevel/test_cem_spiral.m: -------------------------------------------------------------------------------- 1 | function test_cem_spiral 2 | 3 | clc 4 | clear 5 | close all 6 | 7 | f = load('spiral'); 8 | data = f.data; 9 | 10 | % visualization and plotting options 11 | figure('Units', 'normalized', 'OuterPosition', [0 0.3 1 0.7]) 12 | options.visualization.axes = subplot(2,2,[1 3]); 13 | options.plotCost.axes = subplot(2,2,2); 14 | options.plotGradNorm.axes = subplot(2,2,4); 15 | options.visualization.mixture.colorize = true; 16 | options.visualization.stopOnClose = true; 17 | 18 | % common estimation options 19 | options.verbosity = 1; 20 | options.solver = 'lbfgs'; 21 | options.tolCostDiff = 1e-3; 22 | 23 | % split-and-merge options 24 | % options.sm.splitCriterion = 'kl'; 25 | % options.sm.mergeCriterion = 'kl'; 26 | % options.sm.splitInit = 'default'; 27 | % options.sm.mergeInit = 'default'; 28 | % options.sm.numInit = 20; 29 | options.sm.numMin = 1; 30 | options.sm.numMax = 40; 31 | options.sm.mergeMaxCands = 12; 32 | options.sm.splitMaxCands = 12; 33 | options.sm.maxFail = 2; 34 | % options.sm.ComponentD = mvnfactory2(2); 35 | 36 | % inner estimation options 37 | options.inner.full.maxIter = 500; 38 | options.inner.full.tolCostDiff = 1e-7; 39 | options.inner.partial.maxIter = 500; 40 | options.inner.partial.tolCostDiff = 1e-7; 41 | 42 | 43 | % run 44 | cem(data, options) 45 | -------------------------------------------------------------------------------- /tests/highlevel/test_crossvalidation.m: -------------------------------------------------------------------------------- 1 | function test_crossvalidation 2 | 3 | data = 1 + 3.*randn(1, 1000); 4 | 5 | D = mvnfactory(1); 6 | 7 | options.solver = 'cg'; 8 | options.crossval = true; 9 | 10 | theta = D.estimate(data, options) 11 | 12 | assertElementsAlmostEqual(theta.mu, 1, 'absolute', 0.5) 13 | assertElementsAlmostEqual(theta.sigma, 9, 'absolute', 0.5) 14 | -------------------------------------------------------------------------------- /tests/highlevel/test_custom_splitinit.m: -------------------------------------------------------------------------------- 1 | function test_custom_splitinit 2 | 3 | clc 4 | clear 5 | close all 6 | 7 | load data2d 8 | 9 | D = mixturefactory(mvnfactory(2), 1); 10 | theta = D.init(data); 11 | 12 | options.sm.splitinit = @splitinit; 13 | 14 | D.visualize(theta, struct('data', data)); 15 | 16 | [newD, newtheta] = D.split(1, theta, options, data); 17 | 18 | newD.visualize(newtheta, struct('data', data)); 19 | 20 | end 21 | 22 | function [newtheta, store] = splitinit(D, idx, theta, options, data, store) 23 | 24 | % add parameters for an additional component 25 | newtheta = theta; 26 | newtheta.D{end+1} = theta.D{idx}; 27 | % initialize the weights 28 | newtheta.p(idx) = theta.p(idx) / 2; 29 | newtheta.p(end+1) = newtheta.p(idx); 30 | 31 | % initialize the means 32 | Didx = D.component(idx); 33 | pp = Didx.llvec(theta.D{idx}, data); 34 | [~, I] = sort(pp, 'descend'); 35 | I = I(1:10); 36 | [~, C] = kmeans(data(:,I).', 2); 37 | newtheta.D{idx}.mu = C(1,:).'; 38 | newtheta.D{end}.mu = C(2,:).'; 39 | 40 | % initialize the covariance matrices 41 | A = theta.D{idx}.sigma; 42 | d = size(A,1); 43 | newtheta.D{idx}.sigma = det(A)^(1/d) * eye(d); 44 | newtheta.D{end}.sigma = newtheta.D{idx}.sigma; 45 | end 46 | -------------------------------------------------------------------------------- /tests/highlevel/test_ecd.m: -------------------------------------------------------------------------------- 1 | function test_ecd 2 | 3 | n = 10; 4 | nrs = 10000; 5 | x = gammafactory; 6 | D = ecdfactory(n, x); 7 | test_functions(D, nrs) 8 | -------------------------------------------------------------------------------- /tests/highlevel/test_factorial.m: -------------------------------------------------------------------------------- 1 | function test_factorial 2 | 3 | n = 10; 4 | nrs = 1000; 5 | k = 2; 6 | s = mixturefactory(mvnfactory(1), k); 7 | D = factorialfactory(s, n); 8 | 9 | test_functions(D, nrs); -------------------------------------------------------------------------------- /tests/highlevel/test_minibatch.m: -------------------------------------------------------------------------------- 1 | function test_minibatch 2 | 3 | data = 1 + 3.*randn(1, 1000); 4 | 5 | D = mvnfactory(1); 6 | 7 | options.solver = 'cg'; 8 | options.minibatch.size = 10; 9 | options.minibatch.discardhistory = true; 10 | options.minibatch.iter = 1; 11 | 12 | options.crossval = true; 13 | 14 | theta = D.estimate(data, options) 15 | -------------------------------------------------------------------------------- /tests/highlevel/test_mixture.m: -------------------------------------------------------------------------------- 1 | function test_mixture 2 | 3 | n = 10; 4 | nrs = 10000; 5 | x = mvnfactory(n); 6 | D = mixturefactory(x, 3); 7 | test_functions(D, nrs) 8 | 9 | % Calculating kl-divergence 10 | D.kl(theta); 11 | -------------------------------------------------------------------------------- /tests/highlevel/test_mnl.m: -------------------------------------------------------------------------------- 1 | function test_mnl 2 | 3 | 4 | D = mnlfactory(2,2); 5 | data = rand(2,100); 6 | cat = ceil(rand(1,100)*2); 7 | test_functions(D, [data;cat]) 8 | 9 | % Calculating kl-divergence 10 | theta = D.randparam(); 11 | theta2 = D.randparam(); 12 | D.kl(theta, theta2); -------------------------------------------------------------------------------- /tests/highlevel/test_mvn.m: -------------------------------------------------------------------------------- 1 | function test_mvn 2 | 3 | n = 10; 4 | nrs = 10000; 5 | D = mvnfactory(n); 6 | 7 | test_functions(D, nrs) 8 | 9 | % Calculating kl-divergence 10 | theta = D.randparam(); 11 | theta2 = D.randparam(); 12 | D.kl(theta, theta2); -------------------------------------------------------------------------------- /tests/highlevel/test_plotting.m: -------------------------------------------------------------------------------- 1 | function test_plotting 2 | clc 3 | clear 4 | close all 5 | 6 | data = 1 + 3.*randn(1, 10000); 7 | 8 | D = mvnfactory(1); 9 | 10 | options.solver = 'cg'; 11 | 12 | % options.plotcost = true; 13 | % options.plotgradnorm = true; 14 | options.plotitercount = Inf; 15 | options.plotavg = 5; 16 | figure 17 | options.plotcost.axes = subplot(1,2,1); 18 | options.plotgradnorm.axes = subplot(1,2,2); 19 | 20 | options.minibatch.size = 1000; 21 | options.minibatch.iter = 4; 22 | 23 | options.crossval = true; 24 | options.crossval.toliter = 10; 25 | 26 | options.minibatch.discardhistory = false; 27 | 28 | options.miniter = 200; 29 | options.minstepsize = 0; 30 | 31 | options.stopfun = @stopfun; 32 | options.verbosity = 2; 33 | 34 | options.theta0 = D.randparam(); 35 | theta = D.estimate(data, options) 36 | 37 | function stopnow = stopfun(D, theta, info, last) %#ok 38 | % pause(0.1) 39 | stopnow = false; 40 | -------------------------------------------------------------------------------- /tests/highlevel/test_previnfo.m: -------------------------------------------------------------------------------- 1 | function test_previnfo 2 | 3 | data = randn(1,1000)*2+3; 4 | D = mvnfactory(1); 5 | 6 | % get some nice output 7 | options.solver = 'cg'; 8 | options.plotcost.axes = gca; 9 | options.plotitercount = inf; 10 | options.verbosity = 2; 11 | options.maxiter = 50; 12 | options.minibatch.size = 10; 13 | 14 | % don't stop too soon! 15 | options.tolgradnorm = -inf; 16 | options.tolcost = -inf; 17 | options.tolcostdiff = -inf; 18 | options.minstepsize = -inf; 19 | 20 | % crossval 21 | options.crossval = true; 22 | options.miniter = 100; 23 | 24 | % gradnorm 25 | options.plotgradnorm.axes = options.plotcost.axes; 26 | 27 | % first estimation 28 | [theta, D, info, options] = D.estimate(data, options); 29 | 30 | % test previnfo on second estimation 31 | options.previnfo = info; 32 | options.theta0 = theta; 33 | options.maxiter = 100; 34 | [theta, D, info] = D.estimate(data, options); 35 | -------------------------------------------------------------------------------- /tests/highlevel/test_simplex.m: -------------------------------------------------------------------------------- 1 | function test_simplex 2 | profile on 3 | q= 10; 4 | M = simplexKfactory(q,2); 5 | 6 | problem.M = M; 7 | disp('Checking ll gradient using egrad2rgrad'); 8 | problem.costgrad = @(x)costgrad(M,x); 9 | figure(1),checkgradient(problem) 10 | 11 | profile viewer 12 | profile off 13 | function [lik,dll] = costgrad(M,x) 14 | lik = sum(x.^3); 15 | dll = 3*x.^2; 16 | dll = M.egrad2rgrad(x,dll); -------------------------------------------------------------------------------- /tests/highlevel/test_smem.m: -------------------------------------------------------------------------------- 1 | function test_smem 2 | 3 | clc 4 | clear 5 | close all 6 | 7 | f = load('data2d'); 8 | data = f.data; 9 | 10 | % visualization and plotting options 11 | figure('Units', 'normalized', 'OuterPosition', [0 0.3 1 0.7]) 12 | options.visualization.axes = subplot(2,2,[1 3]); 13 | options.plotCost.axes = subplot(2,2,2); 14 | options.plotGradNorm.axes = subplot(2,2,4); 15 | options.visualization.mixture.colorize = true; 16 | options.visualization.stopOnClose = true; 17 | 18 | % common estimation options 19 | options.verbosity = 1; 20 | options.solver = 'lbfgs'; 21 | options.tolCostDiff = 1e-3; 22 | 23 | % % SMEM options 24 | % options.sm.maxcands = 5; 25 | % options.sm.ComponentD = mvnfactory2(2); 26 | 27 | % % inner estimation options 28 | % options.inner.full.maxIter = 500; 29 | % options.inner.full.tolCostDiff = 1e-7; 30 | % options.inner.partial.maxIter = 500; 31 | % options.inner.partial.tolCostDiff = 1e-7; 32 | 33 | 34 | % run 35 | smem(data, 3, options) 36 | -------------------------------------------------------------------------------- /tests/highlevel/test_smile.m: -------------------------------------------------------------------------------- 1 | function test_smile 2 | 3 | clc 4 | clear 5 | close all 6 | 7 | f = load('data2d'); 8 | data = f.data; 9 | 10 | % visualization and plotting options 11 | figure('Units', 'normalized', 'OuterPosition', [0 0.3 1 0.7]) 12 | options.visualization.axes = subplot(2,2,[1 3]); 13 | options.plotCost.axes = subplot(2,2,2); 14 | options.plotGradNorm.axes = subplot(2,2,4); 15 | options.visualization.mixture.colorize = true; 16 | options.visualization.stopOnClose = true; 17 | 18 | % common estimation options 19 | options.verbosity = 1; 20 | options.solver = 'lbfgs'; 21 | options.tolCostDiff = 1e-3; 22 | 23 | % % SMILE options 24 | % options.sm.numInit = 2; 25 | % options.sm.tolCostDiff = 0; 26 | % options.sm.ComponentD = mvnfactory2(2); 27 | 28 | % % inner estimation options 29 | % options.inner.full.maxIter = 500; 30 | % options.inner.full.tolCostDiff = 1e-7; 31 | % options.inner.partial.maxIter = 500; 32 | % options.inner.partial.tolCostDiff = 1e-7; 33 | 34 | 35 | % run 36 | smile(data, 4, options) 37 | -------------------------------------------------------------------------------- /tests/highlevel/test_totalsplit.m: -------------------------------------------------------------------------------- 1 | function theta = test_totalsplit 2 | 3 | clc 4 | clear 5 | close all 6 | warning off all 7 | %reset(RandStream.getGlobalStream); 8 | 9 | load data2d 10 | 11 | figure('units', 'normalized', 'outerposition', [0 0.3 1 0.7]) 12 | % graphical visualization 13 | options.visualization.axes = subplot(2,2,[1 3]); 14 | % options.visualization.mixture.colorize = true; 15 | options.visualization.stopOnClose = true; 16 | % plotting options 17 | options.plotCost.axes = subplot(2,2,2); 18 | options.plotGradNorm.axes = subplot(2,2,4); 19 | 20 | 21 | % main options 22 | options.verbosity = 1; 23 | options.debug = true; 24 | 25 | % options.solver = 'cg'; 26 | % options.crossVal = true; 27 | % options.crossVal.tolIter = 100; 28 | options.regularize = true; 29 | options.penalize = true; 30 | options.miniter = 20; 31 | %options.minibatch.iter = 15; 32 | options.tolCostDiff = 1e-4;%size(data,2) * 1e-4; 33 | % options.tolCostDiff = -Inf; 34 | % options.minibatch.discardHistory = false; 35 | %options.minibatch.size = 500; 36 | options.sm.costType = 2; 37 | % options.inner.full.maxIter = 10; 38 | % options.inner.partial.maxIter = 2; 39 | 40 | options.sm.splitcriterion ='mll'; 41 | options.sm.mergecriterion = 'overlap'; 42 | 43 | options.sm.ComponentD = mvn2factory(2); 44 | 45 | target_num = 4; 46 | theta = totalsplit(data, target_num, options); 47 | 48 | totalmerge(data, theta, 1, options); 49 | -------------------------------------------------------------------------------- /tests/test_gammafactory.m: -------------------------------------------------------------------------------- 1 | function test_suite = test_gammafactory %#ok 2 | initTestSuite; 3 | 4 | function s = setup %#ok<*DEFNU> 5 | % This is run before running each test case and the output is passed to the 6 | % test case. 7 | 8 | s.D = gammafactory(); 9 | 10 | % theta generated by: theta = D.randparam() 11 | s.theta.a = 0.126986816293506; 12 | s.theta.b = 0.913375856139019; 13 | 14 | s.data = [1.497830834908086,2.796958291914378,2.522995379571841,1.007626829964108,2.105402194927377,2.693305810936257,8.214190476877166,4.446194259124519,1.809377887295079,1.597663593258299]; 15 | 16 | 17 | function test_dim(s) 18 | assert(s.D.dim() == 2) 19 | 20 | 21 | function test_datadim(s) 22 | assert(s.D.datadim() == 1) 23 | 24 | 25 | function test_ll(s) 26 | ll = s.D.ll(s.theta, s.data); 27 | 28 | 29 | function test_llvec(s) 30 | llvec = s.D.llvec(s.theta, s.data); 31 | 32 | 33 | function test_llgrad(s) 34 | dll = s.D.llgrad(s.theta, s.data); 35 | 36 | 37 | %TODO 38 | % function test_llgraddata(s) 39 | % dld = s.D.llgraddata(s.theta, s.data); 40 | 41 | 42 | function test_cdf(s) 43 | y = s.D.cdf(s.theta, s.data); 44 | 45 | 46 | function test_pdf(s) 47 | y = s.D.pdf(s.theta, s.data); 48 | 49 | 50 | function test_sample(s) 51 | data = s.D.sample(s.theta); 52 | 53 | data = s.D.sample(s.theta, 5); 54 | 55 | 56 | function test_entropy(s) 57 | h = s.D.entropy(s.theta); 58 | 59 | 60 | function test_kl(s) 61 | kl = s.D.kl(s.theta, s.theta); 62 | 63 | 64 | %TODO 65 | % function test_penalizer(s) 66 | % [costP, gradP] = s.D.penalizer(s.theta, s.data); 67 | 68 | 69 | function test_estimatedefault(s) 70 | theta = s.D.estimatedefault(s.data); 71 | 72 | 73 | function test_init(s) 74 | theta = s.D.init(s.data); 75 | 76 | 77 | function test_randparam(s) 78 | theta = s.D.randparam(); 79 | 80 | 81 | function test_sumparam(s) 82 | theta = s.D.sumparam(s.theta, s.theta); 83 | 84 | 85 | function test_scaleparam(s) 86 | theta = s.D.scaleparam(-1, s.theta); 87 | 88 | 89 | function test_sumgrad(s) 90 | grad1 = s.D.M.egrad2rgrad(s.theta, s.theta); 91 | grad = s.D.sumgrad(grad1, grad1, s.theta); 92 | 93 | 94 | function test_scalegrad(s) 95 | grad1 = s.D.M.egrad2rgrad(s.theta, s.theta); 96 | grad = s.D.scalegrad(-1, grad1, s.theta); 97 | 98 | 99 | function test_fixing(s) 100 | % test fixate 101 | newD = s.D.fixate('b', 3); 102 | assert(newD.dim() == 1) 103 | assert(s.D.dim() == 2) 104 | % test fullparam 105 | theta = newD.randparam(); 106 | fulltheta = newD.fullparam(theta); 107 | assert(fulltheta.b == 3) 108 | % test unfix 109 | newD = newD.unfix('b'); 110 | assert(newD.dim() == 2) 111 | 112 | 113 | -------------------------------------------------------------------------------- /tests/test_mxe_crossvalidation.m: -------------------------------------------------------------------------------- 1 | function test_mxe_crossvalidation 2 | 3 | data = [1 1]; 4 | cvfraction = 0.5; 5 | numkeepsave = 5; 6 | maxiter = 10; 7 | cv_rise_iter = 2; 8 | 9 | cv = mxe_crossvalidation(data, ... 10 | cvfraction, numkeepsave, @costfun); 11 | 12 | for iter = 0:maxiter 13 | theta = iter; 14 | 15 | last = iter+1; 16 | stats.iter = iter; 17 | stats = cv.statsfun(theta, stats); 18 | info(last) = stats; %#ok 19 | stopnow = cv.stopfun(theta, info, last); 20 | if stopnow 21 | assert(iter >= cv_rise_iter) 22 | break 23 | end 24 | end 25 | 26 | assert(cv.hasFinalResult()) 27 | [theta, cost] = cv.finalResult(); %#ok 28 | iter = theta; 29 | assert(iter <= cv_rise_iter) 30 | 31 | 32 | 33 | function cost = costfun(theta, data) %#ok 34 | % theta is the actually the iteration number. The returned cost is 35 | % descending until cv_rise_iter and ascending afterwards. 36 | cost = abs(theta - cv_rise_iter); 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /tests/test_mxe_mergeinfo.m: -------------------------------------------------------------------------------- 1 | function test_mxe_mergeinfo 2 | 3 | info = struct('iter',0,'a',1); 4 | last = 1; 5 | newinfo = struct('b', {2 3 4}, 'iter', {0 1 2}); 6 | maxiter = 10; 7 | [newinfo, newlast] = mxe_mergeinfo(info, last, newinfo, maxiter, true); -------------------------------------------------------------------------------- /tests/test_mxe_minibatch.m: -------------------------------------------------------------------------------- 1 | function test_mxe_minibatch 2 | 3 | idxAll = 1:5; 4 | 5 | options = mxe_options(); 6 | 7 | % test with minibatchsize = 3; 8 | options.minibatch.size = 3; 9 | [mb, idxTrain] = mxe_minibatch(idxAll, options); 10 | assertEqual(idxTrain, [1 2 3]); 11 | idxTrain = mb.next(); 12 | assertEqual(idxTrain, [4 5 1]); 13 | idxTrain = mb.next(); 14 | assertEqual(idxTrain, [2 3 4]); 15 | 16 | % test with minibatchsize > nTrain; 17 | options.minibatch.size = numel(idxAll)+1; 18 | [mb, idxTrain] = mxe_minibatch(idxAll, options); %#ok 19 | assertEqual(idxTrain, idxAll); 20 | 21 | % test with overlap 22 | options.minibatch.size = 3; 23 | options.minibatch.overlap = 2; 24 | [mb, idxTrain] = mxe_minibatch(idxAll, options); 25 | assertEqual(idxTrain, [1 2 3]); 26 | idxTrain = mb.next(); 27 | assertEqual(idxTrain, [2 3 4]); 28 | idxTrain = mb.next(); 29 | assertEqual(idxTrain, [3 4 5]); 30 | idxTrain = mb.next(); 31 | assertEqual(idxTrain, [4 5 1]); 32 | idxTrain = mb.next(); 33 | assertEqual(idxTrain, [5 1 2]); 34 | 35 | end -------------------------------------------------------------------------------- /tests/test_mxe_options.m: -------------------------------------------------------------------------------- 1 | function test_mxe_options 2 | 3 | clear o 4 | o.solver = 'test1'; 5 | o.maxiter = 10; 6 | o.inner.maxiter = 5; 7 | 8 | oo = mxe_options(o); 9 | assert(oo.maxiter == 10) 10 | assert(oo.inner.maxiter == 5) 11 | 12 | ooo = mxe_options(oo); % this should return immediately 13 | ooo = mxe_options(oo, struct('a',1)); % this should go into work 14 | 15 | 16 | io = mxe_inneroptions(oo, [], 'aaa'); 17 | assertEqual(io.solver, 'test1') 18 | 19 | oo.inner.aaa.solver = 'test2'; 20 | io = mxe_inneroptions(oo, [], 'aaa'); 21 | assertEqual(io.solver, 'test2') 22 | 23 | -------------------------------------------------------------------------------- /tests/test_mxe_plot.m: -------------------------------------------------------------------------------- 1 | function test_mxe_plot 2 | 3 | h = figure; 4 | options = mxe_options(); 5 | plot_options = options.plotcost; 6 | plot_options.axes = gca; 7 | plot_options.log = false; 8 | mp = mxe_plot({'sine', 'cosine'}, plot_options); 9 | x = 0:0.1:10; 10 | mp.update(x, sin(x)) 11 | mp.update(x, cos(x), 2) 12 | close(h) 13 | end 14 | -------------------------------------------------------------------------------- /tests/test_mxe_plotavg.m: -------------------------------------------------------------------------------- 1 | function test_mxe_plotavg 2 | 3 | plotx = 1:10; 4 | ploty = 11:20; 5 | 6 | [plotx, ploty] = mxe_plotavg(plotx, ploty, 4); 7 | assertEqual(plotx, [6 10]); 8 | assertEqual(ploty, [14.5 18.5]); 9 | end -------------------------------------------------------------------------------- /tests/test_mxe_readdata.m: -------------------------------------------------------------------------------- 1 | function test_mxe_readdata 2 | 3 | % matrix input 4 | data = mxe_readdata([10 20 30]); 5 | assertEqual(data.data, [10 20 30]); 6 | 7 | data = mxe_readdata([10 20 30], false); 8 | assertEqual(data.data, [10 20 30]); 9 | assertEqual(data.weight, []); 10 | assertEqual(data.index, [1 2 3]); 11 | 12 | % struct input 13 | data = mxe_readdata(struct('data',[10 20 30], 'weight',[0.2 0.3], 'index',[2 3])); 14 | assertEqual(data.data, [20 30]); 15 | assertEqual(data.weight, [0.2 0.3]); 16 | assertEqual(data.index, []); 17 | 18 | data = mxe_readdata(struct('data',[10 20 30], 'weight',[0.2 0.3], 'index',[2 3]), false); 19 | assertEqual(data.data, [10 20 30]); 20 | assertEqual(data.weight, [0.2 0.3]); 21 | assertEqual(data.index, [2 3]); 22 | 23 | data = mxe_readdata(struct('data',[10 20 30], 'weight',[0.1 0.2 0.3])); 24 | assertEqual(data.data, [10 20 30]); 25 | assertEqual(data.weight, [0.1 0.2 0.3]); 26 | assertEqual(data.index, []); 27 | 28 | -------------------------------------------------------------------------------- /thirdparty/lightspeed/README.txt: -------------------------------------------------------------------------------- 1 | This is a library of efficient and useful matlab functions, with an 2 | emphasis on statistics. 3 | See Contents.m for a synopsis. 4 | 5 | You can place the lightspeed directory anywhere. 6 | To make sure lightspeed is always in your path, create a startup.m 7 | file in your matlab directory, if you don't already have one, and add 8 | a line like this: 9 | addpath(genpath('c:\matlab\lightspeed')) 10 | Replace 'c:\matlab\lightspeed' with the location of the lightspeed directory. 11 | 12 | There are some Matlab Extension (MEX) files that need to be compiled. 13 | This can be done in matlab via: 14 | cd c:\matlab\lightspeed 15 | install_lightspeed 16 | 17 | I recommend using Microsoft Visual C++ as the mex compiler, though this is not required. You can set the mex compiler by typing 'mex -setup' in matlab. 18 | 19 | To use Microsoft Visual C++ 2013 with Matlab 8.1 (R2013a), you will need to download this patch: 20 | http://www.mathworks.com/matlabcentral/fileexchange/45878-setting-microsoft-visual-c++-2013-as-default-mex-compiler 21 | 22 | To use Microsoft Visual C++ 2010 with Matlab 7.10 (R2010a), you will need to download this patch: 23 | http://www.mathworks.com/support/solutions/en/data/1-D5W493/?solution=1-D5W493 24 | 25 | To use Microsoft Visual C++ with Matlab 7.0 (R14), you will need to download 26 | R14 service pack 2, as described here: 27 | http://www.mathworks.com/support/solutions/en/data/1-UMEKK/?solution=1-UMEKK 28 | 29 | To compile mex files on a Snow Leopard upgrade: Go to mexopts.sh in your $HOME/.matlab/ directory, and change the line SDKROOT='/Developer/SDKs/MacOSX10.5.sdk' to SDKROOT='/Developer/SDKs/MacOSX10.6.sdk'. That line is not updated during updating mac OSX, so you need to do manually. This file also exists in the standard matlab bin, so if you run mex with the -v option it will tell you which mexopts.sh file it's looking at. You may also need to change some lines in install_lightspeed.m. By default, install_lightspeed.m is set up for 64-bit MacOSX 10.6 with gcc-4.0. If you are using some other version of MacOSX or some other compiler, then you need to edit a few lines (see the comments in that file). Starting with Matlab R2014a, this won't be necessary since lightspeed will pick up the right compiler options automatically. 30 | 31 | You can find timing tests in the tests/ subdirectory. 32 | The test_lightspeed.m script will run all tests, and is a good way to check 33 | that lightspeed installed properly. 34 | 35 | 36 | Tom Minka 37 | -------------------------------------------------------------------------------- /thirdparty/lightspeed/logsumexp.m: -------------------------------------------------------------------------------- 1 | function s = logsumexp(a, dim) 2 | % Returns log(sum(exp(a),dim)) while avoiding numerical underflow. 3 | % Default is dim = 1 (columns). 4 | % logsumexp(a, 2) will sum across rows instead of columns. 5 | % Unlike matlab's "sum", it will not switch the summing direction 6 | % if you provide a row vector. 7 | 8 | % Written by Tom Minka 9 | % (c) Microsoft Corporation. All rights reserved. 10 | 11 | if nargin < 2 12 | dim = 1; 13 | end 14 | 15 | % subtract the largest in each column 16 | [y, i] = max(a,[],dim); 17 | dims = ones(1,ndims(a)); 18 | dims(dim) = size(a,dim); 19 | a = a - repmat(y, dims); 20 | s = y + log(sum(exp(a),dim)); 21 | i = find(~isfinite(y)); 22 | if ~isempty(i) 23 | s(i) = y(i); 24 | end 25 | -------------------------------------------------------------------------------- /thirdparty/manopt/CREDITS.txt: -------------------------------------------------------------------------------- 1 | The Manopt project is led by these people: 2 | 3 | * Nicolas Boumal 4 | * Bamdev Mishra 5 | * Pierre-Antoine Absil 6 | * Rodolphe Sepulchre 7 | 8 | 9 | The following people have written code specifically for Manopt: 10 | 11 | * Nicolas Boumal 12 | * Bamdev Mishra 13 | * Pierre Borckmans 14 | 15 | 16 | Furthermore, code written by the following people can be found in Manopt: 17 | 18 | * Chris Baker 19 | * Pierre-Antoine Absil 20 | * Kyle Gallivan 21 | * Paolo de Leva 22 | * Wynton Moore 23 | * Michael Kleder 24 | -------------------------------------------------------------------------------- /thirdparty/manopt/LICENSE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/thirdparty/manopt/LICENSE.txt -------------------------------------------------------------------------------- /thirdparty/manopt/README.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/thirdparty/manopt/README.txt -------------------------------------------------------------------------------- /thirdparty/manopt/checkinstall/basicexample.m: -------------------------------------------------------------------------------- 1 | function basicexample 2 | 3 | % Verify that Manopt was indeed added to the Matlab path. 4 | if isempty(which('spherefactory')) 5 | error(['You should first add Manopt to the Matlab path.\n' ... 6 | 'Please run importmanopt first.']); 7 | end 8 | 9 | % Generate the problem data. 10 | n = 1000; 11 | A = randn(n); 12 | A = .5*(A+A'); 13 | 14 | % Create the problem structure. 15 | manifold = spherefactory(n); 16 | problem.M = manifold; 17 | 18 | % Define the problem cost function and its gradient. 19 | problem.cost = @(x) -x'*(A*x); 20 | problem.grad = @(x) manifold.egrad2rgrad(x, -2*A*x); 21 | 22 | % Numerically check gradient consistency. 23 | checkgradient(problem); 24 | 25 | % Solve. 26 | % The trust-regions algorithm requires the Hessian. Since we do not 27 | % provide it, it will go for a standard approximation of it. The first 28 | % instruction tells Manopt not to issue a warning when this happens. 29 | warning('off', 'manopt:getHessian:approx'); 30 | [x xcost info] = trustregions(problem); %#ok 31 | 32 | % Display some statistics. 33 | figure; 34 | semilogy([info.iter], [info.gradnorm], '.-'); 35 | xlabel('Iteration #'); 36 | ylabel('Gradient norm'); 37 | title('Convergence of the trust-regions algorithm on the sphere'); 38 | 39 | end 40 | -------------------------------------------------------------------------------- /thirdparty/manopt/importmanopt.m: -------------------------------------------------------------------------------- 1 | % Add Manopt to the path and make all manopt components available. 2 | 3 | % This file is part of Manopt: www.manopt.org. 4 | % Original author: Nicolas Boumal, Jan. 3, 2013. 5 | % Contributors: 6 | % Change log: 7 | % Aug. 7, 2013 (NB): Changed to work without the import command 8 | % (new structure of the toolbox). 9 | % Aug. 8, 2013 (NB): Changed to use addpath_recursive, home brewed. 10 | % Aug. 22, 2013 (NB): Using genpath instead of homecooked 11 | % addpath_recursive. 12 | 13 | addpath(pwd); 14 | 15 | % Recursively add Manopt directories to the Matlab path. 16 | cd manopt; 17 | addpath(genpath(pwd)); 18 | cd ..; 19 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/manifolds/euclidean/euclideanfactory.m: -------------------------------------------------------------------------------- 1 | function M = euclideanfactory(m, n) 2 | % Returns a manifold struct to optimize over m-by-n matrices. 3 | % 4 | % function M = euclideanfactory(m, n) 5 | % 6 | % Returns M, a structure describing the Euclidean space of m-by-n matrices 7 | % equipped with the standard Frobenius distance and associated trace inner 8 | % product as a manifold for Manopt. 9 | 10 | % This file is part of Manopt: www.manopt.org. 11 | % Original author: Nicolas Boumal, Dec. 30, 2012. 12 | % Contributors: 13 | % Change log: 14 | % July 5, 2013 (NB): added egred2rgrad, ehess2rhess, mat, vec, tangent. 15 | 16 | 17 | if ~exist('n', 'var') || isempty(n) 18 | n = 1; 19 | end 20 | 21 | M.name = @() sprintf('Euclidean space R^(%dx%d)', m, n); 22 | 23 | M.dim = @() m*n; 24 | 25 | M.inner = @(x, d1, d2) d1(:).'*d2(:); 26 | 27 | M.norm = @(x, d) norm(d, 'fro'); 28 | 29 | M.dist = @(x, y) norm(x-y, 'fro'); 30 | 31 | M.typicaldist = @() sqrt(m*n); 32 | 33 | M.proj = @(x, d) d; 34 | 35 | M.egrad2rgrad = @(x, g) g; 36 | 37 | M.ehess2rhess = @(x, eg, eh, d) eh; 38 | 39 | M.tangent = M.proj; 40 | 41 | M.exp = @exp; 42 | function y = exp(x, d, t) 43 | if nargin == 3 44 | y = x + t*d; 45 | else 46 | y = x + d; 47 | end 48 | end 49 | 50 | M.retr = M.exp; 51 | 52 | M.log = @(x, y) y-x; 53 | 54 | M.hash = @(x) ['z' hashmd5(x(:))]; 55 | 56 | M.rand = @() randn(m, n); 57 | 58 | M.randvec = @randvec; 59 | function u = randvec(x) %#ok 60 | u = randn(m, n); 61 | u = u / norm(u, 'fro'); 62 | end 63 | 64 | M.lincomb = @lincomb; 65 | function v = lincomb(x, a1, d1, a2, d2) %#ok 66 | if nargin == 3 67 | v = a1*d1; 68 | elseif nargin == 5 69 | v = a1*d1 + a2*d2; 70 | else 71 | error('Bad usage of euclidean.lincomb'); 72 | end 73 | end 74 | 75 | M.zerovec = @(x) zeros(m, n); 76 | 77 | M.transp = @(x1, x2, d) d; 78 | 79 | M.pairmean = @(x1, x2) .5*(x1+x2); 80 | 81 | M.vec = @(x, u_mat) u_mat(:); 82 | M.mat = @(x, u_vec) reshape(u_vec, [m, n]); 83 | M.vecmatareisometries = @() true; 84 | 85 | end 86 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/manifolds/euclidean/symmetricfactory.m: -------------------------------------------------------------------------------- 1 | function M = symmetricfactory(n, k) 2 | % Returns a manifold struct to optimize over k symmetric matrices of size n 3 | % 4 | % function M = symmetricfactory(n) 5 | % function M = symmetricfactory(n, k) 6 | % 7 | % Returns M, a structure describing the Euclidean space of n-by-n symmetric 8 | % matrices equipped with the standard Frobenius distance and associated 9 | % trace inner product, as a manifold for Manopt. 10 | % By default, k = 1. If k > 1, points and vectors are stored in 3D matrices 11 | % X of size nxnxk such that each slice X(:, :, i), for i = 1:k, is 12 | % symmetric. 13 | 14 | % This file is part of Manopt: www.manopt.org. 15 | % Original author: Nicolas Boumal, Jan. 22, 2014. 16 | % Contributors: 17 | % Change log: 18 | 19 | if ~exist('k', 'var') || isempty(k) 20 | k = 1; 21 | end 22 | 23 | M.name = @() sprintf('(Symmetric matrices of size %d)^%d', n, k); 24 | 25 | M.dim = @() k*n*(n+1)/2; 26 | 27 | M.inner = @(x, d1, d2) d1(:).'*d2(:); 28 | 29 | M.norm = @(x, d) norm(d(:), 'fro'); 30 | 31 | M.dist = @(x, y) norm(x(:)-y(:), 'fro'); 32 | 33 | M.typicaldist = @() sqrt(k)*n; 34 | 35 | M.proj = @(x, d) multisym(d); 36 | 37 | M.egrad2rgrad = M.proj; 38 | 39 | %M.ehess2rhess = @(x, eg, eh, d) eh; 40 | 41 | M.tangent = @(x, d) d; 42 | 43 | M.exp = @exp; 44 | function y = exp(x, d, t) 45 | if nargin == 3 46 | y = x + t*d; 47 | else 48 | y = x + d; 49 | end 50 | end 51 | 52 | M.retr = M.exp; 53 | 54 | M.log = @(x, y) y-x; 55 | 56 | M.hash = @(x) ['z' hashmd5(x(:))]; 57 | 58 | M.rand = @() multisym(randn(n, n, k)); 59 | 60 | M.randvec = @randvec; 61 | function u = randvec(x) %#ok 62 | u = multisym(randn(n, n, k)); 63 | u = u / norm(u(:), 'fro'); 64 | end 65 | 66 | M.lincomb = @lincomb; 67 | function v = lincomb(x, a1, d1, a2, d2) %#ok 68 | if nargin == 3 69 | v = a1*d1; 70 | elseif nargin == 5 71 | v = a1*d1 + a2*d2; 72 | else 73 | error('Bad usage of euclidean.lincomb'); 74 | end 75 | end 76 | 77 | M.zerovec = @(x) zeros(n, n, k); 78 | 79 | M.transp = @(x1, x2, d) d; 80 | 81 | M.pairmean = @(x1, x2) .5*(x1+x2); 82 | 83 | M.vec = @(x, u_mat) u_mat(:); 84 | M.mat = @(x, u_vec) reshape(u_vec, [m, n]); 85 | M.vecmatareisometries = @() true; 86 | 87 | end 88 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/manifolds/rotations/randrot.m: -------------------------------------------------------------------------------- 1 | function R = randrot(n, N) 2 | % Generates uniformly random rotation matrices. 3 | % 4 | % function R = randrot(n, N) 5 | % 6 | % R is a n-by-n-by-N matrix such that each slice R(:, :, i) is an 7 | % orthogonal matrix of size n of determinant +1 (i.e., a matrix in SO(n)). 8 | % By default, N = 1. 9 | % Complexity: N times O(n^3). 10 | % Theory in Diaconis and Shahshahani 1987 for the uniformity on O(n); 11 | % With details in Mezzadri 2007, 12 | % "How to generate random matrices from the classical compact groups." 13 | % To ensure matrices in SO(n), we permute the two first columns when 14 | % the determinant is -1. 15 | % 16 | % See also: randskew 17 | 18 | % This file is part of Manopt: www.manopt.org. 19 | % Original author: Nicolas Boumal, Sept. 25, 2012. 20 | % Contributors: 21 | % Change log: 22 | 23 | if nargin < 2 24 | N = 1; 25 | end 26 | 27 | if n == 1 28 | R = ones(1, 1, N); 29 | return; 30 | end 31 | 32 | R = zeros(n, n, N); 33 | 34 | for i = 1 : N 35 | 36 | % Generated as such, Q is uniformly distributed over O(n), the set 37 | % of orthogonal matrices. 38 | A = randn(n); 39 | [Q, RR] = qr(A); 40 | Q = Q * diag(sign(diag(RR))); %% Mezzadri 2007 41 | 42 | % If Q is in O(n) but not in SO(n), we permute the two first 43 | % columns of Q such that det(new Q) = -det(Q), hence the new Q will 44 | % be in SO(n), uniformly distributed. 45 | if det(Q) < 0 46 | Q(:, [1 2]) = Q(:, [2 1]); 47 | end 48 | 49 | R(:, :, i) = Q; 50 | 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/manifolds/rotations/randskew.m: -------------------------------------------------------------------------------- 1 | function S = randskew(n, N) 2 | % Generates random skew symmetric matrices with normal entries. 3 | % 4 | % function S = randskew(n, N) 5 | % 6 | % S is an n-by-n-by-N matrix where each slice S(:, :, i) for i = 1..N is a 7 | % random skew-symmetric matrix with upper triangular entries distributed 8 | % independently following a normal distribution (Gaussian, zero mean, unit 9 | % variance). 10 | % 11 | % See also: randrot 12 | 13 | % This file is part of Manopt: www.manopt.org. 14 | % Original author: Nicolas Boumal, Sept. 25, 2012. 15 | % Contributors: 16 | % Change log: 17 | 18 | 19 | if nargin < 2 20 | N = 1; 21 | end 22 | 23 | % Subindices of the (strictly) upper triangular entries of an n-by-n 24 | % matrix 25 | [I J] = find(triu(ones(n), 1)); 26 | 27 | K = repmat(1:N, n*(n-1)/2, 1); 28 | 29 | % Indices of the strictly upper triangular entries of all N slices of 30 | % an n-by-n-by-N matrix 31 | L = sub2ind([n n N], repmat(I, N, 1), repmat(J, N, 1), K(:)); 32 | 33 | % Allocate memory for N random skew matrices of size n-by-n and 34 | % populate each upper triangular entry with a random number following a 35 | % normal distribution and copy them with opposite sign on the 36 | % corresponding lower triangular side. 37 | S = zeros(n, n, N); 38 | S(L) = randn(size(L)); 39 | S = S-multitransp(S); 40 | 41 | end 42 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/applyStatsfun.m: -------------------------------------------------------------------------------- 1 | function stats = applyStatsfun(problem, x, storedb, options, stats) 2 | % Apply the statsfun function to a stats structure (for solvers). 3 | % 4 | % function stats = applyStatsfun(problem, x, storedb, options, stats) 5 | % 6 | % Applies the options.statsfun user supplied function to the stats 7 | % structure, if it was provided, with the appropriate inputs, and returns 8 | % the (possibly) modified stats structure. 9 | % 10 | % See also: 11 | 12 | % This file is part of Manopt: www.manopt.org. 13 | % Original author: Nicolas Boumal, April 3, 2013. 14 | % Contributors: 15 | % Change log: 16 | 17 | if isfield(options, 'statsfun') 18 | 19 | is_octave = exist('OCTAVE_VERSION', 'builtin'); 20 | if ~is_octave 21 | narg = nargin(options.statsfun); 22 | else 23 | narg = 4; 24 | end 25 | 26 | switch narg 27 | case 3 28 | stats = options.statsfun(problem, x, stats); 29 | case 4 30 | store = getStore(problem, x, storedb); 31 | stats = options.statsfun(problem, x, stats, store); 32 | otherwise 33 | warning('manopt:statsfun', ... 34 | 'statsfun unused: wrong number of inputs'); 35 | end 36 | end 37 | 38 | end 39 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/canGetCost.m: -------------------------------------------------------------------------------- 1 | function candoit = canGetCost(problem) 2 | % Checks whether the cost function can be computed for a problem structure. 3 | % 4 | % function candoit = canGetCost(problem) 5 | % 6 | % Returns true if the cost function can be computed given the problem 7 | % description, false otherwise. 8 | % 9 | % See also: getCost canGetDirectionalDerivative canGetGradient canGetHessian 10 | 11 | % This file is part of Manopt: www.manopt.org. 12 | % Original author: Nicolas Boumal, Dec. 30, 2012. 13 | % Contributors: 14 | % Change log: 15 | 16 | 17 | candoit = isfield(problem, 'cost') || isfield(problem, 'costgrad'); 18 | 19 | end 20 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/canGetDirectionalDerivative.m: -------------------------------------------------------------------------------- 1 | function candoit = canGetDirectionalDerivative(problem) 2 | % Checks whether dir. derivatives can be computed for a problem structure. 3 | % 4 | % function candoit = canGetDirectionalDerivative(problem) 5 | % 6 | % Returns true if the directional derivatives of the cost function can be 7 | % computed given the problem description, false otherwise. 8 | % 9 | % See also: canGetCost canGetGradient canGetHessian 10 | 11 | % This file is part of Manopt: www.manopt.org. 12 | % Original author: Nicolas Boumal, Dec. 30, 2012. 13 | % Contributors: 14 | % Change log: 15 | 16 | candoit = isfield(problem, 'diff') || canGetGradient(problem); 17 | 18 | end 19 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/canGetEuclideanGradient.m: -------------------------------------------------------------------------------- 1 | function candoit = canGetEuclideanGradient(problem) 2 | % Checks whether the Euclidean gradient can be computed for a problem. 3 | % 4 | % function candoit = canGetEuclideanGradient(problem) 5 | % 6 | % Returns true if the Euclidean gradient can be computed given the problem 7 | % description, false otherwise. 8 | % 9 | % See also: canGetGradient getEuclideanGradient 10 | 11 | % This file is part of Manopt: www.manopt.org. 12 | % Original author: Nicolas Boumal, Dec. 30, 2012. 13 | % Contributors: 14 | % Change log: 15 | 16 | 17 | candoit = isfield(problem, 'egrad'); 18 | 19 | end 20 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/canGetGradient.m: -------------------------------------------------------------------------------- 1 | function candoit = canGetGradient(problem) 2 | % Checks whether the gradient can be computed for a problem structure. 3 | % 4 | % function candoit = canGetGradient(problem) 5 | % 6 | % Returns true if the gradient of the cost function can be computed given 7 | % the problem description, false otherwise. 8 | % 9 | % See also: canGetCost canGetDirectionalDerivative canGetHessian 10 | 11 | % This file is part of Manopt: www.manopt.org. 12 | % Original author: Nicolas Boumal, Dec. 30, 2012. 13 | % Contributors: 14 | % Change log: 15 | 16 | candoit = isfield(problem, 'grad') || isfield(problem, 'costgrad') || ... 17 | canGetEuclideanGradient(problem); 18 | 19 | end 20 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/canGetHessian.m: -------------------------------------------------------------------------------- 1 | function candoit = canGetHessian(problem) 2 | % Checks whether the Hessian can be computed for a problem structure. 3 | % 4 | % function candoit = canGetHessian(problem) 5 | % 6 | % Returns true if the Hessian of the cost function can be computed given 7 | % the problem description, false otherwise. 8 | % 9 | % See also: canGetCost canGetDirectionalDerivative canGetGradient 10 | 11 | % This file is part of Manopt: www.manopt.org. 12 | % Original author: Nicolas Boumal, Dec. 30, 2012. 13 | % Contributors: 14 | % Change log: 15 | 16 | candoit = isfield(problem, 'hess') || ... 17 | (isfield(problem, 'ehess') && canGetEuclideanGradient(problem)); 18 | 19 | if ~candoit && ... 20 | (isfield(problem, 'ehess') && ~canGetEuclideanGradient(problem)) 21 | warning('manopt:canGetHessian', ... 22 | ['If the Hessian is supplied as a Euclidean Hessian (ehess), ' ... 23 | 'then the Euclidean gradient must also be supplied (egrad).']); 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/canGetLinesearch.m: -------------------------------------------------------------------------------- 1 | function candoit = canGetLinesearch(problem) 2 | % Checks whether the problem structure can give a line-search a hint. 3 | % 4 | % function candoit = canGetLinesearch(problem) 5 | % 6 | % Returns true if the the problem description includes a mechanism to give 7 | % line-search algorithms a hint as to "how far to look", false otherwise. 8 | % 9 | % See also: getLinesearch 10 | 11 | % This file is part of Manopt: www.manopt.org. 12 | % Original author: Nicolas Boumal, July 17, 2014. 13 | % Contributors: 14 | % Change log: 15 | 16 | 17 | candoit = isfield(problem, 'linesearch'); 18 | 19 | end 20 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/canGetPrecon.m: -------------------------------------------------------------------------------- 1 | function candoit = canGetPrecon(problem) 2 | % Checks whether a preconditioner was specified in the problem description. 3 | % 4 | % function candoit = canGetPrecon(problem) 5 | % 6 | % Returns true if a preconditioner was specified, false otherwise. Notice 7 | % that even if this function returns false, it is still possible to call 8 | % getPrecon, as the default preconditioner is simply the identity operator. 9 | % This check function is mostly useful to tell whether that default 10 | % preconditioner will be in use or not. 11 | % 12 | % See also: canGetDirectionalDerivative canGetGradient canGetHessian 13 | 14 | % This file is part of Manopt: www.manopt.org. 15 | % Original author: Nicolas Boumal, July 3, 2013. 16 | % Contributors: 17 | % Change log: 18 | 19 | candoit = isfield(problem, 'precon'); 20 | 21 | end 22 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/getApproxHessian.m: -------------------------------------------------------------------------------- 1 | function [approxhess, storedb] = getApproxHessian(problem, x, d, storedb) 2 | % Computes an approximation of the Hessian of the cost fun. at x along d. 3 | % 4 | % function [approxhess, storedb] = getApproxHessian(problem, x, d, storedb) 5 | % 6 | % Returns an approximation of the Hessian at x along d of the cost function 7 | % described in the problem structure. The cache database storedb is passed 8 | % along, possibly modified and returned in the process. 9 | % 10 | % If no approximate Hessian was furnished, this call is redirected to 11 | % getHessianFD. 12 | % 13 | % See also: getHessianFD 14 | 15 | % This file is part of Manopt: www.manopt.org. 16 | % Original author: Nicolas Boumal, Dec. 30, 2012. 17 | % Contributors: 18 | % Change log: 19 | 20 | 21 | if isfield(problem, 'approxhess') 22 | %% Compute the approximate Hessian using approxhess. 23 | 24 | is_octave = exist('OCTAVE_VERSION', 'builtin'); 25 | if ~is_octave 26 | narg = nargin(problem.approxhess); 27 | else 28 | narg = 3; 29 | end 30 | 31 | % Check whether the approximate Hessian function wants to deal with 32 | % the store structure or not. 33 | switch narg 34 | case 2 35 | approxhess = problem.approxhess(x, d); 36 | case 3 37 | % Obtain, pass along, and save the store structure 38 | % associated to this point. 39 | store = getStore(problem, x, storedb); 40 | [approxhess store] = problem.approxhess(x, d, store); 41 | storedb = setStore(problem, x, storedb, store); 42 | otherwise 43 | up = MException('manopt:getApproxHessian:badapproxhess', ... 44 | 'approxhess should accept 2 or 3 inputs.'); 45 | throw(up); 46 | end 47 | 48 | else 49 | %% Try to fall back to a standard FD approximation. 50 | 51 | [approxhess, storedb] = getHessianFD(problem, x, d, storedb); 52 | 53 | end 54 | 55 | end 56 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/getCostGrad.m: -------------------------------------------------------------------------------- 1 | function [cost, grad, storedb] = getCostGrad(problem, x, storedb) 2 | % Computes the cost function and the gradient at x in one call if possible. 3 | % 4 | % function [cost, storedb] = getCostGrad(problem, x, storedb) 5 | % 6 | % Returns the value at x of the cost function described in the problem 7 | % structure, as well as the gradient at x. The cache database storedb is 8 | % passed along, possibly modified and returned in the process. 9 | % 10 | % See also: canGetCost canGetGradient getCost getGradient 11 | 12 | % This file is part of Manopt: www.manopt.org. 13 | % Original author: Nicolas Boumal, Dec. 30, 2012. 14 | % Contributors: 15 | % Change log: 16 | 17 | 18 | if isfield(problem, 'costgrad') 19 | %% Compute the cost/grad pair using costgrad. 20 | 21 | is_octave = exist('OCTAVE_VERSION', 'builtin'); 22 | if ~is_octave 23 | narg = nargin(problem.costgrad); 24 | else 25 | narg = 2; 26 | end 27 | 28 | % Check whether the costgrad function wants to deal with the store 29 | % structure or not. 30 | switch narg 31 | case 1 32 | [cost, grad] = problem.costgrad(x); 33 | case 2 34 | % Obtain, pass along, and save the store structure 35 | % associated to this point. 36 | store = getStore(problem, x, storedb); 37 | [cost, grad, store] = problem.costgrad(x, store); 38 | storedb = setStore(problem, x, storedb, store); 39 | otherwise 40 | up = MException('manopt:getCostGrad:badcostgrad', ... 41 | 'costgrad should accept 1 or 2 inputs.'); 42 | throw(up); 43 | end 44 | 45 | else 46 | %% Revert to calling getCost and getGradient separately 47 | 48 | [cost, storedb] = getCost(problem, x, storedb); 49 | [grad, storedb] = getGradient(problem, x, storedb); 50 | 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/getDirectionalDerivative.m: -------------------------------------------------------------------------------- 1 | function [diff, storedb] = getDirectionalDerivative(problem, x, d, storedb) 2 | % Computes the directional derivative of the cost function at x along d. 3 | % 4 | % function [diff, storedb] = getDirectionalDerivative(problem, x, d, storedb) 5 | % 6 | % Returns the derivative at x along d of the cost function described in the 7 | % problem structure. The cache database storedb is passed along, possibly 8 | % modified and returned in the process. 9 | % 10 | % See also: getGradient canGetDirectionalDerivative 11 | 12 | % This file is part of Manopt: www.manopt.org. 13 | % Original author: Nicolas Boumal, Dec. 30, 2012. 14 | % Contributors: 15 | % Change log: 16 | 17 | 18 | if isfield(problem, 'diff') 19 | %% Compute the directional derivative using diff. 20 | 21 | is_octave = exist('OCTAVE_VERSION', 'builtin'); 22 | if ~is_octave 23 | narg = nargin(problem.diff); 24 | else 25 | narg = 3; 26 | end 27 | 28 | % Check whether the diff function wants to deal with the store 29 | % structure or not. 30 | switch narg 31 | case 2 32 | diff = problem.diff(x, d); 33 | case 3 34 | % Obtain, pass along, and save the store structure 35 | % associated to this point. 36 | store = getStore(problem, x, storedb); 37 | [diff store] = problem.diff(x, d, store); 38 | storedb = setStore(problem, x, storedb, store); 39 | otherwise 40 | up = MException('manopt:getDirectionalDerivative:baddiff', ... 41 | 'diff should accept 2 or 3 inputs.'); 42 | throw(up); 43 | end 44 | 45 | elseif canGetGradient(problem) 46 | %% Compute the directional derivative using the gradient. 47 | 48 | % Compute the gradient at x, then compute its inner product with d. 49 | [grad, storedb] = getGradient(problem, x, storedb); 50 | diff = problem.M.inner(x, grad, d); 51 | 52 | else 53 | %% Abandon computing the directional derivative. 54 | 55 | up = MException('manopt:getDirectionalDerivative:fail', ... 56 | ['The problem description is not explicit enough to ' ... 57 | 'compute the directional derivatives of f.']); 58 | throw(up); 59 | 60 | end 61 | 62 | end 63 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/getGlobalDefaults.m: -------------------------------------------------------------------------------- 1 | function opts = getGlobalDefaults() 2 | % Returns a structure with default option values for Manopt. 3 | % 4 | % function opts = getGlobalDefaults() 5 | % 6 | % Returns a structure opts containing the global default options such as 7 | % verbosity level etc. Typically, global defaults are overwritten by solver 8 | % defaults, which are in turn overwritten by user-specified options. 9 | % See the online Manopt documentation for details on options. 10 | % 11 | % See also: mergeOptions 12 | 13 | % This file is part of Manopt: www.manopt.org. 14 | % Original author: Nicolas Boumal, Dec. 30, 2012. 15 | % Contributors: 16 | % Change log: 17 | 18 | 19 | % Verbosity level: 0 is no output at all. The higher the verbosity, the 20 | % more info is printed / displayed during solver execution. 21 | opts.verbosity = 3; 22 | 23 | % If debug is set to true, additional computations may be performed and 24 | % debugging information is outputed during solver execution. 25 | opts.debug = false; 26 | 27 | % Maximum number of store structures to store. If set to 0, caching 28 | % capabilities are not disabled, but the cache will be emptied at each 29 | % iteration of iterative solvers (more specifically: every time the 30 | % solver calls the purgeStoredb tool). 31 | opts.storedepth = 20; 32 | 33 | % Maximum amount of time a solver may execute, in seconds. 34 | opts.maxtime = inf; 35 | 36 | end 37 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/getLinesearch.m: -------------------------------------------------------------------------------- 1 | function [t, storedb] = getLinesearch(problem, x, d, storedb) 2 | % Returns a hint for line-search algorithms. 3 | % 4 | % function [t, storedb] = getLinesearch(problem, x, d, storedb) 5 | % 6 | % For a line-search problem at x along the tangent direction d, computes 7 | % and returns t such that retracting t*d at x yields a good point around 8 | % where to look for a line-search solution. That is: t is a hint as to "how 9 | % far to look" along the line. 10 | % 11 | % The cache database storedb is passed along, possibly modified and 12 | % returned in the process. 13 | % 14 | % See also: canGetLinesearch 15 | 16 | % This file is part of Manopt: www.manopt.org. 17 | % Original author: Nicolas Boumal, July 17, 2014. 18 | % Contributors: 19 | % Change log: 20 | 21 | 22 | if isfield(problem, 'linesearch') 23 | %% Compute the line-search hint function using linesearch. 24 | 25 | is_octave = exist('OCTAVE_VERSION', 'builtin'); 26 | if ~is_octave 27 | narg = nargin(problem.linesearch); 28 | else 29 | narg = 3; 30 | end 31 | 32 | % Check whether the linesearch function wants to deal with the 33 | % store structure or not. 34 | switch narg 35 | case 2 36 | t = problem.linesearch(x, d); 37 | case 3 38 | % Obtain, pass along, and save the store structure 39 | % associated to this point. 40 | store = getStore(problem, x, storedb); 41 | [t, store] = problem.linesearch(x, d, store); 42 | storedb = setStore(problem, x, storedb, store); 43 | otherwise 44 | up = MException('manopt:getLinesearch:badfun', ... 45 | 'linesearch should accept 2 or 3 inputs.'); 46 | throw(up); 47 | end 48 | 49 | else 50 | %% Abandon computing the line-search function. 51 | 52 | up = MException('manopt:getLinesearch:fail', ... 53 | ['The problem description is not explicit enough to ' ... 54 | 'compute a line-search hint.']); 55 | throw(up); 56 | 57 | end 58 | 59 | end 60 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/getPrecon.m: -------------------------------------------------------------------------------- 1 | function [Pd, storedb] = getPrecon(problem, x, d, storedb) 2 | % Applies the preconditioner for the Hessian of the cost at x along d. 3 | % 4 | % function [Pd, storedb] = getPrecon(problem, x, storedb) 5 | % 6 | % Returns as Pd the result of applying the Hessian preconditioner to the 7 | % tangent vector d at point x. If no preconditioner is specified, Pd = d 8 | % (identity). 9 | % 10 | % See also: getHessian 11 | 12 | % This file is part of Manopt: www.manopt.org. 13 | % Original author: Nicolas Boumal, Dec. 30, 2012. 14 | % Contributors: 15 | % Change log: 16 | 17 | 18 | if isfield(problem, 'precon') 19 | %% Compute the preconditioning using precon. 20 | 21 | is_octave = exist('OCTAVE_VERSION', 'builtin'); 22 | if ~is_octave 23 | narg = nargin(problem.precon); 24 | else 25 | narg = 3; 26 | end 27 | 28 | % Check whether the precon function wants to deal with the store 29 | % structure or not. 30 | switch narg 31 | case 2 32 | Pd = problem.precon(x, d); 33 | case 3 34 | % Obtain, pass along, and save the store structure 35 | % associated to this point. 36 | store = getStore(problem, x, storedb); 37 | [Pd store] = problem.precon(x, d, store); 38 | storedb = setStore(problem, x, storedb, store); 39 | otherwise 40 | up = MException('manopt:getPrecon:badprecon', ... 41 | 'precon should accept 2 or 3 inputs.'); 42 | throw(up); 43 | end 44 | 45 | else 46 | %% No preconditioner provided, so just use the identity. 47 | 48 | Pd = d; 49 | 50 | end 51 | 52 | end 53 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/getStore.m: -------------------------------------------------------------------------------- 1 | function store = getStore(problem, x, storedb) 2 | % Extracts a store struct. pertaining to a point from the storedb database. 3 | % 4 | % function store = getStore(problem, x, storedb) 5 | % 6 | % Queries the storedb database of structures (itself a structure) and 7 | % returns the store structure corresponding to the point x. If there is no 8 | % record for the point x, returns an empty structure. 9 | % 10 | % See also: setStore purgeStoredb 11 | 12 | % This file is part of Manopt: www.manopt.org. 13 | % Original author: Nicolas Boumal, Dec. 30, 2012. 14 | % Contributors: 15 | % Change log: 16 | 17 | % Construct the fieldname (key) associated to the queried point x. 18 | key = problem.M.hash(x); 19 | 20 | % If there is a value stored for this key, return it. 21 | % Otherwise, return an empty structure. 22 | if isfield(storedb, key) 23 | store = storedb.(key); 24 | else 25 | store = struct(); 26 | end 27 | 28 | end 29 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/hashmd5.m: -------------------------------------------------------------------------------- 1 | function h = hashmd5(inp) 2 | % Computes the MD5 hash of input data. 3 | % 4 | % function h = hashmd5(inp) 5 | % 6 | % Returns a string containing the MD5 hash of the input variable. The input 7 | % variable may be of any class that can be typecast to uint8 format, which 8 | % is fairly non-restrictive. 9 | 10 | % This file is part of Manopt: www.manopt.org. 11 | % This code is a stripped version of more general hashing code by 12 | % Michael Kleder, Nov 2005. 13 | % Change log: 14 | % Aug. 8, 2013 (NB) : Made x a static (persistent) variable, in the hope 15 | % it will speed it up. Furthermore, the function is 16 | % now Octave compatible. 17 | 18 | is_octave = exist('OCTAVE_VERSION', 'builtin'); 19 | 20 | persistent x; 21 | if isempty(x) && ~is_octave 22 | x = java.security.MessageDigest.getInstance('MD5'); 23 | end 24 | 25 | inp=inp(:); 26 | % Convert strings and logicals into uint8 format 27 | if ischar(inp) || islogical(inp) 28 | inp=uint8(inp); 29 | else % Convert everything else into uint8 format without loss of data 30 | inp=typecast(inp,'uint8'); 31 | end 32 | 33 | % Create hash 34 | if ~is_octave 35 | x.update(inp); 36 | h = typecast(x.digest, 'uint8'); 37 | h = dec2hex(h)'; 38 | % Remote possibility: all hash bytes < 128, so pad: 39 | if(size(h,1))==1 40 | h = [repmat('0',[1 size(h,2)]);h]; 41 | end 42 | h = lower(h(:)'); 43 | else 44 | h = md5sum(char(inp'), true); 45 | end 46 | 47 | end 48 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/mergeOptions.m: -------------------------------------------------------------------------------- 1 | function opts = mergeOptions(opts1, opts2) 2 | % Merges two options structures with one having precedence over the other. 3 | % 4 | % function opts = mergeOptions(opts1, opts2) 5 | % 6 | % input: opts1 and opts2 are two structures. 7 | % output: opts is a structure containing all fields of opts1 and opts2. 8 | % Whenever a field is present in both opts1 and opts2, it is the value in 9 | % opts2 that is kept. 10 | % 11 | % The typical usage is to have opts1 contain default options and opts2 12 | % contain user-specified options that overwrite the defaults. 13 | % 14 | % See also: getGlobalDefaults 15 | 16 | % This file is part of Manopt: www.manopt.org. 17 | % Original author: Nicolas Boumal, Dec. 30, 2012. 18 | % Contributors: 19 | % Change log: 20 | 21 | 22 | if isempty(opts1) 23 | opts1 = struct(); 24 | end 25 | if isempty(opts2) 26 | opts2 = struct(); 27 | end 28 | 29 | opts = opts1; 30 | fields = fieldnames(opts2); 31 | for i = 1 : length(fields) 32 | opts.(fields{i}) = opts2.(fields{i}); 33 | end 34 | 35 | end 36 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/purgeStoredb.m: -------------------------------------------------------------------------------- 1 | function storedb = purgeStoredb(storedb, storedepth) 2 | % Makes sure the storedb database does not exceed some maximum size. 3 | % 4 | % function storedb = purgeStoredb(storedb, storedepth) 5 | % 6 | % Trim the store database storedb such that it contains at most storedepth 7 | % elements (store structures). The 'lastset__' field of the store 8 | % structures is used to delete the oldest elements first. 9 | 10 | % This file is part of Manopt: www.manopt.org. 11 | % Original author: Nicolas Boumal, Dec. 30, 2012. 12 | % Contributors: 13 | % Change log: 14 | % Dec. 6, 2013, NB: 15 | % Now using a persistent uint32 counter instead of cputime to track 16 | % the most recently modified stores. 17 | 18 | 19 | if storedepth <= 0 20 | storedb = struct(); 21 | return; 22 | end 23 | 24 | % Get list of field names (keys). 25 | keys = fieldnames(storedb); 26 | nkeys = length(keys); 27 | 28 | % If we need to remove some of the elements in the database. 29 | if nkeys > storedepth 30 | 31 | % Get the last-set counter of each element: a higher number means 32 | % it was modified more recently. 33 | lastset = zeros(nkeys, 1, 'uint32'); 34 | for i = 1 : nkeys 35 | store = storedb.(keys{i}); 36 | lastset(i) = store.lastset__; 37 | end 38 | 39 | % Sort the counters and determine the threshold above which the 40 | % field needs to be removed. 41 | sortlastset = sort(lastset, 1, 'descend'); 42 | minlastset = sortlastset(storedepth); 43 | 44 | % Remove all fields that are too old. 45 | storedb = rmfield(storedb, keys(lastset < minlastset)); 46 | 47 | end 48 | 49 | end 50 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/privatetools/setStore.m: -------------------------------------------------------------------------------- 1 | function storedb = setStore(problem, x, storedb, store) 2 | % Updates the store struct. pertaining to a point in the storedb database. 3 | % 4 | % function storedb = setStore(problem, x, storedb, store) 5 | % 6 | % Updates the storedb database of structures such that the structure 7 | % corresponding to the point x will be replaced by store. If there was no 8 | % record for the point x, it is created and set to store. The updated 9 | % storedb database is returned. The lastset__ field of the store structure 10 | % keeps track of which stores were updated latest. 11 | 12 | % This file is part of Manopt: www.manopt.org. 13 | % Original author: Nicolas Boumal, Dec. 30, 2012. 14 | % Contributors: 15 | % Change log: 16 | % Dec. 6, 2013, NB: 17 | % Now using a persistent uint32 counter instead of cputime to track 18 | % the most recently modified stores. 19 | 20 | % This persistent counter is used to keep track of the order in which 21 | % store structures are updated. This is used by purgeStoredb to erase 22 | % the least recently useful store structures first when garbage 23 | % collecting. 24 | persistent counter; 25 | if isempty(counter) 26 | counter = uint32(0); 27 | end 28 | 29 | assert(nargout == 1, ... 30 | 'The output of setStore should replace your storedb.'); 31 | 32 | % Construct the fieldname (key) associated to the current point x. 33 | key = problem.M.hash(x); 34 | 35 | % Set the value associated to that key to store. 36 | storedb.(key) = store; 37 | 38 | % Add / update a last-set flag. 39 | storedb.(key).lastset__ = counter; 40 | counter = counter + 1; 41 | 42 | end 43 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/solvers/neldermead/centroid.m: -------------------------------------------------------------------------------- 1 | function y = centroid(M, x) 2 | % Attempts the computation of a centroid of a set of points on amanifold. 3 | % 4 | % function y = centroid(M, x) 5 | % 6 | % M is a structure representing a manifold. x is a cell of points on that 7 | % manifold. 8 | 9 | % This file is part of Manopt: www.manopt.org. 10 | % Original author: Nicolas Boumal, Dec. 30, 2012. 11 | % Contributors: 12 | % Change log: 13 | 14 | 15 | % For now, just apply a few steps of gradient descent for Karcher means 16 | 17 | n = numel(x); 18 | 19 | problem.M = M; 20 | 21 | problem.cost = @cost; 22 | function val = cost(y) 23 | val = 0; 24 | for i = 1 : n 25 | val = val + M.dist(y, x{i})^2; 26 | end 27 | val = val/2; 28 | end 29 | 30 | problem.grad = @grad; 31 | function g = grad(y) 32 | g = M.zerovec(y); 33 | for i = 1 : n 34 | g = M.lincomb(y, 1, g, -1, M.log(y, x{i})); 35 | end 36 | end 37 | 38 | % This line can be uncommented to check that the gradient is indeed 39 | % correct. This should always be the case if the dist and the log 40 | % functions in the manifold are correct. 41 | % checkgradient(problem); 42 | 43 | query = warning('query', 'manopt:getHessian:approx'); 44 | warning('off', 'manopt:getHessian:approx') 45 | options.verbosity = 0; 46 | options.maxiter = 15; 47 | y = trustregions(problem, x{randi(n)}, options); 48 | warning(query.state, 'manopt:getHessian:approx') 49 | 50 | end 51 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/solvers/trustregions/license for original GenRTR code.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007,2012 Christopher G. Baker, Pierre-Antoine Absil, Kyle A. Gallivan 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the names of the contributors nor of their affiliated 12 | institutions may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | For questions, please contact Chris Baker (chris@cgbaker.net) 27 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/tools/identify_linear_piece.m: -------------------------------------------------------------------------------- 1 | function [range, poly] = identify_linear_piece(x, y, window_length) 2 | % Identify a segment of the curve (x, y) that appears to be linear. 3 | % 4 | % function [range poly] = identify_linear_piece(x, y, window_length) 5 | % 6 | % This function attempts to identify a contiguous segment of the curve 7 | % defined by the vectors x and y that appears to be linear. A line is fit 8 | % through the data over all windows of length window_length and the best 9 | % fit is retained. The output specifies the range of indices such that 10 | % x(range) is the portion over which (x, y) is the most linear and the 11 | % output poly specifies a first order polynomial that best fits (x, y) over 12 | % that range, following the usual matlab convention for polynomials 13 | % (highest degree coefficients first). 14 | % 15 | % See also: checkdiff checkgradient checkhessian 16 | 17 | % This file is part of Manopt: www.manopt.org. 18 | % Original author: Nicolas Boumal, July 8, 2013. 19 | % Contributors: 20 | % Change log: 21 | 22 | residues = zeros(length(x)-window_length, 1); 23 | polys = zeros(2, length(residues)); 24 | for i = 1 : length(residues) 25 | range = i:i+window_length; 26 | [poly, meta] = polyfit(x(range), y(range), 1); 27 | residues(i) = meta.normr; 28 | polys(:, i) = poly'; 29 | end 30 | [unused, best] = min(residues); %#ok 31 | range = best:best+window_length; 32 | poly = polys(:, best)'; 33 | 34 | end 35 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/tools/multiprod.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/thirdparty/manopt/manopt/tools/multiprod.m -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/tools/multiprodmultitransp_license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009, Paolo de Leva 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/tools/multiscale.m: -------------------------------------------------------------------------------- 1 | function A = multiscale(scale, A) 2 | % Multiplies the 2D slices in a 3D matrix by individual scalars. 3 | % 4 | % function A = multiscale(scale, A) 5 | % 6 | % Given a vector scale of length N and a 3-dimensional matrix A of size 7 | % n-by-m-by-N, returns a matrix A of same size such that 8 | % A(:, :, k) := scale(k) * A(:, :, k); 9 | % 10 | % See also: multiprod multitransp multitrace 11 | 12 | % This file is part of Manopt: www.manopt.org. 13 | % Original author: Nicolas Boumal, Dec. 30, 2012. 14 | % Contributors: 15 | % Change log: 16 | 17 | 18 | assert(ndims(A) <= 3, ... 19 | ['multiscale is only well defined for matrix arrays of 3 ' ... 20 | 'or less dimensions.']); 21 | [n m N] = size(A); 22 | assert(numel(scale) == N, ... 23 | ['scale must be a vector whose length equals the third ' ... 24 | 'dimension of A, that is, the number of 2D matrix slices ' ... 25 | 'in the 3D matrix A.']); 26 | 27 | scale = scale(:); 28 | A = reshape(bsxfun(@times, reshape(A, n*m, N), scale'), n, m, N); 29 | 30 | end 31 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/tools/multiskew.m: -------------------------------------------------------------------------------- 1 | function Y = multiskew(X) 2 | % Returns the skew-symmetric parts of the matrices in the 3D matrix X. 3 | % 4 | % function Y = multiskew(X) 5 | % 6 | % Y is a 3D matrix the same size as X. Each slice Y(:, :, i) is the 7 | % skew-symmetric part of the slice X(:, :, i). 8 | % 9 | % See also: multiprod multitransp multiscale multisym 10 | 11 | % This file is part of Manopt: www.manopt.org. 12 | % Original author: Nicolas Boumal, Jan. 31, 2013. 13 | % Contributors: 14 | % Change log: 15 | 16 | Y = .5*(X - multitransp(X)); 17 | 18 | end 19 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/tools/multisym.m: -------------------------------------------------------------------------------- 1 | function Y = multisym(X) 2 | % Returns the symmetric parts of the matrices in the 3D matrix X 3 | % 4 | % function Y = multisym(X) 5 | % 6 | % Y is a 3D matrix the same size as X. Each slice Y(:, :, i) is the 7 | % symmetric part of the slice X(:, :, i). 8 | % 9 | % See also: multiprod multitransp multiscale multiskew 10 | 11 | % This file is part of Manopt: www.manopt.org. 12 | % Original author: Nicolas Boumal, Jan. 31, 2013. 13 | % Contributors: 14 | % Change log: 15 | 16 | Y = .5*(X + multitransp(X)); 17 | 18 | end 19 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/tools/multitrace.m: -------------------------------------------------------------------------------- 1 | function tr = multitrace(A) 2 | % Computes the traces of the 2D slices in a 3D matrix. 3 | % 4 | % function tr = multitrace(A) 5 | % 6 | % For a 3-dimensional matrix A of size n-by-n-by-N, returns a column vector 7 | % tr of length N such that tr(k) = trace(A(:, :, k)); 8 | % 9 | % See also: multiprod multitransp multiscale 10 | 11 | % This file is part of Manopt: www.manopt.org. 12 | % Original author: Nicolas Boumal, Dec. 30, 2012. 13 | % Contributors: 14 | % Change log: 15 | 16 | 17 | assert(ndims(A) <= 3, ... 18 | ['multitrace is only well defined for matrix arrays of 3 ' ... 19 | 'or less dimensions.']); 20 | 21 | tr = diagsum(A, 1, 2); 22 | 23 | end 24 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/tools/multitransp.m: -------------------------------------------------------------------------------- 1 | function b = multitransp(a, dim) 2 | %MULTITRANSP Transposing arrays of matrices. 3 | % B = MULTITRANSP(A) is equivalent to B = MULTITRANSP(A, DIM), where 4 | % DIM = 1. 5 | % 6 | % B = MULTITRANSP(A, DIM) is equivalent to 7 | % B = PERMUTE(A, [1:DIM-1, DIM+1, DIM, DIM+2:NDIMS(A)]), where A is an 8 | % array containing N P-by-Q matrices along its dimensions DIM and DIM+1, 9 | % and B is an array containing the Q-by-P transpose (.') of those N 10 | % matrices along the same dimensions. N = NUMEL(A) / (P*Q), i.e. N is 11 | % equal to the number of elements in A divided by the number of elements 12 | % in each matrix. 13 | % 14 | % MULTITRANSP, PERMUTE and IPERMUTE are a generalization of TRANSPOSE 15 | % (.') for N-D arrays. 16 | % 17 | % Example: 18 | % A 5-by-9-by-3-by-2 array may be considered to be a block array 19 | % containing ten 9-by-3 matrices along dimensions 2 and 3. In this 20 | % case, its size is so indicated: 5-by-(9-by-3)-by-2 or 5x(9x3)x2. 21 | % If A is ................ a 5x(9x3)x2 array of 9x3 matrices, 22 | % C = MULTITRANSP(A, 2) is a 5x(3x9)x2 array of 3x9 matrices. 23 | % 24 | % See also PERMUTE, IPERMUTE, MULTIPROD, MULTITRACE, MULTISCALE. 25 | 26 | % $ Version: 1.0 $ 27 | % CODE by: Paolo de Leva (IUSM, Rome, IT) 2005 Sep 9 28 | % COMMENTS by: Code author 2006 Nov 21 29 | % OUTPUT tested by: Code author 2005 Sep 13 30 | % ------------------------------------------------------------------------- 31 | 32 | % Setting DIM if not supplied. 33 | if nargin == 1, dim = 1; end 34 | 35 | % Transposing 36 | order = [1:dim-1, dim+1, dim, dim+2:ndims(a)]; 37 | b = permute(a, order); 38 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt/tools/plotprofile.m: -------------------------------------------------------------------------------- 1 | function cost = plotprofile(problem, x, d, t) 2 | % Plot the cost function along a geodesic or a retraction path. 3 | % 4 | % function plotprofile(problem, x, d, t) 5 | % function costs = plotprofile(problem, x, d, t) 6 | % 7 | % Plot profile evaluates the cost function along a geodesic gamma(t) such 8 | % that gamma(0) = x and the derivative of gamma at 0 is the direction d. 9 | % The input t is a vector specifying for which values of t we must evaluate 10 | % f(gamma(t)) (it may include negative values). 11 | % 12 | % If the function is called with an output, the plot is not drawn and the 13 | % values of the cost are returned for the instants t. 14 | 15 | % This file is part of Manopt: www.manopt.org. 16 | % Original author: Nicolas Boumal, Jan. 9, 2013. 17 | % Contributors: 18 | % Change log: 19 | 20 | % Verify that the problem description is sufficient. 21 | if ~canGetCost(problem) 22 | error('It seems no cost was provided.'); 23 | end 24 | 25 | linesearch_fun = @(t) getCost(problem, problem.M.exp(x, d, t), struct()); 26 | 27 | cost = zeros(size(t)); 28 | for i = 1 : numel(t) 29 | cost(i) = linesearch_fun(t(i)); 30 | end 31 | 32 | if nargout == 0 33 | plot(t, cost); 34 | xlabel('t'); 35 | ylabel('f(Exp_x(t*d))'); 36 | end 37 | 38 | end 39 | -------------------------------------------------------------------------------- /thirdparty/manopt/manopt_version.m: -------------------------------------------------------------------------------- 1 | function [version released] = manopt_version() 2 | % Returns the version of the Manopt package you are running, as a vector. 3 | % 4 | % function [version released] = manopt_version() 5 | % 6 | % version(1) is the primary version number. 7 | % released is the date this version was released, in the same format as the 8 | % date() function in Matlab. 9 | 10 | version = [1, 0, 7]; 11 | released = '12-Aug-2014'; 12 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/Contents.m: -------------------------------------------------------------------------------- 1 | % UTILS Utility package for MATLAB xUnit Test Framework 2 | % 3 | % Array Comparison 4 | % compareFloats - Compare floating-point arrays using tolerance 5 | % 6 | % Test Case Discovery Functions 7 | % isTestCaseSubclass - True for name of TestCase subclass 8 | % 9 | % String Functions 10 | % arrayToString - Convert array to string for display 11 | % comparisonMessage - Assertion message string for comparing two arrays 12 | % containsRegexp - True if string contains regular expression 13 | % isSetUpString - True for string that looks like a setup function 14 | % isTearDownString - True for string that looks like teardown function 15 | % isTestString - True for string that looks like a test function 16 | % stringToCellArray - Convert string to cell array of strings 17 | % 18 | % Miscellaneous Functions 19 | % generateDoc - Publish test scripts in mtest/doc 20 | % parseFloatAssertInputs - Common input-parsing logic for several functions 21 | 22 | % Steven L. Eddins 23 | % Copyright 2008-2009 The MathWorks, Inc. 24 | 25 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/comparisonMessage.m: -------------------------------------------------------------------------------- 1 | function msg = comparisonMessage(user_message, assertion_message, A, B) 2 | %comparisonMessage Generate assertion message when comparing two arrays. 3 | % msg = comparisonMessage(user_message, assertion_message, A, B) returns a 4 | % string appropriate to use in a call to throw inside an assertion function 5 | % that compares two arrays A and B. 6 | % 7 | % The string returned has the following form: 8 | % 9 | % 10 | % 11 | % 12 | % First input: 13 | % 14 | % 15 | % Second input: 16 | % 17 | % 18 | % user_message can be the empty string, '', in which case user_message is 19 | % skipped. 20 | 21 | % Steven L. Eddins 22 | % Copyright 2009 The MathWorks, Inc. 23 | 24 | msg = sprintf('%s\n\n%s\n%s\n\n%s\n%s', ... 25 | assertion_message, ... 26 | 'First input:', ... 27 | xunit.utils.arrayToString(A), ... 28 | 'Second input:', ... 29 | xunit.utils.arrayToString(B)); 30 | 31 | if ~isempty(user_message) 32 | msg = sprintf('%s\n%s', user_message, msg); 33 | end 34 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/containsRegexp.m: -------------------------------------------------------------------------------- 1 | function tf = containsRegexp(str, exp) 2 | %containsRegexp True if string contains regular expression 3 | % TF = containsRegexp(str, exp) returns true if the string str contains the 4 | % regular expression exp. If str is a cell array of strings, then 5 | % containsRegexp tests each string in the cell array, returning the results in 6 | % a logical array with the same size as str. 7 | 8 | % Steven L. Eddins 9 | % Copyright 2008-2009 The MathWorks, Inc. 10 | 11 | % Convert to canonical input form: A cell array of strings. 12 | if ~iscell(str) 13 | str = {str}; 14 | end 15 | 16 | matches = regexp(str, exp); 17 | tf = ~cellfun('isempty', matches); 18 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/generateDoc.m: -------------------------------------------------------------------------------- 1 | function generateDoc 2 | %generateDoc Publish the example scripts in the doc directory 3 | 4 | % Steven L. Eddins 5 | % Copyright 2008-2009 The MathWorks, Inc. 6 | 7 | doc_dir = fullfile(fileparts(which('runxunit')), '..', 'doc'); 8 | addpath(doc_dir); 9 | cd(doc_dir) 10 | mfiles = dir('*.m'); 11 | for k = 1:numel(mfiles) 12 | publish(mfiles(k).name); 13 | cd(doc_dir) 14 | end 15 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/isAlmostEqual.m: -------------------------------------------------------------------------------- 1 | function same = isAlmostEqual(A, B, reltol) 2 | %isAlmostEqual Equality test using relative tolerance 3 | % same = isAlmostEqual(A, B, reltol), for two floating-point arrays A and B, 4 | % tests A and B for equality using the specified relative tolerance. 5 | % isAlmostEqual returns true if the following relationship is satisfied for 6 | % all values in A and B: 7 | % 8 | % abs(A - B) ./ max(abs(A), abs(B)) <= reltol 9 | % 10 | % same = isAlmostEqual(A, B) uses the following value for the relative 11 | % tolerance: 12 | % 13 | % 100 * max(eps(class(A)), eps(class(B))) 14 | % 15 | % If either A or B is not a floating-point array, then isAlmostEqual returns 16 | % the result of isequal(A, B). 17 | 18 | % Steven L. Eddins 19 | % Copyright 2008-2009 The MathWorks, Inc. 20 | 21 | if ~isfloat(A) || ~isfloat(B) 22 | same = isequal(A, B); 23 | return 24 | end 25 | 26 | if nargin < 3 27 | reltol = 100 * max(eps(class(A)), eps(class(B))); 28 | end 29 | 30 | if ~isequal(size(A), size(B)) 31 | same = false; 32 | return 33 | end 34 | 35 | A = A(:); 36 | B = B(:); 37 | 38 | delta = abs(A - B) ./ max(max(abs(A), abs(B)), 1); 39 | 40 | % Some floating-point values require special handling. 41 | delta((A == 0) & (B == 0)) = 0; 42 | delta(isnan(A) & isnan(B)) = 0; 43 | delta((A == Inf) & (B == Inf)) = 0; 44 | delta((A == -Inf) & (B == -Inf)) = 0; 45 | 46 | same = all(delta <= reltol); 47 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/isSetUpString.m: -------------------------------------------------------------------------------- 1 | function tf = isSetUpString(str) 2 | %isSetUpString True if string looks like the name of a setup function 3 | % tf = isSetUpString(str) returns true if the string str looks like the name 4 | % of a setup function. If str is a cell array of strings, then isSetUpString 5 | % tests each string in the cell array, returning the results in a logical 6 | % array with the same size as str. 7 | 8 | % Steven L. Eddins 9 | % Copyright 2008-2009 The MathWorks, Inc. 10 | 11 | setup_exp = '^[sS]et[uU]p'; 12 | tf = xunit.utils.containsRegexp(str, setup_exp); 13 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/isTearDownString.m: -------------------------------------------------------------------------------- 1 | function tf = isTearDownString(str) 2 | %isTearDownString True if string looks like the name of a teardown function 3 | % tf = isTearDownString(str) returns true if the string str looks like the 4 | % name of a teardown function. If str is a cell array of strings, then 5 | % isTearDownString tests each string in the cell array, returning the results 6 | % in a logical array with the same size as str. 7 | 8 | % Steven L. Eddins 9 | % Copyright 2008-2009 The MathWorks, Inc. 10 | 11 | setup_exp = '^[tT]ear[dD]own'; 12 | tf = xunit.utils.containsRegexp(str, setup_exp); 13 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/isTestCaseSubclass.m: -------------------------------------------------------------------------------- 1 | function tf = isTestCaseSubclass(name) 2 | %isTestCaseSubclass True for name of a TestCase subclass 3 | % tf = isTestCaseSubclass(name) returns true if the string name is the name of 4 | % a TestCase subclass on the MATLAB path. 5 | 6 | % Steven L. Eddins 7 | % Copyright 2008-2009 The MathWorks, Inc. 8 | 9 | tf = false; 10 | 11 | class_meta = meta.class.fromName(name); 12 | if isempty(class_meta) 13 | % Not the name of a class 14 | return; 15 | end 16 | 17 | if strcmp(class_meta.Name, 'TestCase') 18 | tf = true; 19 | else 20 | tf = isMetaTestCaseSubclass(class_meta); 21 | end 22 | 23 | function tf = isMetaTestCaseSubclass(class_meta) 24 | 25 | tf = false; 26 | 27 | if strcmp(class_meta.Name, 'TestCase') 28 | tf = true; 29 | else 30 | % Invoke function recursively on parent classes. 31 | super_classes = class_meta.SuperClasses; 32 | for k = 1:numel(super_classes) 33 | if isMetaTestCaseSubclass(super_classes{k}) 34 | tf = true; 35 | break; 36 | end 37 | end 38 | end 39 | 40 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/isTestString.m: -------------------------------------------------------------------------------- 1 | function tf = isTestString(str) 2 | %isTestString True if string looks like the name of a test 3 | % tf = isTestString(str) returns true if the string str looks like the name of 4 | % a test. If str is a cell array of strings, then isTestString tests each 5 | % string in the cell array, returning the results in a logical array with the 6 | % same size as str. 7 | 8 | % Steven L. Eddins 9 | % Copyright 2008-2009 The MathWorks, Inc. 10 | 11 | test_at_beginning = '^[tT]est'; 12 | test_at_end = '[tT]est$'; 13 | 14 | tf = xunit.utils.containsRegexp(str, test_at_beginning) | ... 15 | xunit.utils.containsRegexp(str, test_at_end); 16 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/parseFloatAssertInputs.m: -------------------------------------------------------------------------------- 1 | function params = parseFloatAssertInputs(varargin) 2 | %parseFloatAssertInputs Parse inputs for floating-point assertion functions. 3 | % params = parseFloatAssertInputs(varargin) parses the input arguments for 4 | % assertElementsAlmostEqual, assertVectorsAlmostEqual, and compareFcn. It 5 | % returns a parameter struct containing the fields: 6 | % 7 | % A B Message ToleranceType Tolerance FloorTolerance 8 | 9 | % Steven L. Eddins 10 | % Copyright 2008-2009 The MathWorks, Inc. 11 | 12 | error(nargchk(2, 6, nargin, 'struct')); 13 | 14 | params = struct('A', {[]}, 'B', {[]}, 'ToleranceType', {[]}, ... 15 | 'Tolerance', {[]}, 'FloorTolerance', {[]}, 'Message', {''}); 16 | 17 | % The first two input arguments are always A and B. 18 | params.A = varargin{1}; 19 | params.B = varargin{2}; 20 | varargin(1:2) = []; 21 | 22 | % If the last argument is a message string, process it and remove it from the list. 23 | if (numel(varargin) >= 1) && ischar(varargin{end}) && ... 24 | ~any(strcmp(varargin{end}, {'relative', 'absolute'})) 25 | params.Message = varargin{end}; 26 | varargin(end) = []; 27 | else 28 | params.Message = ''; 29 | end 30 | 31 | try 32 | epsilon = max(eps(class(params.A)), eps(class(params.B))); 33 | catch 34 | epsilon = eps; 35 | end 36 | 37 | if numel(varargin) < 3 38 | % floor_tol not specified; set default. 39 | params.FloorTolerance = sqrt(epsilon); 40 | else 41 | params.FloorTolerance = varargin{3}; 42 | end 43 | 44 | if numel(varargin) < 2 45 | % tol not specified; set default. 46 | params.Tolerance = sqrt(epsilon); 47 | else 48 | params.Tolerance = varargin{2}; 49 | end 50 | 51 | if numel(varargin) < 1 52 | % tol_type not specified; set default. 53 | params.ToleranceType = 'relative'; 54 | else 55 | params.ToleranceType = varargin{1}; 56 | end 57 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/+xunit/+utils/stringToCellArray.m: -------------------------------------------------------------------------------- 1 | function c = stringToCellArray(s) 2 | %stringToCellArray Convert string with newlines to cell array of strings. 3 | % C = stringToCellArray(S) converts the input string S to a cell array of 4 | % strings, breaking up S at new lines. 5 | 6 | % Steven L. Eddins 7 | % Copyright 2009 The MathWorks, Inc. 8 | 9 | if isempty(s) 10 | c = cell(0, 1); 11 | else 12 | c = textscan(s, '%s', 'Delimiter', '\n', 'Whitespace', ''); 13 | c = c{1}; 14 | end 15 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/CommandWindowTestRunDisplay.m: -------------------------------------------------------------------------------- 1 | classdef CommandWindowTestRunDisplay < TestRunDisplay 2 | %CommandWindowTestRunDisplay Print test suite execution results to Command Window. 3 | % CommandWindowTestRunDisplay is a subclass of TestRunMonitor. If a 4 | % CommandWindowTestRunDisplay object is passed to the run method of a 5 | % TestComponent, such as a TestSuite or a TestCase, it will print information 6 | % to the Command Window as the test run proceeds. 7 | % 8 | % CommandWindowTestRunDisplay methods: 9 | % testComponentStarted - Update Command Window display 10 | % testComponentFinished - Update Command Window display 11 | % testCaseFailure - Log test failure information 12 | % testCaseError - Log test error information 13 | % 14 | % CommandWindowTestRunDisplay properties: 15 | % TestCaseCount - Number of test cases executed 16 | % Faults - Struct array of test fault info 17 | % 18 | % See also TestRunLogger, TestRunMonitor, TestSuite 19 | 20 | % Steven L. Eddins 21 | % Copyright 2008-2010 The MathWorks, Inc. 22 | 23 | methods 24 | function self = CommandWindowTestRunDisplay 25 | self = self@TestRunDisplay(1); 26 | end 27 | end 28 | 29 | end 30 | 31 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/TestCaseInDir.m: -------------------------------------------------------------------------------- 1 | %TestCaseInDir Test case requiring temporary directory change 2 | % The TestCaseInDir class defines a test case that has to be run by first 3 | % changing to a specified directory. 4 | % 5 | % The setUp method adds the starting directory to the path and then uses cd to 6 | % change into the specified directory. The tearDown method restores the 7 | % original path and directory. 8 | % 9 | % TestCaseInDir is used by MATLAB xUnit's own test suite in order to test itself. 10 | % 11 | % TestCaseInDir methods: 12 | % TestCaseInDir - Constructor 13 | % 14 | % See also TestCase, TestCaseWithAddPath, TestComponent 15 | 16 | % Steven L. Eddins 17 | % Copyright 2008-2009 The MathWorks, Inc. 18 | 19 | classdef TestCaseInDir < TestCase & TestComponentInDir 20 | 21 | methods 22 | function self = TestCaseInDir(methodName, testDirectory) 23 | %TestCaseInDir Constructor 24 | % TestCaseInDir(testName, testDirectory) constructs a test case 25 | % using the specified name and located in the specified directory. 26 | self = self@TestCase(methodName); 27 | self = self@TestComponentInDir(testDirectory); 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/TestCaseWithAddPath.m: -------------------------------------------------------------------------------- 1 | %TestCaseInDir Test case requiring temporary path modification 2 | % The TestCaseInDir class defines a test case that has to be run by first 3 | % adding a specific directory to the path. 4 | % 5 | % The setUp method adds the directory to the path, and the tearDown method 6 | % restores the original path. 7 | % 8 | % TestCaseWithAddPath is used by MATLAB xUnit's own test suite in order to test 9 | % itself. 10 | % 11 | % TestCaseWithAddPath methods: 12 | % TestCaseWithAddPath - Constructor 13 | % setUp - Add test directory to MATLAB path 14 | % tearDown - Restore original MATLAB path 15 | % 16 | % See also TestCase, TestCaseInDir 17 | 18 | % Steven L. Eddins 19 | % Copyright 2008-2009 The MathWorks, Inc. 20 | 21 | classdef TestCaseWithAddPath < TestCase 22 | properties (SetAccess = private, GetAccess = private) 23 | %TestDirectory - Directory to be added to the path 24 | TestDirectory 25 | 26 | %OriginalPath - Path prior to adding the test directory 27 | OriginalPath 28 | end 29 | 30 | methods 31 | function self = TestCaseWithAddPath(methodName, testDirectory) 32 | %TestCaseInDir Constructor 33 | % TestCaseInDir(testName, testDirectory) constructs a test case 34 | % using the specified name and located in the specified directory. 35 | self = self@TestCase(methodName); 36 | self.TestDirectory = testDirectory; 37 | end 38 | 39 | function setUp(self) 40 | %setUp Add test directory to MATLAB path. 41 | % test_case.setUp() saves the current path in the OriginalPath 42 | % property and then adds the TestDirectory to the MATLAB path. 43 | self.OriginalPath = path; 44 | addpath(self.TestDirectory); 45 | end 46 | 47 | function tearDown(self) 48 | %tearDown Restore original MATLAB path 49 | % test_case.tearDown() restores the saved MATLAB path. 50 | path(self.OriginalPath); 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/TestComponent.m: -------------------------------------------------------------------------------- 1 | classdef TestComponent < handle 2 | %TestComponent Abstract base class for TestCase and TestSuite 3 | % 4 | % TestComponent methods: 5 | % run - Run all test cases in test component 6 | % print - Display summary of test component to Command Window 7 | % numTestCases - Number of test cases in test component 8 | % setUp - Initialize test fixture 9 | % tearDown - Clean up text fixture 10 | % 11 | % TestComponent properties: 12 | % Name - Name of test component 13 | % Location - Directory where test component is defined 14 | % 15 | % See TestCase, TestSuite 16 | 17 | % Steven L. Eddins 18 | % Copyright 2008-2009 The MathWorks, Inc. 19 | 20 | properties 21 | Name = ''; 22 | Location = ''; 23 | end 24 | 25 | properties (Access = 'protected') 26 | PrintIndentationSize = 4 27 | end 28 | 29 | methods (Abstract) 30 | print() 31 | %print Display summary of test component to Command Window 32 | % obj.print() displays information about the test component to the 33 | % Command Window. 34 | 35 | run() 36 | %run Execute test cases 37 | % obj.run() executes all the test cases in the test component 38 | 39 | numTestCases() 40 | %numTestCases Number of test cases in test component 41 | end 42 | 43 | methods 44 | function setUp(self) 45 | %setUp Set up test fixture 46 | % test_component.setUp() is called at the beginning of the run() 47 | % method. Test writers can override setUp if necessary to 48 | % initialize a test fixture. 49 | end 50 | 51 | function tearDown(self) 52 | %tearDown Tear down test fixture 53 | % test_component.tearDown() is at the end of the method. Test 54 | % writers can override tearDown if necessary to clean up a test 55 | % fixture. 56 | end 57 | 58 | end 59 | end -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/TestComponentInDir.m: -------------------------------------------------------------------------------- 1 | %TestComponentInDir Test component requiring temporary directory change 2 | % The TestComponentInDir class defines a test component that has to be run by 3 | % first changing to a specified directory. 4 | % 5 | % The setUp method adds the starting directory to the path and then uses cd to 6 | % change into the specified directory. The tearDown method restores the 7 | % original path and directory. 8 | % 9 | % TestComponentInDir methods: 10 | % TestComponentInDir - Constructor 11 | % setUp - Add test directory to MATLAB path 12 | % tearDown - Restore original MATLAB path 13 | % 14 | % See also TestComponent 15 | 16 | % Steven L. Eddins 17 | % Copyright 2008-2009 The MathWorks, Inc. 18 | 19 | classdef TestComponentInDir < TestComponent 20 | properties (SetAccess = private, GetAccess = protected) 21 | %TestDirectory - Directory to change to in the test fixture 22 | TestDirectory 23 | 24 | %OriginalPath - Path prior to adding the starting directory 25 | OriginalPath 26 | 27 | %OriginalDirectory - Starting directory 28 | OriginalDirectory 29 | end 30 | 31 | methods 32 | function self = TestComponentInDir(testDirectory) 33 | %TestCaseInDir Constructor 34 | % TestCaseInDir(testName, testDirectory) constructs a test case 35 | % using the specified name and located in the specified directory. 36 | self.TestDirectory = testDirectory; 37 | end 38 | 39 | function setUp(self) 40 | %setUp Add test directory to MATLAB path 41 | % test_case.setUp() saves the current directory in the 42 | % OriginalDirectory property, saves the current path in the 43 | % OriginalPath property, and then uses cd to change into the test 44 | % directory. 45 | self.OriginalDirectory = pwd; 46 | self.OriginalPath = path; 47 | addpath(pwd); 48 | cd(self.TestDirectory); 49 | end 50 | 51 | function tearDown(self) 52 | %tearDown Restore original MATLAB path and directory 53 | % test_case.tearDown() restores the original path and directory. 54 | cd(self.OriginalDirectory); 55 | path(self.OriginalPath); 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/TestRunMonitor.m: -------------------------------------------------------------------------------- 1 | %TestRunMonitor Abstract base class for monitoring a running test suite 2 | % The abstract TestRunMonitor class defines an object that can observe and 3 | % record the results of running a test suite. The run() method of a 4 | % TestComponent object takes a TestRunMonitor object as an input argument. 5 | % 6 | % Different test suite logging or reporting functionality can be achieved by 7 | % subclassing TestRunMonitor. For example, see the TestRunLogger and the 8 | % CommandWindowTestRunDisplay classes. 9 | % 10 | % TestRunMonitor methods: 11 | % TestRunMonitor - Constructor 12 | % testComponentStarted - Called at beginning of test component run 13 | % testComponentFinished - Called when test component run finished 14 | % testCaseFailure - Called when a test case fails 15 | % testCaseError - Called when a test case causes an error 16 | % 17 | % See also CommandWindowTestRunDisplay, TestRunLogger, TestCase, TestSuite 18 | 19 | % Steven L. Eddins 20 | % Copyright 2008-2009 The MathWorks, Inc. 21 | 22 | classdef TestRunMonitor < handle 23 | 24 | methods (Abstract) 25 | 26 | testComponentStarted(self, component) 27 | 28 | testComponentFinished(self, component, did_pass) 29 | 30 | testCaseFailure(self, test_case, failure_exception) 31 | 32 | testCaseError(self, test_case, error_exception) 33 | 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/TestSuiteInDir.m: -------------------------------------------------------------------------------- 1 | %TestSuiteInDir Test suite requiring temporary directory change 2 | % The TestSuiteInDir class defines a test suite that has to be run by first 3 | % changing to a specified directory. 4 | % 5 | % The setUp method adds the starting directory to the path and then uses cd to 6 | % change into the specified directory. The tearDown method restores the 7 | % original path and directory. 8 | % 9 | % TestSuiteInDir methods: 10 | % TestSuiteInDir - Constructor 11 | % gatherTestCases - Add test cases found in the target directory 12 | % 13 | % See also TestSuite 14 | 15 | % Steven L. Eddins 16 | % Copyright 2009 The MathWorks, Inc. 17 | 18 | classdef TestSuiteInDir < TestSuite & TestComponentInDir 19 | 20 | methods 21 | function self = TestSuiteInDir(testDirectory) 22 | %TestCaseInDir Constructor 23 | % TestCaseInDir(testName, testDirectory) constructs a test case 24 | % using the specified name and located in the specified directory. 25 | self = self@TestComponentInDir(testDirectory); 26 | 27 | if strcmp(testDirectory, '.') 28 | self.Name = pwd; 29 | self.Location = pwd; 30 | else 31 | [pathstr, name] = fileparts(testDirectory); 32 | self.Name = name; 33 | self.Location = testDirectory; 34 | end 35 | end 36 | 37 | function gatherTestCases(self) 38 | %gatherTestCases Add test cases found in the target directory 39 | % suite.gatherTestCases() automaticall finds all the test cases in 40 | % the directory specified in the constructor call and adds them to 41 | % the suite. 42 | current_dir = pwd; 43 | c = onCleanup(@() cd(current_dir)); 44 | 45 | cd(self.TestDirectory); 46 | tmp = TestSuite.fromPwd(); 47 | self.TestComponents = tmp.TestComponents; 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/assertEqual.m: -------------------------------------------------------------------------------- 1 | function assertEqual(A, B, custom_message) 2 | %assertEqual Assert that inputs are equal 3 | % assertEqual(A, B) throws an exception if A and B are not equal. A and B 4 | % must have the same class and sparsity to be considered equal. 5 | % 6 | % assertEqual(A, B, MESSAGE) prepends the string MESSAGE to the assertion 7 | % message if A and B are not equal. 8 | % 9 | % Examples 10 | % -------- 11 | % % This call returns silently. 12 | % assertEqual([1 NaN 2], [1 NaN 2]); 13 | % 14 | % % This call throws an error. 15 | % assertEqual({'A', 'B', 'C'}, {'A', 'foo', 'C'}); 16 | % 17 | % See also assertElementsAlmostEqual, assertVectorsAlmostEqual 18 | 19 | % Steven L. Eddins 20 | % Copyright 2008-2010 The MathWorks, Inc. 21 | 22 | if nargin < 3 23 | custom_message = ''; 24 | end 25 | 26 | if ~ (issparse(A) == issparse(B)) 27 | message = xunit.utils.comparisonMessage(custom_message, ... 28 | 'One input is sparse and the other is not.', A, B); 29 | throwAsCaller(MException('assertEqual:sparsityNotEqual', '%s', message)); 30 | end 31 | 32 | if ~strcmp(class(A), class(B)) 33 | message = xunit.utils.comparisonMessage(custom_message, ... 34 | 'The inputs differ in class.', A, B); 35 | throwAsCaller(MException('assertEqual:classNotEqual', '%s', message)); 36 | end 37 | 38 | if ~isequalwithequalnans(A, B) 39 | message = xunit.utils.comparisonMessage(custom_message, ... 40 | 'Inputs are not equal.', A, B); 41 | throwAsCaller(MException('assertEqual:nonEqual', '%s', message)); 42 | end 43 | 44 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/assertExceptionThrown.m: -------------------------------------------------------------------------------- 1 | function assertExceptionThrown(f, expectedId, custom_message) 2 | %assertExceptionThrown Assert that specified exception is thrown 3 | % assertExceptionThrown(F, expectedId) calls the function handle F with no 4 | % input arguments. If the result is a thrown exception whose identifier is 5 | % expectedId, then assertExceptionThrown returns silently. If no exception is 6 | % thrown, then assertExceptionThrown throws an exception with identifier equal 7 | % to 'assertExceptionThrown:noException'. If a different exception is thrown, 8 | % then assertExceptionThrown throws an exception identifier equal to 9 | % 'assertExceptionThrown:wrongException'. 10 | % 11 | % assertExceptionThrown(F, expectedId, msg) prepends the string msg to the 12 | % assertion message. 13 | % 14 | % Example 15 | % ------- 16 | % % This call returns silently. 17 | % f = @() error('a:b:c', 'error message'); 18 | % assertExceptionThrown(f, 'a:b:c'); 19 | % 20 | % % This call returns silently. 21 | % assertExceptionThrown(@() sin, 'MATLAB:minrhs'); 22 | % 23 | % % This call throws an error because calling sin(pi) does not error. 24 | % assertExceptionThrown(@() sin(pi), 'MATLAB:foo'); 25 | 26 | % Steven L. Eddins 27 | % Copyright 2008-2010 The MathWorks, Inc. 28 | 29 | noException = false; 30 | try 31 | f(); 32 | noException = true; 33 | 34 | catch exception 35 | if ~strcmp(exception.identifier, expectedId) 36 | message = sprintf('Expected exception %s but got exception %s.', ... 37 | expectedId, exception.identifier); 38 | if nargin >= 3 39 | message = sprintf('%s\n%s', custom_message, message); 40 | end 41 | throwAsCaller(MException('assertExceptionThrown:wrongException', ... 42 | '%s', message)); 43 | end 44 | end 45 | 46 | if noException 47 | message = sprintf('Expected exception "%s", but none thrown.', ... 48 | expectedId); 49 | if nargin >= 3 50 | message = sprintf('%s\n%s', custom_message, message); 51 | end 52 | throwAsCaller(MException('assertExceptionThrown:noException', '%s', message)); 53 | end 54 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/assertFalse.m: -------------------------------------------------------------------------------- 1 | function assertFalse(condition, message) 2 | %assertFalse Assert that input condition is false 3 | % assertFalse(CONDITION, MESSAGE) throws an exception containing the string 4 | % MESSAGE if CONDITION is not false. 5 | % 6 | % MESSAGE is optional. 7 | % 8 | % Examples 9 | % -------- 10 | % assertFalse(isreal(sqrt(-1))) 11 | % 12 | % assertFalse(isreal(sqrt(-1)), ... 13 | % 'Expected isreal(sqrt(-1)) to be false.') 14 | % 15 | % See also assertTrue 16 | 17 | % Steven L. Eddins 18 | % Copyright 2008-2010 The MathWorks, Inc. 19 | 20 | if nargin < 2 21 | message = 'Asserted condition is not false.'; 22 | end 23 | 24 | if ~isscalar(condition) || ~islogical(condition) 25 | throwAsCaller(MException('assertFalse:invalidCondition', ... 26 | 'CONDITION must be a scalar logical value.')); 27 | end 28 | 29 | if condition 30 | throwAsCaller(MException('assertFalse:trueCondition', '%s', message)); 31 | end 32 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/assertTrue.m: -------------------------------------------------------------------------------- 1 | function assertTrue(condition, message) 2 | %assertTrue Assert that input condition is true 3 | % assertTrue(CONDITION, MESSAGE) throws an exception containing the string 4 | % MESSAGE if CONDITION is not true. 5 | % 6 | % MESSAGE is optional. 7 | % 8 | % Examples 9 | % -------- 10 | % % This call returns silently. 11 | % assertTrue(rand < 1, 'Expected output of rand to be less than 1') 12 | % 13 | % % This call throws an error. 14 | % assertTrue(sum(sum(magic(3))) == 0, ... 15 | % 'Expected sum of elements of magic(3) to be 0') 16 | % 17 | % See also assertEqual, assertFalse 18 | 19 | % Steven L. Eddins 20 | % Copyright 2008-2010 The MathWorks, Inc. 21 | 22 | if nargin < 2 23 | message = 'Asserted condition is not true.'; 24 | end 25 | 26 | if ~isscalar(condition) || ~islogical(condition) 27 | throwAsCaller(MException('assertTrue:invalidCondition', ... 28 | 'CONDITION must be a scalar logical value.')); 29 | end 30 | 31 | if ~condition 32 | throwAsCaller(MException('assertTrue:falseCondition', '%s', message)); 33 | end 34 | -------------------------------------------------------------------------------- /thirdparty/matlab-xunit-master/src/initTestSuite.m: -------------------------------------------------------------------------------- 1 | %findSubfunctionTests Utility script used for subfunction-based tests 2 | % This file is a script that is called at the top of M-files containing 3 | % subfunction-based tests. 4 | % 5 | % The top of a typical M-file using this script looks like this: 6 | % 7 | % function test_suite = testFeatureA 8 | % 9 | % findSubfunctionTests; 10 | % 11 | % IMPORTANT NOTE 12 | % -------------- 13 | % The output variable name for an M-file using this script must be test_suite. 14 | 15 | % Steven L. Eddins 16 | % Copyright 2008-2009 The MathWorks, Inc. 17 | 18 | [ST,I] = dbstack('-completenames'); 19 | caller_name = ST(I + 1).name; 20 | caller_file = ST(I + 1).file; 21 | subFcns = which('-subfun', caller_file); 22 | 23 | setup_fcn_name = subFcns(xunit.utils.isSetUpString(subFcns)); 24 | if numel(setup_fcn_name) > 1 25 | error('findSubfunctionTests:tooManySetupFcns', ... 26 | 'Found more than one setup subfunction.') 27 | elseif isempty(setup_fcn_name) 28 | setup_fcn = []; 29 | else 30 | setup_fcn = str2func(setup_fcn_name{1}); 31 | end 32 | 33 | teardown_fcn_name = subFcns(xunit.utils.isTearDownString(subFcns)); 34 | if numel(teardown_fcn_name) > 1 35 | error('findSubfunctionTests:tooManyTeardownFcns', ... 36 | 'Found more than one teardown subfunction.') 37 | elseif isempty(teardown_fcn_name) 38 | teardown_fcn = []; 39 | else 40 | teardown_fcn = str2func(teardown_fcn_name{1}); 41 | end 42 | 43 | test_fcns = cellfun(@str2func, subFcns(xunit.utils.isTestString(subFcns)), ... 44 | 'UniformOutput', false); 45 | 46 | suite = TestSuite; 47 | suite.Name = caller_name; 48 | suite.Location = which(caller_file); 49 | for k = 1:numel(test_fcns) 50 | suite.add(FunctionHandleTestCase(test_fcns{k}, setup_fcn, teardown_fcn)); 51 | end 52 | 53 | if nargout > 0 54 | test_suite = suite; 55 | else 56 | suite.run(); 57 | end 58 | 59 | -------------------------------------------------------------------------------- /thirdparty/randraw/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2005, Alex Bar-Guy 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /thirdparty/randraw/randraw.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utvisionlab/mixest/518bbe32366881223ae0adc25d1ad7ce5c18c563/thirdparty/randraw/randraw.m -------------------------------------------------------------------------------- /thirdparty/vmfmatlab/emsamp.m: -------------------------------------------------------------------------------- 1 | function [data,labels] = emsamp(mixture, n) 2 | % EMSAMP Generates a sample of N data points from Movmf in mixture 3 | % 4 | % Description 5 | % DATA = EMSAMP(MIXTURE,N) generates a data matrix that has N rows 6 | % (n data points) and each point is drawn from the Movmf MIXTURE 7 | % [DATA, LABELS] = EMSAMP(MIXTURE,N) generates along with the data 8 | % a labeling from which gaussian in the mixture a point was 9 | % generated. 10 | % Determine number to sample from each component. Now i am not sure 11 | % if this function is wokring properly????? 12 | % 13 | % SEE also VSAMP 14 | % hacked over from i think from the NN toolbox.. 15 | % 16 | % Author: Suvrit Sra 17 | % (c) The University of Texas at Austin 18 | 19 | 20 | labels=zeros(n,1); 21 | priors = rand(1,n); 22 | 23 | % Pre-allocate data array 24 | data = zeros(n, mixture.dim); 25 | 26 | cum_prior = 0; % Cumulative sum of priors 27 | total_samples = 0; % Cumulative sum of number of sampled points 28 | for j = 1:mixture.num_clus 29 | num_samples = sum(priors >= cum_prior & ... 30 | priors < cum_prior + mixture.priors(j)); 31 | kappa = mixture.kappas(j); 32 | data(total_samples+1:total_samples+num_samples, :) = ... 33 | vsamp((mixture.centers(j, :))', kappa, num_samples); 34 | labels(total_samples+1:total_samples+num_samples) = j; 35 | cum_prior = cum_prior + mixture.priors(j); 36 | total_samples = total_samples + num_samples; 37 | end 38 | -------------------------------------------------------------------------------- /thirdparty/vmfmatlab/house.m: -------------------------------------------------------------------------------- 1 | function [v,b]=house(x) 2 | % HOUSE Returns the householder transf to reduce x to b*e_n 3 | % 4 | % [V,B] = HOUSE(X) Returns vector v and multiplier b so that 5 | % H = eye(n)-b*v*v' is the householder matrix that will transform 6 | % Hx ==> [0 0 0 ... ||x||], where is a constant. 7 | 8 | n=length(x); 9 | 10 | s = x(1:n-1)'*x(1:n-1); 11 | v= [x(1:n-1)' 1]'; 12 | 13 | if (s == 0) 14 | b = 0; 15 | else 16 | m = sqrt(x(n)*x(n) + s); 17 | 18 | if (x(n) <= 0) 19 | v(n) = x(n)-m; 20 | else 21 | v(n) = -s/(x(n)+m); 22 | end 23 | b = 2*v(n)*v(n)/(s + v(n)*v(n)); 24 | v = v/v(n); 25 | end 26 | -------------------------------------------------------------------------------- /thirdparty/vmfmatlab/logbesseli.m: -------------------------------------------------------------------------------- 1 | function [logb,flag] = logbesseli(nu,x) 2 | % log of the Bessel function, extended for large nu and x 3 | % approximation from Eqn 9.7.7 of Abramowitz and Stegun 4 | % http://www.math.sfu.ca/~cbm/aands/page_378.htm 5 | 6 | frac = x/nu; 7 | square = 1 + frac.^2; 8 | root = sqrt(square); 9 | eta = root + log(frac) - log(1+root); 10 | approx = - log(sqrt(2*pi*nu)) + nu*eta - 0.25*log(square); 11 | 12 | logb = approx; 13 | return 14 | 15 | % alternative less accurate approximation from Eqn 9.6.7 16 | % this gives better results on the Classic400 dataset! 17 | 18 | logb = nu*log(x/2) - gammaln(nu+1); 19 | return 20 | 21 | [bessel,flags] = besseli(nu,x); 22 | 23 | if any(flags ~= 0) | any(bessel == Inf) 24 | besselproblem = [x bessel flags] 25 | end 26 | 27 | logb = bessel; 28 | nz = find(bessel > 0); 29 | z = find(bessel == 0); 30 | logb(nz) = log(bessel(nz)); 31 | logb(z) = nu*log(x(z)/2) - gammaln(nu+1); 32 | 33 | %[nu*ones(size(x))'; x'; approx'; logb'] 34 | -------------------------------------------------------------------------------- /thirdparty/vmfmatlab/mixinit.m: -------------------------------------------------------------------------------- 1 | function mixture = mixinit(dim, num_comp) 2 | % MIXINIT Allocates matrices for mixture data structure. 3 | % 4 | % MIXTURE=MIXINIT(DIM, NUM_COMP) 5 | % 6 | % See also: emsamp 7 | 8 | % Set the dimensionality ... corr to 'd' 9 | mixture.dim = dim; 10 | 11 | % Equal priors for all clusters. 12 | mixture.priors = ones(1,num_comp)/num_comp; 13 | 14 | % Record no. of clusters we are dealing with. 15 | mixture.num_clus = num_comp; 16 | 17 | % Initialize centroids to be null. 18 | mixture.centers = zeros(num_comp,dim); 19 | mixture.centers(:,dim)=1; 20 | % The covars(:,:,i) corresponds to \Sigma_i for the mixture. 21 | mixture.kappas = 10*ones(1,num_comp); -------------------------------------------------------------------------------- /thirdparty/vmfmatlab/testmle.m: -------------------------------------------------------------------------------- 1 | function testmle(c,k,n) 2 | % TESTMLE 3 | 4 | p = size(c,1); 5 | x=vsamp(c, k, n); 6 | y=sum(x,1); 7 | tmp = norm(y); 8 | rbar = tmp/n; 9 | mysolve(p, rbar) 10 | y = y/tmp; 11 | y 12 | dot(y,c) 13 | -------------------------------------------------------------------------------- /thirdparty/vmfmatlab/unitrand.m: -------------------------------------------------------------------------------- 1 | function sample = unitrand(dim) 2 | % UNITRAND Generate unit random vector in dim dimensions 3 | % 4 | % SAMPLE = UNITRAND(DIM) Generates a unit random vector that 5 | % comes from a uniform distr on the unit 'dim' dimensional sphere. 6 | % The method used is: generate N normally distr numbers, form a 7 | % vector and normalize to be of unit length! 8 | % 9 | % See: HAKMEN Item 27 10 | 11 | sample = randn(dim,1); 12 | n = norm(sample); 13 | sample = sample/n; 14 | -------------------------------------------------------------------------------- /thirdparty/vmfmatlab/vsamp.m: -------------------------------------------------------------------------------- 1 | function samples = vsamp(center, kappa, n) 2 | % VSAMP returns a set of points sampled from a vMF 3 | % 4 | % SAMPLES = VSAMP(CENTER, KAPPA, N) returns a sample of N points 5 | % from a multi-dimensional von Mises Fisher distribution having 6 | % mean direction given by CENTER and concentration parameter given 7 | % by KAPPA. 8 | % 9 | % CENTER is a column vector 10 | % This implementation is based on the algorithm VM* of A.T.A. Wood 11 | % A. T. A. Wood. Simulation of the von-Mises Fisher 12 | % Distribution. Comm Stat. Comput. Simul. (1994) v. 23 157-164 13 | % 14 | % NOTE: Current Limitation disallows center(1,1) = 0 15 | % 16 | % See also BETARND, MLE 17 | 18 | % d > 1 of course 19 | d = size(center,1); % Dimensionality 20 | l = kappa; % shorthand 21 | t1 = sqrt(4*l*l + (d-1)*(d-1)); 22 | b = (-2*l + t1 )/(d-1); 23 | 24 | x0 = (1-b)/(1+b); 25 | 26 | samples = zeros(n,d); 27 | 28 | m = (d-1)/2; 29 | c = l*x0 + (d-1)*log(1-x0*x0); 30 | 31 | for i=1:n 32 | t = -1000; u = 1; 33 | 34 | while (t < log(u)) 35 | z = betarnd(m , m); % z is a beta rand var 36 | u = rand(1); % u is unif rand var 37 | w = (1 - (1+b)*z)/(1 - (1-b)*z); 38 | t = l*w + (d-1)*log(1-x0*w) - c; 39 | end 40 | v = unitrand(d-1); % d-1 dim unit vector from 41 | % unif distr on sphere 42 | v = v ./ norm(v); 43 | samples(i,1:d-1) = sqrt(1-w*w)*v'; 44 | samples(i,d) = w; 45 | end 46 | 47 | % Now we form A so that we can get Q 48 | % Now we want an orthogonal transf Q such that 49 | % Q*center = [0 0 ... 1] 50 | 51 | % A more eff. way is using householder transformations 52 | % Added on: 1/28/03 53 | % A = eye(d); 54 | % A(:,1)=center; 55 | % Q=mgs(A); 56 | % tmp = Q(:,d); 57 | % Q(:,d) = Q(:,1); 58 | % Q(:,1) = tmp; 59 | 60 | [v,b]=house(center); 61 | Q = eye(d)-b*(v*v.'); 62 | 63 | for i=1:n 64 | tmpv = Q*samples(i,:)'; 65 | samples(i,:) = tmpv'; 66 | end --------------------------------------------------------------------------------