Go to the documentation of this file.
35 from PyClical cimport *
40 cdef inline IndexSet toIndexSet(obj):
42 Return the C++ IndexSet instance wrapped by index_set(obj).
48 Python class index_set wraps C++ class IndexSet.
50 cdef IndexSet *instance
52 cdef inline wrap(index_set self, IndexSet other):
54 Wrap an instance of the C++ class IndexSet.
59 cdef inline IndexSet unwrap(index_set self):
61 Return the wrapped C++ IndexSet instance.
65 cpdef copy(index_set self):
67 Copy this index_set object.
69 >>> s=index_set(1); t=s.copy(); print(t)
76 Construct an object of type index_set.
78 >>> print(index_set(1))
80 >>> print(index_set({1,2}))
82 >>> print(index_set(index_set({1,2})))
84 >>> print(index_set({1,2}))
86 >>> print(index_set({1,2,1}))
88 >>> print(index_set("{1,2,1}"))
90 >>> print(index_set(""))
93 error_msg_prefix =
"Cannot initialize index_set object from"
94 if isinstance(other, index_set):
95 self.
instance = new IndexSet((<index_set>other).unwrap())
96 elif isinstance(other, numbers.Integral):
97 self.
instance = new IndexSet(<int>other)
98 elif isinstance(other, (set, frozenset)):
104 raise IndexError(error_msg_prefix +
" invalid " + repr(other) +
".")
105 except (RuntimeError, TypeError):
106 raise ValueError(error_msg_prefix +
" invalid " + repr(other) +
".")
107 elif isinstance(other, str):
109 bother = other.encode(
"UTF-8")
110 self.
instance = new IndexSet(<char *>bother)
112 raise ValueError(error_msg_prefix +
" invalid string " + repr(other) +
".")
114 raise TypeError(error_msg_prefix +
" " + str(type(other)) +
".")
118 Clean up by deallocating the instance of C++ class IndexSet.
124 Compare two objects of class index_set.
126 >>> index_set(1) == index_set({1})
128 >>> index_set({1}) != index_set({1})
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})
140 >>> index_set({1}) >= index_set({2})
143 if (lhs
is None)
or (rhs
is None):
144 eq = bool(lhs
is rhs)
159 return NotImplemented
161 eq = bool( toIndexSet(lhs) == toIndexSet(rhs) )
167 lt = bool( toIndexSet(lhs) < toIndexSet(rhs) )
173 return not (lt
or eq)
177 return NotImplemented
181 Set the value of an index_set object at index idx to value val.
183 >>> s=index_set({1}); s[2] = True; print(s)
185 >>> s=index_set({1,2}); s[1] = False; print(s)
193 Get the value of an index_set object at an index.
195 >>> index_set({1})[1]
197 >>> index_set({1})[2]
199 >>> index_set({2})[-1]
201 >>> index_set({2})[1]
203 >>> index_set({2})[2]
205 >>> index_set({2})[33]
212 Check that an index_set object contains the index idx: idx in self.
214 >>> 1 in index_set({1})
216 >>> 2 in index_set({1})
218 >>> -1 in index_set({2})
220 >>> 1 in index_set({2})
222 >>> 2 in index_set({2})
224 >>> 33 in index_set({2})
231 Iterate over the indices of an index_set.
233 >>> for i in index_set({-3,4,7}):print(i, end=",")
236 for idx
in range(self.
min(), self.
max()+1):
244 >>> 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}))
245 {-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}
251 Symmetric set difference: exclusive or.
253 >>> print(index_set({1}) ^ index_set({2}))
255 >>> print(index_set({1,2}) ^ index_set({2}))
258 return index_set().wrap( toIndexSet(lhs) ^ toIndexSet(rhs) )
262 Symmetric set difference: exclusive or.
264 >>> x = index_set({1}); x ^= index_set({2}); print(x)
266 >>> x = index_set({1,2}); x ^= index_set({2}); print(x)
269 return self.wrap( self.unwrap() ^ toIndexSet(rhs) )
273 Set intersection: and.
275 >>> print(index_set({1}) & index_set({2}))
277 >>> print(index_set({1,2}) & index_set({2}))
280 return index_set().wrap( toIndexSet(lhs) & toIndexSet(rhs) )
284 Set intersection: and.
286 >>> x = index_set({1}); x &= index_set({2}); print(x)
288 >>> x = index_set({1,2}); x &= index_set({2}); print(x)
291 return self.wrap( self.unwrap() & toIndexSet(rhs) )
297 >>> print(index_set({1}) | index_set({2}))
299 >>> print(index_set({1,2}) | index_set({2}))
302 return index_set().wrap( toIndexSet(lhs) | toIndexSet(rhs) )
308 >>> x = index_set({1}); x |= index_set({2}); print(x)
310 >>> x = index_set({1,2}); x |= index_set({2}); print(x)
313 return self.wrap( self.unwrap() | toIndexSet(rhs) )
317 Cardinality: Number of indices included in set.
319 >>> index_set({-1,1,2}).count()
326 Number of negative indices included in set.
328 >>> index_set({-1,1,2}).count_neg()
335 Number of positive indices included in set.
337 >>> index_set({-1,1,2}).count_pos()
346 >>> index_set({-1,1,2}).min()
355 >>> index_set({-1,1,2}).max()
368 Sign of geometric product of two Clifford basis elements.
370 >>> s = index_set({1,2}); t=index_set({-1}); s.sign_of_mult(t)
377 Sign of geometric square of a Clifford basis element.
379 >>> s = index_set({1,2}); s.sign_of_square()
386 The “official” string representation of self.
388 >>> index_set({1,2}).__repr__()
390 >>> repr(index_set({1,2}))
397 The “informal” string representation of self.
399 >>> index_set({1,2}).__str__()
401 >>> str(index_set({1,2}))
408 Tests for functions that Doctest cannot see.
410 For index_set.__cinit__: Construct index_set.
412 >>> print(index_set(1))
414 >>> print(index_set({1,2}))
416 >>> print(index_set(index_set({1,2})))
418 >>> print(index_set({1,2}))
420 >>> print(index_set({1,2,1}))
422 >>> print(index_set({1,2,1}))
424 >>> print(index_set(""))
426 >>> print(index_set("{"))
427 Traceback (most recent call last):
429 ValueError: Cannot initialize index_set object from invalid string '{'.
430 >>> print(index_set("{1"))
431 Traceback (most recent call last):
433 ValueError: Cannot initialize index_set object from invalid string '{1'.
434 >>> print(index_set("{1,2,100}"))
435 Traceback (most recent call last):
437 ValueError: Cannot initialize index_set object from invalid string '{1,2,100}'.
438 >>> print(index_set({1,2,100}))
439 Traceback (most recent call last):
441 IndexError: Cannot initialize index_set object from invalid {1, 2, 100}.
442 >>> print(index_set([1,2]))
443 Traceback (most recent call last):
445 TypeError: Cannot initialize index_set object from <class 'list'>.
447 For index_set.__richcmp__: Compare two objects of class index_set.
449 >>> index_set(1) == index_set({1})
451 >>> index_set({1}) != index_set({1})
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 >>> index_set({1}) >= index_set({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 >>> None >= index_set({1,2})
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
487 >>> index_set({1,2}) >= None
494 "lexicographic compare" eg. {3,4,5} is less than {3,7,8};
495 -1 if a<b, +1 if a>b, 0 if a==b.
497 >>> compare(index_set({1,2}),index_set({-1,3}))
499 >>> compare(index_set({-1,4}),index_set({-1,3}))
506 Minimum negative index, or 0 if none.
508 >>> min_neg(index_set({1,2}))
515 Maximum positive index, or 0 if none.
517 >>> max_pos(index_set({1,2}))
522 cdef inline vector[scalar_t] list_to_vector(lst):
524 Create a C++ std:vector[scalar_t] from an iterable Python object.
526 cdef vector[scalar_t] v
528 v.push_back(<scalar_t>s)
534 cdef inline Clifford toClifford(obj):
539 Python class clifford wraps C++ class Clifford.
541 cdef Clifford *instance
543 cdef inline wrap(clifford self, Clifford other):
545 Wrap an instance of the C++ class Clifford.
550 cdef inline Clifford unwrap(clifford self):
552 Return the wrapped C++ Clifford instance.
556 cpdef copy(clifford self):
558 Copy this clifford object.
560 >>> x=clifford("1{2}"); y=x.copy(); print(y)
567 Construct an object of type clifford.
569 >>> print(clifford(2))
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 bother = other.encode(
"UTF-8")
600 self.
instance = new Clifford(<char *>bother)
602 raise ValueError(error_msg_prefix +
" invalid string " + repr(other) +
".")
604 raise TypeError(error_msg_prefix +
" " + str(type(other)) +
".")
605 except RuntimeError
as err:
606 raise ValueError(error_msg_prefix +
" " + str(type(other))
607 +
" value " + repr(other) +
":"
609 elif isinstance(ixt, index_set):
610 if isinstance(other, numbers.Real):
611 self.
instance = new Clifford((<index_set>ixt).unwrap(), <scalar_t>other)
612 elif isinstance(other, collections.abc.Sequence):
613 self.
instance = new Clifford(list_to_vector(other), (<index_set>ixt).unwrap())
615 raise TypeError(error_msg_prefix +
" (" + str(type(other))
616 +
", " + repr(ixt) +
").")
618 raise TypeError(error_msg_prefix +
" (" + str(type(other))
619 +
", " + str(type(ixt)) +
").")
623 Clean up by deallocating the instance of C++ class Clifford.
631 >>> x=clifford(index_set({-3,4,7})); -3 in x
632 Traceback (most recent call last):
634 TypeError: Not applicable.
636 raise TypeError(
"Not applicable.")
642 >>> for a in clifford(index_set({-3,4,7})):print(a, end=",")
643 Traceback (most recent call last):
645 TypeError: Not applicable.
647 raise TypeError(
"Not applicable.")
651 Put self into a larger frame, containing the union of self.frame() and index set ixt.
652 This can be used to make multiplication faster, by multiplying within a common frame.
654 >>> clifford("2+3{1}").reframe(index_set({1,2,3}))
656 >>> s=index_set({1,2,3});t=index_set({-3,-2,-1});x=random_clifford(s); x.reframe(t).frame() == (s|t);
659 error_msg_prefix =
"Cannot reframe"
660 if isinstance(ixt, index_set):
663 result.instance = new Clifford(self.unwrap(), (<index_set>ixt).unwrap())
664 except RuntimeError
as err:
665 raise ValueError(error_msg_prefix +
" from " + str(self) +
" to frame "
669 raise TypeError(error_msg_prefix +
" using (" + str(type(ixt)) +
").")
674 Compare objects of type clifford.
676 >>> clifford("{1}") == clifford("1{1}")
678 >>> clifford("{1}") != clifford("1.0{1}")
680 >>> clifford("{1}") != clifford("1.0")
682 >>> clifford("{1,2}") == None
684 >>> clifford("{1,2}") != None
686 >>> None == clifford("{1,2}")
688 >>> None != clifford("{1,2}")
692 if (lhs
is None)
or (rhs
is None):
693 return bool(lhs
is rhs)
695 return bool( toClifford(lhs) == toClifford(rhs) )
697 if (lhs
is None)
or (rhs
is None):
698 return not bool(lhs
is rhs)
700 return bool( toClifford(lhs) != toClifford(rhs) )
701 elif isinstance(lhs, clifford)
or isinstance(rhs, clifford):
702 raise TypeError(
"This comparison operator is not implemented for "
703 + str(type(lhs)) +
", " + str(type(rhs)) +
".")
705 return NotImplemented
709 Subscripting: map from index set to scalar coordinate.
711 >>> clifford("{1}")[index_set(1)]
713 >>> clifford("{1}")[index_set({1})]
715 >>> clifford("{1}")[index_set({1,2})]
717 >>> clifford("2{1,2}")[index_set({1,2})]
720 return self.
instance.getitem(toIndexSet(ixt))
726 >>> print(-clifford("{1}"))
735 >>> print(+clifford("{1}"))
744 >>> print(clifford(1) + clifford("{2}"))
746 >>> print(clifford("{1}") + clifford("{2}"))
749 return clifford().wrap( toClifford(lhs) + toClifford(rhs) )
755 >>> x = clifford(1); x += clifford("{2}"); print(x)
758 return self.wrap( self.unwrap() + toClifford(rhs) )
762 Geometric difference.
764 >>> print(clifford(1) - clifford("{2}"))
766 >>> print(clifford("{1}") - clifford("{2}"))
769 return clifford().wrap( toClifford(lhs) - toClifford(rhs) )
773 Geometric difference.
775 >>> x = clifford(1); x -= clifford("{2}"); print(x)
778 return self.wrap( self.unwrap() - toClifford(rhs) )
784 >>> print(clifford("{1}") * clifford("{2}"))
786 >>> print(clifford(2) * clifford("{2}"))
788 >>> print(clifford("{1}") * clifford("{1,2}"))
791 return clifford().wrap( toClifford(lhs) * toClifford(rhs) )
797 >>> x = clifford(2); x *= clifford("{2}"); print(x)
799 >>> x = clifford("{1}"); x *= clifford("{2}"); print(x)
801 >>> x = clifford("{1}"); x *= clifford("{1,2}"); print(x)
804 return self.wrap( self.unwrap() * toClifford(rhs) )
810 >>> print(clifford("{1}") % clifford("{2}"))
812 >>> print(clifford(2) % clifford("{2}"))
814 >>> print(clifford("{1}") % clifford("{1}"))
816 >>> print(clifford("{1}") % clifford("{1,2}"))
819 return clifford().wrap( toClifford(lhs) % toClifford(rhs) )
825 >>> x = clifford("{1}"); x %= clifford("{2}"); print(x)
827 >>> x = clifford(2); x %= clifford("{2}"); print(x)
829 >>> x = clifford("{1}"); x %= clifford("{1}"); print(x)
831 >>> x = clifford("{1}"); x %= clifford("{1,2}"); print(x)
834 return self.wrap( self.unwrap() % toClifford(rhs) )
840 >>> print(clifford("{1}") & clifford("{2}"))
842 >>> print(clifford(2) & clifford("{2}"))
844 >>> print(clifford("{1}") & clifford("{1}"))
846 >>> print(clifford("{1}") & clifford("{1,2}"))
849 return clifford().wrap( toClifford(lhs) & toClifford(rhs) )
855 >>> x = clifford("{1}"); x &= clifford("{2}"); print(x)
857 >>> x = clifford(2); x &= clifford("{2}"); print(x)
859 >>> x = clifford("{1}"); x &= clifford("{1}"); print(x)
861 >>> x = clifford("{1}"); x &= clifford("{1,2}"); print(x)
864 return self.wrap( self.unwrap() & toClifford(rhs) )
870 >>> print(clifford("{1}") ^ clifford("{2}"))
872 >>> print(clifford(2) ^ clifford("{2}"))
874 >>> print(clifford("{1}") ^ clifford("{1}"))
876 >>> print(clifford("{1}") ^ clifford("{1,2}"))
879 return clifford().wrap( toClifford(lhs) ^ toClifford(rhs) )
885 >>> x = clifford("{1}"); x ^= clifford("{2}"); print(x)
887 >>> x = clifford(2); x ^= clifford("{2}"); print(x)
889 >>> x = clifford("{1}"); x ^= clifford("{1}"); print(x)
891 >>> x = clifford("{1}"); x ^= clifford("{1,2}"); print(x)
894 return self.wrap( self.unwrap() ^ toClifford(rhs) )
900 >>> print(clifford("{1}") / clifford("{2}"))
902 >>> print(clifford(2) / clifford("{2}"))
904 >>> print(clifford("{1}") / clifford("{1}"))
906 >>> print(clifford("{1}") / clifford("{1,2}"))
909 return clifford().wrap( toClifford(lhs) / toClifford(rhs) )
915 >>> x = clifford("{1}"); x /= clifford("{2}"); print(x)
917 >>> x = clifford(2); x /= clifford("{2}"); print(x)
919 >>> x = clifford("{1}"); x /= clifford("{1}"); print(x)
921 >>> x = clifford("{1}"); x /= clifford("{1,2}"); print(x)
924 return self.wrap( self.unwrap() / toClifford(rhs) )
928 Geometric multiplicative inverse.
930 >>> x = clifford("{1}"); print(x.inv())
932 >>> x = clifford(2); print(x.inv())
934 >>> x = clifford("{1,2}"); print(x.inv())
941 Transform left hand side, using right hand side as a transformation.
943 >>> x=clifford("{1,2}") * pi/2; y=clifford("{1}"); print(y|x)
945 >>> x=clifford("{1,2}") * pi/2; y=clifford("{1}"); print(y|exp(x))
948 return clifford().wrap( toClifford(lhs) | toClifford(rhs) )
952 Transform left hand side, using right hand side as a transformation.
954 >>> x=clifford("{1,2}") * pi/2; y=clifford("{1}"); y|=x; print(y)
956 >>> x=clifford("{1,2}") * pi/2; y=clifford("{1}"); y|=exp(x); print(y)
959 return self.wrap( self.unwrap() | toClifford(rhs) )
963 Power: self to the m.
965 >>> x=clifford("{1}"); print(x ** 2)
967 >>> x=clifford("2"); print(x ** 2)
969 >>> x=clifford("2+{1}"); print(x ** 0)
971 >>> x=clifford("2+{1}"); print(x ** 1)
973 >>> x=clifford("2+{1}"); print(x ** 2)
975 >>> i=clifford("{1,2}"); print(exp(pi/2) * (i ** i))
982 Power: self to the m.
984 >>> x=clifford("{1}"); print(x.pow(2))
986 >>> x=clifford("2"); print(x.pow(2))
988 >>> x=clifford("2+{1}"); print(x.pow(0))
990 >>> x=clifford("2+{1}"); print(x.pow(1))
992 >>> x=clifford("2+{1}"); print(x.pow(2))
994 >>> print(clifford("1+{1}+{1,2}").pow(3))
996 >>> i=clifford("{1,2}"); print(exp(pi/2) * i.pow(i))
999 if isinstance(m, numbers.Integral):
1002 return exp(m *
log(self))
1006 Outer product power.
1008 >>> x=clifford("2+{1}"); print(x.outer_pow(0))
1010 >>> x=clifford("2+{1}"); print(x.outer_pow(1))
1012 >>> x=clifford("2+{1}"); print(x.outer_pow(2))
1014 >>> print(clifford("1+{1}+{1,2}").outer_pow(3))
1022 Pure grade-vector part.
1024 >>> print(clifford("{1}")(1))
1026 >>> print(clifford("{1}")(0))
1028 >>> print(clifford("1+{1}+{1,2}")(0))
1030 >>> print(clifford("1+{1}+{1,2}")(1))
1032 >>> print(clifford("1+{1}+{1,2}")(2))
1034 >>> print(clifford("1+{1}+{1,2}")(3))
1043 >>> clifford("1+{1}+{1,2}").scalar()
1045 >>> clifford("{1,2}").scalar()
1054 >>> print(clifford("1+{1}+{1,2}").pure())
1056 >>> print(clifford("{1,2}").pure())
1063 Even part of multivector, sum of even grade terms.
1065 >>> print(clifford("1+{1}+{1,2}").even())
1072 Odd part of multivector, sum of odd grade terms.
1074 >>> print(clifford("1+{1}+{1,2}").odd())
1081 Vector part of multivector, as a Python list, with respect to frm.
1083 >>> print(clifford("1+2{1}+3{2}+4{1,2}").vector_part())
1085 >>> print(clifford("1+2{1}+3{2}+4{1,2}").vector_part(index_set({-1,1,2})))
1088 error_msg_prefix =
"Cannot take vector part of "
1089 cdef vector[scalar_t] vec
1102 except RuntimeError
as err:
1103 raise ValueError(error_msg_prefix + str(self) +
" using invalid "
1104 + repr(frm) +
" as frame:\n\t"
1109 Main involution, each {i} is replaced by -{i} in each term,
1110 eg. clifford("{1}") -> -clifford("{1}").
1112 >>> print(clifford("{1}").involute())
1114 >>> print((clifford("{2}") * clifford("{1}")).involute())
1116 >>> print((clifford("{1}") * clifford("{2}")).involute())
1118 >>> print(clifford("1+{1}+{1,2}").involute())
1125 Reversion, eg. clifford("{1}")*clifford("{2}") -> clifford("{2}")*clifford("{1}").
1127 >>> print(clifford("{1}").reverse())
1129 >>> print((clifford("{2}") * clifford("{1}")).reverse())
1131 >>> print((clifford("{1}") * clifford("{2}")).reverse())
1133 >>> print(clifford("1+{1}+{1,2}").reverse())
1140 Conjugation, reverse o involute == involute o reverse.
1142 >>> print((clifford("{1}")).conj())
1144 >>> print((clifford("{2}") * clifford("{1}")).conj())
1146 >>> print((clifford("{1}") * clifford("{2}")).conj())
1148 >>> print(clifford("1+{1}+{1,2}").conj())
1155 Quadratic form == (rev(x)*x)(0).
1157 >>> print(clifford("1+{1}+{1,2}").quad())
1159 >>> print(clifford("1+{-1}+{1,2}+{1,2,3}").quad())
1166 Norm == sum of squares of coordinates.
1168 >>> clifford("1+{1}+{1,2}").norm()
1170 >>> clifford("1+{-1}+{1,2}+{1,2,3}").norm()
1177 Absolute value: square root of norm.
1179 >>> clifford("1+{-1}+{1,2}+{1,2,3}").abs()
1186 Maximum of absolute values of components of multivector: multivector infinity norm.
1188 >>> clifford("1+{-1}+{1,2}+{1,2,3}").max_abs()
1190 >>> clifford("3+2{1}+{1,2}").max_abs()
1197 Remove all terms of self with relative size smaller than limit.
1199 >>> clifford("1e8+{1}+1e-8{1,2}").truncated(1.0e-6)
1200 clifford("100000000")
1201 >>> clifford("1e4+{1}+1e-4{1,2}").truncated(1.0e-6)
1202 clifford("10000+{1}")
1208 Check if a multivector contains any IEEE NaN values.
1210 >>> clifford().isnan()
1217 Subalgebra generated by all generators of terms of given multivector.
1219 >>> print(clifford("1+3{-1}+2{1,2}+4{-2,7}").frame())
1221 >>> s=clifford("1+3{-1}+2{1,2}+4{-2,7}").frame(); type(s)
1222 <class 'PyClical.index_set'>
1228 The “official” string representation of self.
1230 >>> clifford("1+3{-1}+2{1,2}+4{-2,7}").__repr__()
1231 'clifford("1+3{-1}+2{1,2}+4{-2,7}")'
1237 The “informal” string representation of self.
1239 >>> clifford("1+3{-1}+2{1,2}+4{-2,7}").__str__()
1240 '1+3{-1}+2{1,2}+4{-2,7}'
1246 Tests for functions that Doctest cannot see.
1248 For clifford.__cinit__: Construct an object of type clifford.
1250 >>> print(clifford(2))
1252 >>> print(clifford(2.0))
1254 >>> print(clifford(1.0e-1))
1256 >>> print(clifford("2"))
1258 >>> print(clifford("2{1,2,3}"))
1260 >>> print(clifford(clifford("2{1,2,3}")))
1262 >>> print(clifford("-{1}"))
1264 >>> print(clifford(2,index_set({1,2})))
1266 >>> print(clifford([2,3],index_set({1,2})))
1268 >>> print(clifford([1,2]))
1269 Traceback (most recent call last):
1271 TypeError: Cannot initialize clifford object from <class 'list'>.
1272 >>> print(clifford(None))
1273 Traceback (most recent call last):
1275 TypeError: Cannot initialize clifford object from <class 'NoneType'>.
1276 >>> print(clifford(None,[1,2]))
1277 Traceback (most recent call last):
1279 TypeError: Cannot initialize clifford object from (<class 'NoneType'>, <class 'list'>).
1280 >>> print(clifford([1,2],[1,2]))
1281 Traceback (most recent call last):
1283 TypeError: Cannot initialize clifford object from (<class 'list'>, <class 'list'>).
1284 >>> print(clifford(""))
1285 Traceback (most recent call last):
1287 ValueError: Cannot initialize clifford object from invalid string ''.
1288 >>> print(clifford("{"))
1289 Traceback (most recent call last):
1291 ValueError: Cannot initialize clifford object from invalid string '{'.
1292 >>> print(clifford("{1"))
1293 Traceback (most recent call last):
1295 ValueError: Cannot initialize clifford object from invalid string '{1'.
1296 >>> print(clifford("+"))
1297 Traceback (most recent call last):
1299 ValueError: Cannot initialize clifford object from invalid string '+'.
1300 >>> print(clifford("-"))
1301 Traceback (most recent call last):
1303 ValueError: Cannot initialize clifford object from invalid string '-'.
1304 >>> print(clifford("{1}+"))
1305 Traceback (most recent call last):
1307 ValueError: Cannot initialize clifford object from invalid string '{1}+'.
1309 For clifford.__richcmp__: Compare objects of type clifford.
1311 >>> clifford("{1}") == clifford("1{1}")
1313 >>> clifford("{1}") != clifford("1.0{1}")
1315 >>> clifford("{1}") != clifford("1.0")
1317 >>> clifford("{1,2}") == None
1319 >>> clifford("{1,2}") != None
1321 >>> None == clifford("{1,2}")
1323 >>> None != clifford("{1,2}")
1328 cpdef inline
inv(obj):
1330 Geometric multiplicative inverse.
1332 >>> print(inv(clifford("{1}")))
1334 >>> print(inv(clifford("{-1}")))
1336 >>> print(inv(clifford("{-2,-1}")))
1338 >>> print(inv(clifford("{-1}+{1}")))
1341 return clifford(obj).
inv()
1343 cpdef inline
scalar(obj):
1347 >>> scalar(clifford("1+{1}+{1,2}"))
1349 >>> scalar(clifford("{1,2}"))
1352 return clifford(obj).
scalar()
1354 cpdef inline
real(obj):
1356 Real part: synonym for scalar part.
1358 >>> real(clifford("1+{1}+{1,2}"))
1360 >>> real(clifford("{1,2}"))
1363 return clifford(obj).
scalar()
1365 cpdef inline
imag(obj):
1367 Imaginary part: deprecated (always 0).
1369 >>> imag(clifford("1+{1}+{1,2}"))
1371 >>> imag(clifford("{1,2}"))
1376 cpdef inline
pure(obj):
1380 >>> print(pure(clifford("1+{1}+{1,2}")))
1382 >>> print(pure(clifford("{1,2}")))
1385 return clifford(obj).
pure()
1387 cpdef inline
even(obj):
1389 Even part of multivector, sum of even grade terms.
1391 >>> print(even(clifford("1+{1}+{1,2}")))
1394 return clifford(obj).
even()
1396 cpdef inline
odd(obj):
1398 Odd part of multivector, sum of odd grade terms.
1400 >>> print(odd(clifford("1+{1}+{1,2}")))
1403 return clifford(obj).
odd()
1407 Main involution, each {i} is replaced by -{i} in each term, eg. {1}*{2} -> (-{2})*(-{1})
1409 >>> print(involute(clifford("{1}")))
1411 >>> print(involute(clifford("{2}") * clifford("{1}")))
1413 >>> print(involute(clifford("{1}") * clifford("{2}")))
1415 >>> print(involute(clifford("1+{1}+{1,2}")))
1422 Reversion, eg. {1}*{2} -> {2}*{1}
1424 >>> print(reverse(clifford("{1}")))
1426 >>> print(reverse(clifford("{2}") * clifford("{1}")))
1428 >>> print(reverse(clifford("{1}") * clifford("{2}")))
1430 >>> print(reverse(clifford("1+{1}+{1,2}")))
1433 return clifford(obj).
reverse()
1435 cpdef inline
conj(obj):
1437 Conjugation, reverse o involute == involute o reverse.
1439 >>> print(conj(clifford("{1}")))
1441 >>> print(conj(clifford("{2}") * clifford("{1}")))
1443 >>> print(conj(clifford("{1}") * clifford("{2}")))
1445 >>> print(conj(clifford("1+{1}+{1,2}")))
1448 return clifford(obj).
conj()
1450 cpdef inline
quad(obj):
1452 Quadratic form == (rev(x)*x)(0).
1454 >>> print(quad(clifford("1+{1}+{1,2}")))
1456 >>> print(quad(clifford("1+{-1}+{1,2}+{1,2,3}")))
1459 return clifford(obj).
quad()
1461 cpdef inline
norm(obj):
1463 norm == sum of squares of coordinates.
1465 >>> norm(clifford("1+{1}+{1,2}"))
1467 >>> norm(clifford("1+{-1}+{1,2}+{1,2,3}"))
1470 return clifford(obj).
norm()
1472 cpdef inline
abs(obj):
1474 Absolute value of multivector: multivector 2-norm.
1476 >>> abs(clifford("1+{-1}+{1,2}+{1,2,3}"))
1483 Maximum absolute value of coordinates multivector: multivector infinity-norm.
1485 >>> max_abs(clifford("1+{-1}+{1,2}+{1,2,3}"))
1487 >>> max_abs(clifford("3+2{1}+{1,2}"))
1493 cpdef inline
pow(obj, m):
1495 Integer power of multivector: obj to the m.
1497 >>> x=clifford("{1}"); print(pow(x,2))
1499 >>> x=clifford("2"); print(pow(x,2))
1501 >>> x=clifford("2+{1}"); print(pow(x,0))
1503 >>> x=clifford("2+{1}"); print(pow(x,1))
1505 >>> x=clifford("2+{1}"); print(pow(x,2))
1507 >>> print(pow(clifford("1+{1}+{1,2}"),3))
1509 >>> i=clifford("{1,2}"); print(exp(pi/2) * pow(i, i))
1515 return clifford(obj).
pow(m)
1519 Outer product power of multivector.
1521 >>> print(outer_pow(clifford("1+{1}+{1,2}"),3))
1528 Square root of -1 which commutes with all members of the frame of the given multivector.
1530 >>> print(complexifier(clifford(index_set({1}))))
1532 >>> print(complexifier(clifford(index_set({-1}))))
1534 >>> print(complexifier(index_set({1})))
1536 >>> print(complexifier(index_set({-1})))
1543 Square root of multivector with optional complexifier.
1547 >>> print(sqrt(clifford("2{-1}")))
1549 >>> j=sqrt(-1,complexifier(index_set({1}))); print(j); print(j*j)
1552 >>> j=sqrt(-1,"{1,2,3}"); print(j); print(j*j)
1560 return math.sqrt(obj)
1564 cpdef inline
exp(obj):
1566 Exponential of multivector.
1568 >>> x=clifford("{1,2}") * pi/4; print(exp(x))
1570 >>> x=clifford("{1,2}") * pi/2; print(exp(x))
1574 return math.exp(obj)
1578 cpdef inline
log(obj,i =
None):
1580 Natural logarithm of multivector with optional complexifier.
1582 >>> x=clifford("{-1}"); print((log(x,"{-1}") * 2/pi))
1584 >>> x=clifford("{1,2}"); print((log(x,"{1,2,3}") * 2/pi))
1586 >>> x=clifford("{1,2}"); print((log(x) * 2/pi))
1588 >>> x=clifford("{1,2}"); print((log(x,"{1,2}") * 2/pi))
1589 Traceback (most recent call last):
1591 RuntimeError: check_complex(val, i): i is not a valid complexifier for val
1597 return math.log(obj)
1601 cpdef inline
cos(obj,i =
None):
1603 Cosine of multivector with optional complexifier.
1605 >>> x=clifford("{1,2}"); print(cos(acos(x),"{1,2,3}"))
1607 >>> x=clifford("{1,2}"); print(cos(acos(x)))
1614 return math.cos(obj)
1618 cpdef inline
acos(obj,i =
None):
1620 Inverse cosine of multivector with optional complexifier.
1622 >>> x=clifford("{1,2}"); print(cos(acos(x),"{1,2,3}"))
1624 >>> x=clifford("{1,2}"); print(cos(acos(x),"{-1,1,2,3,4}"))
1626 >>> print(acos(0) / pi)
1628 >>> x=clifford("{1,2}"); print(cos(acos(x)))
1635 return math.acos(obj)
1639 cpdef inline
cosh(obj):
1641 Hyperbolic cosine of multivector.
1643 >>> x=clifford("{1,2}") * pi; print(cosh(x))
1645 >>> x=clifford("{1,2,3}"); print(cosh(acosh(x)))
1647 >>> x=clifford("{1,2}"); print(cosh(acosh(x)))
1651 return math.cosh(obj)
1655 cpdef inline
acosh(obj,i =
None):
1657 Inverse hyperbolic cosine of multivector with optional complexifier.
1659 >>> print(acosh(0,"{-2,-1,1}"))
1661 >>> x=clifford("{1,2,3}"); print(cosh(acosh(x,"{-1,1,2,3,4}")))
1665 >>> x=clifford("{1,2,3}"); print(cosh(acosh(x)))
1667 >>> x=clifford("{1,2}"); print(cosh(acosh(x)))
1674 return math.acosh(obj)
1678 cpdef inline
sin(obj,i =
None):
1680 Sine of multivector with optional complexifier.
1682 >>> s="{-1}"; x=clifford(s); print(asin(sin(x,s),s))
1684 >>> s="{-1}"; x=clifford(s); print(asin(sin(x,s),"{-2,-1,1}"))
1686 >>> x=clifford("{1,2,3}"); print(asin(sin(x)))
1693 return math.sin(obj)
1697 cpdef inline
asin(obj,i =
None):
1699 Inverse sine of multivector with optional complexifier.
1701 >>> s="{-1}"; x=clifford(s); print(asin(sin(x,s),s))
1703 >>> s="{-1}"; x=clifford(s); print(asin(sin(x,s),"{-2,-1,1}"))
1705 >>> print(asin(1) / pi)
1707 >>> x=clifford("{1,2,3}"); print(asin(sin(x)))
1714 return math.asin(obj)
1718 cpdef inline
sinh(obj):
1720 Hyperbolic sine of multivector.
1722 >>> x=clifford("{1,2}") * pi/2; print(sinh(x))
1724 >>> x=clifford("{1,2}") * pi/6; print(sinh(x))
1728 return math.sinh(obj)
1732 cpdef inline
asinh(obj,i =
None):
1734 Inverse hyperbolic sine of multivector with optional complexifier.
1736 >>> x=clifford("{1,2}"); print(asinh(x,"{1,2,3}") * 2/pi)
1738 >>> x=clifford("{1,2}"); print(asinh(x) * 2/pi)
1740 >>> x=clifford("{1,2}") / 2; print(asinh(x) * 6/pi)
1747 return math.asinh(obj)
1751 cpdef inline
tan(obj,i =
None):
1753 Tangent of multivector with optional complexifier.
1755 >>> x=clifford("{1,2}"); print(tan(x,"{1,2,3}"))
1757 >>> x=clifford("{1,2}"); print(tan(x))
1764 return math.tan(obj)
1768 cpdef inline
atan(obj,i =
None):
1770 Inverse tangent of multivector with optional complexifier.
1772 >>> s=index_set({1,2,3}); x=clifford("{1}"); print(tan(atan(x,s),s))
1774 >>> x=clifford("{1}"); print(tan(atan(x)))
1781 return math.atan(obj)
1785 cpdef inline
tanh(obj):
1787 Hyperbolic tangent of multivector.
1789 >>> x=clifford("{1,2}") * pi/4; print(tanh(x))
1793 return math.tanh(obj)
1797 cpdef inline
atanh(obj,i =
None):
1799 Inverse hyperbolic tangent of multivector with optional complexifier.
1801 >>> s=index_set({1,2,3}); x=clifford("{1,2}"); print(tanh(atanh(x,s)))
1803 >>> x=clifford("{1,2}"); print(tanh(atanh(x)))
1810 return math.atanh(obj)
1814 cpdef inline random_clifford(index_set ixt, fill = 1.0):
1816 Random multivector within a frame.
1818 >>> print(random_clifford(index_set({-3,-1,2})).frame())
1821 return clifford().wrap(
clifford().instance.random(ixt.unwrap(), <scalar_t>fill) )
1823 cpdef inline
cga3(obj):
1825 Convert Euclidean 3D multivector to Conformal Geometric Algebra using Doran and Lasenby definition.
1827 >>> x=clifford("2{1}+9{2}+{3}"); print(cga3(x))
1828 87{-1}+4{1}+18{2}+2{3}+85{4}
1830 return clifford().wrap( glucat.cga3(toClifford(obj)) )
1834 Convert CGA3 null vector to standard conformal null vector using Doran and Lasenby definition.
1836 >>> x=clifford("2{1}+9{2}+{3}"); print(cga3std(cga3(x)))
1837 87{-1}+4{1}+18{2}+2{3}+85{4}
1838 >>> x=clifford("2{1}+9{2}+{3}"); print(cga3std(cga3(x))-cga3(x))
1841 return clifford().wrap( glucat.cga3std(toClifford(obj)) )
1843 cpdef inline
agc3(obj):
1845 Convert CGA3 null vector to Euclidean 3D vector using Doran and Lasenby definition.
1847 >>> x=clifford("2{1}+9{2}+{3}"); print(agc3(cga3(x)))
1849 >>> x=clifford("2{1}+9{2}+{3}"); print(agc3(cga3(x))-x)
1852 return clifford().wrap( glucat.agc3(toClifford(obj)) )
1855 scalar_epsilon = epsilon
1862 Abbreviation for clifford.
1868 >>> print(cl(5.0e-1))
1872 >>> print(cl("2{1,2,3}"))
1874 >>> print(cl(cl("2{1,2,3}")))
1880 Abbreviation for index_set.
1882 >>> print(ist("{1,2,3}"))
1888 Abbreviation for clifford(index_set(obj)).
1901 Abbreviation for index_set({-q,...p}).
1903 >>> print(istpq(2,3))
1913 import PyClical, doctest
1914 return doctest.testmod(PyClical)
1916 if __name__ ==
"__main__":
def __contains__(self, idx)
const Multivector< Scalar_T, LO, HI > inv(const Multivector< Scalar_T, LO, HI > &val)
Geometric multiplicative inverse.
const Multivector< Scalar_T, LO, HI > acos(const Multivector< Scalar_T, LO, HI > &val)
Inverse cosine of multivector.
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.
index_t min_neg(const index_set< LO, HI > &ist)
Minimum negative index, or 0 if none.
def clifford_hidden_doctests()
def __pow__(self, m, dummy)
String clifford_to_repr(const Multivector_T &mv)
The “official” string representation of Multivector_T mv.
const Multivector< Scalar_T, LO, HI > atan(const Multivector< Scalar_T, LO, HI > &val)
Inverse tangent of multivector.
def __call__(self, grade)
Scalar_T scalar(const Multivector< Scalar_T, LO, HI > &val)
Scalar part.
def sign_of_mult(self, rhs)
def __richcmp__(lhs, rhs, int, op)
def __cinit__(self, other=0)
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 truncated(self, limit)
const Multivector< Scalar_T, LO, HI > sin(const Multivector< Scalar_T, LO, HI > &val)
Sine of multivector.
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.
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 > involute(const Multivector< Scalar_T, LO, HI > &val)
Main involution, each {i} is replaced by -{i} in each term, eg. {1}*{2} -> (-{2})*(-{1})
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.
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.
Scalar_T real(const Multivector< Scalar_T, LO, HI > &val)
Real part: synonym for scalar part.
def __contains__(self, x)
def __setitem__(self, idx, val)
def __cinit__(self, other=0, ixt=None)
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.
Definitions for 3D Conformal Geometric Algebra [DL].
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.
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.
const Multivector< Scalar_T, LO, HI > even(const Multivector< Scalar_T, LO, HI > &val)
Even part.
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 > pure(const Multivector< Scalar_T, LO, HI > &val)
Pure part.
const Multivector< Scalar_T, LO, HI > cosh(const Multivector< Scalar_T, LO, HI > &val)
Hyperbolic cosine of multivector.
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.
Multivector_T cga3std(const Multivector_T &X)
Convert CGA3 null vector to standard Conformal Geometric Algebra null vector [DL (10....
const Multivector< Scalar_T, LO, HI > sinh(const Multivector< Scalar_T, LO, HI > &val)
Hyperbolic sine of multivector.
const matrix_multi< Scalar_T, LO, HI > exp(const matrix_multi< Scalar_T, LO, HI > &val)
Exponential of multivector.
def __getitem__(self, idx)
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}
Scalar_T abs(const Multivector< Scalar_T, LO, HI > &val)
Absolute value == sqrt(norm)
const Multivector< Scalar_T, LO, HI > asinh(const Multivector< Scalar_T, LO, HI > &val)
Inverse hyperbolic sine of multivector.
def __getitem__(self, ixt)
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.
def vector_part(self, frm=None)
Scalar_T norm(const Multivector< Scalar_T, LO, HI > &val)
Scalar_T norm == sum of norm of coordinates.
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.
Scalar_T quad(const Multivector< Scalar_T, LO, HI > &val)
Scalar_T quadratic form == (rev(x)*x)(0)
const Multivector< Scalar_T, LO, HI > odd(const Multivector< Scalar_T, LO, HI > &val)
Odd part.
String clifford_to_str(const Multivector_T &mv)
The "informal" string representation of Multivector_T mv.
def index_set_hidden_doctests()
const Multivector< Scalar_T, LO, HI > conj(const Multivector< Scalar_T, LO, HI > &val)
Conjugation, rev o invo == invo o rev.
String index_set_to_repr(const Index_Set_T &ist)
The “official” string representation of Index_Set_T ist.
Multivector_T agc3(const Multivector_T &X)
Convert CGA3 null vector to Euclidean 3D vector [DL (10.50)].
const Multivector< Scalar_T, LO, HI > acosh(const Multivector< Scalar_T, LO, HI > &val)
Inverse hyperbolic cosine of multivector.
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 > tan(const Multivector< Scalar_T, LO, HI > &val)
Tangent of multivector.
const Multivector< Scalar_T, LO, HI > asin(const Multivector< Scalar_T, LO, HI > &val)
Inverse sine of multivector.
const Multivector< Scalar_T, LO, HI > pow(const Multivector< Scalar_T, LO, HI > &lhs, int rhs)
Integer 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.
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.
def __truediv__(lhs, rhs)
const Multivector< Scalar_T, LO, HI > reverse(const Multivector< Scalar_T, LO, HI > &val)
Reversion, eg. {1}*{2} -> {2}*{1}.
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 framed_multi< Scalar_T, LO, HI > exp(const framed_multi< Scalar_T, LO, HI > &val)
Exponential of multivector.
Scalar_T imag(const Multivector< Scalar_T, LO, HI > &val)
Imaginary part: deprecated (always 0)
const Multivector< Scalar_T, LO, HI > tanh(const Multivector< Scalar_T, LO, HI > &val)
Hyperbolic tangent of multivector.
const Multivector< Scalar_T, LO, HI > outer_pow(const Multivector< Scalar_T, LO, HI > &lhs, int rhs)
Outer product power of multivector.
def __richcmp__(lhs, rhs, int, op)