summaryrefslogtreecommitdiffstats
path: root/src/armadillo/include/armadillo_bits/gmm_full_bones.hpp
blob: a842a62f04c4d6fe60bd702b8963d72638470a05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// SPDX-License-Identifier: Apache-2.0
// 
// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
// Copyright 2008-2016 National ICT Australia (NICTA)
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------


//! \addtogroup gmm_full
//! @{


namespace gmm_priv
{

template<typename eT>
class gmm_full
  {
  public:
  
  arma_aligned const Mat <eT> means;
  arma_aligned const Cube<eT> fcovs;
  arma_aligned const Row <eT> hefts;
  
  //
  //
  
  inline ~gmm_full();
  inline  gmm_full();
  
  inline            gmm_full(const gmm_full& x);
  inline gmm_full& operator=(const gmm_full& x);
  
  inline explicit            gmm_full(const gmm_diag<eT>& x);
  inline          gmm_full& operator=(const gmm_diag<eT>& x);
  
  inline      gmm_full(const uword in_n_dims, const uword in_n_gaus);
  inline void    reset(const uword in_n_dims, const uword in_n_gaus);
  inline void    reset();
  
  template<typename T1, typename T2, typename T3>
  inline void set_params(const Base<eT,T1>& in_means, const BaseCube<eT,T2>& in_fcovs, const Base<eT,T3>& in_hefts);
  
  template<typename T1> inline void set_means(const Base    <eT,T1>& in_means);
  template<typename T1> inline void set_fcovs(const BaseCube<eT,T1>& in_fcovs);
  template<typename T1> inline void set_hefts(const Base    <eT,T1>& in_hefts);
  
  inline uword n_dims() const;
  inline uword n_gaus() const;
  
  inline bool load(const std::string name);
  inline bool save(const std::string name) const;
  
  inline Col<eT> generate()              const;
  inline Mat<eT> generate(const uword N) const;
  
  template<typename T1> inline eT      log_p(const T1& expr, const gmm_empty_arg& junk1 = gmm_empty_arg(), typename enable_if<((is_arma_type<T1>::value) && (resolves_to_colvector<T1>::value == true ))>::result* junk2 = nullptr) const;
  template<typename T1> inline eT      log_p(const T1& expr, const uword gaus_id,                          typename enable_if<((is_arma_type<T1>::value) && (resolves_to_colvector<T1>::value == true ))>::result* junk2 = nullptr) const;
  
  template<typename T1> inline Row<eT> log_p(const T1& expr, const gmm_empty_arg& junk1 = gmm_empty_arg(), typename enable_if<((is_arma_type<T1>::value) && (resolves_to_colvector<T1>::value == false))>::result* junk2 = nullptr) const;
  template<typename T1> inline Row<eT> log_p(const T1& expr, const uword gaus_id,                          typename enable_if<((is_arma_type<T1>::value) && (resolves_to_colvector<T1>::value == false))>::result* junk2 = nullptr) const;
  
  template<typename T1> inline eT  sum_log_p(const Base<eT,T1>& expr)                      const;
  template<typename T1> inline eT  sum_log_p(const Base<eT,T1>& expr, const uword gaus_id) const;
  
  template<typename T1> inline eT  avg_log_p(const Base<eT,T1>& expr)                      const;
  template<typename T1> inline eT  avg_log_p(const Base<eT,T1>& expr, const uword gaus_id) const;
  
  template<typename T1> inline uword   assign(const T1& expr, const gmm_dist_mode& dist, typename enable_if<((is_arma_type<T1>::value) && (resolves_to_colvector<T1>::value == true ))>::result* junk = nullptr) const;
  template<typename T1> inline urowvec assign(const T1& expr, const gmm_dist_mode& dist, typename enable_if<((is_arma_type<T1>::value) && (resolves_to_colvector<T1>::value == false))>::result* junk = nullptr) const;
  
  template<typename T1> inline urowvec  raw_hist(const Base<eT,T1>& expr, const gmm_dist_mode& dist_mode) const;
  template<typename T1> inline Row<eT> norm_hist(const Base<eT,T1>& expr, const gmm_dist_mode& dist_mode) const;
  
  template<typename T1>
  inline
  bool
  learn
    (
    const Base<eT,T1>&    data,
    const uword           n_gaus,
    const gmm_dist_mode&  dist_mode,
    const gmm_seed_mode&  seed_mode,
    const uword           km_iter,
    const uword           em_iter,
    const eT              var_floor,
    const bool            print_mode
    );
  
  
  //
  
  protected:
  
  
  arma_aligned Cube<eT> inv_fcovs;
  arma_aligned Row<eT>  log_det_etc;
  arma_aligned Row<eT>  log_hefts;
  arma_aligned Col<eT>  mah_aux;
  arma_aligned Cube<eT> chol_fcovs;
  
  //
  
  inline void init(const gmm_full&     x);
  inline void init(const gmm_diag<eT>& x);
  
  inline void init(const uword in_n_dim, const uword in_n_gaus);
  
  inline void init_constants(const bool calc_chol = true);
  
  inline umat internal_gen_boundaries(const uword N) const;
  
  inline eT internal_scalar_log_p(const eT* x                     ) const;
  inline eT internal_scalar_log_p(const eT* x, const uword gaus_id) const;
  
  inline Row<eT> internal_vec_log_p(const Mat<eT>& X                     ) const;
  inline Row<eT> internal_vec_log_p(const Mat<eT>& X, const uword gaus_id) const;
  
  inline eT internal_sum_log_p(const Mat<eT>& X                     ) const;
  inline eT internal_sum_log_p(const Mat<eT>& X, const uword gaus_id) const;
  
  inline eT internal_avg_log_p(const Mat<eT>& X                     ) const;
  inline eT internal_avg_log_p(const Mat<eT>& X, const uword gaus_id) const;
  
  inline uword internal_scalar_assign(const Mat<eT>& X, const gmm_dist_mode& dist_mode) const;
  
  inline void internal_vec_assign(urowvec& out, const Mat<eT>& X, const gmm_dist_mode& dist_mode) const;
  
  inline void internal_raw_hist(urowvec& hist, const Mat<eT>& X, const gmm_dist_mode& dist_mode) const;
  
  //
  
  template<uword dist_id> inline void generate_initial_means(const Mat<eT>& X, const gmm_seed_mode& seed);
  
  template<uword dist_id> inline void generate_initial_params(const Mat<eT>& X, const eT var_floor);
  
  template<uword dist_id> inline bool km_iterate(const Mat<eT>& X, const uword max_iter, const bool verbose);
  
  //
  
  inline bool em_iterate(const Mat<eT>& X, const uword max_iter, const eT var_floor, const bool verbose);
  
  inline void em_update_params(const Mat<eT>& X, const umat& boundaries, field< Mat<eT> >& t_acc_means, field< Cube<eT> >& t_acc_fcovs, field< Col<eT> >& t_acc_norm_lhoods, field< Col<eT> >& t_gaus_log_lhoods, Col<eT>& t_progress_log_lhoods, const eT var_floor);
  
  inline void em_generate_acc(const Mat<eT>& X, const uword start_index, const uword end_index, Mat<eT>& acc_means, Cube<eT>& acc_fcovs, Col<eT>& acc_norm_lhoods, Col<eT>& gaus_log_lhoods, eT& progress_log_lhood) const;
  
  inline void em_fix_params(const eT var_floor);
  };

}


typedef gmm_priv::gmm_full<double>  gmm_full;
typedef gmm_priv::gmm_full<float>  fgmm_full;


//! @}