Hi, do you remember this one?
I've just made comparison of this code to Java, and Cython does, imo, well. The same edit distance loop is only, on average 25 percent faster on JVM.
Thanks.
Hi, do you remember this one?
I've just made comparison of this code to Java, and Cython does, imo, well. The same edit distance loop is only, on average 25 percent faster on JVM.
Thanks.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| def edit_dist_dp(str1, str2, m, n):
store = [[0 for x in range(n + 1)] for x in range(m + 1)]
for i in range(m + 1):
for j in range(n + 1):
if i == 0:
store[i][j] = j
elif j == 0:
store[i][j] = i
elif str1[i - 1] == str2[j - 1]:
store[i][j] = store[i - 1][j - 1]
else:
store[i][j] = 1 + min(store[i][j - 1], store[i - 1][j],
store[i - 1][j - 1])
return store[m][n]
|
1
2
3
4
5
6
7
8
9
10
| import timeit
py = timeit.timeit('edit_distance.edit_dist_dp("asdsdhter", "dsfladrte", 9, 9)',
setup='import edit_distance', number=10000)
cy = timeit.timeit('edit_distance_cy.edit_dist_dp("asdsdhter", "dsfladrte", 9, 9)',
setup='import edit_distance_cy', number=10000)
print(f"Python and Cython times: {py}, Cython: {cy}")
print(f"Cython is {py/cy} x faster than Python")
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| def edit_dist_dp(str1, str2, m, n):
store = [[0 for x in range(n + 1)] for x in range(m + 1)]
cdef int i, j
for i in range(m + 1):
for j in range(n + 1):
if i == 0:
store[i][j] = j
elif j == 0:
store[i][j] = i
elif str1[i - 1] == str2[j - 1]:
store[i][j] = store[i - 1][j - 1]
else:
store[i][j] = 1 + min(store[i][j - 1], store[i - 1][j],
store[i - 1][j - 1])
return store[m][n]
|
1
2
| Python: 0.7150410660033231, Cython: 0.1197679779943428
Cython is 5.970219068381515 x faster than Python
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| cpdef int edit_dist_dp(str str1, str str2, int m, int n):
store = [[0 for x in range(n + 1)] for x in range(m + 1)]
cdef int i, j
for i in range(m + 1):
for j in range(n + 1):
if i == 0:
store[i][j] = j
elif j == 0:
store[i][j] = i
elif str1[i - 1] == str2[j - 1]:
store[i][j] = store[i - 1][j - 1]
else:
store[i][j] = 1 + min(store[i][j - 1], store[i - 1][j],
store[i - 1][j - 1])
return store[m][n]
|
1
2
3
| (project_venv) $ python tests.py
Python: 0.7169225399993593, Cython: 0.07916731700242963
Cython is 9.055789271946113 x faster than Python
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | cpdef int edit_dist_dp(str str1, str str2, int m, int n): cdef int i, j, x, y cdef int store[50][50] for x in range(n + 1): for y in range(m + 1): store[x][y] = 0 for i in range(m + 1): for j in range(n + 1): if i == 0: store[i][j] = j elif j == 0: store[i][j] = i elif str1[i - 1] == str2[j - 1]: store[i][j] = store[i - 1][j - 1] else: store[i][j] = 1 + min(store[i][j - 1], store[i - 1][j], store[i - 1][j - 1]) return store[m][n] |
1 2 3 | (project_venv) $ python tests.py
Python: 0.7155497479980113, Cython: 0.027351742995961104
Cython is 26.16102922960606 x faster than Python
|
def fill_values(formula): """returns genexp with the all fillings with 0 and 1""" letters = "".join(set(re.findall("[A-Za-z]", formula))) for digits in product("10", repeat=len(letters)): table = str.maketrans(letters, "".join(digits)) yield formula.translate(table)
$ ./eval.py Propositional Logic Parser, press help, /h, -h or -usage for help > q ~ a Formula is satisfiable
public class SkewHeap <V extends Comparable<V>> { SkewNode root; public SkewHeap() { this.root = null; } class SkewNode { SkewNode leftChild, rightChild; V data; public SkewNode(V _data, SkewNode _left, SkewNode _right) { this.data = _data; this.leftChild = _left; this.rightChild = _right; } } }
And here the crucial merge:SkewNode merge(SkewNode left, SkewNode right) { if (null == left) return right; if (null == right) return left; if (left.data.compareTo(right.data) < 0 || left.data.compareTo(right.data) == 0) { return new SkewNode(left.data, merge(right, left.rightChild), left.leftChild); } else return new SkewNode(right.data, merge(left, right.rightChild), right.leftChild); }
SkewHeap listToHeap(List list) { SkewHeap o = new SkewHeap(); for (int i = 0; i < list.size(); i++) o.insert((Comparable) list.get(i)); return o; } List heapToList(SkewHeap tree) { List ll = new ArrayList(); try { while (true) { ll.add(tree.pop()); } } catch (IndexOutOfBoundsException e) { return ll; } } List sort(List list) { return heapToList(listToHeap(list)); }
3 2 + 4 3 * +It's enough to take en empty LIFO stack, go through it and:
# input: coefficients of polynomials as a lists u, v != 0 # in order u[0] = free coefficient of u(x), .... # returns polynomials q, r such that u = vq + r(rest) # length u >= length v >= 0 def poly_divide(u, v): m = len(u) - 1 n = len(v) - 1 q = [0] * (m - n + 1) lim = m - n for k in range(lim, -1, -1): q[k] = u[n + k] / v[n] for j in range(n + k - 1, k - 1, -1): u[j] = u[j] - q[k] * v[j - k] return q, u[:n]
def poly_gcd(u, v): if not any(v): return u else: return poly_gcd(v, poly_mod(u, v))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | int partition(int a[], int p, int r) { int t = a[r]; int i = p - 1; for (int j = p; j < r;j++){ if (a[j] <= t) { i += 1; std::swap(a[i], a[j]); } } std::swap(a[i + 1], a[r]); return i + 1; } int quick_select(int a[], int s, int n, int k) { int r = partition_random(a, s, n); if (r - s == k - 1) {return a[r];} else { if (k - 1 < r - s) { return quick_select(a, s, r - 1, k); } else { return quick_select(a, r + 1 , n, k - r + s - 1); } } } int partition_random(int a[], int p, int r) { std::random_device rd; std::mt19937 rng(rd()); std::uniform_int_distribution<int> uni(p, r); auto rn = uni(rng); std::swap(a[r], a[rn]); return partition(a, p, r); } |
1 2 3 4 5 6 7 8 | float median(int a [], int n) { if (n % 2 == 1) return quick_select(a, 0, n - 1, n / 2 + 1); int l = n / 2; int r = n / 2 + 1; return (1.0 * (quick_select(a, 0, n - 1, l) + quick_select(a, 0, n - 1, r))) / 2; } |
template<class A> class optional {
bool _isValid;
A _value;
public:
optional(): _isValid(false) {}
optional(A e) : _isValid(true), _value(e) {}
optional(A e, bool v) : _isValid(v), _value(e) {}
A value() const { return _value; }
bool validation() const {return _isValid;}
};
Pair with value and Boolean indicator, constructors, methods to get values. optional<double> safe_root(double x) {
if (x >= 0) return optional<double>{std::sqrt(x)};
else return optional<double>{};
}
optional<double> safe_reciprocal(double x) {
if (! x == 0) return optional<double> {1 / x};
else return optional<double>{};
}
As definition states, the job is to construct identity and composition. Identity seems easy:optional<double> identity(double x) {
return optional<double>{x};
}
If original identity would go from Double to Double, then a new must go from Double to optional and change the state of isValid to True. There is no logical alternative: True is neutral to conjuction (why conjuction in a moment) and if we don't change a value(the very heart of identity operation), then there still is a value, so indicator must be true. auto const compose = [](auto m1, auto m2) {
return [m1, m2](auto x) {
auto p1 = m1(x);
auto p2 = m2(p1.value());
return optional<double>(p2.value(),
p1.validation() && p2.validation());
};
};
Inside the lambda, p1 and p2 are responsible for the composition of two incoming functions. The value after the second evaluation and the logical conjunction of the two incoming optionals isValid fields is passed to the returned function. Is this really a composition? Well, must be: functions are composable, so check, the second isValid parts are composed by logical and operator which is, I hope, clear. To get a composition with a proper type, both functions validation fields must evaluate to true, if one or both are false, then the composition fails (in the term of a value type evaluation), setting validation to false. And it's also, associative - composition is associative.auto const safe_root_reciprocal = compose(safe_reciprocal, safe_root);
auto const safe_rootIdR = compose(safe_root, identity);
auto const safe_rootIdL = compose(identity, safe_root);
std::cout << safe_root_reciprocal(0).validation() << "\n"; // -> 0
std::cout << safe_root_reciprocal(3).validation() << "\n"; // -> 1
std::cout << safe_root_reciprocal(3).value() << "\n"; // -> 0.57735
std::cout << (safe_rootIdR(2).value()) << "\n"; // -> 1.41421
std::cout << (safe_rootIdL(2).value()) << "\n"; // -> 1.41421
1 2 3 4 5 6 7 8 9 | def factorial(n): if n == 0: return 1 s = 1 while n > 0: s *= n n -= 1 return s print(reduce_series(add, lambda n: n / (factorial(n)), 0, 7)) |