/// <summary> /// Returns the sample cokurtosis between two arrays. /// Arrays should be of equal length, and contain more than one element. /// </summary> /// <param name="arrayA"></param> /// <param name="arrayB"></param> /// <param name="cokurtosisType"></param> public static double Coskurtosis(double[] arrayA, double[] arrayB, CokurtosisType cokurtosisType) { double m4 = FourthCentralCrossMoment(arrayA, arrayB, cokurtosisType); double sd1 = StandardDeviation(arrayA); double sd2 = StandardDeviation(arrayB); if (cokurtosisType == CokurtosisType.AAAB) { return(m4 / (sd1 * sd1 * sd1 * sd2)); } if (cokurtosisType == CokurtosisType.AABB) { return(m4 / (sd1 * sd1 * sd2 * sd2)); } return(m4 / (sd1 * sd2 * sd2 * sd2)); }
/// <summary> /// Returns the sample fourth central cross moment between two arrays. /// Arrays should be of equal length, and contain more than one element. /// </summary> /// <param name="arrayA"></param> /// <param name="arrayB"></param> /// <param name="cokurtosisType"></param> private static double FourthCentralCrossMoment(double[] arrayA, double[] arrayB, CokurtosisType cokurtosisType) { if (arrayA.Length != arrayB.Length) { throw new ArgumentException("arrayA and arrayB should be the same length."); } int n = arrayA.Length; double meanA = Mean(arrayA); double meanB = Mean(arrayB); double m4 = 0; if (cokurtosisType == CokurtosisType.AAAB) { for (int i = 0; i < n; i++) { m4 += (arrayA[i] - meanA) * (arrayA[i] - meanA) * (arrayA[i] - meanA) * (arrayB[i] - meanB); } } else if (cokurtosisType == CokurtosisType.AABB) { for (int i = 0; i < n; i++) { m4 += (arrayA[i] - meanA) * (arrayA[i] - meanA) * (arrayB[i] - meanB) * (arrayB[i] - meanB); } } else { for (int i = 0; i < n; i++) { m4 += (arrayA[i] - meanA) * (arrayB[i] - meanB) * (arrayB[i] - meanB) * (arrayB[i] - meanB); } } m4 *= n * (n - 1) / ((n - 1.0) * (n - 2.0) * (n - 3.0)); //because this is the sample coskew multiply by n(n+1)/(n-1)(n-2)(n-3) rather than 1/n return(m4); }
/// <summary> /// Returns the sample fourth central cross moment between two arrays. /// Arrays should be of equal length, and contain more than one element. /// </summary> /// <param name="arrayA"></param> /// <param name="arrayB"></param> /// <param name="cokurtosisType"></param> private static double FourthCentralCrossMoment(double[] arrayA, double[] arrayB, CokurtosisType cokurtosisType) { if (arrayA.Length != arrayB.Length) throw new ArgumentException("arrayA and arrayB should be the same length."); int n = arrayA.Length; double meanA = Mean(arrayA); double meanB = Mean(arrayB); double m4 = 0; if (cokurtosisType == CokurtosisType.AAAB) { for (int i = 0; i < n; i++) m4 += (arrayA[i] - meanA) * (arrayA[i] - meanA) * (arrayA[i] - meanA) * (arrayB[i] - meanB); } else if (cokurtosisType == CokurtosisType.AABB) { for (int i = 0; i < n; i++) m4 += (arrayA[i] - meanA)*(arrayA[i] - meanA)*(arrayB[i] - meanB)*(arrayB[i] - meanB); } else { for (int i = 0; i < n; i++) m4 += (arrayA[i] - meanA) * (arrayB[i] - meanB) * (arrayB[i] - meanB) * (arrayB[i] - meanB); } m4 *= n * (n - 1) / ((n - 1.0) * (n - 2.0) * (n - 3.0)); //because this is the sample coskew multiply by n(n+1)/(n-1)(n-2)(n-3) rather than 1/n return m4; }
/// <summary> /// Returns the sample cokurtosis between two arrays. /// Arrays should be of equal length, and contain more than one element. /// </summary> /// <param name="arrayA"></param> /// <param name="arrayB"></param> /// <param name="cokurtosisType"></param> public static double Coskurtosis(double[] arrayA, double[] arrayB, CokurtosisType cokurtosisType) { double m4 = FourthCentralCrossMoment(arrayA, arrayB, cokurtosisType); double sd1 = StandardDeviation(arrayA); double sd2 = StandardDeviation(arrayB); if (cokurtosisType == CokurtosisType.AAAB) return m4 / (sd1 * sd1 * sd1 * sd2); if(cokurtosisType == CokurtosisType.AABB) return m4 / (sd1 * sd1 * sd2 * sd2); return m4 / (sd1 * sd2 * sd2 * sd2); }