Related
I have this piece of code above:
N = 8
inf = 99
graph = [[0,0,6,7,0,8,0,0], #1
[0,0,0,3,4,2,0,0], #2
[6,0,0,0,0,3,0,7], #3
[7,3,0,0,9,0,0,0], #4
[0,4,0,9,0,0,5,0], #5
[8,2,3,0,0,0,9,3], #6
[0,0,0,0,5,9,0,0], #7
[0,0,7,0,0,3,0,0]] #8
# Матрица инцидентности для остовного дерева (задаётся пустой)
spanning_tree_graph = [[0,0,0,0,0,0,0,0] for node in range(N)]
selected_nodes = [False for node in range(N)] # какие вершины включены, какие нет
while(False in selected_nodes): # Пока есть невключенные вершины:
minimum = inf
start = 0
end = 0
for i in range(0, N):
if selected_nodes[i]:
for j in range(0+i, N):
if(not selected_nodes[j] and graph[i][j] > 0):
if graph[i][j] < minimum:
minimum = graph[i][j]
start, end = i, j
selected_nodes[end] = True
spanning_tree_graph[start][end] = minimum
if minimum == inf:
spanning_tree_graph[start][end] = 0
spanning_tree_graph[end][start] = spanning_tree_graph[start][end]
print(spanning_tree_graph)
But output is empty, and I don't know why.
I'm trying to render the sorted graph. Like this
[[0, 8, 2, 4, 0, 0, 0, 0], [8, 0, 0, 0, 0, 0, 0, 0], [2, 0, 0, 0, 0, 5, 0, 4], [4, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 4, 0], [0, 0, 5, 0, 0, 0, 0, 0], [0, 0, 0, 0, 4, 0, 0, 0], [0, 0, 4, 0, 0, 0, 0, 0]]
Here is what I believe to be a fixed implementation.
N = 8
inf = 99
graph = [[0,0,6,7,0,8,0,0], #1
[0,0,0,3,4,2,0,0], #2
[6,0,0,0,0,3,0,7], #3
[7,3,0,0,9,0,0,0], #4
[0,4,0,9,0,0,5,0], #5
[8,2,3,0,0,0,9,3], #6
[0,0,0,0,5,9,0,0], #7
[0,0,7,0,0,3,0,0]] #8
# Матрица инцидентности для остовного дерева (задаётся пустой)
spanning_tree_graph = [[0,0,0,0,0,0,0,0] for node in range(N)]
selected_nodes = [False for node in range(N)] # какие вершины включены, какие нет
selected_nodes[0] = True
while(False in selected_nodes): # Пока есть невключенные вершины:
minimum = inf
start = 0
end = 0
for i in range(0, N):
if selected_nodes[i]:
for j in range(0, N):
if(not selected_nodes[j] and graph[i][j] > 0):
if graph[i][j] < minimum:
minimum = graph[i][j]
start, end = i, j
selected_nodes[end] = True
spanning_tree_graph[start][end] = minimum
if minimum == inf:
spanning_tree_graph[start][end] = 0
break
spanning_tree_graph[end][start] = spanning_tree_graph[start][end]
for g in spanning_tree_graph:
print(g)
Here were the bugs that I fixed.
You have to start with a node (any node) in the spanning tree graph for it to get going.
You're looping through pairs to find i a selected node and j not. You were not willing to consider j < i but it might be.
If minimum == inf then the next loop iteration will find the same, and you have an infinite loop. So break with the partial tree.
I modified the print at the end to display in a more convenient format.
I'm having some problems with operator overloading. If you could check please.
The code:
import math
class Mat4:
cells = [ [0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0] ]
#staticmethod
def DET2(a, b, c, d):
return a * d - b * c
#staticmethod
def DET3(a,b,c, d,e,f, g,h,i):
return a * Mat4.DET2(e,f,h,i) - b * Mat4.DET2(d,f,g,i) + c * Mat4.DET2(d,e,g,h)
#staticmethod
def DET4(a,b,c,d, e,f,g,h, i,j,k,l, m,n,o,p):
return ( a * Mat4.DET3(f,g,h,j,k,l,n,o,p) - b * Mat4.DET3(e,g,h,i,k,l,m,o,p) + c * Mat4.DET3(e,f,h,i,j,l,m,n,p) - d * Mat4.DET3(e,f,g,i,j,k,m,n,o))
#staticmethod
def Scale(factor):
res = Mat4()
res.cells = [ [factor,0, 0, 0],
[0, factor, 0, 0],
[0, 0, factor, 0],
[0, 0, 0, 1] ]
return res
def __mul__(self, other):
if isinstance(other, Mat4):
print(self.cells)
print(other.cells)
print("h\n")
out = Mat4()
for row_left in range(4):
for col_right in range(4):
out.cells[row_left][col_right] = 0
for k in range(4):
out.cells[row_left][col_right] += self.cells[row_left][k] * other.cells[k][col_right]
return out
if isinstance(other, int) or isinstance(other, float):
for i in range(4):
for j in range(4):
self.cells[i][j] *= other
return self
def __truediv__(self, other):
print(self.cells)
print(other.GetInversed().cells)
print("pl\n")
return self * other.GetInversed()
#staticmethod
def Identity():
return Mat4.Scale(1)
#staticmethod
def RotationX(angle):
sinTheta = math.sin(angle)
cosTheta = math.cos(angle)
res = Mat4()
res.cells = [ [1, 0, 0, 0],
[0, cosTheta, -sinTheta, 0],
[0, sinTheta, cosTheta, 0],
[0, 0, 0, 1] ]
return res
def GetInversed(self):
a = self.cells[0][0]
b = self.cells[0][1]
c = self.cells[0][2]
d = self.cells[0][3]
e = self.cells[1][0]
f = self.cells[1][1]
g = self.cells[1][2]
h = self.cells[1][3]
i = self.cells[2][0]
j = self.cells[2][1]
k = self.cells[2][2]
l = self.cells[2][3]
m = self.cells[3][0]
n = self.cells[3][1]
o = self.cells[3][2]
p = self.cells[3][3]
min_a = Mat4.DET3(f,g,h,j,k,l,n,o,p)
min_b = Mat4.DET3(e,g,h,i,k,l,m,o,p)
min_c = Mat4.DET3(e,f,h,i,j,l,m,n,p)
min_d = Mat4.DET3(e,f,g,i,j,k,m,n,o)
det_m = a * min_a - b * min_b + c * min_c - d * min_d
res = Mat4()
res.cells[0][0] = min_a
res.cells[1][0] = -min_b
res.cells[2][0] = min_c
res.cells[3][0] = -min_d
res.cells[0][1] = -Mat4.DET3(b,c,d,j,k,l,n,o,p)
res.cells[1][1] = Mat4.DET3(a,c,d,i,k,l,m,o,p)
res.cells[2][1] = -Mat4.DET3(a,b,d,i,j,l,m,n,p)
res.cells[3][1] = Mat4.DET3(a,b,c,i,j,k,m,n,o)
res.cells[0][2] = Mat4.DET3(b,c,d,f,g,h,n,o,p)
res.cells[1][2] = -Mat4.DET3(a,c,d,e,g,h,m,o,p)
res.cells[2][2] = Mat4.DET3(a,b,d,e,f,h,m,n,p)
res.cells[3][2] = -Mat4.DET3(a,b,c,e,f,g,m,n,o)
res.cells[0][3] = -Mat4.DET3(b,c,d,f,g,h,j,k,l)
res.cells[1][3] = Mat4.DET3(a,c,d,e,g,h,i,k,l)
res.cells[2][3] = -Mat4.DET3(a,b,d,e,f,h,i,j,l)
res.cells[3][3] = Mat4.DET3(a,b,c,e,f,g,i,j,k)
return res * ( 1.0 / det_m)
def main():
rotMat = Mat4().RotationX(50)
scaMat = Mat4().Scale(3)
mRes = (rotMat * scaMat) / rotMat
print(mRes.cells)
if __name__ == "__main__":
main()
The result I'm getting:
mRes = [[0.0, 0.0, 0.0, 0.0], [0.0, -0.068840563856158, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]]
The result I should get, because rotation gets subtracted and only the scaling has left:
mRes = [[3, 0, 0, 0], [0, 3, 0, 0], [0, 0, 3, 0], [0, 0, 0, 1]]
The problem is with __mul__ operator because it's having other and self parameters to store same values, but address is not the same:
For some reasons the first time multiplication happens mRes = (rotMat * scaMat) is okay, but the problems comes when the resulted matrix from the division calls division operator, which also calls multiplication operator.
I have a long list complexed of numpy arrays and integers, below is an example:
[array([[2218.67288865]]), array([[1736.90215229]]), array([[1255.13141592]]), array([[773.36067956]]), array([[291.58994319]]), 0, 0, 0, 0, 0, 0, 0, 0, 0]
and i'd like to convert it to a regular list as so:
[2218.67288865, 1736.90215229, 1255.13141592, 773.36067956, 291.58994319, 0, 0, 0, 0, 0, 0, 0, 0, 0]
How can I do that efficiently?
You can use a generator for flattening the nested list:
def convert(obj):
try:
for item in obj:
yield from convert(item)
except TypeError:
yield obj
result = list(convert(data))
list(itertools.from_iterable(itertools.from_iterable(...))) should work for removing 2 levels of nesting: just add or remove copies of itertools.from_iterable(...) as needed.
Here the simplest seems to also be the fastest:
x = [array([[2218.67288865]]), array([[1736.90215229]]), array([[1255.13141592]]), array([[773.36067956]]), array([[291.58994319]]), 0, 0, 0, 0, 0, 0, 0, 0, 0]
[y if y.__class__==int else y.item(0) for y in x]
# [2218.67288865, 1736.90215229, 1255.13141592, 773.36067956, 291.58994319, 0, 0, 0, 0, 0, 0, 0, 0, 0]
timeit(lambda:[y if y.__class__==int else y.item(0) for y in x])
# 2.198630048893392
You can stick to numpy by using np.ravel:
np.hstack([np.ravel(i) for i in l]).tolist()
Output:
[2218.67288865,
1736.90215229,
1255.13141592,
773.36067956,
291.58994319,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0]
I'm trying to implement STDP (Spike-Timing Dependent Plasticity) in tensorflow. It's a bit complicated. Any ideas (to get running entirely within a tensorflow graph)?
It works like this: say I have 2 input neurons, and they connect to 3 output neurons, via this matrix: [[1.0, 1.0, 0.0], [0.0, 0.0, 1.0]] (input neuron 0 connects to output neurons 0 and 1...).
Say I have these spikes for the input neurons (2 neurons, 7 timesteps):
Input Spikes:
[[0, 0, 1, 1, 0, 1, 0],
[1, 1, 0, 0, 0, 0, 1]]
And these spikes for the output neurons (3 neurons, 7 timesteps):
Output Spikes:
[[0, 0, 0, 1, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1]]
Now, for each non-zero weight, I want to compute a dw. For instance, for input neuron 0 connecting to output neuron 0:
The time stamps of the spikes for input neuron 0 are [2, 3, 5], and the timestamps for output neuron 0 are [3, 6]. Now, I compute all the delta times:
Delta Times = [ 2-3, 2-6, 3-3, 3-6, 5-3, 5-6 ] = [ -1, -4, 0, -3, 2, -1 ]
Then, I compute some function (the actual STDP function, which isn't important for this question - some exponential thing)
dw = SUM [ F(-1), F(-4), F(0), F(-3), F(2), F(-1) ]
And that's the dw for the weight connecting input neuron 0 to output neuron 0. Repeat for all non-zero weights.
So I can do all this in numpy, but I'd like to be able to do it entirely within a single tensorflow graph. In particular, I'm stuck on computing the delta times. And how to do all this for all non-zero weights, in parallel.
This is the actual stdp function, btw (the constants can be parameters):
def stdp_f(x):
return tf.where(
x == 0, np.zeros(x.shape), tf.where(
x > 0, 1.0 * tf.exp(-1.0 * x / 10.0), -1.0 * 1.0 * tf.exp(x / 10.0)))
A note on performance: the method given by #jdehesa, below, is both correct and clever. But it also turns out to be slow. In particular, for a real neural network of 784 input neurons feeding into 400 neurons, over 500 time steps, the spike_match = step performs multiplication of (784, 1, 500, 1) and (1, 400, 1, 500) tensors.
I am not familiar with STDP, so I hope I understood correctly what you meant. I think this does what you describe:
import tensorflow as tf
def f(x):
# STDP function
return x * 1
def stdp(input_spikes, output_spikes):
input_shape = tf.shape(input_spikes)
t = input_shape[-1]
# Compute STDP function for all possible time difference values
stdp_values = f(tf.cast(tf.range(-t + 1, t), dtype=input_spikes.dtype))
# Arrange in matrix such that position [i, j] contains f(i - j)
matrix_idx = tf.expand_dims(tf.range(t - 1, 2 * t - 1), 1) + tf.range(0, -t, -1)
stdp_matrix = tf.gather(stdp_values, matrix_idx)
# Find spike matches
spike_match = (input_spikes[:, tf.newaxis, :, tf.newaxis] *
output_spikes[tf.newaxis, :, tf.newaxis, :])
# Sum values where there are spike matches
return tf.reduce_sum(spike_match * stdp_matrix, axis=(2, 3))
# Test
input_spikes = [[0, 0, 1, 1, 0, 1, 0],
[1, 1, 0, 0, 0, 0, 1]]
output_spikes = [[0, 0, 0, 1, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1]]
with tf.Graph().as_default(), tf.Session() as sess:
ins = tf.placeholder(tf.float32, [None, None])
outs = tf.placeholder(tf.float32, [None, None])
res = stdp(ins, outs)
res_val = sess.run(res, feed_dict={ins: input_spikes, outs: output_spikes})
print(res_val)
# [[ -7. 10. -15.]
# [-13. 7. -24.]]
Here I assume that f is probably expensive (and that its value is the same for every pair of neurons), so I compute it only once for every possible time delta and then redistribute the computed values in a matrix, so I can multiply at the pairs of coordinates where the input and output spikes happen.
I used the identity function for f as a placeholder, so the resulting values are actually just the sum of time differences in this case.
EDIT: Just for reference, replacing f with the STDP function you included:
def f(x):
return tf.where(x == 0,
tf.zeros_like(x),
tf.where(x > 0,
1.0 * tf.exp(-1.0 * x / 10.0),
-1.0 * 1.0 * tf.exp(x / 10.0)))
The result is:
[[-3.4020822 2.1660795 -5.694256 ]
[-2.974073 0.45364904 -3.1197631 ]]
I have a function that gets a set of data from a server, sorts and displays it
def load_data(dateStr):
data = get_date(dateStr).splitlines()
result = []
for c in data:
a = c.split(',')
time = a[0]
temp = float(a[1])
solar = float(a[2])
kwH = a[3:]
i = 0
while i < len(power):
power[i] = int(power[i])
i = i+1
result.append((time, temp, solar, tuple(kwH)))
return result
This is what the function returns when you enter in a particular date(only 3 entries out of a long list), the first number in each entry is the time, second is the temperature.
>>> load_data('20-01-2014')
[('05:00', 19.9, 0.0, (0, 0, 0, 0, 0, 0, 0, 18, 34)), ('05:01', 19.9, 0.0, (0, 0, 0, 0, 0, 0, 0, 20, 26)), ('05:02', 19.9, 0.0, (0, 0, 0, 0, 0, 0, 0, 17, 35))
I need write a function to find the maximum temperature of a date, and show all of the times in the day that the maximum occurred. Something like this:
>>> data = load_data('07-10-2011')
>>> max_temp(data)
(18.9, ['13:08', '13:09', '13:10'])
How would I go about this? Or can you point me to anywhere that might have answers
This is one way to do it (this loops over the data twice):
>>> data = [('05:00', 19.9, 0.0, (0, 0, 0, 0, 0, 0, 0, 18, 34)), ('05:01', 19.9, 0.0, (0, 0, 0, 0, 0, 0, 0, 20, 26)), ('05:02', 19.9, 0.0, (0, 0, 0, 0, 0, 0, 0, 17, 35))]
>>> max_temp = max(data, key=lambda x: x[1])[1]
>>> max_temp
19.9
>>> result = [item for item in data if item[1] == max_temp]
>>> result
[('05:00', 19.9, 0.0, (0, 0, 0, 0, 0, 0, 0, 18, 34)), ('05:01', 19.9, 0.0, (0, 0, 0, 0, 0, 0, 0, 20, 26)), ('05:02', 19.9, 0.0, (0, 0, 0, 0, 0, 0, 0, 17, 35))]
The most optimal way to get all matching times for the maximum temperature is to simply loop over the values and track the maximum found so far:
def max_temp(data):
maximum = float('-inf')
times = []
for entry in data:
time, temp = entry[:2]
if temp == maximum:
times.append(time)
elif temp > maximum:
maximum = temp
times = [time]
return maximum, times
This loops over the data just once.
The convenient way (which is probably going to be close in performance anyway) is to use the max() function to find the maximum temperature first, then a list comprehension to return all times with that temperature:
def max_temp(data):
maximum = max(data, key=lambda e: e[1])[1]
return maximum, [e[0] for e in data if e[1] == maximum]
This loops twice over the data, but the max() loop is implemented mostly in C code.
def max_temp(data):
maxt = max([d[1] for d in data])
return (maxt, [d[0] for d in data if d[1] == maxt])