Coverage for /opt/conda/envs/apienv/lib/python3.10/site-packages/daiquiri/core/transform/metrics.py: 78%

49 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-14 02:13 +0000

1# -*- coding: utf-8 -*- 

2""" 

3Vector space metrics 

4""" 

5 

6import numpy 

7 

8 

9class MetricTensor: 

10 """Defines a metric in R^n""" 

11 

12 def __init__(self, M): 

13 if M.shape != M.shape[[0, 0]]: 

14 raise ValueError("Needs to be (n x n)") 

15 self.M = M 

16 

17 @property 

18 def ndim(self): 

19 """Dimension of R^n""" 

20 return self.M.shape[0] 

21 

22 def inner_product(self, v, w): 

23 """ 

24 :param num or array-like: row vectors (nv, n) 

25 :param num or array-like: row vectors (nw, n) 

26 :returns array: (nv, nw) 

27 """ 

28 v = numpy.atleast_2d(v) 

29 w = numpy.atleast_2d(w) 

30 return v.dot(self.M).dot(w.T) 

31 

32 def __call__(self, v, w): 

33 return self.inner_product(v, w) 

34 

35 

36class EuclideanMetricTensor(MetricTensor): 

37 """Metric tensor in Euclidean space. Standard representation has the 

38 identity as the matrix tensor. 

39 """ 

40 

41 def __init__(self, *basis_vectors): 

42 """ 

43 :params basis_vectors: vectors with respect to the standard representation 

44 """ 

45 self.C = basis_vectors 

46 

47 @property 

48 def C(self): 

49 """Columns are the basis vector in the standard representation""" 

50 return self._C 

51 

52 @property 

53 def Ci(self): 

54 """Columns are the standard vector in this representation""" 

55 return self._Ci 

56 

57 @property 

58 def M(self): 

59 """Metric tensor""" 

60 return self._M 

61 

62 @C.setter 

63 def C(self, basis_vectors): 

64 C = numpy.stack(basis_vectors, axis=1) 

65 if C.shape != (C.shape[0], C.shape[0]): 

66 raise ValueError("Needs as many vectors as dimensions") 

67 self._C = C 

68 self._Ci = numpy.linalg.inv(C) 

69 self._M = C.T.dot(C) 

70 

71 @Ci.setter 

72 def Ci(self, standard_vectors): 

73 Ci = numpy.stack(standard_vectors, axis=1) 

74 if Ci.shape != Ci.shape[[0, 0]]: 

75 raise ValueError("Needs as many vectors as dimensions") 

76 self._Ci = Ci 

77 self._C = C = numpy.linalg.inv(Ci) 

78 self._M = C.T.dot(C) 

79 

80 def to_standard(self, vb): 

81 """Convert from this to standard representation 

82 

83 :param array vb: vectors in this representation (nv, n) 

84 :param array: vectors in the standard representation (nv, n) 

85 """ 

86 vb = numpy.atleast_2d(vb) 

87 return self.C.dot(vb.T).T 

88 

89 def from_standard(self, ve): 

90 """Convert from standard to this representation 

91 

92 :param array ve: vectors in the standard representation (nv, n) 

93 :param array: vectors in this representation (nv, n) 

94 """ 

95 ve = numpy.atleast_2d(ve) 

96 return self.Ci.dot(ve.T).T