Goulib.math2

more math, without numpy

In [1]:
from Goulib.notebook import * #useless here for now
from Goulib.math2 import *

Vectors and Matrices

In [2]:
v1=[1,2,3]
v2=[7,8,9]
dot(v1,v2)
Out[2]:
50
In [3]:
m1=[[1,2,3],[5,6,7],[7,8,9]]
dot(m1,v1)
Out[3]:
[14, 38, 50]
In [4]:
m2=transpose(m1)
dot(m1,m2)
Out[4]:
[[14, 38, 50], [38, 110, 146], [50, 146, 194]]
In [5]:
quad(1,3,2) # solves x^2+3*x+2 = 0
Out[5]:
(-1.0, -2.0)
In [6]:
quad(1,2,3,allow_complex=True) # solves x^2+2*x+3 = 0
Out[6]:
((-1+1.4142135623730951j), (-1-1.4142135623730951j))
In [7]:
# in fact numpy.linalg.matrix_power has a bug for large powers
# https://github.com/numpy/numpy/issues/5166
import numpy as np
print(np.linalg.matrix_power([[1,2],[1,0]],100))

#but Goulib.math2.matrix_power is correct:
print(matrix_power([[1,2],[1,0]],100))
[[-1431655765 -1431655766]
 [ 1431655765  1431655766]]
[[845100400152152934331135470251, 845100400152152934331135470250], [422550200076076467165567735125, 422550200076076467165567735126]]

Integer sequences

see OEIS example with many sequences calculated from math2 functions

In [8]:
fibonacci(int(1E18),1000000007) # 1'000'000'000'000'000'000-th fibonacci number almost instantaneously
Out[8]:
209783453

Number Theory

In [9]:
gcd(163231, 152057, 135749) # gcd of n numbers
Out[9]:
151
In [10]:
#extended GCD
#https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
x,y=158179,1729154
gcd,a,b=xgcd(x,y)
gcd,a,b, a*x+b*y==gcd
Out[10]:
(7, -112399, 10282, True)
In [11]:
primes(10) # n first primes
Out[11]:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
In [12]:
sieve(50) # primes up to n
Out[12]:
[2,
 3,
 5,
 7,
 11,
 13,
 17,
 19,
 23,
 29,
 31,
 37,
 41,
 43,
 47,
 53,
 59,
 61,
 67,
 71,
 73,
 79,
 83,
 89,
 97,
 101,
 103,
 107,
 109,
 113,
 127,
 131,
 137,
 139,
 149,
 151,
 157,
 163,
 167,
 173,
 179,
 181,
 191,
 193,
 197,
 199,
 211,
 223,
 227,
 229,
 233,
 239,
 241,
 251,
 257,
 263,
 269,
 271,
 277,
 281,
 283,
 293,
 307,
 311,
 313,
 317,
 331,
 337,
 347,
 349,
 353,
 359,
 367,
 373,
 379,
 383,
 389,
 397,
 401,
 409,
 419,
 421,
 431,
 433,
 439,
 443,
 449,
 457,
 461,
 463,
 467,
 479,
 487,
 491,
 499,
 503,
 509,
 521,
 523,
 541,
 547,
 557,
 563,
 569,
 571,
 577,
 587,
 593,
 599,
 601,
 607,
 613,
 617,
 619,
 631,
 641,
 643,
 647,
 653,
 659,
 661,
 673,
 677,
 683,
 691,
 701,
 709,
 719,
 727,
 733,
 739,
 743,
 751,
 757,
 761,
 769,
 773,
 787,
 797,
 809,
 811,
 821,
 823,
 827,
 829,
 839,
 853,
 857,
 859,
 863,
 877,
 881,
 883,
 887,
 907,
 911,
 919,
 929,
 937,
 941,
 947,
 953,
 967,
 971,
 977,
 983,
 991,
 997]
In [13]:
is_prime(4547337172376300111955330758342147474062293202868155909489)
Out[13]:
True
In [14]:
list(prime_factors(1548))
Out[14]:
[2, 2, 3, 3, 43]
In [15]:
list(factorize(1548)) # group prime factors in a^b tuples
Out[15]:
[(2, 2), (3, 2), (43, 1)]
In [16]:
sorted(list(divisors(1548)))
Out[16]:
[1, 2, 3, 4, 6, 9, 12, 18, 36, 43, 86, 129, 172, 258, 387, 516, 774, 1548]
In [17]:
from Goulib.itertools2 import first
first(filter(is_pandigital,fibonacci_gen())) #nice, isn't it ?
Out[17]:
2504730781961

Distances and Norms

In [18]:
levenshtein('hello','world')
Out[18]:
4
In [19]:
sets_levenshtein(set('hello'),set('world'))
Out[19]:
5

Misc

In [20]:
get_cardinal_name(1548)
Out[20]:
'one thousand five hundred and forty-eight'