How does an algebraic behave?¶

• Neutral element of addition is 0 or {} ?
• neutral element of multiplication is what?
• what is a unit vector?
In [44]:
from __future__ import print_function
from archery import *
from json import dumps
a = mdict(p=mdict(x=1, y=1, z=1), c = mdict(r=34, g=45, b=1, a=.4))

pp = lambda d : print(dumps(d, indent=4))
pp(a)

{
"p": {
"y": 1,
"x": 1,
"z": 1
},
"c": {
"a": 0.4,
"r": 34,
"b": 1,
"g": 45
}
}

In [45]:
pp(a+{})
pp(a+0)
assert(a+0==a+{})
print(0=={} and "Youpi" or "Humm")

{
"p": {
"y": 1,
"x": 1,
"z": 1
},
"c": {
"a": 0.4,
"r": 34,
"b": 1,
"g": 45
}
}
{
"p": {
"y": 1,
"x": 1,
"z": 1
},
"c": {
"a": 0.4,
"r": 34,
"b": 1,
"g": 45
}
}
Humm

In [46]:
assert(a+{}==a+0==1+a-1)
print("it is true")

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-46-7405f7f5a8d0> in <module>()
----> 1 assert(a+{}==a+0==1+a-1)
2 print("it is true")

AssertionError: 

What happened?¶

In [47]:
pp(1+a-1)

{
"p": {
"y": 1,
"x": 1,
"z": 1
},
"c": {
"a": 0.3999999999999999,
"r": 34,
"b": 1,
"g": 45
}
}


I HATE FLOATS since ana num 101

They introduce non commutative behaviours when symbol leads me to think otherwhise.

In [48]:
pp(a*1)
print("hum")
pp(a*mdict(p=1, c=1))
print("hum "*2)
pp(a*a/a)

{
"p": {
"y": 1,
"x": 1,
"z": 1
},
"c": {
"a": 0.4,
"r": 34,
"b": 1,
"g": 45
}
}
hum
{
"p": {
"y": 1,
"x": 1,
"z": 1
},
"c": {
"a": 0.4,
"r": 34,
"b": 1,
"g": 45
}
}
hum hum
{
"p": {
"y": 1.0,
"x": 1.0,
"z": 1.0
},
"c": {
"a": 0.4000000000000001,
"r": 34.0,
"b": 1.0,
"g": 45.0
}
}

In [49]:
pp(a+a)
assert(a+a == 2*a)
print("it is true")

{
"p": {
"y": 2,
"x": 2,
"z": 2
},
"c": {
"a": 0.8,
"r": 68,
"b": 2,
"g": 90
}
}
it is true


Why are your coordinate so conveniently non null?¶

In [50]:
pp(1/(a-1))

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-50-1626f73473a5> in <module>()
----> 1 pp(1/(a-1))

/usr/home/jul/src/archery/archery/trait.py in __rdiv__(self, other)
90
91     def __rdiv__(self, other):
---> 92         return self.__rtruediv__(other)
93
94     def __truediv__(self, other):

/usr/home/jul/src/archery/archery/trait.py in __rtruediv__(self, other)
123         copy = self.copy()
124         if not isinstance(other, MutableMapping):
--> 125             return copy.__iinv__().__iscalmul__(other)
126         return copy / other
127

/usr/home/jul/src/archery/archery/trait.py in __iinv__(self)
117         """in place inversion 1/a"""
118         for k, v in self.items():
--> 119             self[k] = 1/v
120         return self
121

/usr/home/jul/src/archery/archery/trait.py in __rtruediv__(self, other)
123         copy = self.copy()
124         if not isinstance(other, MutableMapping):
--> 125             return copy.__iinv__().__iscalmul__(other)
126         return copy / other
127

/usr/home/jul/src/archery/archery/trait.py in __iinv__(self)
117         """in place inversion 1/a"""
118         for k, v in self.items():
--> 119             self[k] = 1/v
120         return self
121

ZeroDivisionError: division by zero

BUG!!!¶

Not a bug : a feature. let's see. 1/0 make a division by 0 error. But a float is an implicit 1 dimnesional value like this:

In [51]:
b=mdict(IAmAReal=0.0)
1/b

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-51-7f17207597c8> in <module>()
1 b=mdict(IAmAReal=0.0)
----> 2 1/b

/usr/home/jul/src/archery/archery/trait.py in __rdiv__(self, other)
90
91     def __rdiv__(self, other):
---> 92         return self.__rtruediv__(other)
93
94     def __truediv__(self, other):

/usr/home/jul/src/archery/archery/trait.py in __rtruediv__(self, other)
123         copy = self.copy()
124         if not isinstance(other, MutableMapping):
--> 125             return copy.__iinv__().__iscalmul__(other)
126         return copy / other
127

/usr/home/jul/src/archery/archery/trait.py in __iinv__(self)
117         """in place inversion 1/a"""
118         for k, v in self.items():
--> 119             self[k] = 1/v
120         return self
121

ZeroDivisionError: float division by zero

Can we have an intuition of + / * - in eucledian geometry with this dict?¶

Did we invented stuff that have no meanings here?!

• mult is homothetia

How can we make sense of this?

Given an endomorphism in matrice calculus 0 matrice is 0 on all diagonal 1 is 1 on the all the diagonal and if you work with eigenvalues vector if we work with x, y, z then 1 is:

{ x=1, y=1, z=1}
In [52]:
a+0 == a

Out[52]:
True
In [53]:
a*1 == a

Out[53]:
True
In [54]:
pp(a*mdict(p=1,c=1))
u = mdict(p=mdict(x=1,y=1,z=1), c = mdict(r=1,g=1,b=1, a=1))

assert(a*u==a*1)

{
"p": {
"y": 1,
"x": 1,
"z": 1
},
"c": {
"a": 0.4,
"r": 34,
"b": 1,
"g": 45
}
}

In [55]:
a-a == a + (-1 *a)

Out[55]:
True

Basically we just linked translation to homothetia.

We have : adding a vector of opposite direction to itself result in a null vector

So + is a translation of n in every declared direction

ex let's translate p of 1

In [56]:
a+mdict(p=1)

Out[56]:
{'c': {'a': 0.4, 'b': 1, 'g': 45, 'r': 34}, 'p': {'x': 2, 'y': 2, 'z': 2}}

What does * means?

In [57]:
pp(a*mdict(p=1))

{
"p": {
"y": 1,
"x": 1,
"z": 1
}
}


multiplying by a subpath = 1 is equivalent to get a vector in the sub dimension

We have a pretty intuitional behaviour that match what is known of linear algebra

Of course, I could have implemented other algebra for the fun...

Let's implement "Tanimoto" coefficient cf https://en.wikipedia.org/wiki/Cosine_similarity

$$T(A,B) = \frac{A \cdot B}{\|A\|^2 +\|B\|^2 - A \cdot B}$$
In [43]:
cos_sim = lambda a,b : dot(a,b) / (vabs(a*a) + vabs(b*b) - dot(a,b))
this_theme=mdict(foss=.2, math=1, python=1, perl=1)
python_fosdem=mdict(foss=1, python=2, )
fosdem=mdict(python=1, ruby=1, php=1, perl=1, foss=1, crypto=1)
print(vcos(python_fosdem, fosdem))
print(cos_sim(python_fosdem,fosdem))
print("-"*10)
print(vcos(python_fosdem, this_theme))
print(cos_sim(python_fosdem,this_theme))
print("-"*10)
print(vcos(fosdem, this_theme))
print(cos_sim(fosdem,this_theme))

0.547722557505
0.83972565898
----------
0.564288093647
0.601813386531
----------
0.51512219637
1.10998858246


Is there a trick to algebra-ize non algebric types? ¶

In this case cos will not work we use:

$$\forall (u,v) \in E\times E,\ d(u,v) = \|u-v\|.$$

For the distance

You can thus define - \o/

string levensthein/hamming
sets len(a&b)/len(u or b)
tuple/lists Hamming/levenstehin
int as bits ....
fallback 1 - (self==other)

PS : distance must stay symmetric |a-b| == |b-a|

We may not now what is a+b but we may know |a-b|

Conclusion¶

We may define for every algebraic dict (object?!) a distance as long as equal operator is defined

In [ ]: