def test_corrcc(): data1 = np.random.rand(50000) * 2 * np.pi data2 = np.random.rand(50000) * 2 * np.pi assert_allclose(pycircstat.corrcc(data1, data2), 0., rtol=3 * 1e-2, atol=3 * 1e-2)
def cl_corr(x, phase, min_slope, max_slope, ci=.05, bootstrap_iter=1000, return_pval=False): ''' Function to (1) fit a line to circular-linear data and (2) determine the circular-linear correlation coefficient Parameters ---------- x : array real-valued vector of `linear' instances (e.g. places, attenuations, frequencies, etc.) phase : array vector of phases at instances x in rad (values need NOT be restricted to the interval [0, 2pi) [min_slope, max_slope]: float interval of slopes in which the best_slope is determined. In contrast to linear regression, we MUST restrict the range of slopes to some `useful' range determined by prior knowledge. ATTENTION ! because this is a possible source of errors, in particular for low numbers of data points. ci : float level of confidence desired, e.g. .05 for 95 % confidence bootstrap_iter : int number of bootstrap iterations (number of samples if None) return_pval : bool return pvalue instead of confidence interval See also -------- pycircstat.corrcc Returns ------- circ_lin_corr : float circular-linear correlation coefficient ci/pval : array confidence interval slope : float slope of the fitted line in rad phi0_deg : float phase offset of the fitted line in deg RR : float goodness of fit ''' phi0, slope, RR = cl_regression(x, phase, min_slope, max_slope) # fit line to data circ_x = np.mod(2 * np.pi * abs(slope) * x, 2 * np.pi) # convert linear variable to circular one if return_pval: p_uniform = 0.5 pval_x, _ = rayleigh(circ_x) pval_y, _ = rayleigh(phase) if (pval_x > p_uniform) or (pval_y > p_uniform): circ_lin_corr, pval, _ = corr_cc_uniform(circ_x, phase) else: circ_lin_corr, pval, _ = corr_cc(circ_x, phase) return circ_lin_corr, pval, slope, phi0, RR else: circ_lin_corr, ci_out = corrcc(circ_x, phase, ci=ci, bootstrap_iter=bootstrap_iter) return circ_lin_corr, ci_out, slope, phi0, RR
def test_corrcc_ci_2d(): data1 = np.random.rand(2, 200) * np.pi data2 = np.asarray(data1) out1, (out2, out3) = pycircstat.corrcc(data1, data2, ci=0.95, axis=1) exp1, (exp2, exp3) = (np.ones(2), pycircstat.CI(np.ones(2), np.ones(2))) assert_allclose(out1, exp1) assert_allclose(out2, exp2) assert_allclose(out3, exp3)
def find_circular_correlations(two_mod_df: pd.DataFrame): df_nonan = two_mod_df.dropna() grouped = df_nonan.groupby(['Mouse', 'Slide']) correlations = {} mouse = [] slide = [] for name, group in grouped: radians = group.values*2*np.pi/180 n = np.shape(radians)[0] if n < 100: continue corr = circ.corrcc(radians[:, 0], radians[:, 1]) correlations[name] = [corr, n] mouse.append(name[0]) slide.append(name[1]) index = pd.MultiIndex.from_arrays([mouse, slide], names=['Mouse', 'Slide']) correlations = pd.DataFrame.from_dict(correlations, orient='index', columns=['Correlation', 'n']) correlations.set_index(index, inplace=True) return correlations
def circ_lin_regress(phases, coords, theta_r, params): """ """ n = phases.shape[1] pos_x = np.expand_dims(coords[:, 0], 1) pos_y = np.expand_dims(coords[:, 1], 1) # compute predicted phases for angle and phase offset x = np.expand_dims(phases, 2) - params[:, 0] * pos_x - params[:, 1] * pos_y # Compute resultant vector length. This is faster than calling pycircstat.resultant_vector_length x1 = numexpr.evaluate('sum(cos(x) / n, axis=1)') x1 = numexpr.evaluate('x1 ** 2') x2 = numexpr.evaluate('sum(sin(x) / n, axis=1)') x2 = numexpr.evaluate('x2 ** 2') Rs = numexpr.evaluate('-sqrt(x1 + x2)') # for each time and event, find the parameters with the smallest -R min_vals = theta_r[np.argmin(Rs, axis=1)] sl = min_vals[:, 1] * np.array( [np.cos(min_vals[:, 0]), np.sin((min_vals[:, 0]))]) offs = np.arctan2( np.sum(np.sin(phases.T - sl[0, :] * pos_x - sl[1, :] * pos_y), axis=0), np.sum(np.cos(phases.T - sl[0, :] * pos_x - sl[1, :] * pos_y), axis=0)) pos_circ = np.mod(sl[0, :] * pos_x + sl[1, :] * pos_y + offs, 2 * np.pi) # compute circular correlation coefficient between actual phases and predicited phases circ_corr_coef = pycircstat.corrcc(phases.T, pos_circ, axis=0) # compute adjusted r square r2_adj = circ_corr_coef**2 wave_ang = min_vals[:, 0] wave_freq = min_vals[:, 1] return wave_ang, wave_freq, r2_adj
def circ_lin_regress(phases, coords, theta_r, params): """ """ n = phases.shape[1] pos_x = np.expand_dims(coords[:, 0], 1) pos_y = np.expand_dims(coords[:, 1], 1) # compute predicted phases for angle and phase offset x = np.expand_dims(phases, 2) - params[:, 0] * pos_x - params[:, 1] * pos_y # Compute resultant vector length. This is faster than calling pycircstat.resultant_vector_length x1 = numexpr.evaluate('sum(cos(x) / n, axis=1)') x1 = numexpr.evaluate('x1 ** 2') x2 = numexpr.evaluate('sum(sin(x) / n, axis=1)') x2 = numexpr.evaluate('x2 ** 2') Rs = numexpr.evaluate('-sqrt(x1 + x2)') # for each time and event, find the parameters with the smallest -R min_vals = theta_r[np.argmin(Rs, axis=1)] sl = min_vals[:, 1] * np.array([np.cos(min_vals[:, 0]), np.sin((min_vals[:, 0]))]) offs = np.arctan2(np.sum(np.sin(phases.T - sl[0, :] * pos_x - sl[1, :] * pos_y), axis=0), np.sum(np.cos(phases.T - sl[0, :] * pos_x - sl[1, :] * pos_y), axis=0)) pos_circ = np.mod(sl[0, :] * pos_x + sl[1, :] * pos_y + offs, 2 * np.pi) # compute circular correlation coefficient between actual phases and predicited phases circ_corr_coef = pycircstat.corrcc(phases.T, pos_circ, axis=0) # compute adjusted r square r2_adj = circ_corr_coef ** 2 wave_ang = min_vals[:, 0] wave_freq = min_vals[:, 1] return wave_ang, wave_freq, r2_adj
def test_corrcc(): import pycircstat np.random.seed(0) x = np.random.rand(1000) y = np.random.rand(1000) assert_almost_equal(corr_circular(x, y), pycircstat.corrcc(x, y))
def test_corrcc_ci(): data1 = np.random.rand(200) * 2 * np.pi data2 = np.asarray(data1) exp = (1., pycircstat.CI(1., 1.)) assert_equal(pycircstat.corrcc(data1, data2, ci=0.95), exp)