double RegularizedSVDFunction::Evaluate(const arma::mat& parameters) const
{
  // The cost for the optimization is as follows:
  //          f(u, v) = sum((rating(i, j) - u(i).t() * v(j))^2)
  // The sum is over all the ratings in the rating matrix.
  // 'i' points to the user and 'j' points to the item being considered.
  // The regularization term is added to the above cost, where the vectors u(i)
  // and v(j) are regularized for each rating they contribute to.

  double cost = 0.0;

  for (size_t i = 0; i < data.n_cols; i++)
  {
    // Indices for accessing the the correct parameter columns.
    const size_t user = data(0, i);
    const size_t item = data(1, i) + numUsers;

    // Calculate the squared error in the prediction.
    const double rating = data(2, i);
    double ratingError = rating - arma::dot(parameters.col(user),
                                            parameters.col(item));
    double ratingErrorSquared = ratingError * ratingError;

    // Calculate the regularization penalty corresponding to the parameters.
    double userVecNorm = arma::norm(parameters.col(user), 2);
    double itemVecNorm = arma::norm(parameters.col(item), 2);
    double regularizationError = lambda * (userVecNorm * userVecNorm +
                                           itemVecNorm * itemVecNorm);

    cost += (ratingErrorSquared + regularizationError);
  }

  return cost;
}
예제 #2
0
파일: cwt.cpp 프로젝트: GABowers/Vespucci
arma::mat Vespucci::Math::Transform::cwt_spdbc_mat(const arma::mat &X, std::string wavelet, arma::uword qscale,
                            double threshold, std::string threshold_method,
                            arma::uword window_size, arma::field<arma::umat> &peak_positions,
                            arma::mat &baselines)
{
    baselines.set_size(X.n_rows, X.n_cols);
    arma::vec baseline;
    arma::vec spectrum;
    arma::vec current_corrected;
    arma::mat corrected(X.n_rows, X.n_cols);
    arma::umat current_peakpos;
    peak_positions.set_size(X.n_cols);
    arma::uword i;
    try{
        for (i = 0; i < X.n_cols; ++i){
            spectrum = X.col(i);
            current_corrected = Vespucci::Math::Transform::cwt_spdbc(spectrum, wavelet,
                                                   qscale, threshold,
                                                   threshold_method, window_size,
                                                   current_peakpos, baseline);

            peak_positions(i) = current_peakpos;
            baselines.col(i) = baseline;
            corrected.col(i) = current_corrected;
        }
    }catch(std::exception e){
        std::cerr << std::endl << "exception! cwt_spdbc_mat" << std::endl;
        std::cerr << "i = " << i << std::endl;
        std::cerr << e.what();
        throw(e);
    }

    return corrected;
}
void RegularizedSVDFunction<MatType>::Gradient(const arma::mat& parameters,
                                               const size_t start,
                                               GradType& gradient,
                                               const size_t batchSize) const
{
  gradient.zeros(rank, numUsers + numItems);

  // It's possible this could be SIMD-vectorized for additional speedup.
  for (size_t i = start; i < start + batchSize; ++i)
  {
    const size_t user = data(0, i);
    const size_t item = data(1, i) + numUsers;

    // Prediction error for the example.
    const double rating = data(2, i);
    double ratingError = rating - arma::dot(parameters.col(user),
                                            parameters.col(item));

    // Gradient is non-zero only for the parameter columns corresponding to the
    // example.
    gradient.col(user) += 2 * (lambda * parameters.col(user) -
                               ratingError * parameters.col(item));
    gradient.col(item) += 2 * (lambda * parameters.col(item) -
                               ratingError * parameters.col(user));
  }
}
/**
 * Calculates and stores the gradient values given a set of parameters.
 */
void SoftmaxRegressionFunction::Gradient(const arma::mat& parameters,
                                         arma::mat& gradient) const
{
  // Calculate the class probabilities for each training example. The
  // probabilities for each of the classes are given by:
  // p_j = exp(theta_j' * x_i) / sum(exp(theta_k' * x_i))
  // The sum is calculated over all the classes.
  // x_i is the input vector for a particular training example.
  // theta_j is the parameter vector associated with a particular class.
  arma::mat probabilities;
  GetProbabilitiesMatrix(parameters, probabilities);

  // Calculate the parameter gradients.
  gradient.set_size(parameters.n_rows, parameters.n_cols);
  if (fitIntercept)
  {
    // Treating the intercept term parameters.col(0) seperately to avoid
    // the cost of building matrix [1; data].
    arma::mat inner = probabilities - groundTruth;
    gradient.col(0) =
      inner * arma::ones<arma::mat>(data.n_cols, 1) / data.n_cols +
      lambda * parameters.col(0);
    gradient.cols(1, parameters.n_cols - 1) =
      inner * data.t() / data.n_cols +
      lambda * parameters.cols(1, parameters.n_cols - 1);
  }
  else
  {
    gradient = (probabilities - groundTruth) * data.t() / data.n_cols +
               lambda * parameters;
  }
}
예제 #5
0
/**
 * Construct a 2-class dataset out of noisy sines.
 *
 * @param data Input data used to store the noisy sines.
 * @param labels Labels used to store the target class of the noisy sines.
 * @param points Number of points/features in a single sequence.
 * @param sequences Number of sequences for each class.
 * @param noise The noise factor that influences the sines.
 */
void GenerateNoisySines(arma::mat& data,
                        arma::mat& labels,
                        const size_t points,
                        const size_t sequences,
                        const double noise = 0.3)
{
  arma::colvec x =  arma::linspace<arma::Col<double> >(0,
      points - 1, points) / points * 20.0;
  arma::colvec y1 = arma::sin(x + arma::as_scalar(arma::randu(1)) * 3.0);
  arma::colvec y2 = arma::sin(x / 2.0 + arma::as_scalar(arma::randu(1)) * 3.0);

  data = arma::zeros(points, sequences * 2);
  labels = arma::zeros(2, sequences * 2);

  for (size_t seq = 0; seq < sequences; seq++)
  {
    data.col(seq) = arma::randu(points) * noise + y1 +
        arma::as_scalar(arma::randu(1) - 0.5) * noise;
    labels(0, seq) = 1;

    data.col(sequences + seq) = arma::randu(points) * noise + y2 +
        arma::as_scalar(arma::randu(1) - 0.5) * noise;
    labels(1, sequences + seq) = 1;
  }
}
예제 #6
0
파일: fast_score.cpp 프로젝트: cran/JMbayes
// [[Rcpp::export]]
arma::vec gradient_logPosterior_nogammas (double temp, arma::vec event, arma::uvec idGK_fast,
                                 arma::vec event_colSumsW1, arma::mat W1s, arma::vec Bs_gammas,
                                 arma::vec event_colSumsWlong, arma::mat Wlongs, arma::vec alphas,
                                 arma::vec Pw,
                                 arma::vec mean_Bs_gammas, arma::mat Tau_Bs_gammas,
                                 arma::vec mean_alphas, arma::mat Tau_alphas,
                                 double tauBs, double A_tauBs, double B_tauBs) {
    vec Int = Pw % exp(W1s * Bs_gammas + Wlongs * alphas);
    // gradient Bs_gammas
    unsigned int n_Bs_gammas = Bs_gammas.n_rows;
    vec score_Bs_gammas = vec(n_Bs_gammas, fill::zeros);
    for (uword i = 0; i < n_Bs_gammas; ++i) {
        vec H = W1s.col(i) % Int;
        score_Bs_gammas[i] = temp * (event_colSumsW1[i] - sum(H));
    }
    score_Bs_gammas = score_Bs_gammas - tauBs * (Tau_Bs_gammas * (Bs_gammas - mean_Bs_gammas));
    // gradient alphas
    unsigned int n_alphas = alphas.n_rows;
    vec score_alphas = vec(n_alphas, fill::zeros);
    for (uword i = 0; i < n_alphas; ++i) {
        vec H = Wlongs.col(i) % Int;
        score_alphas[i] = temp * (event_colSumsWlong[i] - sum(H));
    }
    score_alphas = score_alphas - (Tau_alphas * (alphas - mean_alphas));
    // gradient tauBs
    vec z = Bs_gammas - mean_Bs_gammas;
    vec score_tauBs = tauBs * (- 0.5 * (z.t() * Tau_Bs_gammas * z) + (A_tauBs - 1) / tauBs - B_tauBs);
    // export results
    vec out = join_cols(score_Bs_gammas, score_alphas);
    out = join_cols(out, score_tauBs);
    return(out);
}
// The step size should be chosen carefully to guarantee convergence given a 
// reasonable number of computations.
int GradientDescent::RunGradientDescent(const Data &data) {
  assert(num_iters_ >= 1);
  const int kNumTrainEx = data.num_train_ex();
  assert(kNumTrainEx >= 1);
  const arma::mat kTrainingFeatures = data.training_features();
  const arma::vec kTrainingLabels = data.training_labels();

  double *j_theta_array = new double[num_iters_];

  // Recall that we are trying to minimize the following cost function:
  // ((training features) * (current weights) - (training labels))^2
  // Each iteration of this algorithm updates the weights as a scaled 
  // version of the gradient of this cost function.
  // This gradient is computed with respect to the weights.
  // Thus, each iteration of gradient descent performs the following:
  // (update) = (step size) * ((training features) * (current weights) - (training labels)) * (training features)
  // (new weights) = (current weights) - (update)
  for(int theta_index=0; theta_index<num_iters_; theta_index++)
  {
    const arma::vec kDiffVec = kTrainingFeatures*theta_-kTrainingLabels;
    const arma::mat kDiffVecTimesTrainFeat = \
      join_rows(kDiffVec % kTrainingFeatures.col(0),\
      kDiffVec % kTrainingFeatures.col(1));
    const arma::vec kThetaNew = theta_-alpha_*(1/(float)kNumTrainEx)*\
      (sum(kDiffVecTimesTrainFeat)).t();
    j_theta_array[theta_index] = ComputeCost(data);
    set_theta(kThetaNew);
  }

  delete [] j_theta_array;

  return 0;
}
예제 #8
0
파일: hmm.hpp 프로젝트: buotex/praktikum
void
HMM::cacheProbabilities(const arma::mat & data) {
  for (unsigned int i = 0; i < N_; ++i) {
    arma::vec weights = BModels_[i].getWeights();
    for (unsigned int l = 0; l < weights.n_elem; ++l) {
      const GM & gm = BModels_[i].getGM(l);
      gammaLts_[i].col(l) = weights(l) * arma::trans(gm.getDataProb(data));
    }
    B_.col(i) = arma::sum(gammaLts_[i],1);
  }
  if (!B_.is_finite()) {
    //B_.print("B");
    for (unsigned int i = 0; i < N_; ++i) {
      arma::vec test = B_.col(i);
      if (!test.is_finite()) {
        arma::vec weights = BModels_[i].getWeights();
        for (unsigned l = 0; l < weights.n_elem; ++l) {
        arma::vec test2 = gammaLts_[i].col(l); 
          if (!test2.is_finite()) {
            const GM & gm = BModels_[i].getGM(l);
            gm.print("gm");
            arma::vec test3 = arma::trans(gm.getDataProb(data));
            //test3.print("test3");
          }
        }
      }
    }
    throw std::runtime_error("probabilities not finite");
  }
}
void LovaszThetaSDP::GradientConstraint(const size_t index,
                                        const arma::mat& coordinates,
                                        arma::mat& gradient)
{
//  Log::Debug << "Gradient of constraint " << index << " is " << std::endl;
  if (index == 0) // This is the constraint Tr(X) = 1.
  {
    gradient = 2 * coordinates; // d/dR (Tr(R R^T)) = 2 R.
//    std::cout << gradient;
    return;
  }

//  Log::Debug << "Evaluating gradient of constraint " << index << " with ";
  size_t i = edges(0, index - 1);
  size_t j = edges(1, index - 1);
//  Log::Debug << "i = " << i << " and j = " << j << "." << std::endl;

  // Since the constraint is (R^T R)_ij, the gradient for (x, y) will be (I
  // derived this for one of the MVU constraints):
  //   0     , y != i, y != j
  //   2 R_xj, y  = i, y != j
  //   2 R_xi, y != i, y  = j
  //   4 R_xy, y  = i, y  = j
  // This results in the gradient matrix having two nonzero rows; for row
  // i, the elements are R_nj, where n is the row; for column j, the elements
  // are R_ni.
  gradient.zeros(coordinates.n_rows, coordinates.n_cols);

  gradient.col(i) = coordinates.col(j);
  gradient.col(j) += coordinates.col(i); // In case j = i (shouldn't happen).

//  std::cout << gradient;
}
예제 #10
0
void FFN<
LayerTypes, OutputLayerType, InitializationRuleType, PerformanceFunction
>::Predict(arma::mat& predictors, arma::mat& responses)
{
  deterministic = true;

  arma::mat responsesTemp;
  ResetParameter(network);
  Forward(arma::mat(predictors.colptr(0), predictors.n_rows, 1, false, true),
      network);
  OutputPrediction(responsesTemp, network);

  responses = arma::mat(responsesTemp.n_elem, predictors.n_cols);
  responses.col(0) = responsesTemp.col(0);

  for (size_t i = 1; i < predictors.n_cols; i++)
  {
    Forward(arma::mat(predictors.colptr(i), predictors.n_rows, 1, false, true),
        network);

    responsesTemp = arma::mat(responses.colptr(i), responses.n_rows, 1, false,
        true);
    OutputPrediction(responsesTemp, network);
    responses.col(i) = responsesTemp.col(0);
  }
}
  /**
   * The update rule for the encoding matrix H.
   * The function takes in all the matrices and only changes the
   * value of the H matrix.
   *
   * @param V Input matrix to be factorized.
   * @param W Basis matrix.
   * @param H Encoding matrix to be updated.
   */
  inline void HUpdate(const MatType& V,
                      const arma::mat& W,
                      arma::mat& H)
  {
    arma::mat deltaH;
    deltaH.zeros(H.n_rows, 1);

    const double val = V(currentItemIndex, currentUserIndex);

    // Update H matrix based on the non-zero entry found in WUpdate function.
    deltaH += (val - arma::dot(W.row(currentItemIndex),
        H.col(currentUserIndex))) * W.row(currentItemIndex).t();
    // Add regularization.
    if (kh != 0)
      deltaH -= kh * H.col(currentUserIndex);

    // Move on to the next entry.
    currentUserIndex = currentUserIndex + 1;
    if (currentUserIndex == V.n_rows)
    {
      currentUserIndex = 0;
      currentItemIndex = (currentItemIndex + 1) % V.n_cols;
    }

    H.col(currentUserIndex++) += u * deltaH;
  }
예제 #12
0
// Fits an alpha and beta parameter according to observation probabilities.
void GammaDistribution::Train(const arma::mat& rdata,
                              const arma::vec& probabilities,
                              const double tol)
{
  // If fittingSet is empty, nothing to do.
  if (arma::size(rdata) == arma::size(arma::mat()))
    return;

  arma::vec meanLogxVec(rdata.n_rows, arma::fill::zeros);
  arma::vec meanxVec(rdata.n_rows, arma::fill::zeros);
  arma::vec logMeanxVec(rdata.n_rows, arma::fill::zeros);

  for (size_t i = 0; i < rdata.n_cols; i++)
  {
    meanLogxVec += probabilities(i) * arma::log(rdata.col(i));
    meanxVec += probabilities(i) * rdata.col(i);
  }

  double totProbability = arma::accu(probabilities);

  meanLogxVec /= totProbability;
  meanxVec /= totProbability;
  logMeanxVec = arma::log(meanxVec);

  // Call the statistics-only GammaDistribution::Train() function to fit the
  // parameters. That function does all the work so we're done.
  Train(logMeanxVec, meanLogxVec, meanxVec, tol);
}
  /**
   * The update rule for the basis matrix W.
   * The function takes in all the matrices and only changes the
   * value of the W matrix.
   *
   * @param V Input matrix to be factorized.
   * @param W Basis matrix to be updated.
   * @param H Encoding matrix.
   */
  inline void WUpdate(const arma::sp_mat& V,
                      arma::mat& W,
                      const arma::mat& H)
  {
    if(!isStart) (*it)++;
    else isStart = false;

    if(*it == V.end())
    {
        delete it;
        it = new arma::sp_mat::const_iterator(V.begin());
    }

    size_t currentUserIndex = it->col();
    size_t currentItemIndex = it->row();

    arma::mat deltaW(1, W.n_cols);
    deltaW.zeros();

    deltaW += (**it - arma::dot(W.row(currentItemIndex), H.col(currentUserIndex)))
                                      * arma::trans(H.col(currentUserIndex));
    if(kw != 0) deltaW -= kw * W.row(currentItemIndex);

    W.row(currentItemIndex) += u*deltaW;
  }
예제 #14
0
/**
 * Estimate the Gaussian distribution from the given observations, taking into
 * account the probability of each observation actually being from this
 * distribution.
 */
void GaussianDistribution::Estimate(const arma::mat& observations,
                                    const arma::vec& probabilities)
{
  if (observations.n_cols > 0)
  {
    mean.zeros(observations.n_rows);
    covariance.zeros(observations.n_rows, observations.n_rows);
  }
  else // This will end up just being empty.
  {
    mean.zeros(0);
    covariance.zeros(0);
    return;
  }

  double sumProb = 0;

  // First calculate the mean, and save the sum of all the probabilities for
  // later normalization.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    mean += probabilities[i] * observations.col(i);
    sumProb += probabilities[i];
  }

  if (sumProb == 0)
  {
    // Nothing in this Gaussian!  At least set the covariance so that it's
    // invertible.
    covariance.diag() += 1e-50;
    return;
  }

  // Normalize.
  mean /= sumProb;

  // Now find the covariance.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    arma::vec obsNoMean = observations.col(i) - mean;
    covariance += probabilities[i] * (obsNoMean * trans(obsNoMean));
  }

  // This is probably biased, but I don't know how to unbias it.
  covariance /= sumProb;

  // Ensure that the covariance is positive definite.
  if (det(covariance) <= 1e-50)
  {
    Log::Debug << "GaussianDistribution::Estimate(): Covariance matrix is not "
        << "positive definite. Adding perturbation." << std::endl;

    double perturbation = 1e-30;
    while (det(covariance) <= 1e-50)
    {
      covariance.diag() += perturbation;
      perturbation *= 10; // Slow, but we don't want to add too much.
    }
  }
}
  /**
   * The update rule for the basis matrix W.  The function takes in all the
   * matrices and only changes the value of the W matrix.
   *
   * @param V Input matrix to be factorized.
   * @param W Basis matrix to be updated.
   * @param H Encoding matrix.
   */
  inline void WUpdate(const MatType& V,
                      arma::mat& W,
                      const arma::mat& H)
  {
    arma::mat deltaW;
    deltaW.zeros(1, W.n_cols);

    // Loop until a non-zero entry is found.
    while(true)
    {
      const double val = V(currentItemIndex, currentUserIndex);
      // Update feature vector if current entry is non-zero and break the loop.
      if (val != 0)
      {
        deltaW += (val - arma::dot(W.row(currentItemIndex),
            H.col(currentUserIndex))) * H.col(currentUserIndex).t();

        // Add regularization.
        if (kw != 0)
          deltaW -= kw * W.row(currentItemIndex);
        break;
      }
    }

    W.row(currentItemIndex) += u * deltaW;
  }
예제 #16
0
파일: interval.cpp 프로젝트: helske/bssm
// [[Rcpp::depends(BH)]]
// [[Rcpp::depends(RcppArmadillo)]]
arma::mat intervals(arma::mat& means, const arma::mat& sds, const arma::vec& probs, unsigned int n_ahead) {
 
  boost::math::tools::eps_tolerance<double> tol;
  
  arma::mat intv(n_ahead, probs.n_elem);
  
  for (unsigned int i = 0; i < n_ahead; i++) {
    double lower = means.col(i).min() - 2 * sds.col(i).max();
    double upper = means.col(i).max() + 2 * sds.col(i).max();
    for (unsigned int j = 0; j < probs.n_elem; j++) {
      boost::uintmax_t max_iter = 1000;
      objective_gaussian f(means.col(i), sds.col(i), probs(j));
      std::pair<double, double> r =
        boost::math::tools::bisect(f, lower, upper, tol, max_iter);
      if (!tol(r.first, r.second) || (max_iter >= 1000)) {
        max_iter = 10000;
        r =  boost::math::tools::bisect(f, 1000 * lower, 1000 * upper, tol, max_iter);
      }
      intv(i, j) = r.first + (r.second - r.first) / 2.0;
      lower = intv(i, j);
    }
    
  }
  return intv;
}
예제 #17
0
파일: cwt.cpp 프로젝트: GABowers/Vespucci
arma::mat Vespucci::Math::Transform::cwtPeakAnalysis(const arma::mat &X,
                              std::string wavelet, arma::uword qscale,
                              double threshold, std::string threshold_method,
                              arma::mat &transform)
{
    transform.set_size(X.n_rows, X.n_cols);
    arma::uvec scales(1);
    scales(0) = qscale;
    arma::uword i;
    arma::umat peak_positions;
    arma::mat peak_extrema(X.n_rows, X.n_cols);
    arma::vec spectrum, current_transform, dtransform, peak_magnitudes;
    try{
        for (i = 0; i < X.n_cols; ++i){
            spectrum = X.col(i);
            current_transform = Vespucci::Math::Transform::cwt(spectrum, wavelet, scales);
            transform.col(i) = current_transform;
            dtransform = Vespucci::Math::diff(transform, 1);
            dtransform.insert_rows(0, 1, true); //dtransform(i) is derivative at transform(i)
            peak_positions = Vespucci::Math::PeakFinding::FindPeakPositions(transform, dtransform,
                                                         threshold, threshold_method,
                                                         peak_magnitudes);
            peak_extrema.col(i) = Vespucci::Math::PeakFinding::PeakExtrema(X.n_elem, peak_positions);
        }
    }
    catch(std::exception e){
        std::cerr << "CWTPeakAnalysis" << std::endl;
        std::cerr << "i = " << i << std::endl;
        throw(e);
    }
    return peak_extrema;
}
size_t MaxVarianceNewCluster::EmptyCluster(const MatType& data,
                                           const size_t emptyCluster,
                                           const arma::mat& oldCentroids,
                                           arma::mat& newCentroids,
                                           arma::Col<size_t>& clusterCounts,
                                           MetricType& metric,
                                           const size_t iteration)
{
  // If necessary, calculate the variances and assignments.
  if (iteration != this->iteration || assignments.n_elem != data.n_cols)
    Precalculate(data, oldCentroids, clusterCounts, metric);
  this->iteration = iteration;

  // Now find the cluster with maximum variance.
  arma::uword maxVarCluster;
  variances.max(maxVarCluster);

  // Now, inside this cluster, find the point which is furthest away.
  size_t furthestPoint = data.n_cols;
  double maxDistance = -DBL_MAX;
  for (size_t i = 0; i < data.n_cols; ++i)
  {
    if (assignments[i] == maxVarCluster)
    {
      const double distance = std::pow(metric.Evaluate(data.col(i),
          newCentroids.col(maxVarCluster)), 2.0);

      if (distance > maxDistance)
      {
        maxDistance = distance;
        furthestPoint = i;
      }
    }
  }

  // Take that point and add it to the empty cluster.
  newCentroids.col(maxVarCluster) *= (double(clusterCounts[maxVarCluster]) /
      double(clusterCounts[maxVarCluster] - 1));
  newCentroids.col(maxVarCluster) -= (1.0 / (clusterCounts[maxVarCluster] - 1.0)) *
      arma::vec(data.col(furthestPoint));
  clusterCounts[maxVarCluster]--;
  clusterCounts[emptyCluster]++;
  newCentroids.col(emptyCluster) = arma::vec(data.col(furthestPoint));
  assignments[furthestPoint] = emptyCluster;

  // Modify the variances, as necessary.
  variances[emptyCluster] = 0;
  // One has already been subtracted from clusterCounts[maxVarCluster].
  variances[maxVarCluster] = (1.0 / (clusterCounts[maxVarCluster])) *
      ((clusterCounts[maxVarCluster] + 1) * variances[maxVarCluster] - maxDistance);

  // Output some debugging information.
  Log::Debug << "Point " << furthestPoint << " assigned to empty cluster " <<
      emptyCluster << ".\n";

  return 1; // We only changed one point.
}
void NeuralNetwork::normalizeFeatures(arma::mat& input) const
{
    //this needs to be tweaked. not okay..
    for (unsigned int feature = 0; feature < input.n_cols; ++feature)
    {
        double mean = arma::mean(input.col(feature));
        double stddev = arma::stddev(input.col(feature));
        input.col(feature) = (input.col(feature) - mean) / stddev;
    }
}
예제 #20
0
/**
 * Estimate the Gaussian distribution from the given observations, taking into
 * account the probability of each observation actually being from this
 * distribution.
 */
void GaussianDistribution::Train(const arma::mat& observations,
                                 const arma::vec& probabilities)
{
  if (observations.n_cols > 0)
  {
    mean.zeros(observations.n_rows);
    covariance.zeros(observations.n_rows, observations.n_rows);
  }
  else // This will end up just being empty.
  {
    // TODO(stephentu): same as above
    mean.zeros(0);
    covariance.zeros(0);
    return;
  }

  double sumProb = 0;

  // First calculate the mean, and save the sum of all the probabilities for
  // later normalization.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    mean += probabilities[i] * observations.col(i);
    sumProb += probabilities[i];
  }

  if (sumProb == 0)
  {
    // Nothing in this Gaussian!  At least set the covariance so that it's
    // invertible.
    covariance.diag() += 1e-50;
    FactorCovariance();
    return;
  }

  // Normalize.
  if (sumProb > 0)
    mean /= sumProb;

  // Now find the covariance.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    arma::vec obsNoMean = observations.col(i) - mean;
    covariance += probabilities[i] * (obsNoMean * trans(obsNoMean));
  }

  // This is probably biased, but I don't know how to unbias it.
  if (sumProb > 0)
    covariance /= sumProb;

  // Ensure that the covariance is positive definite.
  gmm::PositiveDefiniteConstraint::ApplyConstraint(covariance);

  FactorCovariance();
}
예제 #21
0
  /**
   * Initialize the dictionary randomly from a normal distribution, such that
   * each atom has a norm of 1.  This is simple enough to be included with the
   * definition.
   *
   * @param data Dataset to use for initialization.
   * @param atoms Number of atoms (columns) in the dictionary.
   * @param dictionary Dictionary to initialize.
   */
  static void Initialize(const arma::mat& data,
                         const size_t atoms,
                         arma::mat& dictionary)
  {
    // Create random dictionary.
    dictionary.randn(data.n_rows, atoms);

    // Normalize each atom.
    for (size_t j = 0; j < atoms; ++j)
      dictionary.col(j) /= norm(dictionary.col(j), 2);
  }
예제 #22
0
  void UpdateWeights(const VecType& trainingPoint,
                     arma::mat& weights,
                     arma::vec& biases,
                     const size_t incorrectClass,
                     const size_t correctClass,
                     const double instanceWeight = 1.0)
  {
    weights.col(incorrectClass) -= instanceWeight * trainingPoint;
    biases(incorrectClass) -= instanceWeight;

    weights.col(correctClass) += instanceWeight * trainingPoint;
    biases(correctClass) += instanceWeight;
  }
예제 #23
0
 static inline force_inline size_t EmptyCluster(
     const MatType& /* data */,
     const size_t emptyCluster,
     const arma::mat& oldCentroids,
     arma::mat& newCentroids,
     arma::Col<size_t>& /* clusterCounts */,
     MetricType& /* metric */,
     const size_t /* iteration */)
 {
   // Take the last iteration's centroid.
   newCentroids.col(emptyCluster) = oldCentroids.col(emptyCluster);
   return 0; // No points were changed.
 }
예제 #24
0
  /**
   * This function is called to update the weightVectors matrix.
   *  It decreases the weights of the incorrectly classified class while
   * increasing the weight of the correct class it should have been classified to.
   *
   * @param trainData The training dataset.
   * @param weightVectors Matrix of weight vectors.
   * @param rowIndex Index of the row which has been incorrectly predicted.
   * @param labelIndex Index of the vector in trainData.
   * @param vectorIndex Index of the class which should have been predicted.
   * @param D Cost of mispredicting the labelIndex instance.
   */
  void UpdateWeights(const arma::mat& trainData,
                     arma::mat& weightVectors,
                     const size_t labelIndex,
                     const size_t vectorIndex,
                     const size_t rowIndex,
                     const arma::rowvec& D)
  {
    weightVectors.row(rowIndex) = weightVectors.row(rowIndex) - 
                                  D(labelIndex) * trainData.col(labelIndex).t();

    weightVectors.row(vectorIndex) = weightVectors.row(vectorIndex) +
                                     D(labelIndex) * trainData.col(labelIndex).t();
  }
예제 #25
0
void grow(statelist &state, parmlist &parms, arma::mat &R, uword j, uword s, int i) {

   state.S(j) += 1;
   state.B(j) = beta_f(parms.beta(state.S(j)), i, parms.max_inf(state.S(j)));
   state.F += kernel2(distance(state, j), parms.m(state.S(j))) * i * (parms.lamda(state.S(j)) - parms.lamda(s));
   state.E = fmax(0, 1 - sum(parms.omega(state.S)) / parms.K);
   R.col(0) = state.E * parms.f(state.S);
   R(j, 1) = parms.d(state.S(j)) + i * parms.alpha(state.S(j)) * (1 - parms.r(state.S(j)));
   R(j, 2) = parms.g(state.S(j));
   R.col(3) = (state.F + lamda_interp(state, parms)) % state.B;
   R(j, 4) = i * parms.mu(state.S(j));
   R(j, 5) = i * parms.alpha(state.S(j)) * parms.r(state.S(j));
}
arma::mat ss::dsim(double Ts, arma::mat const &u){
	setsizes();
	mat ysim(ny, u.n_cols);
	mat xsim;
	xsim = zeros(nx, 1);
	ysim.col(0) = C * xsim;
	for (uword i = 1; i < u.n_cols; i++){ /*simple euler*/
		//xsim = xsim + Ts*(A*xsim + B*u.col(i));
		xsim = (A*xsim + B*u.col(i));
		ysim.col(i) = C * xsim + D * u.col(i);
	}
	return ysim;
}
//[[Rcpp::export]]
List GibbsRegress (arma::mat y, arma::mat x, int N=1000, int burnin=500){
  int n = y.n_cols;
  arma::mat beta(3,1); beta.fill(0);
  double sigma2 =1;
  arma::mat sbeta(N-burnin,3); //
  arma::colvec ssigma2(N-burnin); //
  /* valores para os hiperparâmetros da a priori */
  double a=2.1, b=1.1, m_0=0, m_1=0, m_2=0, v_0=10, v_1=10, v_2=10;
  
  for(int t=0; t<N; t++){
    arma::mat mi = x*beta ;
    double soma = arma::as_scalar( sum( pow( y-mi, 2) ) );
    double A = a + 0.5*n;
    double B = b + 0.5*soma;
    sigma2 = 1/R::rgamma(A,1/B); // gerando sigma2
    //printf("sigma2:%f \n",sigma2);
    double rest0 = 0, soma1=0;
    
    for(int i=0; i<n; i++){
      rest0 = arma::as_scalar( x.row(i)*beta - beta(0,0)*x(i,0) );
      soma1 += ( y(i,0)-rest0);
    } 
    double V0= 1/( (n/sigma2)+(1/v_0) );
    double M0= V0*( (soma1/sigma2) + (m_0/v_0));
    beta(0,0)=R::rnorm(M0,sqrt(V0)); // gerando b0
    double rest1=0, soma2=0;
    for(int i=0; i<n; i++){
      rest1 = arma::as_scalar( x.row(i)*beta - beta(1,0)*x(i,1) );
      soma2 += x(i,1)*( y(i,0)-rest1);
      } 
    double V1=1/( arma::as_scalar( (sum( pow(x.col(1),2) ))/sigma2 ) + (1/v_1));
    double M1=V1*( (soma2/sigma2) + (m_1/v_1) );
    beta(1,0)=R::rnorm(M1,sqrt(V1));
    
    double rest2=0, soma3=0;
    for(int i=0; i<n; i++){
      rest2 = arma::as_scalar( x.row(i)*beta - beta(2,0)*x(i,2) );
      soma3 += x(i,2)*( y(i,0)-rest2);
      } 
    double V2=1/( arma::as_scalar( (sum( pow(x.col(2),2 ) ))/sigma2) +(1/v_2) );
    double M2=V2*((soma3/sigma2) + (m_2/v_2) );
    beta(2,0)=R::rnorm(M2,sqrt(V2));
    if(t>burnin){
      sbeta.row(t-burnin)=beta.t();
      ssigma2(t-burnin)=sigma2; }
  }
  List saida;
  saida["betas"]=sbeta;
  saida["sigma2"]=ssigma2;
  return saida;
}
예제 #28
0
/***
 * Calculate the gradient.
 */
void RosenbrockWoodFunction::Gradient(const arma::mat& coordinates,
                                      arma::mat& gradient)
{
  gradient.set_size(4, 2);

  arma::vec grf(4);
  arma::vec gwf(4);

  rf.Gradient(coordinates.col(0), grf);
  wf.Gradient(coordinates.col(1), gwf);

  gradient.col(0) = grf;
  gradient.col(1) = gwf;
}
예제 #29
0
/**
 * Estimate the Gaussian distribution directly from the given observations.
 *
 * @param observations List of observations.
 */
void GaussianDistribution::Train(const arma::mat& observations)
{
  if (observations.n_cols > 0)
  {
    mean.zeros(observations.n_rows);
    covariance.zeros(observations.n_rows, observations.n_rows);
  }
  else // This will end up just being empty.
  {
    // TODO(stephentu): why do we allow this case? why not throw an error?
    mean.zeros(0);
    covariance.zeros(0);
    return;
  }

  // Calculate the mean.
  for (size_t i = 0; i < observations.n_cols; i++)
    mean += observations.col(i);

  // Normalize the mean.
  mean /= observations.n_cols;

  // Now calculate the covariance.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    arma::vec obsNoMean = observations.col(i) - mean;
    covariance += obsNoMean * trans(obsNoMean);
  }

  // Finish estimating the covariance by normalizing, with the (1 / (n - 1)) so
  // that it is the unbiased estimator.
  covariance /= (observations.n_cols - 1);

  // Ensure that the covariance is positive definite.
  if (det(covariance) <= 1e-50)
  {
    Log::Debug << "GaussianDistribution::Train(): Covariance matrix is not "
        << "positive definite. Adding perturbation." << std::endl;

    double perturbation = 1e-30;
    while (det(covariance) <= 1e-50)
    {
      covariance.diag() += perturbation;
      perturbation *= 10; // Slow, but we don't want to add too much.
    }
  }

  FactorCovariance();
}
예제 #30
0
  /**
   * This function is called to update the weightVectors matrix.  It decreases
   * the weights of the incorrectly classified class while increasing the weight
   * of the correct class it should have been classified to.
   *
   * @param trainData The training dataset.
   * @param weightVectors Matrix of weight vectors.
   * @param rowIndex Index of the row which has been incorrectly predicted.
   * @param labelIndex Index of the vector in trainData.
   * @param vectorIndex Index of the class which should have been predicted.
   * @param D Cost of mispredicting the labelIndex instance.
   */
  void UpdateWeights(const arma::mat& trainData,
                     arma::mat& weightVectors,
                     const size_t labelIndex,
                     const size_t vectorIndex,
                     const size_t rowIndex,
                     const arma::rowvec& D)
  {
    weightVectors.row(rowIndex).subvec(1, weightVectors.n_cols - 1) -=
        D(labelIndex) * trainData.col(labelIndex).t();
    weightVectors(rowIndex, 0) -= D(labelIndex);

    weightVectors.row(vectorIndex).subvec(1, weightVectors.n_cols - 1) +=
        D(labelIndex) * trainData.col(labelIndex).t();
    weightVectors(vectorIndex, 0) += D(labelIndex);
  }