34 from PyClical cimport *
39 cdef inline IndexSet toIndexSet(obj):
41 Return the C++ IndexSet instance wrapped by index_set(obj). 47 Python class index_set wraps C++ class IndexSet. 49 cdef IndexSet *instance
51 cdef inline wrap(index_set self, IndexSet other):
53 Wrap an instance of the C++ class IndexSet. 58 cdef inline IndexSet unwrap(index_set self):
60 Return the wrapped C++ IndexSet instance. 64 cpdef copy(index_set self):
66 Copy this index_set object. 68 >>> s=index_set(1); t=s.copy(); print t 75 Construct an object of type index_set. 77 >>> print index_set(1) 79 >>> print index_set({1,2}) 81 >>> print index_set(index_set({1,2})) 83 >>> print index_set({1,2}) 85 >>> print index_set({1,2,1}) 87 >>> print index_set("{1,2,1}") 89 >>> print index_set("") 92 error_msg_prefix =
"Cannot initialize index_set object from" 93 if isinstance(other, index_set):
94 self.
instance = new IndexSet((<index_set>other).unwrap())
95 elif isinstance(other, numbers.Integral):
96 self.
instance = new IndexSet(<int>other)
97 elif isinstance(other, (set, frozenset)):
103 raise IndexError(error_msg_prefix +
" invalid " + repr(other) +
".")
104 except (RuntimeError, TypeError):
105 raise ValueError(error_msg_prefix +
" invalid " + repr(other) +
".")
106 elif isinstance(other, str):
108 self.
instance = new IndexSet(<char *>other)
110 raise ValueError(error_msg_prefix +
" invalid string " + repr(other) +
".")
112 raise TypeError(error_msg_prefix +
" " + str(type(other)) +
".")
116 Clean up by deallocating the instance of C++ class IndexSet. 122 Compare two objects of class index_set. 124 >>> index_set(1) == index_set({1}) 126 >>> index_set({1}) != index_set({1}) 128 >>> index_set({1}) != index_set({2}) 130 >>> index_set({1}) == index_set({2}) 132 >>> index_set({1}) < index_set({2}) 134 >>> index_set({1}) <= index_set({2}) 136 >>> index_set({1}) > index_set({2}) 138 >>> index_set({1}) >= index_set({2}) 141 if (lhs
is None)
or (rhs
is None):
142 eq = bool(lhs
is rhs)
157 return NotImplemented
159 eq = bool( toIndexSet(lhs) == toIndexSet(rhs) )
165 lt = bool( toIndexSet(lhs) < toIndexSet(rhs) )
171 return not (lt
or eq)
175 return NotImplemented
179 Set the value of an index_set object at index idx to value val. 181 >>> s=index_set({1}); s[2] = True; print s 183 >>> s=index_set({1,2}); s[1] = False; print s 191 Get the value of an index_set object at an index. 193 >>> index_set({1})[1] 195 >>> index_set({1})[2] 197 >>> index_set({2})[-1] 199 >>> index_set({2})[1] 201 >>> index_set({2})[2] 203 >>> index_set({2})[33] 210 Check that an index_set object contains the index idx: idx in self. 212 >>> 1 in index_set({1}) 214 >>> 2 in index_set({1}) 216 >>> -1 in index_set({2}) 218 >>> 1 in index_set({2}) 220 >>> 2 in index_set({2}) 222 >>> 33 in index_set({2}) 229 Iterate over the indices of an index_set. 231 >>> for i in index_set({-3,4,7}): print i, 234 for idx
in range(self.
min(), self.
max()+1):
242 >>> print ~index_set({-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}) 243 {-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32} 249 Symmetric set difference: exclusive or. 251 >>> print index_set({1}) ^ index_set({2}) 253 >>> print index_set({1,2}) ^ index_set({2}) 256 return index_set().wrap( toIndexSet(lhs) ^ toIndexSet(rhs) )
260 Symmetric set difference: exclusive or. 262 >>> x = index_set({1}); x ^= index_set({2}); print x 264 >>> x = index_set({1,2}); x ^= index_set({2}); print x 267 return self.wrap( self.unwrap() ^ toIndexSet(rhs) )
271 Set intersection: and. 273 >>> print index_set({1}) & index_set({2}) 275 >>> print index_set({1,2}) & index_set({2}) 278 return index_set().wrap( toIndexSet(lhs) & toIndexSet(rhs) )
282 Set intersection: and. 284 >>> x = index_set({1}); x &= index_set({2}); print x 286 >>> x = index_set({1,2}); x &= index_set({2}); print x 289 return self.wrap( self.unwrap() & toIndexSet(rhs) )
295 >>> print index_set({1}) | index_set({2}) 297 >>> print index_set({1,2}) | index_set({2}) 300 return index_set().wrap( toIndexSet(lhs) | toIndexSet(rhs) )
306 >>> x = index_set({1}); x |= index_set({2}); print x 308 >>> x = index_set({1,2}); x |= index_set({2}); print x 311 return self.wrap( self.unwrap() | toIndexSet(rhs) )
315 Cardinality: Number of indices included in set. 317 >>> index_set({-1,1,2}).count() 324 Number of negative indices included in set. 326 >>> index_set({-1,1,2}).count_neg() 333 Number of positive indices included in set. 335 >>> index_set({-1,1,2}).count_pos() 344 >>> index_set({-1,1,2}).min() 353 >>> index_set({-1,1,2}).max() 366 Sign of geometric product of two Clifford basis elements. 368 >>> s = index_set({1,2}); t=index_set({-1}); s.sign_of_mult(t) 375 Sign of geometric square of a Clifford basis element. 377 >>> s = index_set({1,2}); s.sign_of_square() 384 The “official” string representation of self. 386 >>> index_set({1,2}).__repr__() 388 >>> repr(index_set({1,2})) 395 The “informal” string representation of self. 397 >>> index_set({1,2}).__str__() 399 >>> str(index_set({1,2})) 406 Tests for functions that Doctest cannot see. 408 For index_set.__cinit__: Construct index_set. 410 >>> print index_set(1) 412 >>> print index_set({1,2}) 414 >>> print index_set(index_set({1,2})) 416 >>> print index_set({1,2}) 418 >>> print index_set({1,2,1}) 420 >>> print index_set({1,2,1}) 422 >>> print index_set("") 424 >>> print index_set("{") 425 Traceback (most recent call last): 427 ValueError: Cannot initialize index_set object from invalid string '{'. 428 >>> print index_set("{1") 429 Traceback (most recent call last): 431 ValueError: Cannot initialize index_set object from invalid string '{1'. 432 >>> print index_set("{1,2,100}") 433 Traceback (most recent call last): 435 ValueError: Cannot initialize index_set object from invalid string '{1,2,100}'. 436 >>> print index_set({1,2,100}) 437 Traceback (most recent call last): 439 IndexError: Cannot initialize index_set object from invalid set([1, 2, 100]). 440 >>> print index_set([1,2]) 441 Traceback (most recent call last): 443 TypeError: Cannot initialize index_set object from <type 'list'>. 445 For index_set.__richcmp__: Compare two objects of class index_set. 447 >>> index_set(1) == index_set({1}) 449 >>> index_set({1}) != index_set({1}) 451 >>> index_set({1}) != index_set({2}) 453 >>> index_set({1}) == index_set({2}) 455 >>> index_set({1}) < index_set({2}) 457 >>> index_set({1}) <= index_set({2}) 459 >>> index_set({1}) > index_set({2}) 461 >>> index_set({1}) >= index_set({2}) 463 >>> None == index_set({1,2}) 465 >>> None != index_set({1,2}) 467 >>> None < index_set({1,2}) 469 >>> None <= index_set({1,2}) 471 >>> None > index_set({1,2}) 473 >>> None >= index_set({1,2}) 475 >>> index_set({1,2}) == None 477 >>> index_set({1,2}) != None 479 >>> index_set({1,2}) < None 481 >>> index_set({1,2}) <= None 483 >>> index_set({1,2}) > None 485 >>> index_set({1,2}) >= None 492 "lexicographic compare" eg. {3,4,5} is less than {3,7,8}; 493 -1 if a<b, +1 if a>b, 0 if a==b. 495 >>> compare(index_set({1,2}),index_set({-1,3})) 497 >>> compare(index_set({-1,4}),index_set({-1,3})) 504 Minimum negative index, or 0 if none. 506 >>> min_neg(index_set({1,2})) 513 Maximum positive index, or 0 if none. 515 >>> max_pos(index_set({1,2})) 520 cdef inline vector[scalar_t] list_to_vector(lst):
522 Create a C++ std:vector[scalar_t] from an iterable Python object. 524 cdef vector[scalar_t] v
526 v.push_back(<scalar_t>s)
532 cdef inline Clifford toClifford(obj):
537 Python class clifford wraps C++ class Clifford. 539 cdef Clifford *instance
541 cdef inline wrap(clifford self, Clifford other):
543 Wrap an instance of the C++ class Clifford. 548 cdef inline Clifford unwrap(clifford self):
550 Return the wrapped C++ Clifford instance. 554 cpdef copy(clifford self):
556 Copy this clifford object. 558 >>> x=clifford("1{2}"); y=x.copy(); print y 565 Construct an object of type clifford. 567 >>> print clifford(2) 569 >>> print clifford(2L) 571 >>> print clifford(2.0) 573 >>> print clifford(1.0e-1) 575 >>> print clifford("2") 577 >>> print clifford("2{1,2,3}") 579 >>> print clifford(clifford("2{1,2,3}")) 581 >>> print clifford("-{1}") 583 >>> print clifford(2,index_set({1,2})) 585 >>> print clifford([2,3],index_set({1,2})) 588 error_msg_prefix =
"Cannot initialize clifford object from" 591 if isinstance(other, clifford):
592 self.
instance = new Clifford((<clifford>other).unwrap())
593 elif isinstance(other, index_set):
594 self.
instance = new Clifford((<index_set>other).unwrap(), <scalar_t>1.0)
595 elif isinstance(other, numbers.Real):
596 self.
instance = new Clifford(<scalar_t>other)
597 elif isinstance(other, str):
599 self.
instance = new Clifford(<char *>other)
601 raise ValueError(error_msg_prefix +
" invalid string " + repr(other) +
".")
603 raise TypeError(error_msg_prefix +
" " + str(type(other)) +
".")
604 except RuntimeError
as err:
605 raise ValueError(error_msg_prefix +
" " + str(type(other))
606 +
" value " + repr(other) +
":" 608 elif isinstance(ixt, index_set):
609 if isinstance(other, numbers.Real):
610 self.
instance = new Clifford((<index_set>ixt).unwrap(), <scalar_t>other)
611 elif isinstance(other, collections.Sequence):
612 self.
instance = new Clifford(list_to_vector(other), (<index_set>ixt).unwrap())
614 raise TypeError(error_msg_prefix +
" (" + str(type(other))
615 +
", " + repr(ixt) +
").")
617 raise TypeError(error_msg_prefix +
" (" + str(type(other))
618 +
", " + str(type(ixt)) +
").")
622 Clean up by deallocating the instance of C++ class Clifford. 630 >>> x=clifford(index_set({-3,4,7})); -3 in x 631 Traceback (most recent call last): 633 TypeError: Not applicable. 635 raise TypeError(
"Not applicable.")
641 >>> for a in clifford(index_set({-3,4,7})): print a, 642 Traceback (most recent call last): 644 TypeError: Not applicable. 646 raise TypeError(
"Not applicable.")
650 Put self into a larger frame, containing the union of self.frame() and index set ixt. 651 This can be used to make multiplication faster, by multiplying within a common frame. 653 >>> clifford("2+3{1}").reframe(index_set({1,2,3})) 655 >>> s=index_set({1,2,3});t=index_set({-3,-2,-1});x=random_clifford(s); x.reframe(t).frame() == (s|t); 658 error_msg_prefix =
"Cannot reframe" 659 if isinstance(ixt, index_set):
662 result.instance = new Clifford(self.unwrap(), (<index_set>ixt).unwrap())
663 except RuntimeError
as err:
664 raise ValueError(error_msg_prefix +
" from " + str(self) +
" to frame " 668 raise TypeError(error_msg_prefix +
" using (" + str(type(ixt)) +
").")
673 Compare objects of type clifford. 675 >>> clifford("{1}") == clifford("1{1}") 677 >>> clifford("{1}") != clifford("1.0{1}") 679 >>> clifford("{1}") != clifford("1.0") 681 >>> clifford("{1,2}") == None 683 >>> clifford("{1,2}") != None 685 >>> None == clifford("{1,2}") 687 >>> None != clifford("{1,2}") 691 if (lhs
is None)
or (rhs
is None):
692 return bool(lhs
is rhs)
694 return bool( toClifford(lhs) == toClifford(rhs) )
696 if (lhs
is None)
or (rhs
is None):
697 return not bool(lhs
is rhs)
699 return bool( toClifford(lhs) != toClifford(rhs) )
700 elif isinstance(lhs, clifford)
or isinstance(rhs, clifford):
701 raise TypeError(
"This comparison operator is not implemented for " 702 + str(type(lhs)) +
", " + str(type(rhs)) +
".")
704 return NotImplemented
708 Subscripting: map from index set to scalar coordinate. 710 >>> clifford("{1}")[index_set(1)] 712 >>> clifford("{1}")[index_set({1})] 714 >>> clifford("{1}")[index_set({1,2})] 716 >>> clifford("2{1,2}")[index_set({1,2})] 719 return self.
instance.getitem(toIndexSet(ixt))
725 >>> print -clifford("{1}") 734 >>> print +clifford("{1}") 743 >>> print clifford(1) + clifford("{2}") 745 >>> print clifford("{1}") + clifford("{2}") 748 return clifford().wrap( toClifford(lhs) + toClifford(rhs) )
754 >>> x = clifford(1); x += clifford("{2}"); print x 757 return self.wrap( self.unwrap() + toClifford(rhs) )
761 Geometric difference. 763 >>> print clifford(1) - clifford("{2}") 765 >>> print clifford("{1}") - clifford("{2}") 768 return clifford().wrap( toClifford(lhs) - toClifford(rhs) )
772 Geometric difference. 774 >>> x = clifford(1); x -= clifford("{2}"); print x 777 return self.wrap( self.unwrap() - toClifford(rhs) )
783 >>> print clifford("{1}") * clifford("{2}") 785 >>> print clifford(2) * clifford("{2}") 787 >>> print clifford("{1}") * clifford("{1,2}") 790 return clifford().wrap( toClifford(lhs) * toClifford(rhs) )
796 >>> x = clifford(2); x *= clifford("{2}"); print x 798 >>> x = clifford("{1}"); x *= clifford("{2}"); print x 800 >>> x = clifford("{1}"); x *= clifford("{1,2}"); print x 803 return self.wrap( self.unwrap() * toClifford(rhs) )
809 >>> print clifford("{1}") % clifford("{2}") 811 >>> print clifford(2) % clifford("{2}") 813 >>> print clifford("{1}") % clifford("{1}") 815 >>> print clifford("{1}") % clifford("{1,2}") 818 return clifford().wrap( toClifford(lhs) % toClifford(rhs) )
824 >>> x = clifford("{1}"); x %= clifford("{2}"); print x 826 >>> x = clifford(2); x %= clifford("{2}"); print x 828 >>> x = clifford("{1}"); x %= clifford("{1}"); print x 830 >>> x = clifford("{1}"); x %= clifford("{1,2}"); print x 833 return self.wrap( self.unwrap() % toClifford(rhs) )
839 >>> print clifford("{1}") & clifford("{2}") 841 >>> print clifford(2) & clifford("{2}") 843 >>> print clifford("{1}") & clifford("{1}") 845 >>> print clifford("{1}") & clifford("{1,2}") 848 return clifford().wrap( toClifford(lhs) & toClifford(rhs) )
854 >>> x = clifford("{1}"); x &= clifford("{2}"); print x 856 >>> x = clifford(2); x &= clifford("{2}"); print x 858 >>> x = clifford("{1}"); x &= clifford("{1}"); print x 860 >>> x = clifford("{1}"); x &= clifford("{1,2}"); print x 863 return self.wrap( self.unwrap() & toClifford(rhs) )
869 >>> print clifford("{1}") ^ clifford("{2}") 871 >>> print clifford(2) ^ clifford("{2}") 873 >>> print clifford("{1}") ^ clifford("{1}") 875 >>> print clifford("{1}") ^ clifford("{1,2}") 878 return clifford().wrap( toClifford(lhs) ^ toClifford(rhs) )
884 >>> x = clifford("{1}"); x ^= clifford("{2}"); print x 886 >>> x = clifford(2); x ^= clifford("{2}"); print x 888 >>> x = clifford("{1}"); x ^= clifford("{1}"); print x 890 >>> x = clifford("{1}"); x ^= clifford("{1,2}"); print x 893 return self.wrap( self.unwrap() ^ toClifford(rhs) )
899 >>> print clifford("{1}") / clifford("{2}") 901 >>> print clifford(2) / clifford("{2}") 903 >>> print clifford("{1}") / clifford("{1}") 905 >>> print clifford("{1}") / clifford("{1,2}") 908 return clifford().wrap( toClifford(lhs) / toClifford(rhs) )
914 >>> x = clifford("{1}"); x /= clifford("{2}"); print x 916 >>> x = clifford(2); x /= clifford("{2}"); print x 918 >>> x = clifford("{1}"); x /= clifford("{1}"); print x 920 >>> x = clifford("{1}"); x /= clifford("{1,2}"); print x 923 return self.wrap( self.unwrap() / toClifford(rhs) )
927 Geometric multiplicative inverse. 929 >>> x = clifford("{1}"); print x.inv() 931 >>> x = clifford(2); print x.inv() 933 >>> x = clifford("{1,2}"); print x.inv() 940 Transform left hand side, using right hand side as a transformation. 942 >>> x=clifford("{1,2}") * pi/2; y=clifford("{1}"); print y|x 944 >>> x=clifford("{1,2}") * pi/2; y=clifford("{1}"); print y|exp(x) 947 return clifford().wrap( toClifford(lhs) | toClifford(rhs) )
951 Transform left hand side, using right hand side as a transformation. 953 >>> x=clifford("{1,2}") * pi/2; y=clifford("{1}"); y|=x; print y 955 >>> x=clifford("{1,2}") * pi/2; y=clifford("{1}"); y|=exp(x); print y 958 return self.wrap( self.unwrap() | toClifford(rhs) )
962 Power: self to the m. 964 >>> x=clifford("{1}"); print x ** 2 966 >>> x=clifford("2"); print x ** 2 968 >>> x=clifford("2+{1}"); print x ** 0 970 >>> x=clifford("2+{1}"); print x ** 1 972 >>> x=clifford("2+{1}"); print x ** 2 974 >>> i=clifford("{1,2}");print exp(pi/2) * (i ** i) 981 Power: self to the m. 983 >>> x=clifford("{1}"); print x.pow(2) 985 >>> x=clifford("2"); print x.pow(2) 987 >>> x=clifford("2+{1}"); print x.pow(0) 989 >>> x=clifford("2+{1}"); print x.pow(1) 991 >>> x=clifford("2+{1}"); print x.pow(2) 993 >>> print clifford("1+{1}+{1,2}").pow(3) 995 >>> i=clifford("{1,2}");print exp(pi/2) * i.pow(i) 998 if isinstance(m, numbers.Integral):
1001 return exp(m *
log(self))
1005 Outer product power. 1007 >>> x=clifford("2+{1}"); print x.outer_pow(0) 1009 >>> x=clifford("2+{1}"); print x.outer_pow(1) 1011 >>> x=clifford("2+{1}"); print x.outer_pow(2) 1013 >>> print clifford("1+{1}+{1,2}").outer_pow(3) 1021 Pure grade-vector part. 1023 >>> print clifford("{1}")(1) 1025 >>> print clifford("{1}")(0) 1027 >>> print clifford("1+{1}+{1,2}")(0) 1029 >>> print clifford("1+{1}+{1,2}")(1) 1031 >>> print clifford("1+{1}+{1,2}")(2) 1033 >>> print clifford("1+{1}+{1,2}")(3) 1042 >>> clifford("1+{1}+{1,2}").scalar() 1044 >>> clifford("{1,2}").scalar() 1053 >>> print clifford("1+{1}+{1,2}").pure() 1055 >>> print clifford("{1,2}").pure() 1062 Even part of multivector, sum of even grade terms. 1064 >>> print clifford("1+{1}+{1,2}").even() 1071 Odd part of multivector, sum of odd grade terms. 1073 >>> print clifford("1+{1}+{1,2}").odd() 1080 Vector part of multivector, as a Python list, with respect to frm. 1082 >>> print clifford("1+2{1}+3{2}+4{1,2}").vector_part() 1084 >>> print clifford("1+2{1}+3{2}+4{1,2}").vector_part(index_set({-1,1,2})) 1087 error_msg_prefix =
"Cannot take vector part of " 1088 cdef vector[scalar_t] vec
1101 except RuntimeError
as err:
1102 raise ValueError(error_msg_prefix + str(self) +
" using invalid " 1103 + repr(frm) +
" as frame:\n\t" 1108 Main involution, each {i} is replaced by -{i} in each term, 1109 eg. clifford("{1}") -> -clifford("{1}"). 1111 >>> print clifford("{1}").involute() 1113 >>> print (clifford("{2}") * clifford("{1}")).involute() 1115 >>> print (clifford("{1}") * clifford("{2}")).involute() 1117 >>> print clifford("1+{1}+{1,2}").involute() 1124 Reversion, eg. clifford("{1}")*clifford("{2}") -> clifford("{2}")*clifford("{1}"). 1126 >>> print clifford("{1}").reverse() 1128 >>> print (clifford("{2}") * clifford("{1}")).reverse() 1130 >>> print (clifford("{1}") * clifford("{2}")).reverse() 1132 >>> print clifford("1+{1}+{1,2}").reverse() 1139 Conjugation, reverse o involute == involute o reverse. 1141 >>> print (clifford("{1}")).conj() 1143 >>> print (clifford("{2}") * clifford("{1}")).conj() 1145 >>> print (clifford("{1}") * clifford("{2}")).conj() 1147 >>> print clifford("1+{1}+{1,2}").conj() 1154 Quadratic form == (rev(x)*x)(0). 1156 >>> print clifford("1+{1}+{1,2}").quad() 1158 >>> print clifford("1+{-1}+{1,2}+{1,2,3}").quad() 1165 Norm == sum of squares of coordinates. 1167 >>> clifford("1+{1}+{1,2}").norm() 1169 >>> clifford("1+{-1}+{1,2}+{1,2,3}").norm() 1176 Absolute value: square root of norm. 1178 >>> clifford("1+{-1}+{1,2}+{1,2,3}").abs() 1185 Maximum of absolute values of components of multivector: multivector infinity norm. 1187 >>> clifford("1+{-1}+{1,2}+{1,2,3}").max_abs() 1189 >>> clifford("3+2{1}+{1,2}").max_abs() 1196 Remove all terms of self with relative size smaller than limit. 1198 >>> clifford("1e8+{1}+1e-8{1,2}").truncated(1.0e-6) 1199 clifford("100000000") 1200 >>> clifford("1e4+{1}+1e-4{1,2}").truncated(1.0e-6) 1201 clifford("10000+{1}") 1207 Check if a multivector contains any IEEE NaN values. 1209 >>> clifford().isnan() 1216 Subalgebra generated by all generators of terms of given multivector. 1218 >>> print clifford("1+3{-1}+2{1,2}+4{-2,7}").frame() 1220 >>> s=clifford("1+3{-1}+2{1,2}+4{-2,7}").frame(); type(s) 1221 <type 'PyClical.index_set'> 1227 The “official” string representation of self. 1229 >>> clifford("1+3{-1}+2{1,2}+4{-2,7}").__repr__() 1230 'clifford("1+3{-1}+2{1,2}+4{-2,7}")' 1236 The “informal” string representation of self. 1238 >>> clifford("1+3{-1}+2{1,2}+4{-2,7}").__str__() 1239 '1+3{-1}+2{1,2}+4{-2,7}' 1245 Tests for functions that Doctest cannot see. 1247 For clifford.__cinit__: Construct an object of type clifford. 1249 >>> print clifford(2) 1251 >>> print clifford(2L) 1253 >>> print clifford(2.0) 1255 >>> print clifford(1.0e-1) 1257 >>> print clifford("2") 1259 >>> print clifford("2{1,2,3}") 1261 >>> print clifford(clifford("2{1,2,3}")) 1263 >>> print clifford("-{1}") 1265 >>> print clifford(2,index_set({1,2})) 1267 >>> print clifford([2,3],index_set({1,2})) 1269 >>> print clifford([1,2]) 1270 Traceback (most recent call last): 1272 TypeError: Cannot initialize clifford object from <type 'list'>. 1273 >>> print clifford(None) 1274 Traceback (most recent call last): 1276 TypeError: Cannot initialize clifford object from <type 'NoneType'>. 1277 >>> print clifford(None,[1,2]) 1278 Traceback (most recent call last): 1280 TypeError: Cannot initialize clifford object from (<type 'NoneType'>, <type 'list'>). 1281 >>> print clifford([1,2],[1,2]) 1282 Traceback (most recent call last): 1284 TypeError: Cannot initialize clifford object from (<type 'list'>, <type 'list'>). 1285 >>> print clifford("") 1286 Traceback (most recent call last): 1288 ValueError: Cannot initialize clifford object from invalid string ''. 1289 >>> print clifford("{") 1290 Traceback (most recent call last): 1292 ValueError: Cannot initialize clifford object from invalid string '{'. 1293 >>> print clifford("{1") 1294 Traceback (most recent call last): 1296 ValueError: Cannot initialize clifford object from invalid string '{1'. 1297 >>> print clifford("+") 1298 Traceback (most recent call last): 1300 ValueError: Cannot initialize clifford object from invalid string '+'. 1301 >>> print clifford("-") 1302 Traceback (most recent call last): 1304 ValueError: Cannot initialize clifford object from invalid string '-'. 1305 >>> print clifford("{1}+") 1306 Traceback (most recent call last): 1308 ValueError: Cannot initialize clifford object from invalid string '{1}+'. 1310 For clifford.__richcmp__: Compare objects of type clifford. 1312 >>> clifford("{1}") == clifford("1{1}") 1314 >>> clifford("{1}") != clifford("1.0{1}") 1316 >>> clifford("{1}") != clifford("1.0") 1318 >>> clifford("{1,2}") == None 1320 >>> clifford("{1,2}") != None 1322 >>> None == clifford("{1,2}") 1324 >>> None != clifford("{1,2}") 1329 cpdef inline
inv(obj):
1331 Geometric multiplicative inverse. 1333 >>> print inv(clifford("{1}")) 1335 >>> print inv(clifford("{-1}")) 1337 >>> print inv(clifford("{-2,-1}")) 1339 >>> print inv(clifford("{-1}+{1}")) 1342 return clifford(obj).
inv()
1344 cpdef inline
scalar(obj):
1348 >>> scalar(clifford("1+{1}+{1,2}")) 1350 >>> scalar(clifford("{1,2}")) 1353 return clifford(obj).
scalar()
1355 cpdef inline
real(obj):
1357 Real part: synonym for scalar part. 1359 >>> real(clifford("1+{1}+{1,2}")) 1361 >>> real(clifford("{1,2}")) 1364 return clifford(obj).
scalar()
1366 cpdef inline
imag(obj):
1368 Imaginary part: deprecated (always 0). 1370 >>> imag(clifford("1+{1}+{1,2}")) 1372 >>> imag(clifford("{1,2}")) 1377 cpdef inline
pure(obj):
1381 >>> print pure(clifford("1+{1}+{1,2}")) 1383 >>> print pure(clifford("{1,2}")) 1386 return clifford(obj).
pure()
1388 cpdef inline
even(obj):
1390 Even part of multivector, sum of even grade terms. 1392 >>> print even(clifford("1+{1}+{1,2}")) 1395 return clifford(obj).
even()
1397 cpdef inline
odd(obj):
1399 Odd part of multivector, sum of odd grade terms. 1401 >>> print odd(clifford("1+{1}+{1,2}")) 1404 return clifford(obj).
odd()
1408 Main involution, each {i} is replaced by -{i} in each term, eg. {1}*{2} -> (-{2})*(-{1}) 1410 >>> print involute(clifford("{1}")) 1412 >>> print involute(clifford("{2}") * clifford("{1}")) 1414 >>> print involute(clifford("{1}") * clifford("{2}")) 1416 >>> print involute(clifford("1+{1}+{1,2}")) 1423 Reversion, eg. {1}*{2} -> {2}*{1} 1425 >>> print reverse(clifford("{1}")) 1427 >>> print reverse(clifford("{2}") * clifford("{1}")) 1429 >>> print reverse(clifford("{1}") * clifford("{2}")) 1431 >>> print reverse(clifford("1+{1}+{1,2}")) 1434 return clifford(obj).
reverse()
1436 cpdef inline
conj(obj):
1438 Conjugation, reverse o involute == involute o reverse. 1440 >>> print conj(clifford("{1}")) 1442 >>> print conj(clifford("{2}") * clifford("{1}")) 1444 >>> print conj(clifford("{1}") * clifford("{2}")) 1446 >>> print conj(clifford("1+{1}+{1,2}")) 1449 return clifford(obj).
conj()
1451 cpdef inline
quad(obj):
1453 Quadratic form == (rev(x)*x)(0). 1455 >>> print quad(clifford("1+{1}+{1,2}")) 1457 >>> print quad(clifford("1+{-1}+{1,2}+{1,2,3}")) 1460 return clifford(obj).
quad()
1462 cpdef inline
norm(obj):
1464 norm == sum of squares of coordinates. 1466 >>> norm(clifford("1+{1}+{1,2}")) 1468 >>> norm(clifford("1+{-1}+{1,2}+{1,2,3}")) 1471 return clifford(obj).
norm()
1473 cpdef inline
abs(obj):
1475 Absolute value of multivector: multivector 2-norm. 1477 >>> abs(clifford("1+{-1}+{1,2}+{1,2,3}")) 1484 Maximum absolute value of coordinates multivector: multivector infinity-norm. 1486 >>> max_abs(clifford("1+{-1}+{1,2}+{1,2,3}")) 1488 >>> max_abs(clifford("3+2{1}+{1,2}")) 1494 cpdef inline
pow(obj, m):
1496 Integer power of multivector: obj to the m. 1498 >>> x=clifford("{1}"); print pow(x,2) 1500 >>> x=clifford("2"); print pow(x,2) 1502 >>> x=clifford("2+{1}"); print pow(x,0) 1504 >>> x=clifford("2+{1}"); print pow(x,1) 1506 >>> x=clifford("2+{1}"); print pow(x,2) 1508 >>> print pow(clifford("1+{1}+{1,2}"),3) 1510 >>> i=clifford("{1,2}");print exp(pi/2) * pow(i, i) 1516 return clifford(obj).
pow(m)
1520 Outer product power of multivector. 1522 >>> print outer_pow(clifford("1+{1}+{1,2}"),3) 1529 Square root of -1 which commutes with all members of the frame of the given multivector. 1531 >>> print complexifier(clifford(index_set({1}))) 1533 >>> print complexifier(clifford(index_set({-1}))) 1535 >>> print complexifier(index_set({1})) 1537 >>> print complexifier(index_set({-1})) 1544 Square root of multivector with optional complexifier. 1548 >>> print sqrt(clifford("2{-1}")) 1550 >>> j=sqrt(-1,complexifier(index_set({1}))); print j; print j*j 1553 >>> j=sqrt(-1,"{1,2,3}"); print j; print j*j 1561 return math.sqrt(obj)
1565 cpdef inline
exp(obj):
1567 Exponential of multivector. 1569 >>> x=clifford("{1,2}") * pi/4; print exp(x) 1571 >>> x=clifford("{1,2}") * pi/2; print exp(x) 1575 return math.exp(obj)
1579 cpdef inline
log(obj,i =
None):
1581 Natural logarithm of multivector with optional complexifier. 1583 >>> x=clifford("{-1}"); print (log(x,"{-1}") * 2/pi) 1585 >>> x=clifford("{1,2}"); print (log(x,"{1,2,3}") * 2/pi) 1587 >>> x=clifford("{1,2}"); print (log(x) * 2/pi) 1589 >>> x=clifford("{1,2}"); print (log(x,"{1,2}") * 2/pi) 1590 Traceback (most recent call last): 1592 RuntimeError: check_complex(val, i): i is not a valid complexifier for val 1598 return math.log(obj)
1602 cpdef inline
cos(obj,i =
None):
1604 Cosine of multivector with optional complexifier. 1606 >>> x=clifford("{1,2}"); print cos(acos(x),"{1,2,3}") 1608 >>> x=clifford("{1,2}"); print cos(acos(x)) 1615 return math.cos(obj)
1619 cpdef inline
acos(obj,i =
None):
1621 Inverse cosine of multivector with optional complexifier. 1623 >>> x=clifford("{1,2}"); print cos(acos(x),"{1,2,3}") 1625 >>> x=clifford("{1,2}"); print cos(acos(x),"{-1,1,2,3,4}") 1627 >>> print acos(0) / pi 1629 >>> x=clifford("{1,2}"); print cos(acos(x)) 1636 return math.acos(obj)
1640 cpdef inline
cosh(obj):
1642 Hyperbolic cosine of multivector. 1644 >>> x=clifford("{1,2}") * pi; print cosh(x) 1646 >>> x=clifford("{1,2,3}"); print cosh(acosh(x)) 1648 >>> x=clifford("{1,2}"); print cosh(acosh(x)) 1652 return math.cosh(obj)
1656 cpdef inline
acosh(obj,i =
None):
1658 Inverse hyperbolic cosine of multivector with optional complexifier. 1660 >>> print acosh(0,"{-2,-1,1}") 1662 >>> x=clifford("{1,2,3}"); print cosh(acosh(x,"{-1,1,2,3,4}")) 1666 >>> x=clifford("{1,2,3}"); print cosh(acosh(x)) 1668 >>> x=clifford("{1,2}"); print cosh(acosh(x)) 1675 return math.acosh(obj)
1679 cpdef inline
sin(obj,i =
None):
1681 Sine of multivector with optional complexifier. 1683 >>> s="{-1}"; x=clifford(s); print asin(sin(x,s),s) 1685 >>> s="{-1}"; x=clifford(s); print asin(sin(x,s),"{-2,-1,1}") 1687 >>> x=clifford("{1,2,3}"); print asin(sin(x)) 1694 return math.sin(obj)
1698 cpdef inline
asin(obj,i =
None):
1700 Inverse sine of multivector with optional complexifier. 1702 >>> s="{-1}"; x=clifford(s); print asin(sin(x,s),s) 1704 >>> s="{-1}"; x=clifford(s); print asin(sin(x,s),"{-2,-1,1}") 1706 >>> print asin(1) / pi 1708 >>> x=clifford("{1,2,3}"); print asin(sin(x)) 1715 return math.asin(obj)
1719 cpdef inline
sinh(obj):
1721 Hyperbolic sine of multivector. 1723 >>> x=clifford("{1,2}") * pi/2; print sinh(x) 1725 >>> x=clifford("{1,2}") * pi/6; print sinh(x) 1729 return math.sinh(obj)
1733 cpdef inline
asinh(obj,i =
None):
1735 Inverse hyperbolic sine of multivector with optional complexifier. 1737 >>> x=clifford("{1,2}"); print asinh(x,"{1,2,3}") * 2/pi 1739 >>> x=clifford("{1,2}"); print asinh(x) * 2/pi 1741 >>> x=clifford("{1,2}") / 2; print asinh(x) * 6/pi 1748 return math.asinh(obj)
1752 cpdef inline
tan(obj,i =
None):
1754 Tangent of multivector with optional complexifier. 1756 >>> x=clifford("{1,2}"); print tan(x,"{1,2,3}") 1758 >>> x=clifford("{1,2}"); print tan(x) 1765 return math.tan(obj)
1769 cpdef inline
atan(obj,i =
None):
1771 Inverse tangent of multivector with optional complexifier. 1773 >>> s=index_set({1,2,3}); x=clifford("{1}"); print tan(atan(x,s),s) 1775 >>> x=clifford("{1}"); print tan(atan(x)) 1782 return math.atan(obj)
1786 cpdef inline
tanh(obj):
1788 Hyperbolic tangent of multivector. 1790 >>> x=clifford("{1,2}") * pi/4; print tanh(x) 1794 return math.tanh(obj)
1798 cpdef inline
atanh(obj,i =
None):
1800 Inverse hyperbolic tangent of multivector with optional complexifier. 1802 >>> s=index_set({1,2,3}); x=clifford("{1,2}"); print tanh(atanh(x,s)) 1804 >>> x=clifford("{1,2}"); print tanh(atanh(x)) 1811 return math.atanh(obj)
1815 cpdef inline random_clifford(index_set ixt, fill = 1.0):
1817 Random multivector within a frame. 1819 >>> print random_clifford(index_set({-3,-1,2})).frame() 1822 return clifford().wrap(
clifford().instance.random(ixt.unwrap(), <scalar_t>fill) )
1824 cpdef inline
cga3(obj):
1826 Convert Euclidean 3D multivector to Conformal Geometric Algebra using Doran and Lasenby definition. 1828 >>> x=clifford("2{1}+9{2}+{3}"); print cga3(x) 1829 87{-1}+4{1}+18{2}+2{3}+85{4} 1831 return clifford().wrap( glucat.cga3(toClifford(obj)) )
1835 Convert CGA3 null vector to standard conformal null vector using Doran and Lasenby definition. 1837 >>> x=clifford("2{1}+9{2}+{3}"); print cga3std(cga3(x)) 1838 87{-1}+4{1}+18{2}+2{3}+85{4} 1839 >>> x=clifford("2{1}+9{2}+{3}"); print cga3std(cga3(x))-cga3(x) 1842 return clifford().wrap( glucat.cga3std(toClifford(obj)) )
1844 cpdef inline
agc3(obj):
1846 Convert CGA3 null vector to Euclidean 3D vector using Doran and Lasenby definition. 1848 >>> x=clifford("2{1}+9{2}+{3}"); print agc3(cga3(x)) 1850 >>> x=clifford("2{1}+9{2}+{3}"); print agc3(cga3(x))-x 1853 return clifford().wrap( glucat.agc3(toClifford(obj)) )
1861 Abbreviation for clifford. 1869 >>> print cl(5.0e-1) 1873 >>> print cl("2{1,2,3}") 1875 >>> print cl(cl("2{1,2,3}")) 1881 Abbreviation for index_set. 1883 >>> print ist("{1,2,3}") 1889 Abbreviation for clifford(index_set(obj)). 1902 Abbreviation for index_set({-q,...p}). 1904 >>> print istpq(2,3) 1914 import PyClical, doctest
1915 return doctest.testmod(PyClical)
1917 if __name__ ==
"__main__":
const Multivector< Scalar_T, LO, HI > pure(const Multivector< Scalar_T, LO, HI > &val)
Pure part.
def __getitem__(self, idx)
const Multivector< Scalar_T, LO, HI > asinh(const Multivector< Scalar_T, LO, HI > &val)
Inverse hyperbolic sine of multivector.
int compare(const index_set< LO, HI > &a, const index_set< LO, HI > &b)
"lexicographic compare" eg. {3,4,5} is less than {3,7,8}
const Multivector< Scalar_T, LO, HI > sqrt(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Square root of multivector with specified complexifier.
String clifford_to_str(const Multivector_T &mv)
The "informal" string representation of Multivector_T mv.
const Multivector< Scalar_T, LO, HI > acosh(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse hyperbolic cosine of multivector with specified complexifier.
String index_set_to_repr(const Index_Set_T &ist)
The “official” string representation of Index_Set_T ist.
const Multivector< Scalar_T, LO, HI > sinh(const Multivector< Scalar_T, LO, HI > &val)
Hyperbolic sine of multivector.
Scalar_T abs(const Multivector< Scalar_T, LO, HI > &val)
Absolute value == sqrt(norm)
const matrix_multi< Scalar_T, LO, HI > exp(const matrix_multi< Scalar_T, LO, HI > &val)
Exponential of multivector.
const Multivector< Scalar_T, LO, HI > log(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Natural logarithm of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > conj(const Multivector< Scalar_T, LO, HI > &val)
Conjugation, rev o invo == invo o rev.
const Multivector< Scalar_T, LO, HI > atanh(const Multivector< Scalar_T, LO, HI > &val)
Inverse hyperbolic tangent of multivector.
const Multivector< Scalar_T, LO, HI > acosh(const Multivector< Scalar_T, LO, HI > &val)
Inverse hyperbolic cosine of multivector.
Scalar_T quad(const Multivector< Scalar_T, LO, HI > &val)
Scalar_T quadratic form == (rev(x)*x)(0)
Scalar_T norm(const Multivector< Scalar_T, LO, HI > &val)
Scalar_T norm == sum of norm of coordinates.
const Multivector< Scalar_T, LO, HI > odd(const Multivector< Scalar_T, LO, HI > &val)
Odd part.
def __getitem__(self, ixt)
const Multivector< Scalar_T, LO, HI > pow(const Multivector< Scalar_T, LO, HI > &lhs, int rhs)
Integer power of multivector.
def __contains__(self, idx)
const Multivector< Scalar_T, LO, HI > tan(const Multivector< Scalar_T, LO, HI > &val)
Tangent of multivector.
Scalar_T imag(const Multivector< Scalar_T, LO, HI > &val)
Imaginary part: deprecated (always 0)
String clifford_to_repr(const Multivector_T &mv)
The “official” string representation of Multivector_T mv.
const Multivector< Scalar_T, LO, HI > asin(const Multivector< Scalar_T, LO, HI > &val)
Inverse sine of multivector.
const Multivector< Scalar_T, LO, HI > outer_pow(const Multivector< Scalar_T, LO, HI > &lhs, int rhs)
Outer product power of multivector.
const Multivector< Scalar_T, LO, HI > sin(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Sine of multivector with specified complexifier.
def __richcmp__(lhs, rhs, int, op)
const Multivector< Scalar_T, LO, HI > atanh(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse hyperbolic tangent of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > reverse(const Multivector< Scalar_T, LO, HI > &val)
Reversion, eg. {1}*{2} -> {2}*{1}.
const framed_multi< Scalar_T, LO, HI > exp(const framed_multi< Scalar_T, LO, HI > &val)
Exponential of multivector.
const Multivector< Scalar_T, LO, HI > cos(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Cosine of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > tanh(const Multivector< Scalar_T, LO, HI > &val)
Hyperbolic tangent of multivector.
const Multivector< Scalar_T, LO, HI > acos(const Multivector< Scalar_T, LO, HI > &val)
Inverse cosine of multivector.
index_t min_neg(const index_set< LO, HI > &ist)
Minimum negative index, or 0 if none.
def __richcmp__(lhs, rhs, int, op)
const Multivector< Scalar_T, LO, HI > inv(const Multivector< Scalar_T, LO, HI > &val)
Geometric multiplicative inverse.
const Multivector< Scalar_T, LO, HI > asin(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse sine of multivector with specified complexifier.
Scalar_T scalar(const Multivector< Scalar_T, LO, HI > &val)
Scalar part.
def sign_of_mult(self, rhs)
def __cinit__(self, other=0)
Definitions for 3D Conformal Geometric Algebra [DL].
def __call__(self, grade)
const Multivector< Scalar_T, LO, HI > complexifier(const Multivector< Scalar_T, LO, HI > &val)
Square root of -1 which commutes with all members of the frame of the given multivector.
const Multivector< Scalar_T, LO, HI > atan(const Multivector< Scalar_T, LO, HI > &val)
Inverse tangent of multivector.
const Multivector< Scalar_T, LO, HI > involute(const Multivector< Scalar_T, LO, HI > &val)
Main involution, each {i} is replaced by -{i} in each term, eg. {1}*{2} -> (-{2})*(-{1}) ...
def truncated(self, limit)
const Multivector< Scalar_T, LO, HI > sin(const Multivector< Scalar_T, LO, HI > &val)
Sine of multivector.
const Multivector< Scalar_T, LO, HI > atan(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse tangent of multivector with specified complexifier.
def __pow__(self, m, dummy)
const Multivector< Scalar_T, LO, HI > tan(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Tangent of multivector with specified complexifier.
const matrix_multi< Scalar_T, LO, HI > sqrt(const matrix_multi< Scalar_T, LO, HI > &val, const matrix_multi< Scalar_T, LO, HI > &i, bool prechecked)
Square root of multivector with specified complexifier.
Scalar_T real(const Multivector< Scalar_T, LO, HI > &val)
Real part: synonym for scalar part.
def __setitem__(self, idx, val)
def __contains__(self, x)
const Multivector< Scalar_T, LO, HI > acos(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse cosine of multivector with specified complexifier.
const matrix_multi< Scalar_T, LO, HI > log(const matrix_multi< Scalar_T, LO, HI > &val, const matrix_multi< Scalar_T, LO, HI > &i, bool prechecked)
Natural logarithm of multivector with specified complexifier.
String index_set_to_str(const Index_Set_T &ist)
The "informal" string representation of Index_Set_T ist.
const Multivector< Scalar_T, LO, HI > cos(const Multivector< Scalar_T, LO, HI > &val)
Cosine of multivector.
index_t max_pos(const index_set< LO, HI > &ist)
Maximum positive index, or 0 if none.
def __cinit__(self, other=0, ixt=None)
def index_set_hidden_doctests()
def clifford_hidden_doctests()
const Multivector< Scalar_T, LO, HI > asinh(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse hyperbolic sine of multivector with specified complexifier.
Scalar_T max_abs(const Multivector< Scalar_T, LO, HI > &val)
Maximum of absolute values of components of multivector: multivector infinity norm.
const Multivector< Scalar_T, LO, HI > cosh(const Multivector< Scalar_T, LO, HI > &val)
Hyperbolic cosine of multivector.
Multivector_T cga3std(const Multivector_T &X)
Convert CGA3 null vector to standard Conformal Geometric Algebra null vector [DL (10.52)].
const Multivector< Scalar_T, LO, HI > even(const Multivector< Scalar_T, LO, HI > &val)
Even part.
def vector_part(self, frm=None)
Multivector_T agc3(const Multivector_T &X)
Convert CGA3 null vector to Euclidean 3D vector [DL (10.50)].