Similar algorithm implementation producing different results - python

I'm trying to understand the Karatsuba multiplication algorithm. I've written the following code:
def karatsuba_multiply(x, y):
# split x and y
len_x = len(str(x))
len_y = len(str(y))
if len_x == 1 or len_y == 1:
return x*y
n = max(len_x, len_y)
n_half = 10**(n // 2)
a = x // n_half
b = x % n_half
c = y // n_half
d = y % n_half
ac = karatsuba_multiply(a, c)
bd = karatsuba_multiply(b, d)
ad_plus_bc = karatsuba_multiply((a+b), (c+d)) - ac - bd
return (10**n * ac) + (n_half * ad_plus_bc) + bd
This test case does not work:
print(karatsuba_multiply(1234, 5678)) ## returns 11686652, should be 7006652‬
But if I use the following code from this answer, the test case produces the correct answer:
def karat(x,y):
if len(str(x)) == 1 or len(str(y)) == 1:
return x*y
else:
m = max(len(str(x)),len(str(y)))
m2 = m // 2
a = x // 10**(m2)
b = x % 10**(m2)
c = y // 10**(m2)
d = y % 10**(m2)
z0 = karat(b,d)
z1 = karat((a+b),(c+d))
z2 = karat(a,c)
return (z2 * 10**(2*m2)) + ((z1 - z2 - z0) * 10**(m2)) + (z0)
Both functions look like they're doing the same thing. Why doesn't mine work?

It seems that in with kerat_multiply implementation you can't use the correct formula for the last return.
In the original kerat implementation the value m2 = m // 2 is multiplied by 2 in the last return (z2 * 10**(2*m2)) + ((z1 - z2 - z0) * 10**(m2)) + (z0) (2*m2)
So you i think you need either to add a new variable as below where n2 == n // 2 so that you can multiply it by 2 in the last return, or use the original implementation.
Hoping it helps :)
EDIT: This is explain by the fact that 2 * n // 2 is different from 2 * (n // 2)
n = max(len_x, len_y)
n_half = 10**(n // 2)
n2 = n // 2
a = x // n_half
b = x % n_half
c = y // n_half
d = y % n_half
ac = karatsuba_multiply(a, c)
bd = karatsuba_multiply(b, d)
ad_plus_bc = karatsuba_multiply((a + b), (c + d)) - ac - bd
return (10**(2 * n2) * ac) + (n_half * (ad_plus_bc)) + bd

Related

How to create a Single Vector having 2 Dimensions?

I have used the Equation of Motion (Newtons Law) for a simple spring and mass scenario incorporating it into the given 2nd ODE equation y" + (k/m)x = 0; y(0) = 3; y'(0) = 0.
I have then been able to run a code that calculates and compares the Exact Solution with the Runge-Kutta Method Solution.
It works fine...however, I have recently been asked not to separate my values of 'x' and 'v', but use a single vector 'x' that has two dimensions ( i.e. 'x' and 'v' can be handled by x(1) and x(2) ).
MY CODE:
# Given is y" + (k/m)x = 0; y(0) = 3; y'(0) = 0
# Parameters
h = 0.01; #Step Size
t = 100.0; #Time(sec)
k = 1;
m = 1;
x0 = 3;
v0 = 0;
# Exact Analytical Solution
te = np.arange(0, t ,h);
N = len(te);
w = (k / m) ** 0.5;
x_exact = x0 * np.cos(w * te);
v_exact = -x0 * w * np.sin(w * te);
# Runge-kutta Method
x = np.empty(N);
v = np.empty(N);
x[0] = x0;
v[0] = v0;
def f1 (t, x, v):
x = v
return x
def f2 (t, x, v):
v = -(k / m) * x
return v
for i in range(N - 1): #MAIN LOOP
K1x = f1(te[i], x[i], v[i])
K1v = f2(te[i], x[i], v[i])
K2x = f1(te[i] + h / 2, x[i] + h * K1x / 2, v[i] + h * K1v / 2)
K2v = f2(te[i] + h / 2, x[i] + h * K1x / 2, v[i] + h * K1v / 2)
K3x = f1(te[i] + h / 2, x[i] + h * K2x / 2, v[i] + h * K2v / 2)
K3v = f2(te[i] + h / 2, x[i] + h * K2x / 2, v[i] + h * K2v / 2)
K4x = f1(te[i] + h, x[i] + h * K3x, v[i] + h * K3v)
K4v = f2(te[i] + h, x[i] + h * K3x, v[i] + h * K3v)
x[i + 1] = x[i] + h / 6 * (K1x + 2 * K2x + 2 * K3x + K4x)
v[i + 1] = v[i] + h / 6 * (K1v + 2 * K2v + 2 * K3v + K4v)
Can anyone help me understand how I can create this single vector having 2 dimensions, and how to fix my code up please?
You can use np.array() function, here is an example of what you're trying to do:
x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
Unsure of your exact expectations of what you are wanting besides just having a 2 lists inside a single list. Though I do hope this link will help answer your issue.
https://www.tutorialspoint.com/python_data_structure/python_2darray.htm?

python performance tips for looping calculation

Python 2.7, Windows 7.
I'm looking for tips on how to make a calculation heavy script run faster. First an idea of what I'm doing:
Starting with a given color, I want to generate a list of 30 more colors (rgb values) that are maximally distinctive to the human eye from one another, and with the front of the list more distinctive than the end.
Currently, I estimate that the script will take ~48 hours to complete. I could let it run over the weekend, but I figured I would take the opportunity to learn something about python performance.
An overview what the code does:
gen_colours() contains a loop that runs 30 times. Each time 4 processes run multi(n, l, g) which contains the big loop iterating over each r, g, and b value between 0 and 255 (r value is split between processes so it loops 64 times). The inner most loop contains another loop that checks the rgb value against rgb values already found by calling compute_dist([r, g, b], c).
Anyways, without completely restructuring my code, things to help speed it up would be cool. Also, running all four cpus at max for 48 hours...issues there?
Code:
from math import sqrt, pow, atan2, atan, sin, cos, exp, radians, degrees
from fractions import Fraction
import time
import multiprocessing
def to_xyz(rgb):
r = rgb[0] / 255.0
g = rgb[1] / 255.0
b = rgb[2] / 255.0
f = Fraction(12, 5)
if r > 0.04045:
r = ((r + 0.055) / 1.055) ** f
else:
r /= 12.92
if g > 0.04045:
g = ((g + 0.055) / 1.055) ** f
else:
g /= 12.92
if b > 0.04045:
b = ((b + 0.055) / 1.055) ** f
else:
b /= 12.92
r *= 100
g *= 100
b *= 100
# Observer = 2 degrees, Illuminant = D65
x = r * 0.4124 + g * 0.3576 + b * 0.1805
y = r * 0.2126 + g * 0.7152 + b * 0.0722
z = r * 0.0193 + g * 0.1192 + b * 0.9505
return [x, y, z]
def to_lab(xyz):
x = xyz[0]
y = xyz[1]
z = xyz[2]
# Observer= 2deg, Illuminant= D65
x /= 95.047
y /= 100.0
z /= 108.883
f = Fraction(1, 3)
if x > 0.008856:
x **= f
else:
x = 7.787 * x + 0.13793103448
if y > 0.008856:
y **= f
else:
y = 7.787 * y + 0.13793103448
if z > 0.008856:
z **= f
else:
z = 7.787 * z + 0.13793103448
L = 116 * y - 16
a = 500 * (x - y)
b = 200 * (y - z)
return [L, a, b]
def compute_dist(rgb1, rgb2):
""" Compute the apparent difference in colours using CIEDE2000 standards """
xyz1 = to_xyz(rgb1)
xyz2 = to_xyz(rgb2)
lab1 = to_lab(xyz1)
lab2 = to_lab(xyz2)
a1 = lab1[1]
a2 = lab2[1]
b1 = lab1[2]
b2 = lab2[2]
L1 = lab1[0]
L2 = lab2[0]
c1 = sqrt(a1 * a1 + b1 * b1)
c2 = sqrt(a2 * a2 + b2 * b2)
c = (c1 + c2) / 2
crs = c ** 7
x = 0.5 - 0.5 * sqrt(crs / (crs + 6103515625))
temp = (1 + x) * a1
c1 = sqrt(temp * temp + b1 * b1)
h1 = hue(temp, b1)
temp = (1 + x) * a2
c2 = sqrt(temp * temp + b2 * b2)
h2 = hue(temp, b2)
dL = L2 - L1
dc = c2 - c1
if c1 * c2 == 0:
dh = 0
else:
temp = round(h2 - h1, 12)
if abs(temp) <= 180:
dh = h2 - h1
else:
if temp > 180:
dh = h2 - h1 - 360
else:
dh = h2 - h1 + 360
dh = sqrt(c1 * c2) * sin(radians(dh / 2))
dh += dh
lav = (L1 + L2) / 2
cav = (c1 + c2) / 2
if c1 * c2 == 0:
htot = h1 + h2
else:
temp = abs(round(h1 - h2, 12))
if temp > 180:
if h2 + h1 < 360:
htot = h1 + h2 + 360
else:
htot = h1 + h2 - 360
else:
htot = h1 + h2
htot /= 2
T = 1 - 0.17 * cos(radians(htot - 30)) + 0.24 * cos(radians(2 * htot)) + 0.32 * cos(radians(3 * htot + 6)) - 0.20 * cos(radians(4 * htot - 63))
htotdtme = (htot / 25) - 11
xPH = 30 * exp(-htotdtme * htotdtme)
cavrs = cav ** 7
scocp = sqrt(cavrs / (cavrs + 6103515625))
xRC = scocp + scocp
lavmf = lav - 50
lavmfs = lavmf * lavmf
SL = 1 + 0.015 * lavmfs / sqrt(20 + lavmfs)
SC = 1 + 0.045 * cav
SH = 1 + 0.015 * cav * T
RT = -sin(radians(xPH + xPH)) * xRC
dL /= SL
dc /= SC
dh /= SH
dE = sqrt(dL * dL + dc * dc + dh * dh + RT * dc * dh)
return dE
def hue(a, b): # Function returns CIELAB-Hue value
c = 0
if a >= 0 and b == 0:
return 0
if a < 0 and b == 0:
return 180
if a == 0 and b > 0:
return 90
if a == 0 and b < 0:
return 270
if a > 0 and b > 0:
c = 0
elif a < 0:
c = 180
elif b < 0:
c = 360
return degrees(atan(b / a)) + c
def multi(p, l, q):
f = 0
n = []
s = p * 64
e = (p + 1) * 64
for r in xrange(s, e):
for g in xrange(256):
for b in xrange(256):
s = 1000 # smallest dist
for c in l: # compare to existing colours
d = compute_dist([r, g, b], c)
if d < s:
s = d
if s > f:
n = [r, g, b]
f = s
q.put(f)
q.put(n)
def gen_colours(start_col=[68, 68, 68]):
out = open('colour_output.txt', 'w')
l = [start_col]
if __name__ == '__main__':
q0 = multiprocessing.Queue()
q1 = multiprocessing.Queue()
q2 = multiprocessing.Queue()
q3 = multiprocessing.Queue()
for h in xrange(30): # create 30 more colours
p0 = multiprocessing.Process(target=multi, args=[0, l, q0])
p1 = multiprocessing.Process(target=multi, args=[1, l, q1])
p2 = multiprocessing.Process(target=multi, args=[2, l, q2])
p3 = multiprocessing.Process(target=multi, args=[3, l, q3])
p0.start()
p1.start()
p2.start()
p3.start()
p0.join()
p1.join()
p2.join()
p3.join()
d0 = q0.get()
d1 = q1.get()
d2 = q2.get()
d3 = q3.get()
c0 = q0.get()
c1 = q1.get()
c2 = q2.get()
c3 = q3.get()
d = [d0, d1, d2, d3]
c = [c0, c1, c2, c3]
m = max(d)
i = d.index(m)
n = c[i]
l.append(n)
out.write("[" + str(n[0]) + ", " + str(n[1]) + ", " + str(n[2]) + "]\n")
print "\nnew colour added: " + str(l)
out.close()
print "Done"
gen_colours()
Any tips?
Edit:
An obvious improvement is the fact that I'm calculating Lab values on found rgb colors every time. I added a list to store Lab values for these so that it doesn't need to do this each loop. This reduced time by about 1/4. Not a Python performance improvement that I'm looking for however.
I'm sure a color that is R:100 G:100 B:101 would not be a "maximally distinctive" solution if color R:100 G:100 B:100 is chosen already.
One quick improvement you could make is to omit checking colors which are similar (ie. R and G values which are the same that have a B value within a given range).
You're doing way too much work.
It appears that you are working in a 24-bit RGB color-space when most monitor/gamut/ambient/eye combinations afford far less discriminability than your CIE calculations produce.
Assuming you are doing this to provide real-world colors for real-eyes, you also have to account for the myriad forms of colorblindness which reduces you to less than 12-bit useful color-space. Even if we are just talking about luminance, as luminance approaches the lower third of the device gamut, noticable differences become ever sparser.
The problem that you have is algorithmic; that is, you are working too hard to get detailed results when the added detail is irrelevant. Between #000 and #fff, there are only 4096 possible colors and the red-green axis can be rejected out of hand.

Need help vectorizing some Python code

I have some code that I need help vectorizing.
I want to convert the following to vector form, how can I? I want to get rid of the inner loop - apparently, it's possible to do so.
X is an NxD matrix. y is a 1xD vector.
def foo(X, y, mylambda, N, D, epsilon):
...
for j in xrange(D):
aj = 0
cj = 0
for i in xrange(N):
aj += 2 * (X[i,j] ** 2)
cj += 2 * (X[i,j] * (y[i] - w.transpose()*X[i].transpose() + w[j]*X[i,j]))
...
If I call numpy.vectorize() on the function, it throws an error at runtime.
Complete code:
import scipy
import scipy.io
import numpy
from numpy import linalg
from scipy import *
def data(N, d, k, sigma, seed=12231):
random.seed(seed)
X = randn(N, d)
wg = zeros(1 + d)
wg[1:k + 1] = 10 * sign(randn(k))
eps = randn(N) * sigma
y = X.dot(wg[1:]) + wg[0] + eps
return (y, X)
def foo(X, y, mylambda, n, D, epsilon):
identityMatrix = numpy.matrix(numpy.identity(D))
w = (X.transpose() * X + mylambda * identityMatrix).getI() * X.transpose() * y
newweight = (X.transpose() * X + mylambda * identityMatrix).getI() * X.transpose() * y
iterate = 1
iteration = 0
while iterate > 0 and iteration < 10000:
iteration += 1
iterate = 0
maxerror = 0
for j in xrange(D):
aj = 0
cj = 0
for i in xrange(n):
aj += 2 * (X[i,j] ** 2)
cj += 2 * (X[i,j] * (y[i] - w.transpose()*X[i].transpose() + w[j]*X[i,j]))
if cj < -mylambda:
newweight[j,0] = (cj + mylambda)/ aj
elif cj > mylambda:
newweight[j,0] = (cj - mylambda)/ aj
else:
newweight[j,0] = 0
if abs(newweight[j,0] - w[j,0]) > epsilon:
iterate += 1
if abs(newweight[j,0] - w[j,0]) > maxerror:
maxerror = abs(newweight[j,0] - w[j,0])
w[j,0] = newweight[j,0]
N, D, k = 50, 75, 5
(y, X) = data(N, D, k, 1, 123)
X = numpy.matrix(X)
y = numpy.matrix(y).transpose()
foo(X, y, 1, N, D, 0.1)
You can replace:
aj = 0
cj = 0
for i in xrange(n):
aj += 2 * (X[i,j] ** 2)
cj += 2 * (X[i,j] * (y[i] - w.transpose()*X[i].transpose() + w[j]*X[i,j]))
with:
aj = 2*np.sum(X[:,j].T*X[:,j])
cj = 2*np.sum(np.multiply(X[:, j].T, (y.T - w.T*X.T + w[j] * X[:, j].T)))

TypeError 'float' object is not callable while using a for loop [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
# Prototype of N-R for a system of two non-linear equations
#evaluating functions of two variables
# f(x,y)=1.6 * x ** 2 + 3.6 * x * y - 7.8 * x - 2.6 * y + 5.2
# g(x,y)=0.9 * y ** 2 + 3.1 * x **2 - 6.2 * x + 6.2 * y
# x = 0.5
# y =0.4
from math import *
eq1 = raw_input('Enter the equation 1: ')
eq2 = raw_input('Enter the equation 2: ')
x0 = float(input('Enter x: '))
y0 = float(input('Enter y: '))
def f(x,y):
return eval(eq1)
def g(x,y):
return eval(eq2)
Ea_X = 1
x = x0
y = y0
for n in range(1, 8):
a = (f(x + 1e-06, y) - f(x,y)) / 1e-06 #in this one start the trouble
b = (f(x, y + 1e-06) - f(x,y)) / 1e-06
c = 0 - f(x,y)
d = (g(x + 1e-06, y) - g(x,y)) / 1e-06
eE = (g(x, y + 1e-06) - g(x,y)) / 1e-06
f = 0 - g(x,y)
print "f(x, y)= ", eq1
print "g(x, y)= ", eq2
print """x y """
print x, y
print """a b c d e f """
print a, b, c, d, e, f
print """
a * x + b * y = c
d * x + e * y = f
"""
print a," * x + ",b," * y = ",c
print d," * x + ",eE," * y = ",f
_Sy = (c - a * f / d) / (b - a * eE / d)
_Sx = (f / d) - (eE / d) * _Sy
Ea_X = (_Sx ** 2 + _Sy ** 2)**0.5
x = x + _Sx
y = y + _Sy
print "Sx = ", _Sx
print "Sy = ", _Sy
print "x = ", x
print "y = ", y
print "|X_1 - X_0| = ", Ea_X
I've been testing the Newton-Rapson method for two non-linear equations,
the prototype code works but then I was thinking in making it more
useful, because the prototype is about the input of the 2 equations
and the first guesses, and it would be good to implement a for loop
instead of starting the process like 6 or 10 to resolve just one
of the so many equations that I'm working with
# Prototype of N-R for a system of two non-linear equations
# f(x,y)=1.6 * x ** 2 + 3.6 * x * y - 7.8 * x - 2.6 * y + 5.2
# g(x,y)=0.9 * y ** 2 + 3.1 * x **2 - 6.2 * x + 6.2 * y
# x = 0.5
# y =0.4
# evaluating functions of two variables
from math import *
eq1 = raw_input('Enter the equation 1: ')
eq2 = raw_input('Enter the equation 2: ')
x0 = float(input('Enter x: '))
y0 = float(input('Enter y: '))
def f(x,y):
return eval(eq1)
def g(x,y):
return eval(eq2)
Ea_X = 1
x = x0
y = y0
a = (f(x + 1e-06, y) - f(x,y)) / 1e-06
b = (f(x, y + 1e-06) - f(x,y)) / 1e-06
c = 0 - f(x,y)
d = (g(x + 1e-06, y) - g(x,y)) / 1e-06
eE = (g(x, y + 1e-06) - g(x,y)) / 1e-06
f = 0 - g(x,y)
print "f(x, y)= ", eq1
print "g(x, y)= ", eq2
print """x y """
print x, y
print """a b c d e f """
print a, b, c, d, e, f
print """
a * x + b * y = c
d * x + e * y = f
"""
print a," * x + ",b," * y = ",c
print d," * x + ",eE," * y = ",f
_Sy = (c - a * f / d) / (b - a * eE / d)
_Sx = (f / d) - (eE / d) * _Sy
Ea_X = (_Sx ** 2 + _Sy ** 2)**0.5
x = x + _Sx
y = y + _Sy
print "Sx = ", _Sx
print "Sy = ", _Sy
print "x = ", x
print "y = ", y
print "|X_1 - X_0| = ", Ea_X
In the line
f = 0 - g(x,y)
you assign a number to the name f. Since functions and other variables share a namespace in Python (a function is just a callable object, bound to any variable), this makes future iterations fail. Pick another name for the value you're assigning in the above line.
Here is the problem:
f = 0 - g(x,y)
You are rebinding f from a function to a float.

Restricting values for curve_fit (scipy.optimize)

I'm trying to fit a logistic growth curve to my data using curve_fit using the following function as the input.
def logistic(x, y0, k, d, a, b):
if b > 0 and a > 0:
y = (k * pow(1 + np.exp(d - (a * b * x) ), (-1/b) )) + y0
elif b >= -1 or b < 0 or a < 0:
y = (k * pow(1 - np.exp(d - (a * b * x) ), (-1/b) )) + y0
return y
As you can see the function i am using has some restrictions on the values it can accept for parameter a and b. Any guess on how to handle the incorrect values? Should the input function raise an exception or return a dummy value?
Thanks in advance.
When the parameters fall out of the admissible range, return a wildly huge number (far from the data to be fitted). This will (hopefully) penalize this choice of parameters so much that curve_fit will settle on some other admissible set of parameters as optimal:
def logistic(x, y0, k, d, a, b):
if b > 0 and a > 0:
y = (k * pow(1 + np.exp(d - (a * b * x) ), (-1/b) )) + y0
elif b >= -1 or b < 0 or a < 0:
y = (k * pow(1 - np.exp(d - (a * b * x) ), (-1/b) )) + y0
else:
y = 1e10
return y

Categories