/// <summary> /// Perform CCA analysis on columns of two number tables. /// </summary> /// <param name="tableX">A number table.</param> /// <param name="tableY">A number table.</param> /// <returns>A PlsResult structure.</returns> /// <remarks>This method finds directions for tableX and tableY; so that these two tables will /// have maximal correlation in those directions.</remarks> public PlsResult DoCCA(INumberTable tableX, INumberTable tableY) { double[][] X = (double[][])tableX.Matrix; double[][] Y = (double[][])tableY.Matrix; double[][] Cxy = Covariance(X, Y); double[][] Cyx = Covariance(Y, X); IMathAdaptor math = MultivariateAnalysisPlugin.App.GetMathAdaptor(); double[][] rCxx = math.InvertMatrix(Covariance(X, X)); double[][] rCyy = math.InvertMatrix(Covariance(Y, Y)); MakeSymmetric(rCxx); MakeSymmetric(rCyy); double[][] A = MatrixProduct(rCxx, Cxy); double[][] B = MatrixProduct(rCyy, Cyx); double[][] Cx = MatrixProduct(A, B); double[][] Cy = MatrixProduct(B, A); double[][] Wx, Wy; double[] Rx, Ry; math.EigenDecomposition(Cx, out Wx, out Rx); math.EigenDecomposition(Cy, out Wy, out Ry); // // Rx and Ry should be the equal upto permutation and dimension. // Wy can be calculated from Wx by Ry = sqrt(1/Rx) * B * Rx // /* * double x0 = Math.Sqrt(Rx[0]); * double x1 = Math.Sqrt(Rx[1]); * double x2 = Math.Sqrt(Rx[2]); * * double y0 = Math.Sqrt(Ry[0]); * double y1 = Math.Sqrt(Ry[1]); * double y2 = Math.Sqrt(Ry[2]); * * 0.7165 0.4906 0.2668 */ SortEigenVectors(Wx, Rx); SortEigenVectors(Wy, Ry); //ValidateMatrix(Wx); //ValidateMatrix(Wy); PlsResult ret = new PlsResult(); ret.ProjectionX = EigenProjection(tableX, Wx); ret.ProjectionY = EigenProjection(tableY, Wy); ret.EigenVectorsX = Wx; ret.EigenVectorsY = Wy; ret.EigenValuesX = Rx; ret.EigenValuesY = Ry; return(ret); }
/// <summary> /// Perform PLS analysis on columns of two number tables. /// </summary> /// <param name="tableX">A number table.</param> /// <param name="tableY">A number table.</param> /// <returns>A PlsResult structure.</returns> /// <remarks>This method finds directions for tableX and tableY; so that these two tables will /// have maximal covariance in those directions.</remarks> public PlsResult DoPLS(INumberTable tableX, INumberTable tableY) { double[][] Cxy = Covariance((double[][])tableX.Matrix, (double[][])tableY.Matrix); double[][] Cyx = Covariance((double[][])tableY.Matrix, (double[][])tableX.Matrix); double[][] CxyCyx = MatrixProduct(Cxy, Cyx); double[][] CyxCxy = MatrixProduct(Cyx, Cxy); IMathAdaptor math = MultivariateAnalysisPlugin.App.GetMathAdaptor(); double[][] Wx, Wy; double[] Rx, Ry; // These two matrix might be slightly asymmetric due to calculation errors. MakeSymmetric(CxyCyx); MakeSymmetric(CyxCxy); math.EigenDecomposition(CxyCyx, out Wx, out Rx); math.EigenDecomposition(CyxCxy, out Wy, out Ry); SortEigenVectors(Wx, Rx); SortEigenVectors(Wy, Ry); PlsResult ret = new PlsResult(); ret.ProjectionX = EigenProjection(tableX, Wx); ret.ProjectionY = EigenProjection(tableY, Wy); ret.EigenVectorsX = Wx; ret.EigenVectorsY = Wy; ret.EigenValuesX = Rx; ret.EigenValuesY = Ry; return(ret); }