Compositions in Fuzzy Relations - MATLAB/Python - python

I want to calculate Fuzzy Relation Compositions on MATLAB/Python and was wondering if there are any built-in functions in MATLAB or Python for doing this...
here's an example :
R1 = [{ 3, 4, .7}, {3, 5, 0}, { 4, 4, 1}, { 4, 5, .1}]
R2 = [{ 3,3, 0}, { 3, 5, .1}, { 4, 4, 0}, { 4, 5, .6}]
I'm trying to calculate :
R1oR2
I'm looking for 'Max-Min' and 'Max-Product' approaches...

Ok... since no one gave an answer, I ended up writing it by myself... here's the Python Code:
import numpy as np
# Max-Min Composition given by Zadeh
def maxMin(x, y):
z = []
for x1 in x:
for y1 in y.T:
z.append(max(np.minimum(x1, y1)))
return np.array(z).reshape((x.shape[0], y.shape[1]))
# Max-Product Composition given by Rosenfeld
def maxProduct(x, y):
z = []
for x1 in x:
for y1 in y.T:
z.append(max(np.multiply(x1, y1)))
return np.array(z).reshape((x.shape[0], y.shape[1]))
# 3 arrays for the example
r1 = np.array([[1, 0, .7], [.3, .2, 0], [0, .5, 1]])
r2 = np.array([[.6, .6, 0], [0, .6, .1], [0, .1, 0]])
r3 = np.array([[1, 0, .7], [0, 1, 0], [.7, 0, 1]])
print "R1oR2 => Max-Min :\n" + str(maxMin(r1, r2)) + "\n"
print "R1oR2 => Max-Product :\n" + str(maxProduct(r1, r2)) + "\n\n"
print "R1oR3 => Max-Min :\n" + str(maxMin(r1, r3)) + "\n"
print "R1oR3 => Max-Product :\n" + str(maxProduct(r1, r3)) + "\n\n"
print "R1oR2oR3 => Max-Min :\n" + str(maxMin(r1, maxMin(r2, r3))) + "\n"
print "R1oR2oR3 => Max-Product :\n" + str(maxProduct(r1, maxProduct(r2, r3))) + "\n\n"
and here's the answer it gives:
R1oR2 => Max-Min :
[[ 0.6 0.6 0. ]
[ 0.3 0.3 0.1]
[ 0. 0.5 0.1]]
R1oR2 => Max-Product :
[[ 0.6 0.6 0. ]
[ 0.18 0.18 0.02]
[ 0. 0.3 0.05]]
R1oR3 => Max-Min :
[[ 1. 0. 0.7]
[ 0.3 0.2 0.3]
[ 0.7 0.5 1. ]]
R1oR3 => Max-Product :
[[ 1. 0. 0.7 ]
[ 0.3 0.2 0.21]
[ 0.7 0.5 1. ]]
R1oR2oR3 => Max-Min :
[[ 0.6 0.6 0.6]
[ 0.3 0.3 0.3]
[ 0.1 0.5 0.1]]
R1oR2oR3 => Max-Product :
[[ 0.6 0.6 0.42 ]
[ 0.18 0.18 0.126]
[ 0.035 0.3 0.05 ]]

Related

how to remove serial numbers from dictionary for further operations?

I just converted a dictionary into an array... something like this
dict_t = {1: 0.1, 2: 0.2, 3: 0.3, 4: 0.4 }
this is what I obtained:-
w = [[ 1. 0.1 ]
[ 2. 0.2 ]
[ 3. 0.3 ]
[ 4. 0.4 ]
this is what I desired:-
question 1 - how to get the below-desired result ?
w = [[ 0.1 ]
[ 0.2 ]
[ 0.3 ]
[ 0.4 ]]
further, I was indexing these values into a matrix format.
question-2 how to index the value of w ?
for each value of w, I want this (F matrix) local matrix,
F = np.array([0],[wl/2],[-wll/12],[0],[wl/2],[wll/12])
further, all these F matrices should be added in a particular fashion to get the global matrix (shown below in the desired operation)
after all the operation delta_F will give a column matrix .
dof = 15
delta_F = np.zeros(15)
for i in range(w):
F = np.array([0],[w*l/2],[-w*l*l/12],[0],[w*l/2],[w*l*l/12])
rows, cols = dof,1
F_temp = [([0]*cols) for i in range(rows)]
F_temp[3i:3i+6,0] = F
delta_F += F_temp
print(delta_F)
desired operation:-
enter image description here
Question 1, this should give the output you want:
dict_t = {1: 0.1, 2: 0.2, 3: 0.3, 4: 0.4 }
output = [[v for v in dict_t.values()]]
print(output) #[[0.1, 0.2, 0.3, 0.4]]

Index array with the result of .nonzero()

I am having difficulties selecting rows using two condition in Numpy. The following code does not return the intended output
tot_length=0.3
steps=0.1
start_val=0.0
list_no =np.arange(start_val, tot_length, steps)
x, y, z = np.meshgrid(*[list_no for _ in range(3)], sparse=True)
a = ((x>=y) & (y>=z)).nonzero() # this maybe the problem
output
(array([0, 0, 0, 1, 1, 1, 1, 2, 2, 2]), array([0, 1, 2, 1, 1, 2, 2, 2, 2, 2]), array([0, 0, 0, 0, 1, 0, 1, 0, 1, 2]))
whereas, the intended output
[[0. 0. 0. ]
[0.1 0. 0. ]
[0.1 0.1 0. ]
[0.1 0.1 0.1]
[0.2 0. 0. ]
[0.2 0.1 0. ]
[0.2 0.1 0.1]
[0.2 0.2 0. ]
[0.2 0.2 0.1]
[0.2 0.2 0.2]]
ndarray.nonzero as well as np.where return tuples of arrays of indices. This makes unpacking those indices into separate arrays, which can then be used to index along a given axis. Stacking them up into a 2D array is trivial though, simply build a new array and transpose as:
ix = np.array(((x>=y) & (y>=z)).nonzero()).T
Then you can easily use the array of indices to index list_no as:
list_no[ix]
array([[0. , 0. , 0. ],
[0. , 0.1, 0. ],
[0. , 0.2, 0. ],
[0.1, 0.1, 0. ],
[0.1, 0.1, 0.1],
[0.1, 0.2, 0. ],
[0.1, 0.2, 0.1],
[0.2, 0.2, 0. ],
[0.2, 0.2, 0.1],
[0.2, 0.2, 0.2]])

Add complementary values to numpy array

I have a 1D numpy array, for example the following:
import numpy as np
arr = np.array([0.33, 0.2, 0.8, 0.9])
Now I would like to change the array so that also one minus the value is included. That means the array should look like:
[[0.77, 0.33],
[0.8, 0.2],
[0.2, 0.8],
[0.1, 0.9]]
How can this be done?
>>> np.vstack((1 - arr, arr)).T
array([[0.67, 0.33],
[0.8 , 0.2 ],
[0.2 , 0.8 ],
[0.1 , 0.9 ]])
Alternatively, you can create an empty array and fill in entries:
>>> np.empty((*arr.shape, 2))
>>> x[..., 0] = 1 - arr
>>> x[..., 1] = arr
>>> x
array([[0.67, 0.33],
[0.8 , 0.2 ],
[0.2 , 0.8 ],
[0.1 , 0.9 ]])
Try column_stack
np.column_stack([1 - arr, arr])
Out[33]:
array([[0.67, 0.33],
[0.8 , 0.2 ],
[0.2 , 0.8 ],
[0.1 , 0.9 ]])
Use:
arr=np.insert(1-arr,np.arange(len(arr)),arr).reshape(-1,2)
arr
Output:
array([[0.33, 0.67],
[0.2 , 0.8 ],
[0.8 , 0.2 ],
[0.9 , 0.1 ]])

Convert list of value related with another list of id to matrices

I have data with list of id
a = [52, 10, 31]
b = [20, 43]
c = [43, 20, 10, 52]
and the score of id like above
a = [0.89, 0.75, 0.6]
b = [0.9, 0.86]
c = [0.98, 0.78, 0.65, 0.63]
I want to convert to matrices 3(a, b, c) x 5(union of id and sort id ascending) like this
matrices = [[0.75 0 0.6 0 0.89]
[0 0.9 0 0.86 0 ]
[0.65 0.78 0 0.98 0.63]]
Anyone can solve this? Thanks
With plain Python lists, you could try something like the following:
indices = [[1, 3, 5], [2, 4], [1, 2, 4, 5]]
scores = [[0.75, 0.6, 0.89], [0.9, 0.86], [0.65, 0.78, 0.98, 0.63]]
matrix = [[0] * 5 for _ in range(3)]
for i, (ind, scr) in enumerate(zip(indices, scores)):
for k, s in zip(ind, scr):
matrix[i][k-1] = s
print(matrix)
# [[0.75, 0, 0.6, 0, 0.89], [0, 0.9, 0, 0.86, 0], [0.65, 0.78, 0, 0.98, 0.63]]
Or as a horrible one-liner:
>>> [[next(scr) if i+1 in ind else 0 for i in range(5)]
... for ind, scr in ((set(ind), iter(scr)) for ind, scr in zip(indices, scores))]
...
[[0.75, 0, 0.6, 0, 0.89],
[0, 0.9, 0, 0.86, 0],
[0.65, 0.78, 0, 0.98, 0.63]]
Update: If the ids are not the indices, you have to re-map them first, then, you can continue with the first approach.
ids = [52, 10, 31], [20, 43], [43, 20, 10, 52]
scores = [0.89, 0.75, 0.6], [0.9, 0.86], [0.98, 0.78, 0.65, 0.63]
d = {x: i+1 for i, x in enumerate(sorted(set.union(*map(set, ids))))}
# {52: 5, 10: 1, 43: 4, 20: 2, 31: 3}
matrix = [[0] * max(d.values()) for _ in range(len(ids))]
for i, (ind, scr) in enumerate(zip(ids, scores)):
for k, s in zip(ind, scr):
matrix[i][d[k]-1] = s
print(matrix)
# [[0.75, 0, 0.6, 0, 0.89], [0, 0.9, 0, 0.86, 0], [0.65, 0.78, 0, 0.98, 0.63]]
Assuming that you fill the 0s beforehand:
Using something like:
a = [1, 3, 5]
b1 = [x for x in range(a[0], a[-1] + 1)]
a = set(a)
missing_elem = list(a ^ set(b1))
print((missing_elem))
OUTPUT:
[2,4]
and then append those to the original list a
Now:
import numpy as np
a = [0.75, 0, 0.6, 0, 0.89]
b = [0, 0.9, 0, 0.86, 0]
c = [0.65, 0.78, 0, 0.98, 0.63]
print(np.column_stack((a,b,c)))
OUTPUT:
[[0.75 0. 0.65]
[0. 0.9 0.78]
[0.6 0. 0. ]
[0. 0.86 0.98]
[0.89 0. 0.63]]
It looks like you want to create a sparse matrix, you may try coo_matrix from scipy
import numpy as np
from scipy.sparse import coo_matrix
data_a = [0.75, 0.6, 0.89]
data_b = [0.9, 0.86]
data_c = [0.65, 0.78, 0.98, 0.63]
id_a = [1, 3, 5]
id_b = [2, 4]
id_c = [1, 2, 4, 5]
sp_a = coo_matrix((data_a, ([0] * len(data_a), [x - 1 for x in id_a])), shape=(1, 5)).toarray()
sp_b = coo_matrix((data_b, ([0] * len(data_b), [x - 1 for x in id_b])), shape=(1, 5)).toarray()
sp_c = coo_matrix((data_c, ([0] * len(data_c), [x - 1 for x in id_c])), shape=(1, 5)).toarray()
matrices = np.vstack([sp_a, sp_b, sp_c])
print(matrices)
# >>> matrices
# array([[0.75, 0. , 0.6 , 0. , 0.89],
# [0. , 0.9 , 0. , 0.86, 0. ],
# [0.65, 0.78, 0. , 0.98, 0.63]])
It's a dirty code, but you'll get the results.
a_id = [1, 3, 5]
b_id = [2, 4]
c_id = [1, 2, 4, 5]
a_score = [0.75, 0.6, 0.89]
b_score = [0.9, 0.86]
c_score = [0.65, 0.78, 0.98, 0.63]
N, M = 3, 5
matrices = []
for i in range(N):
matrices.append([0 for j in range(M)])
for i in range(N):
for j in range(M):
try:
if i == 0:
matrices[i][a_id[j]-1] = a_score[j]
elif i == 1:
matrices[i][b_id[j]-1] = b_score[j]
else:
matrices[i][c_id[j]-1] = c_score[j]
except:
pass
print(matrices)
How about this if there are many ids and scores?
list_id = []
list_score = []
list_id.extend((a_id, b_id, c_id))
list_score.extend((a_score, b_score, c_score))
N, M = len(list_score), max(map(max, list_id))
matrices = []
for i in range(N):
matrices.append([0 for j in range(M)])
for i in range(N):
for j in range(M):
try:
matrices[i][list_id[i][j] - 1] = list_score[i][j]
except IndexError:
pass

Finding the Steady State Output of a Linear Recurrent Network

I'm taking a Computational Neuroscience class on Coursera. So far it's been going great! However, I'm getting a little stuck on one of the quiz problems.
I am not taking this class for a certificate or anything. Solely for fun. I already took the quiz and after awhile, I guessed the answer, so this is not even going to be answering the quiz.
The question is framed as the following:
Suppose that we had a linear recurrent network of 5 input nodes and 5 output nodes. Let us say that our network's weight matrix W is:
W = [0.6 0.1 0.1 0.1 0.1]
[0.1 0.6 0.1 0.1 0.1]
[0.1 0.1 0.6 0.1 0.1]
[0.1 0.1 0.1 0.6 0.1]
[0.1 0.1 0.1 0.1 0.6]
(Essentially, all 0.1, besides 0.6 on the diagonals.)
Suppose that we have a static input vector u:
u = [0.6]
[0.5]
[0.6]
[0.2]
[0.1]
Finally, suppose that we have a recurrent weight matrix M:
M = [-0.25, 0, 0.25, 0.25, 0]
[0, -0.25, 0, 0.25, 0.25]
[0.25, 0, -0.25, 0, 0.25]
[0.25, 0.25, 0, -0.25, 0]
[0, 0.25, 0.25, 0, -0.25]
Which of the following is the steady state output v_ss of the network?
(Hint: See the lecture on recurrent networks, and consider writing some Octave or Matlab code to handle the eigenvectors/values (you may use the "eig" function))'
The notes for the class can be found here. Specifically, the equation for the steady state formula can be found on slides 5 and 6.
I have the following code.
import numpy as np
# Construct W, the network weight matrix
W = np.ones((5,5))
W = W / 10.
np.fill_diagonal(W, 0.6)
# Construct u, the static input vector
u = np.zeros(5)
u[0] = 0.6
u[1] = 0.5
u[2] = 0.6
u[3] = 0.2
u[4] = 0.1
# Connstruct M, the recurrent weight matrix
M = np.zeros((5,5))
np.fill_diagonal(M, -0.25)
for i in range(3):
M[2+i][i] = 0.25
M[i][2+i] = 0.25
for i in range(2):
M[3+i][i] = 0.25
M[i][3+i] = 0.25
# We need to matrix multiply W and u together to get h
# NOTE: cannot use W * u, that's going to do a scalar multiply
# it's element wise otherwise
h = W.dot(u)
print 'This is h'
print h
# Ok then the big deal is:
# h dot e_i
# v_ss = sum_(over all eigens) ------------ e_i
# 1 - lambda_i
eigs = np.linalg.eig(M)
eigenvalues = eigs[0]
eigenvectors = eigs[1]
v_ss = np.zeros(5)
for i in range(5):
v_ss += (np.dot(h,eigenvectors[:, i]))/((1.0-eigenvalues[i])) * eigenvectors[:,i]
print 'This is our steady state v_ss'
print v_ss
The correct answer is:
[0.616, 0.540, 0.609, 0.471, 0.430]
This is what I am getting:
This is our steady state v_ss
[ 0.64362264 0.5606784 0.56007018 0.50057043 0.40172501]
Can anyone spot my bug? Thank you so much! I greatly appreciate it and apologize for the long blog post. Essentially, all you need to look at, is slide 5 and 6 on that top link.
I tryied your solution with my matrices:
W = np.array([[0.6 , 0.1 , 0.1 , 0.1 , 0.1],
[0.1 , 0.6 , 0.1 , 0.1 , 0.1],
[0.1 , 0.1 , 0.6 , 0.1 , 0.1],
[0.1 , 0.1 , 0.1 , 0.6 , 0.1],
[0.1 , 0.1 , 0.1 , 0.1 , 0.6]])
u = np.array([.6, .5, .6, .2, .1])
M = np.array([[-0.75 , 0 , 0.75 , 0.75 , 0],
[0 , -0.75 , 0 , 0.75 , 0.75],
[0.75 , 0 , -0.75 , 0 , 0.75],
[0.75 , 0.75 , 0.0 , -0.75 , 0],
[0 , 0.75 , 0.75 , 0 , -0.75]])
and your code generated the right solution:
This is h
[ 0.5 0.45 0.5 0.3 0.25]
This is our steady state v_ss
[ 1.663354 1.5762684 1.66344153 1.56488258 1.53205348]
Maybe the problem is with the Test on coursera. Have you tryed to contact them on the forum?

Categories