def linear_rf_operator(rf_size, phy_params, dt, calculating_brf=False): """ Calculates the linear operator A needed to convert brf to prf & vis-versa prf = (A^{-1})brf brf = (A)prf Inputs: - size of the prf and/or brf (assumed to be same) - physiological parameters - time resolution of data: - if you wish to calculate brf (return A), or prf (return inverse of A) Outputs: - np.array of size (hrf_size,1) linear operator to convert hrfs """ import numpy as np tau_m_inv = 1. / phy_params['tau_m'] alpha_w = phy_params['alpha_w'] alpha_w_inv = 1. / phy_params['alpha_w'] E0 = phy_params['E0'] V0 = phy_params['V0'] k1, k2, k3 = create_k_parameters(phy_params) c = tau_m_inv * (1 + (1 - E0) * np.log(1 - E0) / E0) from pyhrf.sandbox.physio import buildOrder1FiniteDiffMatrix_central D = buildOrder1FiniteDiffMatrix_central(rf_size, dt) # numpy matrix eye = np.matrix(np.eye(rf_size)) # numpy matrix A3 = -tau_m_inv * ((D + (alpha_w_inv * tau_m_inv) * eye).I) A4 = -c * (D + tau_m_inv * eye).I + (D + tau_m_inv * eye).I * ( (1 - alpha_w) * alpha_w_inv * tau_m_inv**2) * (D + alpha_w_inv * tau_m_inv * eye).I # A = V0 * ( (k1+k2)*A4 + (k3-k2)* A3 ) # A = h x2^{-1} = Omega^{-1} # linear vs non-linear if phy_params['linear']: sign = 1. if phy_params['obata']: # change of sign sign = -1 # A = h x2^{-1} = Omega^{-1} A = V0 * ((k1 + k2) * A4 + sign * (k3 - k2) * A3) else: # non-linear A = V0 * \ (k1 * A4 + k2 * (eye - (eye - A4) * np.linalg.inv(eye - A3)) + k3 * A3) if (calculating_brf): return A.A else: # calculating_prf return (A.I).A
def linear_rf_operator(rf_size, phy_params, dt, calculating_brf=False): """ Calculates the linear operator A needed to convert brf to prf & vis-versa prf = (A^{-1})brf brf = (A)prf Inputs: - size of the prf and/or brf (assumed to be same) - physiological parameters - time resolution of data: - if you wish to calculate brf (return A), or prf (return inverse of A) Outputs: - np.array of size (hrf_size,1) linear operator to convert hrfs """ import numpy as np tau_m_inv = 1. / phy_params['tau_m'] alpha_w = phy_params['alpha_w'] alpha_w_inv = 1. / phy_params['alpha_w'] E0 = phy_params['E0'] V0 = phy_params['V0'] k1, k2, k3 = create_k_parameters(phy_params) c = tau_m_inv * (1 + (1 - E0) * np.log(1 - E0) / E0) from pyhrf.sandbox.physio import buildOrder1FiniteDiffMatrix_central D = buildOrder1FiniteDiffMatrix_central(rf_size, dt) # numpy matrix eye = np.matrix(np.eye(rf_size)) # numpy matrix A3 = - tau_m_inv * ((D + (alpha_w_inv * tau_m_inv) * eye).I) A4 = - c * (D + tau_m_inv * eye).I + (D + tau_m_inv * eye).I * ((1 - alpha_w) * alpha_w_inv * tau_m_inv**2) * (D + alpha_w_inv * tau_m_inv * eye).I # A = V0 * ( (k1+k2)*A4 + (k3-k2)* A3 ) # A = h x2^{-1} = Omega^{-1} # linear vs non-linear if phy_params['linear']: sign = 1. if phy_params['obata']: # change of sign sign = -1 # A = h x2^{-1} = Omega^{-1} A = V0 * ((k1 + k2) * A4 + sign * (k3 - k2) * A3) else: # non-linear A = V0 * \ (k1 * A4 + k2 * (eye - (eye - A4) * np.linalg.inv(eye - A3)) + k3 * A3) if (calculating_brf): return A.A else: # calculating_prf return (A.I).A
def linear_rf_operator(rf_size, phy_params, dt, calculating_brf=False): """ Calculates the linear operator A needed to convert brf to prf & vis-versa prf = (A^{-1})brf brf = (A)prf Inputs: - size of the prf and/or brf (assumed to be same) - physiological parameters - time resolution of data: - if you wish to calculate brf (return A), or prf (return inverse of A) Outputs: - np.array of size (hrf_size,1) linear operator to convert hrfs """ import numpy as np tau_m_inv = 1. / phy_params['tau_m'] alpha_w = phy_params['alpha_w'] alpha_w_inv = 1. / phy_params['alpha_w'] E0 = phy_params['E0'] V0 = phy_params['V0'] k1 = phy_params['k1'] k2 = phy_params['k2'] k3 = phy_params['k3'] c = tau_m_inv * (1 + (1 - E0) * np.log(1 - E0) / E0) from pyhrf.sandbox.physio import buildOrder1FiniteDiffMatrix_central D = buildOrder1FiniteDiffMatrix_central(rf_size, dt) #numpy matrix eye = np.matrix(np.eye(int(rf_size))) #numpy matrix A3 = tau_m_inv * ((D + (alpha_w_inv * tau_m_inv) * eye).I) A4 = c * (D + tau_m_inv * eye).I - (D + tau_m_inv * eye).I * ( (1 - alpha_w) * alpha_w_inv * tau_m_inv**2) * (D + alpha_w_inv * tau_m_inv * eye).I A = V0 * ((k1 + k2) * A4 + (k3 - k2) * A3) # A = h x2^{-1} = Omega^{-1} if (calculating_brf): return -A.A else: #calculating_prf return -(A.I).A
def linear_rf_operator(rf_size, phy_params, dt, calculating_brf=False): """ Calculates the linear operator A needed to convert brf to prf & vis-versa prf = (A^{-1})brf brf = (A)prf Inputs: - size of the prf and/or brf (assumed to be same) - physiological parameters - time resolution of data: - if you wish to calculate brf (return A), or prf (return inverse of A) Outputs: - np.array of size (hrf_size,1) linear operator to convert hrfs """ import numpy as np tau_m_inv = 1./phy_params['tau_m'] alpha_w = phy_params['alpha_w'] alpha_w_inv = 1./phy_params['alpha_w'] E0 = phy_params['E0'] V0 = phy_params['V0'] k1 = phy_params['k1'] k2 = phy_params['k2'] k3 = phy_params['k3'] c = tau_m_inv * ( 1 + (1-E0)*np.log(1-E0)/E0 ) from pyhrf.sandbox.physio import buildOrder1FiniteDiffMatrix_central D = buildOrder1FiniteDiffMatrix_central(rf_size,dt) #numpy matrix eye = np.matrix(np.eye(rf_size)) #numpy matrix A3 = tau_m_inv*( (D + (alpha_w_inv*tau_m_inv)*eye).I ) A4 = c * (D+tau_m_inv*eye).I - (D+tau_m_inv*eye).I*((1-alpha_w)*alpha_w_inv* tau_m_inv**2)* (D+alpha_w_inv*tau_m_inv*eye).I A = V0 * ( (k1+k2)*A4 + (k3-k2)* A3 ) if (calculating_brf): return -A.A else: #calculating_prf return -(A.I).A
def calc_linear_rfs(simu_brf, simu_prf, phy_params, dt, normalized_rfs=True): """ Calculate 'prf given brf' and 'brf given prf' based on the a linearization around steady state of the physiological model as described in Friston 2000. Input: - simu_brf, simu_prf: brf and prf from the physiological simulation from which you wish to calculate the respective prf and brf. Assumed to be of size (1,hrf.size) - phy_params - normalized_rfs: set to True if simu_hrfs are normalized Output: - calc_brf, calc_prf: np.arrays of shape (hrf.size, 1) - q_linear, v_linear: q and v calculated according to the linearized model Note: These calculations do not account for any rescaling between brf and prf. This means the input simu_brf, simu_prf should NOT be rescaled. ** Warning**: - this function assumes prf.size == brf.size and uses this to build D, I - if making modifications: calc_brf, calc_prf have a truncation error (due to the finite difference matrix used) on the order of O(dt)^2. If for any reason a hack is later implemented to set the y-intecepts of brf_calc, prf_calc to zero by setting the first row of X4, X3 = 0, this will raise a singular matrix error in the calculation of calc_prf (due to X.I command), so this error is helpful in this case """ D = buildOrder1FiniteDiffMatrix_central(simu_prf.size, dt) #numpy matrix I = np.matrix(np.eye(simu_prf.size)) #numpy matrix #TODO: elimlinate prf.size dependency tau_m = phy_params['tau_m'] tau_m_inv = 1. / tau_m #when tau_m=1, singular matrix formed by (D+tau_m_inv*I) alpha_w = phy_params['alpha_w'] alpha_w_inv = 1. / phy_params['alpha_w'] E0 = phy_params['E0'] V0 = phy_params['V0'] k1 = phy_params['k1'] k2 = phy_params['k2'] k3 = phy_params['k3'] c = tau_m_inv * (1 + (1 - E0) * np.log(1 - E0) / E0) #transform to (hrf.size,1) matrix for calcs simu_prf = np.matrix(simu_prf).transpose() simu_brf = np.matrix(simu_brf).transpose() X3 = tau_m_inv * ((D + (alpha_w_inv * tau_m_inv) * I).I) X4= c *(D+tau_m_inv*I).I - (D+tau_m_inv*I).I*((1-alpha_w)*alpha_w_inv*\ tau_m_inv**2)* (D+alpha_w_inv*tau_m_inv*I).I X = V0 * ((k1 + k2) * X4 + (k3 - k2) * X3) #for error checking q_linear = 1 - X4 * (-simu_prf) v_linear = 1 - X3 * (-simu_prf) calc_brf = X * (-simu_prf) calc_prf = -X.I * simu_brf #convert to np.arrays calc_prf = calc_prf.A calc_brf = calc_brf.A q_linear = q_linear.A v_linear = v_linear.A if normalized_rfs: calc_prf /= (calc_prf**2).sum()**.5 calc_brf /= (calc_brf**2).sum()**.5 return calc_brf, calc_prf, q_linear, v_linear
def calc_linear_rfs(simu_brf, simu_prf, phy_params, dt, normalized_rfs=True): """ Calculate 'prf given brf' and 'brf given prf' based on the a linearization around steady state of the physiological model as described in Friston 2000. Input: - simu_brf, simu_prf: brf and prf from the physiological simulation from which you wish to calculate the respective prf and brf. Assumed to be of size (1,hrf.size) - phy_params - normalized_rfs: set to True if simu_hrfs are normalized Output: - calc_brf, calc_prf: np.arrays of shape (hrf.size, 1) - q_linear, v_linear: q and v calculated according to the linearized model Note: These calculations do not account for any rescaling between brf and prf. This means the input simu_brf, simu_prf should NOT be rescaled. ** Warning**: - this function assumes prf.size == brf.size and uses this to build D, I - if making modifications: calc_brf, calc_prf have a truncation error (due to the finite difference matrix used) on the order of O(dt)^2. If for any reason a hack is later implemented to set the y-intecepts of brf_calc, prf_calc to zero by setting the first row of X4, X3 = 0, this will raise a singular matrix error in the calculation of calc_prf (due to X.I command), so this error is helpful in this case """ D = buildOrder1FiniteDiffMatrix_central(simu_prf.size,dt) #numpy matrix I = np.matrix(np.eye(simu_prf.size)) #numpy matrix #TODO: elimlinate prf.size dependency tau_m = phy_params['tau_m'] tau_m_inv = 1./tau_m #when tau_m=1, singular matrix formed by (D+tau_m_inv*I) alpha_w = phy_params['alpha_w'] alpha_w_inv = 1./phy_params['alpha_w'] E0 = phy_params['E0'] V0 = phy_params['V0'] k1 = phy_params['k1'] k2 = phy_params['k2'] k3 = phy_params['k3'] c = tau_m_inv * ( 1 + (1-E0)*np.log(1-E0)/E0 ) #transform to (hrf.size,1) matrix for calcs simu_prf = np.matrix(simu_prf).transpose() simu_brf = np.matrix(simu_brf).transpose() X3 = tau_m_inv*( (D + (alpha_w_inv*tau_m_inv)*I).I ) X4= c *(D+tau_m_inv*I).I - (D+tau_m_inv*I).I*((1-alpha_w)*alpha_w_inv*\ tau_m_inv**2)* (D+alpha_w_inv*tau_m_inv*I).I X = V0 * ( (k1+k2)*X4 + (k3-k2)* X3 ) #for error checking q_linear = 1-X4*(-simu_prf) v_linear = 1-X3*(-simu_prf) calc_brf = X*(-simu_prf) calc_prf = -X.I*simu_brf #convert to np.arrays calc_prf = calc_prf.A calc_brf = calc_brf.A q_linear = q_linear.A v_linear = v_linear.A if normalized_rfs: calc_prf /= (calc_prf**2).sum()**.5 calc_brf /= (calc_brf**2).sum()**.5 return calc_brf, calc_prf, q_linear, v_linear