Skip to content
/ SAS Public

Assessing the similarity of real matrices with arbitrary shape.

License

Notifications You must be signed in to change notification settings

INM-6/SAS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SAS: Singular Angle Similarity

Method for comparing the singular angle similarity of arbitrary matrices of the same shape, based on singular value decomposition.

Properties of SAS

  • SAS attains values between $0$ and $1$ where higher values imply greater similarity.
  • SAS is invariant under actions of identical orthogonal maps from the left or the right on the compared matrices.
  • SAS is invariant under transposition of both matrices; this includes the consistent permutation of rows and columns as a special case.
  • SAS is invariant under scaling with a positive factor; in particular, SAS $= 1$ for $M_b = c_{1} M_a$ where $c_1 \in \mathbb{R}^+$.
  • SAS is zero if scaled with a negative factor; in particular, SAS $= 0$ for $M_b = c_2 M_a$ where $c_{2} \in \mathbb{R}^-$.

The formal derivation of the measure and its properties is presented here. In particular, the linked manuscript provides cases for which SAS detects similarity where traditional measures such as the Frobenius norm or the cosine similarity fail.

Installation

pip install .

Example use

Comparing single matrices

import numpy as np
import sas

# parameters
dim = 10

# create matrices
matrix_a = np.random.normal(0, 1, (dim, dim))
matrix_b = np.random.normal(0, 1, (dim, dim))

# calculate similarity
similarity = sas.compare(matrix_a, matrix_b)

Calculating the similarity across instances

Here, we show that two generative models of matrices can be distinguished from each other: a normally distributed matrix with a block in its upper left quarter is more similar to another instantiation of the same matrix type than to a normally distributed matrix with no blocks.

import numpy as np
import sas

# parameters
dim = 10
reps = 10

# create matrices
matrices = {'normal_block_1': [np.random.normal(0, 1, (dim, dim)) for _ in range(reps)],
			'normal_block_2': [np.random.normal(0, 1, (dim, dim)) for _ in range(reps)],
			'normal_noblock': [np.random.normal(0, 1, (dim, dim)) for _ in range(reps)]}
for rep in range(reps):
	matrices['normal_block_1'][rep][:dim//2, :dim//2] += np.random.normal(2, 1, (dim//2, dim//2))
	matrices['normal_block_2'][rep][:dim//2, :dim//2] += np.random.normal(2, 1, (dim//2, dim//2))

# calculate self- and cross-similarity
self_similarity = [sas.compare(matrices['normal_block_1'][i], matrices['normal_block_2'][i]) for i in range(reps)]
cross_similarity = [sas.compare(matrices['normal_block_1'][i], matrices['normal_noblock'][i]) for i in range(reps)]

# calculate effect size between similarity distributions
# effect size > 1 indicates statistical separability
effect_size = sas.effect_size(self_similarity, cross_similarity)

Contact

Jasper Albers

About

Assessing the similarity of real matrices with arbitrary shape.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages