@@ -103,6 +103,69 @@ public static double Pearson(IList<double> sample1, IList<double> sample2)
103103 return sxy / Math . Sqrt ( sxx * syy ) ;
104104 }
105105
106+ /// <summary>
107+ /// Computes the Pearson correlation coefficient matrix for the variables in a 2D array.
108+ /// </summary>
109+ /// <param name="samples">
110+ /// A 2D array of size [n, p] where each row is one observation and each column is one variable.
111+ /// </param>
112+ /// <returns>
113+ /// A p×p matrix C where C[j,k] is the Pearson correlation between column j and column k of <paramref name="samples"/>.
114+ /// </returns>
115+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="samples"/> is null.</exception>
116+ /// <exception cref="ArgumentException">Thrown if <paramref name="samples"/> has zero columns.</exception>
117+ public static double [ , ] Pearson ( double [ , ] samples )
118+ {
119+ if ( samples == null )
120+ throw new ArgumentNullException ( nameof ( samples ) ) ;
121+
122+ int n = samples . GetLength ( 0 ) ;
123+ int p = samples . GetLength ( 1 ) ;
124+ if ( p == 0 )
125+ throw new ArgumentException ( "Input must have at least one column." , nameof ( samples ) ) ;
126+
127+ // 1) Compute means for each column
128+ double [ ] means = new double [ p ] ;
129+ for ( int j = 0 ; j < p ; j ++ )
130+ for ( int i = 0 ; i < n ; i ++ )
131+ means [ j ] += samples [ i , j ] ;
132+ for ( int j = 0 ; j < p ; j ++ )
133+ means [ j ] /= n ;
134+
135+ // 2) Compute sum of squares (ss) and cross-products (cov)
136+ double [ ] ss = new double [ p ] ;
137+ double [ , ] cov = new double [ p , p ] ;
138+ for ( int i = 0 ; i < n ; i ++ )
139+ {
140+ for ( int j = 0 ; j < p ; j ++ )
141+ {
142+ double dx = samples [ i , j ] - means [ j ] ;
143+ ss [ j ] += dx * dx ;
144+ for ( int k = j ; k < p ; k ++ )
145+ {
146+ double dy = samples [ i , k ] - means [ k ] ;
147+ cov [ j , k ] += dx * dy ;
148+ }
149+ }
150+ }
151+ // mirror upper triangle to lower
152+ for ( int j = 0 ; j < p ; j ++ )
153+ for ( int k = j + 1 ; k < p ; k ++ )
154+ cov [ k , j ] = cov [ j , k ] ;
155+
156+ // 3) Build correlation matrix
157+ double [ , ] corr = new double [ p , p ] ;
158+ for ( int j = 0 ; j < p ; j ++ )
159+ {
160+ for ( int k = 0 ; k < p ; k ++ )
161+ {
162+ corr [ j , k ] = cov [ j , k ] / Math . Sqrt ( ss [ j ] * ss [ k ] ) ;
163+ }
164+ }
165+
166+ return corr ;
167+ }
168+
106169 /// <summary>
107170 /// Computes the Spearman ranked correlation coefficient.
108171 /// </summary>
@@ -122,6 +185,35 @@ public static double Spearman(IList<double> sample1, IList<double> sample2)
122185 return Pearson ( rank1 , rank2 ) ;
123186 }
124187
188+ /// <summary>
189+ /// Computes the Spearman correlation coefficient matrix for the variables in a 2D array.
190+ /// </summary>
191+ /// <param name="samples">
192+ /// A 2D array of size [n, p] where each row is one observation and each column is one variable.
193+ /// </param>
194+ /// <returns>
195+ /// A p×p matrix C where C[j,k] is the Spearman correlation between column j and column k of <paramref name="samples"/>.
196+ /// </returns>
197+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="samples"/> is null.</exception>
198+ /// <exception cref="ArgumentException">Thrown if <paramref name="samples"/> has zero columns.</exception>
199+ public static double [ , ] Spearman ( double [ , ] samples )
200+ {
201+ if ( samples == null )
202+ throw new ArgumentNullException ( nameof ( samples ) ) ;
203+
204+ int n = samples . GetLength ( 0 ) ;
205+ int p = samples . GetLength ( 1 ) ;
206+ if ( p == 0 )
207+ throw new ArgumentException ( "Input must have at least one column." , nameof ( samples ) ) ;
208+
209+ var ranks = new double [ n , p ] ;
210+ for ( int i = 0 ; i < p ; i ++ )
211+ {
212+ ranks . SetColumn ( i , Statistics . RanksInPlace ( samples . GetColumn ( i ) ) ) ;
213+ }
214+ return Pearson ( ranks ) ;
215+ }
216+
125217 /// <summary>
126218 /// Computes Kendall's Tau ranked correlation coefficient.
127219 /// </summary>
0 commit comments