@@ -6,15 +6,20 @@ from cython.view cimport array as cvarray
6
6
from libc .math cimport log , sqrt , isnan , NAN
7
7
from cpython .mem cimport PyMem_Malloc , PyMem_Realloc , PyMem_Free
8
8
cimport scipy .linalg .cython_blas as blas
9
+ cimport numpy as cnp
9
10
11
+ cnp .import_array ()
12
+
13
+ ctypedef cnp .int64_t int_t
14
+ ctypedef cnp .float64_t float_t
10
15
11
16
@cython .boundscheck (False )
12
17
@cython .cdivision (True )
13
- cpdef double [:] calc (
14
- double [:, :] data , long [:] desc ,
15
- long [:] cv_desc , int n ,
16
- int method_idx , double [:, :] noise = None ,
17
- double prior_lambda = 1 , double prior_weight = 0.1 ,
18
+ cpdef float_t [:] calc (
19
+ float_t [:, :] data , int_t [:] desc ,
20
+ int_t [:] cv_desc , int n ,
21
+ int method_idx , float_t [:, :] noise = None ,
22
+ float_t prior_lambda = 1 , float_t prior_weight = 0.1 ,
18
23
int weighting = 1 , int crossval = 0 ):
19
24
# calculates an RDM from a double array of data with integer descriptors
20
25
# There are no checks or saveguards in this function!
@@ -37,17 +42,17 @@ cpdef double [:] calc(
37
42
# 0: each row has equal weight
38
43
# 1: rows weighted by number of valid measurements
39
44
cdef :
40
- double [:] vec_i
41
- double [:] vec_j
42
- double weight , sim
43
- double [:] weights
44
- double [:] values
45
+ float_t [:] vec_i
46
+ float_t [:] vec_j
47
+ float_t weight , sim
48
+ float_t [:] weights
49
+ float_t [:] values
45
50
int i , j , idx
46
51
int n_rdm = (n * (n - 1 )) / 2
47
52
int n_dim = data .shape [1 ]
48
- double prior_lambda_l = prior_lambda * prior_weight
49
- double prior_weight_l = 1 + prior_weight
50
- double [:, :] log_data
53
+ float_t prior_lambda_l = prior_lambda * prior_weight
54
+ float_t prior_weight_l = 1 + prior_weight
55
+ float_t [:, :] log_data
51
56
if (method_idx > 4 ) or (method_idx < 1 ):
52
57
raise ValueError ('dissimilarity method not recognized!' )
53
58
# precompute stuff for poisson KL
@@ -58,8 +63,8 @@ cpdef double [:] calc(
58
63
for j in range (n_dim ):
59
64
data [i , j ] = (data [i , j ] + prior_lambda_l ) / prior_weight_l
60
65
log_data [i , j ] = log (data [i , j ])
61
- weights = < double [:(n_rdm + n )]> PyMem_Malloc ((n_rdm + n ) * sizeof (double ))
62
- values = < double [:(n_rdm + n )]> PyMem_Malloc ((n_rdm + n ) * sizeof (double ))
66
+ weights = < float_t [:(n_rdm + n )]> PyMem_Malloc ((n_rdm + n ) * sizeof (float_t ))
67
+ values = < float_t [:(n_rdm + n )]> PyMem_Malloc ((n_rdm + n ) * sizeof (float_t ))
63
68
for idx in range (n_rdm + n ):
64
69
weights [idx ] = 0
65
70
values [idx ] = 0
@@ -74,7 +79,7 @@ cpdef double [:] calc(
74
79
sim , weight = euclid (data [i ], data [i ], n_dim )
75
80
else :
76
81
sim = mahalanobis (data [i ], data [i ], n_dim , noise )
77
- weight = < double > n_dim
82
+ weight = < float_t > n_dim
78
83
elif method_idx == 4 : # method in ['poisson', 'poisson_cv']:
79
84
sim , weight = poisson_cv (data [i ], data [i ], log_data [i ], log_data [i ], n_dim )
80
85
idx = desc [i ]
@@ -97,7 +102,7 @@ cpdef double [:] calc(
97
102
sim , weight = euclid (data [i ], data [j ], n_dim )
98
103
else :
99
104
sim = mahalanobis (data [i ], data [j ], n_dim , noise )
100
- weight = < double > n_dim
105
+ weight = < float_t > n_dim
101
106
elif method_idx == 4 : # method in ['poisson', 'poisson_cv']:
102
107
sim , weight = poisson_cv (data [i ], data [j ], log_data [i ], log_data [j ], n_dim )
103
108
if weight > 0 :
@@ -124,25 +129,25 @@ cpdef double [:] calc(
124
129
125
130
@cython .boundscheck (False )
126
131
@cython .cdivision (True )
127
- cpdef (double , double ) calc_one (
128
- double [:, :] data_i , double [:, :] data_j ,
129
- long [:] cv_desc_i , long [:] cv_desc_j ,
132
+ cpdef (float_t , float_t ) calc_one (
133
+ float_t [:, :] data_i , float_t [:, :] data_j ,
134
+ int_t [:] cv_desc_i , int_t [:] cv_desc_j ,
130
135
int n_i , int n_j ,
131
- int method_idx , double [:, :] noise = None ,
132
- double prior_lambda = 1 , double prior_weight = 0.1 ,
136
+ int method_idx , float_t [:, :] noise = None ,
137
+ float_t prior_lambda = 1 , float_t prior_weight = 0.1 ,
133
138
int weighting = 1 ):
134
139
cdef :
135
140
#double [:] values = np.zeros(n_i * n_j)
136
141
#double [:] weights = np.zeros(n_i * n_j)
137
- double [:] vec_i
138
- double [:] vec_j
139
- double weight , sim , weight_sum , value
142
+ float_t [:] vec_i
143
+ float_t [:] vec_j
144
+ float_t weight , sim , weight_sum , value
140
145
int i , j
141
146
int n_dim = data_i .shape [1 ]
142
- double prior_lambda_l = prior_lambda * prior_weight
143
- double prior_weight_l = 1 + prior_weight
144
- double [:, :] log_data_i
145
- double [:, :] log_data_j
147
+ float_t prior_lambda_l = prior_lambda * prior_weight
148
+ float_t prior_weight_l = 1 + prior_weight
149
+ float_t [:, :] log_data_i
150
+ float_t [:, :] log_data_j
146
151
if (method_idx > 4 ) or (method_idx < 1 ):
147
152
raise ValueError ('dissimilarity method not recognized!' )
148
153
# precompute stuff for poisson KL
@@ -173,7 +178,7 @@ cpdef (double, double) calc_one(
173
178
sim , weight = euclid (data_i [i ], data_j [j ], n_dim )
174
179
else :
175
180
sim = mahalanobis (data_i [i ], data_j [j ], n_dim , noise )
176
- weight = < double > n_dim
181
+ weight = < float_t > n_dim
177
182
elif method_idx == 4 : # method in ['poisson', 'poisson_cv']:
178
183
sim , weight = poisson_cv (data_i [i ], data_j [j ], log_data_i [i ], log_data_j [j ], n_dim )
179
184
if weight > 0 :
@@ -191,8 +196,8 @@ cpdef (double, double) calc_one(
191
196
192
197
193
198
@cython .boundscheck (False )
194
- cpdef (double , double ) similarity (double [:] vec_i , double [:] vec_j , int method_idx ,
195
- int n_dim , double [:, :] noise ):
199
+ cpdef (float_t , float_t ) similarity (float_t [:] vec_i , float_t [:] vec_j , int method_idx ,
200
+ int n_dim , float_t [:, :] noise ):
196
201
"""
197
202
double similarity(double [:] vec_i, double [:] vec_j, int method_idx,
198
203
int n_dim, double [:, :] noise=None)
@@ -203,8 +208,8 @@ cpdef (double, double) similarity(double [:] vec_i, double [:] vec_j, int method
203
208
204
209
Mahalanobis distances require full measurement vectors at the moment!
205
210
"""
206
- cdef double sim
207
- cdef double weight
211
+ cdef float_t sim
212
+ cdef float_t weight
208
213
if method_idx == 1 : # method == 'euclidean':
209
214
sim , weight = euclid (vec_i , vec_j , n_dim )
210
215
elif method_idx == 2 : # method == 'correlation':
@@ -214,15 +219,15 @@ cpdef (double, double) similarity(double [:] vec_i, double [:] vec_j, int method
214
219
sim , weight = euclid (vec_i , vec_j , n_dim )
215
220
else :
216
221
sim = mahalanobis (vec_i , vec_j , n_dim , noise )
217
- weight = < double > n_dim
222
+ weight = < float_t > n_dim
218
223
return sim , weight
219
224
220
225
221
226
@cython .boundscheck (False )
222
- cdef (double , double ) euclid (double [:] vec_i , double [:] vec_j , int n_dim ):
227
+ cdef (float_t , float_t ) euclid (float_t [:] vec_i , float_t [:] vec_j , int n_dim ):
223
228
cdef :
224
- double sim = 0
225
- double weight = 0
229
+ float_t sim = 0
230
+ float_t weight = 0
226
231
int i
227
232
for i in range (n_dim ):
228
233
if not isnan (vec_i [i ]) and not isnan (vec_j [i ]):
@@ -233,12 +238,12 @@ cdef (double, double) euclid(double [:] vec_i, double [:] vec_j, int n_dim):
233
238
234
239
@cython .boundscheck (False )
235
240
@cython .cdivision (True )
236
- cdef (double , double ) poisson_cv (double [:] vec_i , double [:] vec_j ,
237
- double [:] log_vec_i , double [:] log_vec_j ,
241
+ cdef (float_t , float_t ) poisson_cv (float_t [:] vec_i , float_t [:] vec_j ,
242
+ float_t [:] log_vec_i , float_t [:] log_vec_j ,
238
243
int n_dim ):
239
244
cdef :
240
- double sim = 0
241
- double weight = 0
245
+ float_t sim = 0
246
+ float_t weight = 0
242
247
int i
243
248
for i in range (n_dim ):
244
249
if not isnan (vec_i [i ]) and not isnan (vec_j [i ]):
@@ -249,20 +254,20 @@ cdef (double, double) poisson_cv(double [:] vec_i, double [:] vec_j,
249
254
250
255
251
256
@cython .boundscheck (False )
252
- cdef double mahalanobis (double [:] vec_i , double [:] vec_j , int n_dim ,
253
- double [:, :] noise ):
257
+ cdef float_t mahalanobis (float_t [:] vec_i , float_t [:] vec_j , int n_dim ,
258
+ float_t [:, :] noise ):
254
259
cdef :
255
- double * vec1
256
- double * vec2
260
+ float_t * vec1
261
+ float_t * vec2
257
262
int * finite
258
263
int zero = 0
259
264
int one = 1
260
- double onef = 1.0
261
- double zerof = 0.0
265
+ float_t onef = 1.0
266
+ float_t zerof = 0.0
262
267
char trans = b'n'
263
- double sim = 0.0
268
+ float_t sim = 0.0
264
269
int i , j , k , l , n_finite
265
- double [:, :] noise_small
270
+ float_t [:, :] noise_small
266
271
finite = < int * > PyMem_Malloc (n_dim * sizeof (int ))
267
272
# use finite as a bool to choose the non-nan values
268
273
n_finite = 0
@@ -272,11 +277,10 @@ cdef double mahalanobis(double [:] vec_i, double [:] vec_j, int n_dim,
272
277
n_finite += 1
273
278
else :
274
279
finite [i ] = 0
275
- vec1 = < double * > PyMem_Malloc (n_finite * sizeof (double ))
276
- vec2 = < double * > PyMem_Malloc (n_finite * sizeof (double ))
277
- vec3 = < double * > PyMem_Malloc (n_finite * sizeof (double ))
278
- #noise_small = <double [:n_finite, :n_finite]> PyMem_Malloc(n_finite * n_finite * sizeof(double))
279
- noise_small = cvarray (shape = (n_finite , n_finite ), itemsize = sizeof (double ), format = "d" )
280
+ vec1 = < float_t * > PyMem_Malloc (n_finite * sizeof (float_t ))
281
+ vec2 = < float_t * > PyMem_Malloc (n_finite * sizeof (float_t ))
282
+ vec3 = < float_t * > PyMem_Malloc (n_finite * sizeof (float_t ))
283
+ noise_small = cvarray (shape = (n_finite , n_finite ), itemsize = sizeof (float_t ), format = "d" )
280
284
k = 0
281
285
for i in range (n_dim ):
282
286
if finite [i ]:
@@ -300,15 +304,15 @@ cdef double mahalanobis(double [:] vec_i, double [:] vec_j, int n_dim,
300
304
301
305
@cython .boundscheck (False )
302
306
@cython .cdivision (True )
303
- cdef (double , double ) correlation (double [:] vec_i , double [:] vec_j , int n_dim ):
307
+ cdef (float_t , float_t ) correlation (float_t [:] vec_i , float_t [:] vec_j , int n_dim ):
304
308
cdef :
305
- double si = 0.0
306
- double sj = 0.0
307
- double si2 = 0.0
308
- double sj2 = 0.0
309
- double sij = 0.0
310
- double sim
311
- double weight = 0
309
+ float_t si = 0.0
310
+ float_t sj = 0.0
311
+ float_t si2 = 0.0
312
+ float_t sj2 = 0.0
313
+ float_t sij = 0.0
314
+ float_t sim
315
+ float_t weight = 0
312
316
int i
313
317
for i in range (n_dim ):
314
318
if not isnan (vec_i [i ]) and not isnan (vec_j [i ]):
0 commit comments