예제 #1
0
파일: Algos.hpp 프로젝트: welcheb/codeare
/**
 * @brief     Diagonal of biggest square matrix from top left
 *
 * Usage:
 * @code
 *   Matrix<cxfl> m   = rand<double> (2,3);
 *   Matrix<cxfl> d   = diag (m);
 * @endcode
 *
 * @param  M  Matrix
 * @return    Highest non-one dimension
 */
template <class T> inline static  Matrix<T> diag (const Matrix<T>& M) {
    assert (is2d(M));
    size_t sz = (std::min)(size(M,0),size(M,1));
    Matrix<T> res (sz,1);
    for (size_t i = 0; i < sz; ++i)
        res(i) = M(i,i);
    return res;
}
예제 #2
0
파일: Creators.hpp 프로젝트: kvahed/codeare
template<class T> inline static Matrix<T>
zpad (const Matrix<T>& a, size_t m, size_t n) {
	assert(is2d(a));
	size_t am = size(a,0), an = size(a,1);
	assert(am<=m);
	assert(an<=n);
	size_t am2 = (m-am)/2, an2 = (n-an)/2;
	Matrix<T> ret(m,n);
	for (size_t i = 0; i < an; ++i)
		std::copy(&a(0,i), &a(0,i)+am, &ret(am2,i+an2));
	return ret;
}
예제 #3
0
/**
 * @brief          Matrix matrix multiplication
 *
 * Usage:
 * @code{.cpp}
 *   Matrix<cxfl> m = rand<cxfl> (20,10);
 *   Matrix<cxfl> x = rand<cxfl> (10, 6);
 *  
 *   m   = gemm (m, b, 'N', 'C');
 * @endcode
 *
 * @see            BLAS routine xGEMM
 *
 * @param  A       Left factor
 * @param  B       Right factor
 * @param  transa  (N: A*... | T: A.'*... | C: A'*...) transpose left factor
 * @param  transb  (N: ...*B | T: ...*B.' | C: ...*B') transpose right factor
 * @return         Product
 */
template<class T> inline Matrix<T> 
gemm (const Matrix<T>& A, const Matrix<T>& B, char transa = 'N', char transb = 'N') {
    
    assert (isvec(A)||is2d(A));
    assert (isvec(B)||is2d(B));
    
	int aw, ah, bw, bh, m, n, k;
	T   alpha = (T)1., beta = (T)0.;
    
	aw = (int)size(A,1); ah = (int)size(A,0), bw = (int)size(B,1), bh = (int)size(B,0);
    
    // Check inner dimensions
	if      ( transa == 'N'                   &&  transb == 'N'                  ) assert (aw == bh);
	else if ( transa == 'N'                   && (transb == 'T' || transb == 'C')) assert (aw == bw);
	else if ((transa == 'T' || transa == 'C') &&  transb == 'N'                  ) assert (ah == bh);
	else if ((transa == 'T' || transa == 'C') && (transb == 'T' || transb == 'C')) assert (ah == bw);
	
	if (transa == 'N') {
		m = ah;
		k = aw;
	} else if (transa == 'T' || transa == 'C') {
		m = aw;
		k = ah;
	}
	
	if (transb == 'N')
		n = bw;
	else if (transb == 'T' || transb == 'C')
		n = bh;

	Matrix<T> C(m,n);
	
	LapackTraits<T>::gemm (transa, transb, m, n, k, alpha, A.Ptr(), ah, B.Ptr(), bh, beta, &C[0], m);
    
	return C;
	
}
예제 #4
0
파일: DFT.hpp 프로젝트: nomissretep/codeare
/**
 * @brief         Hann window
 * 
 * @param   size  Side lengths
 * @param   t     Scaling factor
 * @return        Window
 */
template <class T> inline Matrix< std::complex<T> >
hannwindow (const Matrix<size_t>& size, const T& t) {
	
	size_t dim = size.Dim(0);
	assert (dim > 1 && dim < 4);
	
	Matrix<double> res;
	
	if      (dim == 1) res = Matrix<double> (size[0], 1);
	else if (dim == 2) res = Matrix<double> (size[0], size[1]);
	else               res = Matrix<double> (size[0], size[1], size[2]);
	
	float          h, d;
	float          m[3];
	
	if (isvec(res)) {
		
		m[0] = 0.5 * size[0];
		m[1] = 0.0;
		m[2] = 0.0;
		
	} else if (is2d(res)) {
		
		m[0] = 0.5 * size[0];
		m[1] = 0.5 * size[1];
		m[2] = 0.0;
		
	} else {
		
		m[0] = 0.5 * size[0];
		m[1] = 0.5 * size[1];
		m[2] = 0.5 * size[2];
		
	}
	
	res = squeeze(res);
	
	for (size_t s = 0; s < res.Dim(2); s++)
		for (size_t r = 0; r < res.Dim(1); r++)
			for (size_t c = 0; c < res.Dim(0); c++) {
				d = pow( (float)pow(((float)c-m[0])/m[0],2) + pow(((float)r-m[1])/m[1],2) + pow(((float)s-m[2])/m[2],2) , (float)0.5);
				h = (d < 1) ? (0.5 + 0.5 * cos (PI * d)) : 0.0;
				res(c,r,s) = t * h;
			}
	
	return res;
	
}
예제 #5
0
/**
 * @brief                Moore penrose pseudo-invert
 *
 * Usage:
 * @code{.cpp}
 *   Matrix<cxfl> m = rand<cxfl> (10,6);
 *
 *   m = pinv (m);
 * @endcode
 *
 * @see                  Lapack xGELS
 *
 * @param  m             Matrix
 * @param  trans         Transpose m before pinv?
 * @return               Pseudo-inverse
 */
template<class T> inline Matrix<T>
pinv (const Matrix<T>& m, char trans = 'N') {
    
	Matrix<T> mm (m);
    
    assert (is2d(m));

	container<T> work = container<T>(1);
    
	int  M      =  size(m, 0);
	int  N      =  size(m, 1);
    
	int  nrhs   =  M;
	int  lda    =  M;
	int  ldb    =  MAX(M,N);
	int  lwork  = -1;
	int  info   =  0;

	Matrix<T> b = eye<T>(ldb);
    
	LapackTraits<T>::gels (trans, M, N, nrhs, mm, lda, b, ldb, work, lwork, info);
    
	lwork = (int) TypeTraits<T>::Real(work[0]);
	work.resize(lwork);

	LapackTraits<T>::gels (trans, M, N, nrhs, mm, lda, b, ldb, work, lwork, info);
    
	if (M > N)
		for (int i = 0; i < M; i++)
			memcpy (&b[i*N], &b[i*M], N * sizeof(T));
    
	b = resize (b, N, M);

	if (info > 0)
		printf ("ERROR XGELS: the algorithm for computing the SVD failed to converge;\n %i off-diagonal elements " \
                "of an intermediate bidiagonal form\n did not converge to zero.", info);
	else if (info < 0)
		printf ("ERROR XGELS: the %i-th argument had an illegal value.", -info);
    
	return b;
    
}
예제 #6
0
/**
 * @brief        Cholesky decomposition of positive definite quadratic matrix
 *
 * Usage:
 * @code{.cpp}
 *   Matrix<cxfl> m = rand<cxfl> (20,10);
 *   
 *   m = m.prodt(m); // m*m' Must be positive definite 
 *   m = chol (m);
 * @endcode
 *
 * @see          LAPACK driver xPOTRF
 * 
 * @param  A     Incoming matrix
 * @param  uplo  Use upper/lower triangle for decomposition ('U': default/'L')
 * @return       Cholesky decomposition
 */
template<class T> inline Matrix<T> 
chol (const Matrix<T>& A, char uplo = 'U') {
    
    assert(is2d(A));
	
	Matrix<T> res  = A;
	int       info = 0, n = A.Height();
	
	LapackTraits<T>::potrf (uplo, n, &res[0], n, info);
	
	if (info > 0)
		printf ("\nERROR - XPOTRF: the leading minor of order %i is not\n positive definite, and the factorization " \
                "could not be\n completed!\n\n", info);
	else if (info < 0)
		printf ("\nERROR - XPOTRF: the %i-th argument had an illegal value.\n\n!", -info);
    
    for (size_t i = 0; i < n-1; i++)
        for (size_t j = i+1; j < n; j++)
            res(j,i) = T(0);
	
	return res;
	
}
예제 #7
0
template<class T, class S> inline boost::tuple<Matrix<T>,Matrix<S>,Matrix<T> >
svd2 (const Matrix<T>& IN, char jobz = 'N') {
    
	typedef typename LapackTraits<T>::RType T2;
	boost::tuple<Matrix<T>,Matrix<S>,Matrix<T> > ret;
    
    assert (is2d(IN));
    assert (jobz == 'N' || jobz == 'S' || jobz == 'A');
    
	Matrix<T> A (IN);
	
	int   m, n, lwork, info = 0, lda, mn, ldu = 1, ucol = 1, ldvt = 1, vtcol = 1;

	container<T2> rwork;
	container<T>  work = container<T>(1);
	
	m     =  A.Height(); n = A.Width();
	lwork = -1;
	lda   =  m;
	mn    =  MIN(m,n);
	
	if (jobz != 'N')
		ldu = m;
    
	if      (jobz == 'A') {
		ldvt =  n;
		vtcol = (m>=n) ? mn : n;
		ucol =  m;
	} else if (jobz == 'S') {
		ucol = mn;
		ldvt = mn;
		vtcol = (m>=n) ? mn : n;
	}

	Matrix<S>& s = boost::get<1>(ret) = Matrix<S>(  mn,  IONE);
	Matrix<T>& U = boost::get<0>(ret) = Matrix<T>( ldu,  ucol);
	Matrix<T>& V = boost::get<2>(ret) = Matrix<T>(ldvt, vtcol);
	
	container<int> iwork = container<int>(8 * mn);
	
	size_t nr = (typeid(T) == typeid(cxfl) || typeid(T) == typeid(cxdb)) ?
			((jobz == 'N') ? mn * 7 : mn * (5 * mn + 7)) : 1;
	rwork.resize(nr);

	// Workspace query
	LapackTraits<T>::gesdd (jobz, m, n, &A[0], lda, &s[0], &U[0], ldu, &V[0],
			ldvt, &work[0], lwork, &rwork[0], &iwork[0], info);
	
	lwork = (int) TypeTraits<T>::Real(work[0]);
	work.resize(lwork);
    
	// SVD
	LapackTraits<T>::gesdd (jobz, m, n, &A[0], lda, &s[0], &U[0], ldu, &V[0],
			ldvt, &work[0], lwork, &rwork[0], &iwork[0], info);
    
    
    // Traspose the baby
	V = !V;
	V = conj(V);
	
	if (info > 0)
		printf ("\nERROR - XGESDD: The updating process of SBDSDC did not converge.\n\n");
	else if (info < 0)
		printf ("\nERROR - XGESDD: The %i-th argument had an illegal value.\n\n", -info); 
	
	return ret;
	
}