Ejemplo n.º 1
0
  void Model::
  computeInverseMassInertia()
  {
    if (ainv_upper_triangular_.empty()) {
      ainv_upper_triangular_.resize(ndof_ * (ndof_ + 1) / 2);
    }
    
    deFloat const one(1);
    for (size_t irow(0); irow < ndof_; ++irow) {
      taoJoint * joint(kgm_tree_->info[irow].joint);
      
      // Compute one column of Ainv by solving forward dynamics of the
      // corresponding joint having a unit torque, while all the
      // others remain unactuated. This works on the kgm_tree because
      // it has zero speeds, thus the Coriolis-centrifgual effects are
      // zero, and by using zero gravity we get pure system dynamics:
      // acceleration = mass_inv * force (in matrix form).
      joint->setTau(&one);
      taoDynamics::fwdDynamics(kgm_tree_->root, &zero_gravity);
      joint->zeroTau();
      
      // Retrieve the column of Ainv by reading the joint
      // accelerations generated by the column-selecting unit torque
      // (into a flattened upper triangular matrix).
      for (size_t icol(0); icol <= irow; ++icol) {
	kgm_tree_->info[icol].joint->getDDQ(&ainv_upper_triangular_[squareToTriangularIndex(irow, icol, ndof_)]);
      }
    }
    
    // Reset all the accelerations.
    for (size_t ii(0); ii < ndof_; ++ii) {
      kgm_tree_->info[ii].joint->zeroDDQ();
    }
  }
Ejemplo n.º 2
0
autoConfusion Confusion_groupStimuli (Confusion me, const char32 *labels, const char32 *newLabel, long newpos) {
	try {
		long ncondense = Melder_countTokens (labels);
		autoNUMvector<long> irow (1, my numberOfRows);

		for (long i = 1; i <= my numberOfRows; i++) {
			irow[i] = i;
		}

		for (char32 *token = Melder_firstToken (labels); token != nullptr; token = Melder_nextToken ()) {
			for (long i = 1; i <= my numberOfRows; i++) {
				if (Melder_equ (token, my rowLabels[i])) {
					irow[i] = 0;
					break;
				}
			}
		}
		long nfound = 0;
		for (long i = 1; i <= my numberOfRows; i++) {
			if (irow[i] == 0) {
				nfound ++;
			}
		}
		if (nfound == 0) {
			Melder_throw (U"Invalid stimulus labels.");
		}
		if (nfound != ncondense) {
			Melder_warning (U"One or more of the given stimulus labels are suspect.");
		}
		long newnstim = my numberOfRows - nfound + 1;
		if (newpos < 1) {
			newpos = 1;
		}
		if (newpos > newnstim) {
			newpos = newnstim;
		}
		autoConfusion thee = Confusion_create (newnstim, my numberOfColumns);
		NUMstrings_copyElements (my columnLabels, thy columnLabels, 1, my numberOfColumns);

		TableOfReal_setRowLabel (thee.get(), newpos, newLabel);
		long inewrow = 1;
		for (long i = 1; i <= my numberOfRows; i++) {
			long rowpos = newpos;
			if (irow[i] > 0) {
				if (inewrow == newpos) {
					inewrow++;
				}
				rowpos = inewrow;
				inewrow++;
				TableOfReal_setRowLabel (thee.get(), rowpos, my rowLabels[i]);
			}
			for (long j = 1; j <= my numberOfColumns; j++) {
				thy data[rowpos][j] += my data[i][j];
			}
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": stimuli not grouped.");
	}
}
Ejemplo n.º 3
0
  void Model::
  computeMassInertia()
  {
    if (a_upper_triangular_.empty()) {
      a_upper_triangular_.resize(ndof_ * (ndof_ + 1) / 2);
    }
    
    deFloat const one(1);
    for (size_t irow(0); irow < ndof_; ++irow) {
      taoJoint * joint(kgm_joints_[irow]);
      
      // Compute one column of A by solving inverse dynamics of the
      // corresponding joint having a unit acceleration, while all the
      // others remain fixed. This works on the KGM tree because it
      // has zero speeds, thus the Coriolis-centrifgual effects are
      // zero, and by using zero gravity we get pure system dynamics:
      // force = mass * acceleration (in matrix form).
      joint->setDDQ(&one);
      taoDynamics::invDynamics(kgm_root_, &zero_gravity);
      joint->zeroDDQ();
      
      // Retrieve the column of A by reading the joint torques
      // required for the column-selecting unit acceleration (into a
      // flattened upper triangular matrix).
      
      for (size_t icol(0); icol <= irow; ++icol) {
	kgm_joints_[icol]->getTau(&a_upper_triangular_[squareToTriangularIndex(irow, icol, ndof_)]);
      }
    }
    
    // Reset all the torques.
    for (size_t ii(0); ii < ndof_; ++ii) {
      kgm_joints_[ii]->zeroTau();
    }
  }
Ejemplo n.º 4
0
  bool Model::
  computeJacobian(taoDNode const * node,
		  double gx, double gy, double gz,
		  Matrix & jacobian) const
  {
    if ( ! node) {
      return false;
    }
    ancestry_table_t::const_iterator iae(ancestry_table_.find(const_cast<taoDNode*>(node)));
    if (iae == ancestry_table_.end()) {
      return false;
    }
    ancestry_list_t const & alist(iae->second);
    
#ifdef DEBUG
    fprintf(stderr, "computeJacobian()\ng: [% 4.2f % 4.2f % 4.2f]\n", gx, gy, gz);
#endif // DEBUG
    
    // \todo Implement support for more than one joint per node, and
    // 	more than one DOF per joint.
    jacobian = Matrix::Zero(6, ndof_);
    ancestry_list_t::const_iterator ia(alist.begin());
    ancestry_list_t::const_iterator iend(alist.end());
    for (/**/; ia != iend; ++ia) {
      deVector6 Jg_col;
      ia->joint->getJgColumns(&Jg_col);
      int const icol(ia->id);
      
#ifdef DEBUG
      fprintf(stderr, "iJg[%d]: [ % 4.2f % 4.2f % 4.2f % 4.2f % 4.2f % 4.2f]\n",
	      icol,
	      Jg_col.elementAt(0), Jg_col.elementAt(1), Jg_col.elementAt(2),
	      Jg_col.elementAt(3), Jg_col.elementAt(4), Jg_col.elementAt(5));
#endif // DEBUG
      
      for (size_t irow(0); irow < 6; ++irow) {
	jacobian.coeffRef(irow, icol) = Jg_col.elementAt(irow);
      }
      
      // Add the effect of the joint rotation on the translational
      // velocity at the global point (column-wise cross product with
      // [gx;gy;gz]). Note that Jg_col.elementAt(3) is the
      // contribution to omega_x etc, because the upper 3 elements of
      // Jg_col are v_x etc.  (And don't ask me why we have to
      // subtract the cross product, it probably got inverted
      // somewhere)
      jacobian.coeffRef(0, icol) -= -gz * Jg_col.elementAt(4) + gy * Jg_col.elementAt(5);
      jacobian.coeffRef(1, icol) -=  gz * Jg_col.elementAt(3) - gx * Jg_col.elementAt(5);
      jacobian.coeffRef(2, icol) -= -gy * Jg_col.elementAt(3) + gx * Jg_col.elementAt(4);
      
#ifdef DEBUG
      fprintf(stderr, "0Jg[%d]: [ % 4.2f % 4.2f % 4.2f % 4.2f % 4.2f % 4.2f]\n",
	      icol,
	      jacobian.coeff(0, icol), jacobian.coeff(1, icol), jacobian.coeff(2, icol),
	      jacobian.coeff(3, icol), jacobian.coeff(4, icol), jacobian.coeff(5, icol));
#endif // DEBUG
      
    }
    return true;
  }
Ejemplo n.º 5
0
ublas::vector<ublas::matrix<double> > wishart_InvA_rnd(const int df, ublas::matrix<double>& S, const int mc) {
  // Generates wishart matrix allowing for singular wishart
  size_t p = S.size1();
  ublas::vector<double> D(p);
  ublas::matrix<double> P(p, p);
  ublas::matrix<double> F(p, p);
  F = ublas::zero_matrix<double>(p, p);

  // make copy of S
  // ublas::matrix<double> SS(S);

  lapack::gesvd('A', 'A', S, D, P, F);
  // svd0(S, P, D, F);
  // P = trans(P);

  //! correct for singular matrix
  std::vector<size_t> ii;
  for (size_t i=0; i<D.size(); ++i)
    if (D(i) > norm_inf(D)*1e-9)
      ii.push_back(i);
  
  size_t r = ii.size();
  ublas::indirect_array<> idx(r);
  for (size_t i=0; i<r; ++i)
    idx(i) = ii[i];

  ublas::indirect_array<> irow(p);
  for (size_t i=0; i<irow.size(); ++ i) 
    irow(i) = i;
  ublas::matrix<double> Q(p, r);
  // Q = prod(project(P, irow, idx), diagm(ublas::apply_to_all<functor::inv_sqrt<double> >(project(D, idx))));
  // rprod does not seem any faster than diagonalizing D before multiplication
  // Q = rprod(project(P, irow, idx), ublas::apply_to_all<functor::inv_sqrt<double> >(D));
  axpy_prod(project(trans(P), irow, idx), diagm(ublas::apply_to_all<functor::inv_sqrt<double> >(project(D, idx))), Q, true);

  // generate mc samples
  ublas::vector<ublas::matrix<double> > K(mc);
  for (int i=0; i<mc; ++i)
    K(i) = wishart_1(df, Q, p, r);
  return K;
}
Ejemplo n.º 6
0
  bool Model::
  computeJacobian(taoDNode const * node,
		  double gx, double gy, double gz,
		  Matrix & jacobian) const
  {
    if ( ! node) {
      return false;
    }
    
#ifdef DEBUG
    fprintf(stderr, "computeJacobian()\ng: [% 4.2f % 4.2f % 4.2f]\n", gx, gy, gz);
#endif // DEBUG
    
    // \todo Implement support for more than one joint per node, and
    // 	more than one DOF per joint.
    jacobian.resize(6, ndof_);
    for (size_t icol(0); icol < ndof_; ++icol) {
      deVector6 Jg_col;	// in NDOF case, this will become an array of deVector6...
      // in NOJ case, we will have to loop over all joints of a node...
      kgm_joints_[icol]->getJgColumns(&Jg_col);
      
#ifdef DEBUG
      fprintf(stderr, "iJg[%zu]: [ % 4.2f % 4.2f % 4.2f % 4.2f % 4.2f % 4.2f]\n",
	      icol,
	      Jg_col.elementAt(0), Jg_col.elementAt(1), Jg_col.elementAt(2),
	      Jg_col.elementAt(3), Jg_col.elementAt(4), Jg_col.elementAt(5));
#endif // DEBUG
      
      for (size_t irow(0); irow < 6; ++irow) {
	jacobian.coeffRef(irow, icol) = Jg_col.elementAt(irow);
      }
      
      // Add the effect of the joint rotation on the translational
      // velocity at the global point (column-wise cross product with
      // [gx;gy;gz]). Note that Jg_col.elementAt(3) is the
      // contribution to omega_x etc, because the upper 3 elements of
      // Jg_col are v_x etc.  (And don't ask me why we have to
      // subtract the cross product, it probably got inverted
      // somewhere)
      jacobian.coeffRef(0, icol) -= -gz * Jg_col.elementAt(4) + gy * Jg_col.elementAt(5);
      jacobian.coeffRef(1, icol) -=  gz * Jg_col.elementAt(3) - gx * Jg_col.elementAt(5);
      jacobian.coeffRef(2, icol) -= -gy * Jg_col.elementAt(3) + gx * Jg_col.elementAt(4);
      
#ifdef DEBUG
      fprintf(stderr, "0Jg[%zu]: [ % 4.2f % 4.2f % 4.2f % 4.2f % 4.2f % 4.2f]\n",
	      icol,
	      jacobian.coeff(0, icol), jacobian.coeff(1, icol), jacobian.coeff(2, icol),
	      jacobian.coeff(3, icol), jacobian.coeff(4, icol), jacobian.coeff(5, icol));
#endif // DEBUG
      
    }
    return true;
  }
Ejemplo n.º 7
0
  bool Model::
  getInverseMassInertia(Matrix & inverse_mass_inertia) const
  {
    if (ainv_upper_triangular_.empty()) {
      return false;
    }
    
    inverse_mass_inertia.resize(ndof_, ndof_);
    for (size_t irow(0); irow < ndof_; ++irow) {
      for (size_t icol(0); icol <= irow; ++icol) {
	inverse_mass_inertia.coeffRef(irow, icol) = ainv_upper_triangular_[squareToTriangularIndex(irow, icol, ndof_)];
	if (irow != icol) {
	  inverse_mass_inertia.coeffRef(icol, irow) = inverse_mass_inertia.coeff(irow, icol);
	}
      }
    }
    
    return true;
  }
Ejemplo n.º 8
0
T GaussJordan(VVT &a, VVT &b) {
  const int n = a.size();
  const int m = b[0].size();
  VI irow(n), icol(n), ipiv(n);
  T det = 1;

  for (int i = 0; i < n; i++) {
    int pj = -1, pk = -1;
    for (int j = 0; j < n; j++) if (!ipiv[j])
      for (int k = 0; k < n; k++) if (!ipiv[k])
        if (pj == -1 || fabs(a[j][k]) > fabs(a[pj][pk])) { pj = j; pk = k; }
    if (fabs(a[pj][pk]) < EPS) { return 0; }
    ipiv[pk]++;
    swap(a[pj], a[pk]);
    swap(b[pj], b[pk]);
    if (pj != pk) det *= -1;
    irow[i] = pj;
    icol[i] = pk;

    T c = 1.0 / a[pk][pk];
    det *= a[pk][pk];
    a[pk][pk] = 1.0;
    for (int p = 0; p < n; p++) a[pk][p] *= c;
    for (int p = 0; p < m; p++) b[pk][p] *= c;
    for (int p = 0; p < n; p++) if (p != pk) {
      c = a[p][pk];
      a[p][pk] = 0;
      for (int q = 0; q < n; q++) a[p][q] -= a[pk][q] * c;
      for (int q = 0; q < m; q++) b[p][q] -= b[pk][q] * c;      
    }
  }

  for (int p = n-1; p >= 0; p--) if (irow[p] != icol[p]) {
    for (int k = 0; k < n; k++) swap(a[k][irow[p]], a[k][icol[p]]);
  }

  return det;
}
Ejemplo n.º 9
0
long
ARPACKEigenSolver::solveSparse(int nev, bool shift_invert, double sigma, char * which, int ncv, double tol, int maxit,
                               double * resid, bool AutoShift)
{
#ifdef THEA_HAVE_SUPERLU

    MatrixWrapper<double>::SparseColumnMatrix const & scm = matrix.getSparseColumnMatrix();
    if (scm.isEmpty())
    {
        THEA_WARNING << getName() << ": Attempting to compute eigenvalues of an empty matrix -- no eigenpairs computed";
        return 0;
    }

    // Create the matrix
    alwaysAssertM(MatrixUtil::isSquare(scm), std::string(getName()) + ": Operator matrix is not square");
    alwaysAssertM(scm.isValid(), std::string(getName()) + ": Operator matrix has invalid internal state");

    TheaArray<int> irow(scm.getRowIndices().begin(),    scm.getRowIndices().end());
    TheaArray<int> pcol(scm.getColumnIndices().begin(), scm.getColumnIndices().end());
    int nnz = (int)scm.numSetElements();

    // Repeat the isValid() checks to check if something got screwed up during the conversion
    alwaysAssertM(irow.size() == scm.getValues().size(),
                  std::string(getName()) + ": irow and nzval arrays should have same size");
    alwaysAssertM(pcol.size() == (array_size_t)scm.numRows() + 1,
                  getName() + format(": pcol array should have %d + 1 = %d entries, instead has %d entries", scm.numRows(),
                                     scm.numRows() + 1, (int)pcol.size()));
    alwaysAssertM(nnz == pcol[pcol.size() - 1],
                  std::string(getName()) + ": (n + 1)th entry of pcol array should be number of non-zeros");

    ARluNonSymMatrix<double, double> arm(scm.numRows(), nnz, const_cast<double *>(&scm.getValues()[0]), &irow[0], &pcol[0]);

    // Setup the problem
    shared_ptr< ARluNonSymStdEig<double> > eig =
        shift_invert ? shared_ptr< ARluNonSymStdEig<double> >(new ARluNonSymStdEig<double>(nev, arm, sigma, which, ncv, tol,
                maxit, resid, AutoShift))
        : shared_ptr< ARluNonSymStdEig<double> >(new ARluNonSymStdEig<double>(nev, arm, which, ncv, tol, maxit,
                resid, AutoShift));
    eig->Trace();

    // Find eigenpairs
    array_size_t nconv = (array_size_t)eig->FindEigenvectors();

    eigenvalues.resize(nconv);
    eigenvectors.resize(nconv);

    array_size_t n = (array_size_t)scm.numRows();
    for (array_size_t i = 0; i < nconv; ++i)
    {
        eigenvalues[i] = Eigenvalue(eig->EigenvalueReal((int)i), eig->EigenvalueImag((int)i));

        eigenvectors[i].resize(n);
        for (array_size_t j = 0; j < n; ++j)
            eigenvectors[i][j] = std::complex<double>(eig->EigenvectorReal((int)i, (int)j), eig->EigenvectorImag((int)i, (int)j));
    }

    return (long)nconv;

#else

    throw Error(std::string(getName()) + ": Sparse linear solver (SuperLU) not available");

#endif
}
Ejemplo n.º 10
0
Row Project::get(Dir dir)
	{
	static Record emptyrec;

	if (first)
		{
		first = false;
		src_hdr = source->header();
		proj_hdr = src_hdr.project(flds);
		if (strategy == LOOKUP)
			{
			if (idx)
				idx->free();
			idx = new VVtree(td = new TempDest);
			indexed = false;
			}
		}
	if (strategy == COPY)
		{
		return source->get(dir);
		}
	else if (strategy == SEQUENTIAL)
		{
		if (dir == NEXT)
			{
			// output the first of each group
			// i.e. skip over rows the same as previous output
			Row row;
			do
				if (Eof == (row = source->get(NEXT)))
					return Eof;
				while (! rewound && equal(proj_hdr, row, currow));
			rewound = false;
			prevrow = currow;
			currow = row;
			// output the first row of a new group
			return Row(lisp(emptyrec, row_to_key(src_hdr, row, flds)));
			}
		else // dir == PREV
			{
			// output the last of each group
			// i.e. output when *next* record is different
			// (to get the same records as NEXT)
			if (rewound)
				prevrow = source->get(PREV);
			rewound = false;
			Row row;
			do
				{
				if (Eof == (row = prevrow))
					return Eof;
				prevrow = source->get(PREV);
				}
				while (equal(proj_hdr, row, prevrow));
			// output the last row of a group
			currow = row;
			return Row(lisp(emptyrec, row_to_key(src_hdr, row, flds)));
			}
		}
	else
		{
		verify(strategy == LOOKUP);
		if (rewound)
			{
			rewound = false;
			if (dir == PREV && ! indexed)
				{
				// pre-build the index
				Row row;
				while (Eof != (row = source->get(NEXT)))
					{
					Record key = row_to_key(src_hdr, row, flds);
					Vdata data(row.data);
					for (Lisp<Record> rs = row.data; ! nil(rs); ++rs)
						td->addref(rs->ptr());
					// insert will only succeed on first of dups
					idx->insert(VVslot(key, &data));
					}
				source->rewind();
				indexed = true;
				}
			}
		Row row;
		while (Eof != (row = source->get(dir)))
			{
			Record key = row_to_key(src_hdr, row, flds);
			VVtree::iterator iter = idx->find(key);
			if (iter == idx->end())
				{
				for (Lisp<Record> rs = row.data; ! nil(rs); ++rs)
					td->addref(rs->ptr());
				Vdata data(row.data);
				verify(idx->insert(VVslot(key, &data)));
				return Row(lisp(emptyrec, key));
				}
			else
				{
				Vdata* d = iter->data;
				Records rs;
				for (int i = d->n - 1; i >= 0; --i)
					rs.push(Record::from_int(d->r[i], theDB()->mmf));
				Row irow(rs);
				if (row == irow)
					return Row(lisp(emptyrec, key));
				}
			}
		if (dir == NEXT)
			indexed = true;
		return Eof;
		}
	}
Ejemplo n.º 11
0
void Bayes::sample_muOmega() {
  double tau = 10.0;
  int d0 = p + 2;
  // matrix_t S0(p, p);
  ublas::matrix<double> S0(p, p);
  S0 = d0 * ublas::identity_matrix<double>(p, p)/4.0;
  
  std::vector<int> idx;
  ublas::indirect_array<> irow(p);
  // projection - want every row
  for (size_t i=0; i<irow.size(); ++i)
    irow(i) = i;
  
  // size_t rank;
  ublas::matrix<double> S(p, p);
  // matrix_t SS(p, p);
  ublas::matrix<double> SS(p, p);
  ublas::matrix<double> Omega_inv(p, p);

  // identity matrix for inverting cholesky factorization
  ublas::matrix<double> I(p, p);
  I.assign(ublas::identity_matrix<double> (p, p));
  ublas::symmetric_adaptor<ublas::matrix<double>, ublas::upper> SH(I);

  // triangular matrix for cholesky_decompose
  ublas::triangular_matrix<double, ublas::lower, ublas::row_major> L(p, p);

  int df;
  for (int j=0; j<k; ++j) {
    idx = find_all(z, j);
    int n_idx = idx.size();

    ublas::matrix<double> xx(p, n_idx);
    ublas::matrix<double> e(p, n_idx);
    // ublas::matrix<double> m(p, 1);
    ublas::vector<double> m(p);

    ublas::indirect_array<> icol(n_idx);
    for (size_t i=0; i<idx.size(); ++i)
      icol(i) = idx[i];
    if (n_idx > 0) {
      double a = tau/(1.0 + n_idx*tau);
      //! REFACTOR - should be able to do matrix_sum directly on projection rather than make a copy?
      xx.assign(project(x, irow, icol));
      m.assign(ublas::matrix_sum(xx, 1)/n_idx);
      // e.assign(xx - outer_prod(column(m, 0), ublas::scalar_vector<double>(n_idx, 1)));
      e.assign(xx - outer_prod(m, ublas::scalar_vector<double>(n_idx, 1)));
      S.assign(prod(e, trans(e)) + outer_prod(m, m) * n_idx * a/tau);
      // SS = trans(S) + S0;
      SS = S + S0;
      df = d0 + n_idx;

      // Omega(j).assign(wishart_rnd(df, SS));
      Omega(j).assign(wishart_InvA_rnd(df, SS));
      SH.assign(Omega(j));
      cholesky_decompose(SH, L);
      Omega_inv.assign(solve(SH, I, ublas::upper_tag()));
      mu(j).assign(a*n_idx*m + sqrt(a)*prod(Omega_inv, Rmath::rnorm(0, 1, p)));
    } else {
      // Omega(j).assign(wishart_rnd(d0, S0));
      Omega(j).assign(wishart_InvA_rnd(d0, S0));
      SH.assign(Omega(j));
      cholesky_decompose(SH, L);
      Omega_inv.assign(solve(SH, I, ublas::upper_tag()));
      mu(j).assign(sqrt(tau) * prod(Omega_inv, Rmath::rnorm(0, 1, p)));
    }
  }
}