CORRM
Updated 2024-03-04 16:47:05.203000
Syntax
SELECT * FROM [westclintech].[wct].[CORRM](
<@Matrix_RangeQuery, nvarchar(max),>
,<@Is3N, bit,>)
Description
Use the table-valued function CORRM to calculate a correlation matrix. Given a matrix Am,n and a covariance matrix Cn,n = COVM(Am,n), then each element in correlation matrix Rn,n is calculated as:
R_{i,j}=\frac{C_{i,j}}{\sqrt{C_{i,i}}\times\sqrt{C_{j,j}}
For example:
A=\begin{bmatrix}1&-10&120&20\\2&20&30&-40\\3&-40&90&80\end{bmatrix}
C=\begin{bmatrix}1&-15&-15&30\\-15&900&-900&-1800\\-15&-900&2100&1800\\30&-1800&1800&3600\end{bmatrix}
R=\begin{bmatrix}\frac{1}{\sqrt{1}\times\sqrt{1}}&\frac{-15}{\sqrt{1}\times\sqrt{900}}&\frac{-15}{\sqrt{1}\times\sqrt{2100}}&\frac{30}{\sqrt{1}\times\sqrt{3600}}\\\\\frac{-15}{\sqrt{900}\times\sqrt{1}}&\frac{900}{\sqrt{900}\times\sqrt{900}}&\frac{-900}{\sqrt{900}\times\sqrt{2100}}&\frac{-1800}{\sqrt{900}\times\sqrt{3600}}\\\\\frac{-15}{\sqrt{2100}\times\sqrt{1}}&\frac{-900}{\sqrt{2100}\times\sqrt{2100}}&\frac{2100}{\sqrt{2100}\times\sqrt{2100}}&\frac{1800}{\sqrt{2100}\times\sqrt{3600}}\\\\\frac{30}{\sqrt{3600}\times\sqrt{3600}}&\frac{-1800}{\sqrt{3600}\times\sqrt{900}}&\frac{1800}{\sqrt{3600}\times\sqrt{2100}}&\frac{3600}{\sqrt{3600}\times\sqrt{3600}}\end{bmatrix}
Arguments
@Matrix_RangeQuery
the SELECT statement, as text, used to return the input matrix for this function. The SELECT statement specifies the column names from the table or view or can be used to enter the matrix values directly. Data returned from the @Matrix_RangeQuery select must be of the type float or of a type that implicitly converts to float.
@Is3N
a bit value identifying the form for the resultant table returned by @Matrix_RangeQuery. Enter 'True' for a resultant table in 3rd normal form. Enter 'False' for a de-normalized table in 'spreadsheet' form.
Return Type
table
{"columns": [{"field": "colName", "headerName": "Name", "header": "name"}, {"field": "colDatatype", "headerName": "Type", "header": "type"}, {"field": "colDesc", "headerName": "Description", "header": "description", "minWidth": 1000}], "rows": [{"id": "a5e20ce9-987d-4529-b263-f0e087c3d242", "colName": "RowNum", "colDatatype": "int", "colDesc": "The zero-based row index for the matrix"}, {"id": "5011dc3f-2e66-4da6-ae16-1be0762aee51", "colName": "ColNum", "colDatatype": "int", "colDesc": "The zero-based column index for the matrix"}, {"id": "4e829646-a637-4b7a-ba5b-d4c2854e2bf0", "colName": "ItemValue", "colDatatype": "float", "colDesc": "The value at RowNum, ColNum"}]}
Remarks
If @Is3N is NULL then @Is3N = 'False'.
Use MCORR for a matrix stored as a string.
If @Is3N is'True' then the result table should be returned as row, column, and value.
If the array contains NULL, then NULL will be returned.
The function returns an error if the array contains a non-numeric value.
If the supplied input is a vector, then result will be the (sample) variance.
Examples
In this example @Matrix_RangeQuery returns the matrix from a derived table embodied in the statement. The matrix is in spreadsheet form.
SELECT *
FROM wct.CORRM(
'SELECT
x1,x2,x3,x4,x5,x6,x7,x8
FROM (VALUES
(1,1,1,1,1,1,1,1)
,(2,3,4,5,6,7,8,9)
,(4,9,16,25,36,49,64,81)
)n(x1,x2,x3,x4,x5,x6,x7,x8)',
'False'
);
This produces the following result.
{"columns":[{"field":"RowNum","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"ColNum","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"ItemValue","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"}],"rows":[{"RowNum":"0","ColNum":"0","ItemValue":"1"},{"RowNum":"0","ColNum":"1","ItemValue":"0.995870594885822"},{"RowNum":"0","ColNum":"2","ItemValue":"0.989743318610787"},{"RowNum":"0","ColNum":"3","ItemValue":"0.98432413828809"},{"RowNum":"0","ColNum":"4","ItemValue":"0.9798637100972"},{"RowNum":"0","ColNum":"5","ItemValue":"0.97622103992743"},{"RowNum":"0","ColNum":"6","ItemValue":"0.973222701448379"},{"RowNum":"0","ColNum":"7","ItemValue":"0.970725343394151"},{"RowNum":"1","ColNum":"0","ItemValue":"0.995870594885822"},{"RowNum":"1","ColNum":"1","ItemValue":"1"},{"RowNum":"1","ColNum":"2","ItemValue":"0.998625428903524"},{"RowNum":"1","ColNum":"3","ItemValue":"0.996270962773436"},{"RowNum":"1","ColNum":"4","ItemValue":"0.993944095928862"},{"RowNum":"1","ColNum":"5","ItemValue":"0.991869783800371"},{"RowNum":"1","ColNum":"6","ItemValue":"0.990071896570823"},{"RowNum":"1","ColNum":"7","ItemValue":"0.988522467870286"},{"RowNum":"2","ColNum":"0","ItemValue":"0.989743318610787"},{"RowNum":"2","ColNum":"1","ItemValue":"0.998625428903524"},{"RowNum":"2","ColNum":"2","ItemValue":"1"},{"RowNum":"2","ColNum":"3","ItemValue":"0.999423797128766"},{"RowNum":"2","ColNum":"4","ItemValue":"0.998337488459583"},{"RowNum":"2","ColNum":"5","ItemValue":"0.997176464952738"},{"RowNum":"2","ColNum":"6","ItemValue":"0.996078416265654"},{"RowNum":"2","ColNum":"7","ItemValue":"0.995082098645899"},{"RowNum":"3","ColNum":"0","ItemValue":"0.98432413828809"},{"RowNum":"3","ColNum":"1","ItemValue":"0.996270962773436"},{"RowNum":"3","ColNum":"2","ItemValue":"0.999423797128766"},{"RowNum":"3","ColNum":"3","ItemValue":"1"},{"RowNum":"3","ColNum":"4","ItemValue":"0.999718640088218"},{"RowNum":"3","ColNum":"5","ItemValue":"0.999150742946594"},{"RowNum":"3","ColNum":"6","ItemValue":"0.998507503106759"},{"RowNum":"3","ColNum":"7","ItemValue":"0.997870827960502"},{"RowNum":"4","ColNum":"0","ItemValue":"0.9798637100972"},{"RowNum":"4","ColNum":"1","ItemValue":"0.993944095928862"},{"RowNum":"4","ColNum":"2","ItemValue":"0.998337488459583"},{"RowNum":"4","ColNum":"3","ItemValue":"0.999718640088218"},{"RowNum":"4","ColNum":"4","ItemValue":"1"},{"RowNum":"4","ColNum":"5","ItemValue":"0.999846989517886"},{"RowNum":"4","ColNum":"6","ItemValue":"0.999522026579879"},{"RowNum":"4","ColNum":"7","ItemValue":"0.999137118134003"},{"RowNum":"5","ColNum":"0","ItemValue":"0.97622103992743"},{"RowNum":"5","ColNum":"1","ItemValue":"0.991869783800371"},{"RowNum":"5","ColNum":"2","ItemValue":"0.997176464952738"},{"RowNum":"5","ColNum":"3","ItemValue":"0.999150742946594"},{"RowNum":"5","ColNum":"4","ItemValue":"0.999846989517886"},{"RowNum":"5","ColNum":"5","ItemValue":"1"},{"RowNum":"5","ColNum":"6","ItemValue":"0.999909873371905"},{"RowNum":"5","ColNum":"7","ItemValue":"0.999710773674355"},{"RowNum":"6","ColNum":"0","ItemValue":"0.973222701448379"},{"RowNum":"6","ColNum":"1","ItemValue":"0.990071896570823"},{"RowNum":"6","ColNum":"2","ItemValue":"0.996078416265654"},{"RowNum":"6","ColNum":"3","ItemValue":"0.998507503106759"},{"RowNum":"6","ColNum":"4","ItemValue":"0.999522026579879"},{"RowNum":"6","ColNum":"5","ItemValue":"0.999909873371905"},{"RowNum":"6","ColNum":"6","ItemValue":"1"},{"RowNum":"6","ColNum":"7","ItemValue":"0.99994354800767"},{"RowNum":"7","ColNum":"0","ItemValue":"0.970725343394151"},{"RowNum":"7","ColNum":"1","ItemValue":"0.988522467870286"},{"RowNum":"7","ColNum":"2","ItemValue":"0.995082098645899"},{"RowNum":"7","ColNum":"3","ItemValue":"0.997870827960502"},{"RowNum":"7","ColNum":"4","ItemValue":"0.999137118134003"},{"RowNum":"7","ColNum":"5","ItemValue":"0.999710773674355"},{"RowNum":"7","ColNum":"6","ItemValue":"0.99994354800767"},{"RowNum":"7","ColNum":"7","ItemValue":"1"}]}
Note that the results are returned in third-normal form. If we wanted to a more traditional (de-normalized) presentation of the results, we can us the PIVOT function. Also note that we can use * to select all the columns. We have rounded the results to 4 decimal place for ease of viewing.
SELECT ROUND([0], 4) as [0],
ROUND([1], 4) as [1],
ROUND([2], 4) as [2],
ROUND([3], 4) as [3],
ROUND([4], 4) as [4],
ROUND([5], 4) as [5],
ROUND([6], 4) as [6],
ROUND([7], 4) as [7]
FROM
(
SELECT *
FROM wct.CORRM(
'SELECT
*
FROM (VALUES
(1,1,1,1,1,1,1,1)
,(2,3,4,5,6,7,8,9)
,(4,9,16,25,36,49,64,81)
)n(x1,x2,x3,x4,x5,x6,x7,x8)',
'False'
)
) d
PIVOT
(
SUM(ItemValue)
for ColNum in ([0], [1], [2], [3], [4], [5], [6], [7])
) as P;
This produces the following result.
{"columns":[{"field":"0","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"1","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"2","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"3","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"4","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"5","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"6","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"7","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"}],"rows":[{"0":"1","1":"0.9959","2":"0.9897","3":"0.9843","4":"0.9799","5":"0.9762","6":"0.9732","7":"0.9707"},{"0":"0.9959","1":"1","2":"0.9986","3":"0.9963","4":"0.9939","5":"0.9919","6":"0.9901","7":"0.9885"},{"0":"0.9897","1":"0.9986","2":"1","3":"0.9994","4":"0.9983","5":"0.9972","6":"0.9961","7":"0.9951"},{"0":"0.9843","1":"0.9963","2":"0.9994","3":"1","4":"0.9997","5":"0.9992","6":"0.9985","7":"0.9979"},{"0":"0.9799","1":"0.9939","2":"0.9983","3":"0.9997","4":"1","5":"0.9998","6":"0.9995","7":"0.9991"},{"0":"0.9762","1":"0.9919","2":"0.9972","3":"0.9992","4":"0.9998","5":"1","6":"0.9999","7":"0.9997"},{"0":"0.9732","1":"0.9901","2":"0.9961","3":"0.9985","4":"0.9995","5":"0.9999","6":"1","7":"0.9999"},{"0":"0.9707","1":"0.9885","2":"0.9951","3":"0.9979","4":"0.9991","5":"0.9997","6":"0.9999","7":"1"}]}
Let's put several matrices into a table and calculate the correlation matrix for each. We will use CROSS APPLY to calculate to the correlation matrix for each matrix. Note that we have to convert the matrix identifier (which is defined as int) to a varchar to include it in the WHERE clause of @Matrix_RangeQuery.
CREATE TABLE #c
(
Matrix int,
rn int,
x1 float,
x2 float,
x3 float,
PRIMARY KEY (
Matrix,
rn
)
);
INSERT INTO #c
VALUES
(100, 1, -11, -41, 36);
INSERT INTO #c
VALUES
(100, 2, -31, 41, -47);
INSERT INTO #c
VALUES
(100, 3, 48, -38, 33);
INSERT INTO #c
VALUES
(100, 4, 8, 44, -10);
INSERT INTO #c
VALUES
(101, 1, 39, 6, -7);
INSERT INTO #c
VALUES
(101, 2, 33, -49, 16);
INSERT INTO #c
VALUES
(101, 3, 14, 29, 13);
INSERT INTO #c
VALUES
(101, 4, 35, -38, -50);
INSERT INTO #c
VALUES
(101, 5, 9, -32, -25);
INSERT INTO #c
VALUES
(102, 1, 29, 49, -17);
INSERT INTO #c
VALUES
(102, 2, 35, 28, 28);
INSERT INTO #c
VALUES
(102, 3, -34, -29, -49);
INSERT INTO #c
VALUES
(102, 4, 0, -5, 0);
INSERT INTO #c
VALUES
(102, 5, -17, 14, 24);
INSERT INTO #c
VALUES
(102, 6, 44, 3, -23);
SELECT n.MATRIX,
k.*
FROM
(SELECT DISTINCT MATRIX FROM #c) n
CROSS APPLY wct.CORRM('SELECT
x1,x2,x3
FROM
#c
WHERE MATRIX = ' + cast(n.Matrix as varchar(max)) + ' ORDER by rn', 'False')
k;
This produces the following result.
{"columns":[{"field":"MATRIX","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"RowNum","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"ColNum","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"ItemValue","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"}],"rows":[{"MATRIX":"100","RowNum":"0","ColNum":"0","ItemValue":"1"},{"MATRIX":"100","RowNum":"0","ColNum":"1","ItemValue":"-0.483356996796483"},{"MATRIX":"100","RowNum":"0","ColNum":"2","ItemValue":"0.633890426031688"},{"MATRIX":"100","RowNum":"1","ColNum":"0","ItemValue":"-0.483356996796483"},{"MATRIX":"100","RowNum":"1","ColNum":"1","ItemValue":"1"},{"MATRIX":"100","RowNum":"1","ColNum":"2","ItemValue":"-0.913359160170441"},{"MATRIX":"100","RowNum":"2","ColNum":"0","ItemValue":"0.633890426031688"},{"MATRIX":"100","RowNum":"2","ColNum":"1","ItemValue":"-0.913359160170441"},{"MATRIX":"100","RowNum":"2","ColNum":"2","ItemValue":"1"},{"MATRIX":"101","RowNum":"0","ColNum":"0","ItemValue":"1"},{"MATRIX":"101","RowNum":"0","ColNum":"1","ItemValue":"-0.230728768997873"},{"MATRIX":"101","RowNum":"0","ColNum":"2","ItemValue":"-0.107306924177497"},{"MATRIX":"101","RowNum":"1","ColNum":"0","ItemValue":"-0.230728768997873"},{"MATRIX":"101","RowNum":"1","ColNum":"1","ItemValue":"1"},{"MATRIX":"101","RowNum":"1","ColNum":"2","ItemValue":"0.374980979068184"},{"MATRIX":"101","RowNum":"2","ColNum":"0","ItemValue":"-0.107306924177497"},{"MATRIX":"101","RowNum":"2","ColNum":"1","ItemValue":"0.374980979068184"},{"MATRIX":"101","RowNum":"2","ColNum":"2","ItemValue":"1"},{"MATRIX":"102","RowNum":"0","ColNum":"0","ItemValue":"1"},{"MATRIX":"102","RowNum":"0","ColNum":"1","ItemValue":"0.640154472423516"},{"MATRIX":"102","RowNum":"0","ColNum":"2","ItemValue":"0.23474788750615"},{"MATRIX":"102","RowNum":"1","ColNum":"0","ItemValue":"0.640154472423516"},{"MATRIX":"102","RowNum":"1","ColNum":"1","ItemValue":"1"},{"MATRIX":"102","RowNum":"1","ColNum":"2","ItemValue":"0.503721652740323"},{"MATRIX":"102","RowNum":"2","ColNum":"0","ItemValue":"0.23474788750615"},{"MATRIX":"102","RowNum":"2","ColNum":"1","ItemValue":"0.503721652740323"},{"MATRIX":"102","RowNum":"2","ColNum":"2","ItemValue":"1"}]}
In this example we calculate the correlation matrix from a derived table in 3rd normal form.
SELECT *
FROM wct.CORRM(
'SELECT
rownum,colnum,itemvalue
FROM (VALUES
(0,0,1),(0,1,1),(0,2,1),(0,3,1),(0,4,1),(0,5,1),(0,6,1),(0,7,1)
,(1,0,2),(1,1,3),(1,2,4),(1,3,5),(1,4,6),(1,5,7),(1,6,8),(1,7,9)
,(2,0,4),(2,1,9),(2,2,16),(2,3,25),(2,4,36),(2,5,49),(2,6,64),(2,7,
81)
)n(rownum,colnum,itemvalue)',
'True'
);
This produces the following result.
{"columns":[{"field":"RowNum","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"ColNum","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"},{"field":"ItemValue","headerClass":"ag-right-aligned-header","cellClass":"ag-right-aligned-cell"}],"rows":[{"RowNum":"0","ColNum":"0","ItemValue":"1"},{"RowNum":"0","ColNum":"1","ItemValue":"0.995870594885822"},{"RowNum":"0","ColNum":"2","ItemValue":"0.989743318610787"},{"RowNum":"0","ColNum":"3","ItemValue":"0.98432413828809"},{"RowNum":"0","ColNum":"4","ItemValue":"0.9798637100972"},{"RowNum":"0","ColNum":"5","ItemValue":"0.97622103992743"},{"RowNum":"0","ColNum":"6","ItemValue":"0.973222701448379"},{"RowNum":"0","ColNum":"7","ItemValue":"0.970725343394151"},{"RowNum":"1","ColNum":"0","ItemValue":"0.995870594885822"},{"RowNum":"1","ColNum":"1","ItemValue":"1"},{"RowNum":"1","ColNum":"2","ItemValue":"0.998625428903524"},{"RowNum":"1","ColNum":"3","ItemValue":"0.996270962773436"},{"RowNum":"1","ColNum":"4","ItemValue":"0.993944095928862"},{"RowNum":"1","ColNum":"5","ItemValue":"0.991869783800371"},{"RowNum":"1","ColNum":"6","ItemValue":"0.990071896570823"},{"RowNum":"1","ColNum":"7","ItemValue":"0.988522467870286"},{"RowNum":"2","ColNum":"0","ItemValue":"0.989743318610787"},{"RowNum":"2","ColNum":"1","ItemValue":"0.998625428903524"},{"RowNum":"2","ColNum":"2","ItemValue":"1"},{"RowNum":"2","ColNum":"3","ItemValue":"0.999423797128766"},{"RowNum":"2","ColNum":"4","ItemValue":"0.998337488459583"},{"RowNum":"2","ColNum":"5","ItemValue":"0.997176464952738"},{"RowNum":"2","ColNum":"6","ItemValue":"0.996078416265654"},{"RowNum":"2","ColNum":"7","ItemValue":"0.995082098645899"},{"RowNum":"3","ColNum":"0","ItemValue":"0.98432413828809"},{"RowNum":"3","ColNum":"1","ItemValue":"0.996270962773436"},{"RowNum":"3","ColNum":"2","ItemValue":"0.999423797128766"},{"RowNum":"3","ColNum":"3","ItemValue":"1"},{"RowNum":"3","ColNum":"4","ItemValue":"0.999718640088218"},{"RowNum":"3","ColNum":"5","ItemValue":"0.999150742946594"},{"RowNum":"3","ColNum":"6","ItemValue":"0.998507503106759"},{"RowNum":"3","ColNum":"7","ItemValue":"0.997870827960502"},{"RowNum":"4","ColNum":"0","ItemValue":"0.9798637100972"},{"RowNum":"4","ColNum":"1","ItemValue":"0.993944095928862"},{"RowNum":"4","ColNum":"2","ItemValue":"0.998337488459583"},{"RowNum":"4","ColNum":"3","ItemValue":"0.999718640088218"},{"RowNum":"4","ColNum":"4","ItemValue":"1"},{"RowNum":"4","ColNum":"5","ItemValue":"0.999846989517886"},{"RowNum":"4","ColNum":"6","ItemValue":"0.999522026579879"},{"RowNum":"4","ColNum":"7","ItemValue":"0.999137118134003"},{"RowNum":"5","ColNum":"0","ItemValue":"0.97622103992743"},{"RowNum":"5","ColNum":"1","ItemValue":"0.991869783800371"},{"RowNum":"5","ColNum":"2","ItemValue":"0.997176464952738"},{"RowNum":"5","ColNum":"3","ItemValue":"0.999150742946594"},{"RowNum":"5","ColNum":"4","ItemValue":"0.999846989517886"},{"RowNum":"5","ColNum":"5","ItemValue":"1"},{"RowNum":"5","ColNum":"6","ItemValue":"0.999909873371905"},{"RowNum":"5","ColNum":"7","ItemValue":"0.999710773674355"},{"RowNum":"6","ColNum":"0","ItemValue":"0.973222701448379"},{"RowNum":"6","ColNum":"1","ItemValue":"0.990071896570823"},{"RowNum":"6","ColNum":"2","ItemValue":"0.996078416265654"},{"RowNum":"6","ColNum":"3","ItemValue":"0.998507503106759"},{"RowNum":"6","ColNum":"4","ItemValue":"0.999522026579879"},{"RowNum":"6","ColNum":"5","ItemValue":"0.999909873371905"},{"RowNum":"6","ColNum":"6","ItemValue":"1"},{"RowNum":"6","ColNum":"7","ItemValue":"0.99994354800767"},{"RowNum":"7","ColNum":"0","ItemValue":"0.970725343394151"},{"RowNum":"7","ColNum":"1","ItemValue":"0.988522467870286"},{"RowNum":"7","ColNum":"2","ItemValue":"0.995082098645899"},{"RowNum":"7","ColNum":"3","ItemValue":"0.997870827960502"},{"RowNum":"7","ColNum":"4","ItemValue":"0.999137118134003"},{"RowNum":"7","ColNum":"5","ItemValue":"0.999710773674355"},{"RowNum":"7","ColNum":"6","ItemValue":"0.99994354800767"},{"RowNum":"7","ColNum":"7","ItemValue":"1"}]}
See Also
MCORR - Correlation matrix using a formatted matrix as input
COVM - Table-valued function to calculate the covariance matrix
CORREL - Aggregate function to calculate the correlation coefficient
PEARSON - Aggregate function to calculate the correlation coefficient