2
2
from typing import Union
3
3
4
4
import numpy as np
5
- from scipy .sparse import lil_matrix
5
+ from scipy .sparse . coo import coo_matrix
6
6
7
7
from ._typing_utils import Float
8
- from ._typing_utils import FloatArray
8
+ from ._typing_utils import Matrix
9
+ from ._utils import coo_matrix_builder
9
10
10
11
11
12
def build_frame_cost_matrix (
12
- dist_matrix : FloatArray ,
13
- track_cost_cutoff : Float ,
13
+ dist_matrix : coo_matrix_builder ,
14
+ * ,
14
15
track_start_cost : Optional [Float ],
15
16
track_end_cost : Optional [Float ],
16
- ) -> lil_matrix :
17
+ ) -> coo_matrix :
17
18
"""Build sparce array for frame-linking cost matrix.
18
19
19
20
Parameters
20
21
----------
21
- dist_matrix : FloatArray
22
+ dist_matrix : Matrix or `_utils.coo_matrix_builder`
22
23
The distance matrix for points at time t and t+1.
23
- track_cost_cutoff : Float, optional
24
- The distance cutoff for the connected points in the track
25
24
track_start_cost : Float, optional
26
25
The cost for starting the track (b in Jaqaman et al 2008 NMeth)
27
26
track_end_cost : Float, optional
@@ -35,43 +34,43 @@ def build_frame_cost_matrix(
35
34
M = dist_matrix .shape [0 ]
36
35
N = dist_matrix .shape [1 ]
37
36
38
- C = lil_matrix ((M + N , N + M ), dtype = np .float32 )
39
- ind = np . where (dist_matrix < track_cost_cutoff )
40
- C [( * ind ,)] = dist_matrix [( * ind ,)]
37
+ C = coo_matrix_builder ((M + N , N + M ), dtype = np .float32 )
38
+ C . append_matrix (dist_matrix )
39
+
41
40
if track_start_cost is None :
42
- track_start_cost = np .concatenate (C .data ). max ( ) * 1.05
41
+ track_start_cost = np .max (C .data ) * 1.05
43
42
if track_end_cost is None :
44
- track_end_cost = np .concatenate (C .data ).max () * 1.05
43
+ track_end_cost = np .max (C .data ) * 1.05
44
+
45
45
C [np .arange (M , M + N ), np .arange (N )] = np .ones (N ) * track_end_cost
46
46
C [np .arange (M ), np .arange (N , N + M )] = np .ones (M ) * track_start_cost
47
- ind2 = [ind [1 ] + M , ind [0 ] + N ]
48
- min_val = np .concatenate (C .data ).min () if len (C .data ) > 0 else 0
49
- C [(* ind2 ,)] = min_val
47
+ min_val = np .min (C .data ) if len (C .data ) > 0 else 0
48
+ C [dist_matrix .col + M , dist_matrix .row + N ] = min_val
50
49
51
- return C
50
+ return C . to_coo_matrix ()
52
51
53
52
54
53
def build_segment_cost_matrix (
55
- gap_closing_dist_matrix : Union [lil_matrix , FloatArray ],
56
- splitting_dist_matrix : Union [lil_matrix , FloatArray ],
57
- merging_dist_matrix : Union [lil_matrix , FloatArray ],
54
+ gap_closing_dist_matrix : Union [coo_matrix_builder , Matrix ],
55
+ splitting_dist_matrix : Union [coo_matrix_builder , Matrix ],
56
+ merging_dist_matrix : Union [coo_matrix_builder , Matrix ],
58
57
track_start_cost : Optional [Float ],
59
58
track_end_cost : Optional [Float ],
60
59
no_splitting_cost : Optional [Float ],
61
60
no_merging_cost : Optional [Float ],
62
61
alternative_cost_factor : Float = 1.05 ,
63
62
alternative_cost_percentile : Float = 90 ,
64
63
alternative_cost_percentile_interpolation : str = "lower" ,
65
- ) -> lil_matrix :
64
+ ) -> coo_matrix :
66
65
"""Build sparce array for segment-linking cost matrix.
67
66
68
67
Parameters
69
68
----------
70
- gap_closing_dist_matrix : lil_matrix or FloatArray
69
+ gap_closing_dist_matrix : coo_matrix_builder or Matrix
71
70
The distance matrix for closing gaps between segment i and j.
72
- splitting_dist_matrix : lil_matrix or FloatArray
71
+ splitting_dist_matrix : coo_matrix_builder or Matrix
73
72
The distance matrix for splitting between segment i and time/index j
74
- merging_dist_matrix : lil_matrix or FloatArray
73
+ merging_dist_matrix : coo_matrix_builder or Matrix
75
74
The distance matrix for merging between segment i and time/index j
76
75
track_start_cost : Float, optional
77
76
The cost for starting the track (b in Jaqaman et al 2008 NMeth)
@@ -92,7 +91,7 @@ def build_segment_cost_matrix(
92
91
93
92
Returns
94
93
-------
95
- cost_matrix : Optional[FloatArray ]
94
+ cost_matrix : Optional[coo_matrix ]
96
95
the cost matrix for frame linking, None if not appropriate
97
96
"""
98
97
M = gap_closing_dist_matrix .shape [0 ]
@@ -104,14 +103,14 @@ def build_segment_cost_matrix(
104
103
105
104
S = 2 * M + N1 + N2
106
105
107
- C = lil_matrix ((S , S ), dtype = np .float32 )
106
+ C = coo_matrix_builder ((S , S ), dtype = np .float32 )
108
107
109
- C [: M , : M ] = gap_closing_dist_matrix
110
- C [ M : M + N1 , : M ] = splitting_dist_matrix . T
111
- C [: M , M : M + N2 ] = merging_dist_matrix
108
+ C . append_matrix ( gap_closing_dist_matrix )
109
+ C . append_matrix ( splitting_dist_matrix . T , shift = ( M , 0 ))
110
+ C . append_matrix ( merging_dist_matrix , shift = ( 0 , M ))
112
111
113
- all_data = np . concatenate ( C . data )
114
- if len ( all_data ) == 0 :
112
+ upper_left_size = C . size ( )
113
+ if upper_left_size == 0 :
115
114
return None
116
115
117
116
# Note:
@@ -133,7 +132,7 @@ def build_segment_cost_matrix(
133
132
):
134
133
alternative_cost = (
135
134
np .percentile (
136
- all_data ,
135
+ C . data ,
137
136
alternative_cost_percentile ,
138
137
interpolation = alternative_cost_percentile_interpolation ,
139
138
)
@@ -152,11 +151,12 @@ def build_segment_cost_matrix(
152
151
C [np .arange (2 * M + N1 , S ), np .arange (M , M + N2 )] = np .ones (N2 ) * no_merging_cost
153
152
C [np .arange (M ), np .arange (M + N2 , 2 * M + N2 )] = np .ones (M ) * track_end_cost
154
153
C [np .arange (M , M + N1 ), np .arange (2 * M + N2 , S )] = np .ones (N1 ) * no_splitting_cost
155
- subC = C [: M + N1 , : M + N2 ]
156
- inds = subC .nonzero ()
157
154
min_val = np .min (
158
155
[track_start_cost , track_end_cost , no_splitting_cost , no_merging_cost ]
159
156
)
160
- C [inds [1 ] + M + N1 , inds [0 ] + M + N2 ] = min_val
161
157
162
- return C
158
+ upper_left_rows = C .row [:upper_left_size ]
159
+ upper_left_cols = C .col [:upper_left_size ]
160
+ C [upper_left_cols + M + N1 , upper_left_rows + M + N2 ] = min_val
161
+
162
+ return C .to_coo_matrix ()
0 commit comments