# Sebastian Raschka 2014-2020 # mlxtend Machine Learning Library Extensions # # Functions for different linear algebra operations. # Author: Sebastian Raschka # # License: BSD 3 clause import numpy as np def vectorspace_orthonormalization(ary, # method='gram-schmidt', eps=1e-13): """Transforms a set of column vectors to a orthonormal basis. Given a set of orthogonal vectors, this functions converts such column vectors, arranged in a matrix, into orthonormal basis vectors. Parameters ---------- ary : array-like, shape=[num_vectors, num_vectors] An orthogonal set of vectors (arranged as columns in a matrix) eps : float (default: 1e-13) A small tolerance value to determine whether the vector norm is zero or not. Returns ---------- arr : array-like, shape=[num_vectors, num_vectors] An orthonormal set of vectors (arranged as columns) Examples ----------- For usage examples, please see http://rasbt.github.io/mlxtend/user_guide/math/vectorspace_orthonormalization/ """ # Gram-Schmidt Process # 1) col i for i = 0: keep & normalize: # 2) col i for i > 1: # 2a) project column i+1 onto i # 2b) subtract column i from projection vector # 2c) Normalize if linearly independent, # and set to zero otherwise arr = ary.astype(np.float).copy() for i in range(arr.shape[1]): for j in range(i): # 2a) & 2b) arr[:, i] -= np.dot(arr[:, i], arr[:, j]) * arr[:, j] # 2c tmp = np.linalg.norm(arr[:, i]) is_linearly_indepedent = tmp > eps if is_linearly_indepedent: arr[:, i] /= tmp else: arr[:, i] = np.zeros(arr[:, i].shape) # elif method == 'qr-factorization': # Q, R = np.linalg.qr(ary) # arr = Q # QR factorization is not used here because of non-useful # results in cases of linear dependence # else: # raise ValueError("Method must be 'gram-schmidt'" # "or 'qr-factorization'") return arr def vectorspace_dimensionality(ary): """Computes the hyper-volume spanned by a vector set Parameters ---------- ary : array-like, shape=[num_vectors, num_vectors] An orthogonal set of vectors (arranged as columns in a matrix) Returns ---------- dimensions : int An integer indicating the "dimensionality" hyper-volume spanned by the vector set Examples ----------- For usage examples, please see http://rasbt.github.io/mlxtend/user_guide/math/vectorspace_dimensionality/ """ # Note that since the vectors of # an orthonormal vectoset have unit length or are zero, # the sum of the individual # norms equals the dimensionality of that vector space return int(np.sum(np.linalg.norm( vectorspace_orthonormalization(ary), axis=0)))