@@ -43,9 +43,11 @@ def segmented_IVIM_fit(bvalues, dw_data, b_cutoff = 200, bounds=([0.0001, 0.0, 0
43
43
return D , f , Dp
44
44
45
45
46
- def d_fit_iterative_wls (bvalues_D , log_signal , max_iter = 500 , tolerance = 1e-6 ):
46
+ def d_fit_iterative_wls (bvalues_D , log_signal , max_iter = 50 ):
47
47
"""
48
48
Function to calculate D using an iterative wlls on the log(signal)
49
+ weights for the wlls are initialized from the predicted signal of a lls as described in
50
+ http://dx.doi.org/10.1016/j.neuroimage.2013.05.028 equation (7)
49
51
50
52
Parameters:
51
53
log_signal: the log() of the signal above the threshold for segmented fitting
@@ -54,25 +56,23 @@ def d_fit_iterative_wls(bvalues_D, log_signal, max_iter=500, tolerance= 1e-6):
54
56
55
57
max_iter: the maximum number of iterations for WLS
56
58
57
- tolerance: the tolerance for early stopping of the WLS
58
59
"""
59
60
60
- bvals = sm .add_constant (bvalues_D )
61
- weights = np .ones_like (log_signal )
61
+ bvals = sm .add_constant (- bvalues_D )
62
+ # First do a LLS to initialize the weights
63
+ beta_lls = np .linalg .lstsq (bvals , log_signal , rcond = None )[0 ]
64
+ # initialize the weights based on the predicted signals W=diag(exp(2*X*Beta_lls))
65
+ init_weights = np .exp (2 * bvals @beta_lls )
66
+ weights = init_weights
62
67
63
68
for i in range (max_iter ):
64
69
# Weighted linear regression
65
70
model = sm .WLS (log_signal , bvals , weights = weights )
66
71
results = model .fit ()
67
- signal_pred = results .predict (bvals )
68
- residuals = log_signal - signal_pred
69
- new_weights = 1 / np .maximum (residuals ** 2 , 1e-10 )
70
-
71
- if np .linalg .norm (new_weights - weights ) < tolerance :
72
- break
72
+ # The weights for the next iteration are based on the predicted signal of this iteration
73
+ new_weights = np .exp (2 * bvals @results .params )
73
74
weights = new_weights
74
75
75
- ln_b0_intercept , D_neg = results .params
76
+ ln_b0_intercept , D = results .params
76
77
b0_intercept = np .exp (ln_b0_intercept )
77
- D = - D_neg
78
78
return D , b0_intercept
0 commit comments