src/linear_model.cpp #
defines an example linear model class type More…
Namespaces #
| Name |
|---|
| example An example namespace. |
Detailed Description #
This file defines an example linear model class type.
Source code #
//===-- linear_model.cpp - Linear Model Class -----------------------------===//
//
// Copyright 2021 Michael Bolus
//
// 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.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
#include <egcpp>
namespace example {
LinearModel::LinearModel(const arma::mat& x,
const arma::mat& z)
: n_x(x.n_rows),
n_y(z.n_rows),
C_(arma::mat(n_y, n_x, arma::fill::zeros)),
d_(arma::vec(n_y, arma::fill::zeros)),
R_(arma::mat(n_y, n_y, arma::fill::zeros)) {
size_t n_t(x.n_cols); // number of time samples
// solve for C+d:
arma::mat sum_zx(n_y, n_x + 1, arma::fill::zeros);
arma::vec x1(n_x + 1, arma::fill::zeros);
x1[n_x] = 1.0;
// covariance of input data
arma::mat sum_x1_x1(n_x + 1, n_x + 1, arma::fill::zeros);
for (size_t t = 1; t < n_t; t++) {
x1.subvec(0, n_x - 1) = x.col(t);
sum_zx += z.col(t) * x1.t();
sum_x1_x1 += x1 * x1.t();
// if input x were *not* deterministic and had own covar, P
// sum_E_x1_x1.submat(0, 0, n_x - 1, n_x - 1) += P.slice(t);
}
arma::mat Cd = sum_zx * arma::inv_sympd(sum_x1_x1);
C_ = Cd.submat(0, 0, n_y - 1, n_x - 1);
d_ = vectorise(Cd.submat(0, n_x, n_y - 1, n_x));
// Ghahgramani, Hinton 1996:
arma::mat sum_zz(n_y, n_y, arma::fill::zeros);
arma::mat sum_yz(n_y, n_y, arma::fill::zeros);
for (size_t t = 1; t < n_t; t++) {
sum_zz += z.col(t) * z.col(t).t();
sum_yz += (C_ * x.col(t) + d_) * z.col(t).t();
}
R_ = (sum_zz - sum_yz) / n_t;
}
LinearModel::LinearModel(const arma::mat& C,
const arma::vec& d,
const arma::mat& R)
: n_x(C.n_cols),
n_y(C.n_rows),
C_(arma::mat(n_y, n_x, arma::fill::zeros)),
d_(arma::vec(n_y, arma::fill::zeros)),
R_(arma::mat(n_y, n_y, arma::fill::zeros)) {
C_ = C;
d_ = d;
R_ = R;
}
auto LinearModel::simulate(const arma::mat& x, bool add_noise)
-> arma::mat {
size_t n_t(x.n_cols); // number of time samples
arma::mat y_hat(n_y, n_t);
y_hat = C_ * x;
y_hat.each_col() += d_;
if (add_noise) {
y_hat += arma::mvnrnd(arma::vec(n_y).fill(0), R_, n_t);
}
return y_hat;
}
} // namespace example
Updated on 4 March 2021 at 09:51:17 CST