- 21, Oct 2024
- #1
Базисные векторы геометрической алгебры:
$$(e_0=1), e_1, e_2,\dots,e_n$$
Все они квадратичны к 1 (мы не рассматриваем векторы, квадратичные к -1 или нулю)
$$e_i \cdot e_i = 1$$
Они ассоциативны и антикоммутативны (кроме \$e_0=1\$, который ассоциативен и коммутативный)
$$e_i \cdot e_j =-e_j \cdot e_i \: \; (i\neq j); \;и\; я,j > 0$$
Например, этот продукт упрощен до
$$e_1 \cdot e_3 \cdot e_3 \cdot e_5\cdot e_4 \cdot e_5 \\
= e_1 \cdot (e_3 \cdot e_3) \cdot (e_5\cdot e_4) \cdot e_5 \\
= e_1 \cdot (1) \cdot (-e_4\cdot e_5) \cdot e_5 \\
= e_1 \cdot (-e_4) \cdot (e_5 \cdot e_5) \\ = e_1 \cdot (-e_4) \cdot (1) \\
= - e_1 \cdot e_4$$
(обратите внимание, что упрощенный продукт сортируется по индексу \$e\$)
Испытание
Если произведение базисных векторов представлено целым числом со знаком, где каждый бит равен 1, если вектор присутствует, или 0, если вектор отсутствует. $$\begin{выравнивание}
0101011 & = e_0 \cdot e_1 \cdot e_3 \cdot e_5 \\ & = e_0^1 \cdot e_1^1 \cdot e_2^0 \cdot e_3^1 \cdot e_4^0 \cdot e_5^1 \cdot e_6^0 \\ -0101011 & = -e_0 \cdot e_1 \cdot e_3 \cdot e_5
\end{align}$$
Учитывая два целых числа со знаком \$a\$, \$b\$ (вы можете выбрать числовую кодировку для отрицательных значений), выведите произведение \$c= a \:. б\$
Входные данные представляют собой только 2 целых числа со знаком. Есть много
способы кодирования целых чисел со знаком
. Вы можете выбрать кого угодно, но входные данные — только две переменные.
Обратите внимание, что \$| с |= |а|\; исключающее ИЛИ \; |b|\$ , но самое сложное — найти знак.
Если язык не позволяет целочисленному типу кодировать нули со знаком (\$-00000\$), код должен возвращать \$-00001\$ (поскольку \$-e_0^0=-e_0^1=-1\ $)
Поскольку \$x=e_0 \cdot x=x \cdot e_0\$, то \$x=x \;OR\; 1\$, поэтому одинаково допустимо возвращать 0 или 1 для \$e_0\$
Вам следует рассчитать как минимум 4 базисных вектора \$e_0=1, e_1, e_2, e_3\$
Вот генератор таблицы умножения
(для проверки правильных ответов), который также предлагает код на C++, C#, Python и Rust (на веб-странице необходимо вручную указать, сколько векторов соответствует 1, -1 и 0. Вы можете установить 3 (или более) положительных, 0 отрицательный и 0 Ноль)
Вот
Код Rosetta на многих языках
по геометрической алгебре
Пример:
учитывая а, б:$$a=e_1 \cdot e_2=00110$$
"""3D Projective Geometric Algebra.
Written by a generator written by enki.
"""
__author__ = 'Enki'
import math
class R300:
def __init__(self, value=0, index=0):
"""Initiate a new R300.
Optional, the component index can be set with value.
"""
self.mvec = [0] * 8
self._base = ["1", "e1", "e2", "e3", "e12", "e13", "e23", "e123"]
#self._base = ["0001", "0010", "0100", "1000", "0110", "1010", "1100", "1110"]
if (value != 0):
self.mvec[index] = value
@classmethod
def fromarray(cls, array):
"""Initiate a new R300 from an array-like object.
The first axis of the array is assumed to correspond to the elements
of the algebra, and needs to have the same length. Any other dimensions
are left unchanged, and should have simple operations such as addition
and multiplication defined. NumPy arrays are therefore a perfect
candidate.
:param array: array-like object whose length is the dimension of the algebra.
:return: new instance of R300.
"""
self = cls()
if len(array) != len(self):
raise TypeError('length of array must be identical to the dimension '
'of the algebra.')
self.mvec = array
return self
def __str__(self):
if isinstance(self.mvec, list):
res = ' + '.join(filter(None, [("%.7f" % x).rstrip("0").rstrip(".") + (["",self._base[i]][i > 0]) if abs(x) > 0.000001 else None for i,x in enumerate(self)]))
#res = ' + '.join([x for i,x in enumerate(self)])
else: # Assume array-like, redirect str conversion
res = str(self.mvec)
if (res == ''):
return "0"
return res
def __getitem__(self, key):
return self.mvec[key]
def __setitem__(self, key, value):
self.mvec[key] = value
def __len__(self):
return len(self.mvec)
def __invert__(a):
"""R300.Reverse
Reverse the order of the basis blades.
"""
res = a.mvec.copy()
res[0] = a[0]
res[1] = a[1]
res[2] = a[2]
res[3] = a[3]
res[4] = -a[4]
res[5] = -a[5]
res[6] = -a[6]
res[7] = -a[7]
return R300.fromarray(res)
def Dual(a):
"""R300.Dual
Poincare duality operator.
"""
res = a.mvec.copy()
res[0] = -a[7]
res[1] = -a[6]
res[2] = a[5]
res[3] = -a[4]
res[4] = a[3]
res[5] = -a[2]
res[6] = a[1]
res[7] = a[0]
return R300.fromarray(res)
def Conjugate(a):
"""R300.Conjugate
Clifford Conjugation
"""
res = a.mvec.copy()
res[0] = a[0]
res[1] = -a[1]
res[2] = -a[2]
res[3] = -a[3]
res[4] = -a[4]
res[5] = -a[5]
res[6] = -a[6]
res[7] = a[7]
return R300.fromarray(res)
def Involute(a):
"""R300.Involute
Main involution
"""
res = a.mvec.copy()
res[0] = a[0]
res[1] = -a[1]
res[2] = -a[2]
res[3] = -a[3]
res[4] = a[4]
res[5] = a[5]
res[6] = a[6]
res[7] = -a[7]
return R300.fromarray(res)
def __mul__(a,b):
"""R300.Mul
The geometric product.
"""
if type(b) in (int, float):
return a.muls(b)
res = a.mvec.copy()
res[0] = b[0] * a[0] + b[1] * a[1] + b[2] * a[2] + b[3] * a[3] - b[4] * a[4] - b[5] * a[5] - b[6] * a[6] - b[7] * a[7]
res[1] = b[1] * a[0] + b[0] * a[1] - b[4] * a[2] - b[5] * a[3] + b[2] * a[4] + b[3] * a[5] - b[7] * a[6] - b[6] * a[7]
res[2] = b[2] * a[0] + b[4] * a[1] + b[0] * a[2] - b[6] * a[3] - b[1] * a[4] + b[7] * a[5] + b[3] * a[6] + b[5] * a[7]
res[3] = b[3] * a[0] + b[5] * a[1] + b[6] * a[2] + b[0] * a[3] - b[7] * a[4] - b[1] * a[5] - b[2] * a[6] - b[4] * a[7]
res[4] = b[4] * a[0] + b[2] * a[1] - b[1] * a[2] + b[7] * a[3] + b[0] * a[4] - b[6] * a[5] + b[5] * a[6] + b[3] * a[7]
res[5] = b[5] * a[0] + b[3] * a[1] - b[7] * a[2] - b[1] * a[3] + b[6] * a[4] + b[0] * a[5] - b[4] * a[6] - b[2] * a[7]
res[6] = b[6] * a[0] + b[7] * a[1] + b[3] * a[2] - b[2] * a[3] - b[5] * a[4] + b[4] * a[5] + b[0] * a[6] + b[1] * a[7]
res[7] = b[7] * a[0] + b[6] * a[1] - b[5] * a[2] + b[4] * a[3] + b[3] * a[4] - b[2] * a[5] + b[1] * a[6] + b[0] * a[7]
return R300.fromarray(res)
__rmul__ = __mul__
def __xor__(a,b):
res = a.mvec.copy()
res[0] = b[0] * a[0]
res[1] = b[1] * a[0] + b[0] * a[1]
res[2] = b[2] * a[0] + b[0] * a[2]
res[3] = b[3] * a[0] + b[0] * a[3]
res[4] = b[4] * a[0] + b[2] * a[1] - b[1] * a[2] + b[0] * a[4]
res[5] = b[5] * a[0] + b[3] * a[1] - b[1] * a[3] + b[0] * a[5]
res[6] = b[6] * a[0] + b[3] * a[2] - b[2] * a[3] + b[0] * a[6]
res[7] = b[7] * a[0] + b[6] * a[1] - b[5] * a[2] + b[4] * a[3] + b[3] * a[4] - b[2] * a[5] + b[1] * a[6] + b[0] * a[7]
return R300.fromarray(res)
def __and__(a,b):
res = a.mvec.copy()
res[7] = 1 * (a[7] * b[7])
res[6] = 1 * (a[6] * b[7] + a[7] * b[6])
res[5] = -1 * (a[5] * -1 * b[7] + a[7] * b[5] * -1)
res[4] = 1 * (a[4] * b[7] + a[7] * b[4])
res[3] = 1 * (a[3] * b[7] + a[5] * -1 * b[6] - a[6] * b[5] * -1 + a[7] * b[3])
res[2] = -1 * (a[2] * -1 * b[7] + a[4] * b[6] - a[6] * b[4] + a[7] * b[2] * -1)
res[1] = 1 * (a[1] * b[7] + a[4] * b[5] * -1 - a[5] * -1 * b[4] + a[7] * b[1])
res[0] = 1 * (a[0] * b[7] + a[1] * b[6] - a[2] * -1 * b[5] * -1 + a[3] * b[4] + a[4] * b[3] - a[5] * -1 * b[2] * -1 + a[6] * b[1] + a[7] * b[0])
return R300.fromarray(res)
def __or__(a,b):
res = a.mvec.copy()
res[0] = b[0] * a[0] + b[1] * a[1] + b[2] * a[2] + b[3] * a[3] - b[4] * a[4] - b[5] * a[5] - b[6] * a[6] - b[7] * a[7]
res[1] = b[1] * a[0] + b[0] * a[1] - b[4] * a[2] - b[5] * a[3] + b[2] * a[4] + b[3] * a[5] - b[7] * a[6] - b[6] * a[7]
res[2] = b[2] * a[0] + b[4] * a[1] + b[0] * a[2] - b[6] * a[3] - b[1] * a[4] + b[7] * a[5] + b[3] * a[6] + b[5] * a[7]
res[3] = b[3] * a[0] + b[5] * a[1] + b[6] * a[2] + b[0] * a[3] - b[7] * a[4] - b[1] * a[5] - b[2] * a[6] - b[4] * a[7]
res[4] = b[4] * a[0] + b[7] * a[3] + b[0] * a[4] + b[3] * a[7]
res[5] = b[5] * a[0] - b[7] * a[2] + b[0] * a[5] - b[2] * a[7]
res[6] = b[6] * a[0] + b[7] * a[1] + b[0] * a[6] + b[1] * a[7]
res[7] = b[7] * a[0] + b[0] * a[7]
return R300.fromarray(res)
def __add__(a,b):
"""R300.Add
Multivector addition
"""
if type(b) in (int, float):
return a.adds(b)
res = a.mvec.copy()
res[0] = a[0] + b[0]
res[1] = a[1] + b[1]
res[2] = a[2] + b[2]
res[3] = a[3] + b[3]
res[4] = a[4] + b[4]
res[5] = a[5] + b[5]
res[6] = a[6] + b[6]
res[7] = a[7] + b[7]
return R300.fromarray(res)
__radd__ = __add__
def __sub__(a,b):
"""R300.Sub
Multivector subtraction
"""
if type(b) in (int, float):
return a.subs(b)
res = a.mvec.copy()
res[0] = a[0] - b[0]
res[1] = a[1] - b[1]
res[2] = a[2] - b[2]
res[3] = a[3] - b[3]
res[4] = a[4] - b[4]
res[5] = a[5] - b[5]
res[6] = a[6] - b[6]
res[7] = a[7] - b[7]
return R300.fromarray(res)
def __rsub__(a,b):
"""R300.Sub
Multivector subtraction
"""
return b + -1 * a
def smul(a,b):
res = a.mvec.copy()
res[0] = a * b[0]
res[1] = a * b[1]
res[2] = a * b[2]
res[3] = a * b[3]
res[4] = a * b[4]
res[5] = a * b[5]
res[6] = a * b[6]
res[7] = a * b[7]
return R300.fromarray(res)
def muls(a,b):
res = a.mvec.copy()
res[0] = a[0] * b
res[1] = a[1] * b
res[2] = a[2] * b
res[3] = a[3] * b
res[4] = a[4] * b
res[5] = a[5] * b
res[6] = a[6] * b
res[7] = a[7] * b
return R300.fromarray(res)
def sadd(a,b):
res = a.mvec.copy()
res[0] = a + b[0]
res[1] = b[1]
res[2] = b[2]
res[3] = b[3]
res[4] = b[4]
res[5] = b[5]
res[6] = b[6]
res[7] = b[7]
return R300.fromarray(res)
def adds(a,b):
res = a.mvec.copy()
res[0] = a[0] + b
res[1] = a[1]
res[2] = a[2]
res[3] = a[3]
res[4] = a[4]
res[5] = a[5]
res[6] = a[6]
res[7] = a[7]
return R300.fromarray(res)
def ssub(a,b):
res = a.mvec.copy()
res[0] = a - b[0]
res[1] = -b[1]
res[2] = -b[2]
res[3] = -b[3]
res[4] = -b[4]
res[5] = -b[5]
res[6] = -b[6]
res[7] = -b[7]
return R300.fromarray(res)
def subs(a,b):
res = a.mvec.copy()
res[0] = a[0] - b
res[1] = a[1]
res[2] = a[2]
res[3] = a[3]
res[4] = a[4]
res[5] = a[5]
res[6] = a[6]
res[7] = a[7]
return R300.fromarray(res)
def norm(a):
return abs((a * a.Conjugate())[0]) ** 0.5
def inorm(a):
return a.Dual().norm()
def normalized(a):
return a * (1 / a.norm())
e1 = R300(1.0, 1)
e2 = R300(1.0, 2)
e3 = R300(1.0, 3)
e12 = R300(1.0, 4)
e13 = R300(1.0, 5)
e23 = R300(1.0, 6)
e123 = R300(1.0, 7)
if __name__ == '__main__':
#print("e1*e1 :", str(e1*e1))
#print("pss :", str(e123))
#print("pss*pss :", str(e123*e123))
a = [R300(1.0, i) for i in range(0, 8) ]
b = [-1 * x for x in a]
a = a + b
print("Vectors:")
[print(str(x)) for x in a ]
print("Products")
def javascriptCode(a,b):
def ArnauldEncoding(x):
answer= str(x)
if answer[0]=="-":
return answer[1:]+"1"
else:
return answer+"0"
return "".join(["console.log(\"0b",ArnauldEncoding(a) , "\",\"*\",\"0b" , ArnauldEncoding(b),"\",\"=\",","f(0b" , ArnauldEncoding(a) , ")(0b" , ArnauldEncoding(b) , ").toString(2), \"== \",\"" , ArnauldEncoding(a * b),"\")"])
def RubyCode(a,b):
return "".join(["[","0b",str(a),",","0b",str(b),"],"]).replace("0b-","-0b")
if True:
Productos = ["".join([str(x),"*",str(y),"=",str(x * y)]) for x in a for y in a]
#Productos = [javascriptCode(x,y) for x in a for y in a]
#Productos = [RubyCode(x,y) for x in a for y in a]
#Productos = [str(x*y) for x in a for y in a]
Origen = ["1e1", "1e2", "1e3", "1e12", "1e13", "1e23", "1e123"]
Destino = ["0010", "0100", "1000", "0110", "1010", "1100", "1110"]
Reemplazo = dict(zip(Origen, Destino))
Binario = Productos
for key in sorted(Reemplazo, key=len, reverse=True): # Through keys sorted by length
Binario = [x.replace(key,Reemplazo[key]) for x in Binario]
[print(x) for x in Binario]
a = a
возможные продукты: