/// <summary> /// Returns the sample coskewness 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="coskewnessType"></param> public static double Coskewness(double[] arrayA, double[] arrayB, CoskewnessType coskewnessType) { double m3 = ThirdCentralCrossMoment(arrayA, arrayB, coskewnessType); double sd1 = StandardDeviation(arrayA); double sd2 = StandardDeviation(arrayB); if (coskewnessType == CoskewnessType.AAB) return m3/(sd1*sd1*sd2); return m3 / (sd1 * sd2 * sd2); }
/// <summary> /// Returns the sample coskewness 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="coskewnessType"></param> public static double Coskewness(double[] arrayA, double[] arrayB, CoskewnessType coskewnessType) { double m3 = ThirdCentralCrossMoment(arrayA, arrayB, coskewnessType); double sd1 = StandardDeviation(arrayA); double sd2 = StandardDeviation(arrayB); if (coskewnessType == CoskewnessType.AAB) { return(m3 / (sd1 * sd1 * sd2)); } return(m3 / (sd1 * sd2 * sd2)); }
/// <summary> /// Returns the sample third 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="coskewnessType"></param> private static double ThirdCentralCrossMoment(double[] arrayA, double[] arrayB, CoskewnessType coskewnessType) { 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 m3 = 0; if (coskewnessType == CoskewnessType.AAB) { for (int i = 0; i < n; i++) { m3 += (arrayA[i] - meanA) * (arrayA[i] - meanA) * (arrayB[i] - meanB); } } else { for (int i = 0; i < n; i++) { m3 += (arrayA[i] - meanA) * (arrayB[i] - meanB) * (arrayB[i] - meanB); } } m3 *= n / ((n - 1.0) * (n - 2.0)); //because this is the sample coskew multiply by n/(n-1)(n-2) rather than 1/n return(m3); }
/// <summary> /// Returns the sample third 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="coskewnessType"></param> private static double ThirdCentralCrossMoment(double[] arrayA, double[] arrayB, CoskewnessType coskewnessType) { 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 m3 = 0; if (coskewnessType == CoskewnessType.AAB) { for (int i = 0; i < n; i++) m3 += (arrayA[i] - meanA) * (arrayA[i] - meanA) * (arrayB[i] - meanB); } else { for (int i = 0; i < n; i++) m3 += (arrayA[i] - meanA) * (arrayB[i] - meanB) * (arrayB[i] - meanB); } m3 *= n / ((n - 1.0) * (n - 2.0)); //because this is the sample coskew multiply by n/(n-1)(n-2) rather than 1/n return m3; }