Example #1
0
    def test_basis_fem_result(self):
        """Class SpharaBasis, method basis, mode='fem', triangular test mesh

        Determine the SPHARA basis with FEM discretization for a
        triangular mesh with 118 vertices. The valid basis vectors of
        the SPHARA basis can point in opposite directions
        (multiplication by -1). To compare the calculated basis with
        the reference basis, the transposed matrix of the calculated
        basis is multiplied by the matrix of the reference basis. If
        the calculated basis is correct, then the result matrix of the
        matrix multiplication contains only the elements 1 and -1 at
        the main diagonal, all other elements of the matrix are 0 or
        very small.

        """
        testtrimesh = tm.TriMesh(self.testdatatriangles, self.testdatavertices)
        sb_fem = sb.SpharaBasis(testtrimesh, mode='fem')
        sb_fem_fun, sb_fem_freq = sb_fem.basis()
        self.assertTrue(
            np.allclose(
                np.absolute(
                    np.matmul(
                        np.matmul(np.transpose(sb_fem_fun),
                                  self.testdatamassmatrix),
                        self.testdataspharabasisfemweight)),
                np.identity(np.size(sb_fem_freq)))
            and np.allclose(sb_fem_freq, self.testdataspharanatfreqfemweight))
Example #2
0
    def test_spharaby_basis_constructor(self):
        """
        Class SpharaBasis, constructor, type exception

        Raise an exception if triangsampel has a wrong type.
        """
        with self.assertRaises(TypeError) as cm:
            sb.SpharaBasis([1, 2, 3, 4])
        err = cm.exception
        self.assertEqual(str(err), 'triangsamples is no instance of TriMesh')
Example #3
0
    def test_basis_fem_simple(self):
        """
        Class SpharaBasis, method basis, mode='fem', simple triangular mesh

        Determine the SPHARA basis with fem edge weight
        for a simple triangular mesh, 3 vertices, single triangle.

        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
        sb_fem = sb.SpharaBasis(testtrimesh, mode='fem')
        sb_fem_fun, sb_fem_freq = sb_fem.basis()
        self.assertTrue(
            np.allclose(sb_fem_fun, [[0.53452248, -0.49487166, 1.42857143],
                                     [0.53452248, -0.98974332, -1.14285714],
                                     [0.53452248, 1.48461498, -0.28571429]])
            and np.allclose(sb_fem_freq,
                            [2.33627569e-16, 1.71428571e+00, 5.14285714e+00]))
Example #4
0
    def test_basis_unit_simple(self):
        """
        Class SpharaBasis, method basis, mode='unit', simple triangular mesh

        Determine the SPHARA basis with unit edge weight for a simple
        triangular mesh, 3 vertices, single triangle.
        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1, 0, 0], [0, 2, 0], [0, 0, 3]])
        sb_unit = sb.SpharaBasis(testtrimesh, mode='unit')
        sb_unit_fun, sb_unit_freq = sb_unit.basis()
        # print(sb_unit_freq.shape)
        self.assertTrue(
            np.allclose(sb_unit_fun, [[0.57735027, 0.81649658, 0.],
                                      [0.57735027, -0.40824829, -0.70710678],
                                      [0.57735027, -0.40824829, 0.70710678]])
            and np.allclose(sb_unit_freq,
                            [2.22044605e-15, 3.00000000e+00, 3.00000000e+00]))
Example #5
0
    def test_basis_inveuclid_simple(self):
        """
        Class SpharaBasis, method basis, mode='inv_euclidean', simple
        triangular mesh

        Determine the SPHARA basis with inverse euclidean edge weight
        for a simple triangular mesh, 3 vertices, single triangle.

        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1, 0, 0], [0, 2, 0], [0, 0, 3]])
        sb_ie = sb.SpharaBasis(testtrimesh, mode='inv_euclidean')
        sb_ie_fun, sb_ie_freq = sb_ie.basis()
        self.assertTrue(
            np.allclose(
                sb_ie_fun,
                [[-0.577350269189626, -0.328082121693334, 0.747682277502862],
                 [-0.577350269189626, -0.483470785430218, -0.657968590665356],
                 [-0.577350269189626, 0.811552907123552, -0.0897136868375066]])
            and np.allclose(sb_ie_freq,
                            [0.0, 0.886644827600501, 1.19493809165832]))
######################################################################
# Determining SPHARA bases using different discretisation approaches
# ------------------------------------------------------------------
# Computing the basis functions
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#
# In the final step of the tutorial we will calculate SPHARA bases for
# the given :term:`EEG` sensor setup. For this we create three
# instances of the class :class:`spharapy.spharabasis.SpharaBasis`. We
# use the three discretization approaches implemented in this class
# for the Laplace-Beltrami operator: unit weighting ('unit') and
# inverse Euclidean weigthing ('inv_euclidean') of the edges of the
# triangular mesh as well as the FEM discretization ('fem')

# 'unit' discretization
sphara_basis_unit = sb.SpharaBasis(mesh_eeg, 'unit')
basis_functions_unit, natural_frequencies_unit = sphara_basis_unit.basis()

# 'inv_euclidean' discretization
sphara_basis_ie = sb.SpharaBasis(mesh_eeg, 'inv_euclidean')
basis_functions_ie, natural_frequencies_ie = sphara_basis_ie.basis()

# 'fem' discretization
sphara_basis_fem = sb.SpharaBasis(mesh_eeg, 'fem')
basis_functions_fem, natural_frequencies_fem = sphara_basis_fem.basis()

######################################################################
# Visualization the basis functions
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# The first 15 spatially low-frequency SPHARA basis functions are
# shown below, starting with DC at the top left.
# print all implemented methods of the TriMesh class
print([func for func in dir(tm.TriMesh) if not func.startswith('__')])

######################################################################

# create an instance of the TriMesh class
simple_mesh = tm.TriMesh(trilist, vertlist)

######################################################################
# For the simple triangle mesh an instance of the class SpharaBasis is
# created and the finite element discretization ('fem') is used. The
# complete set of SPHARA basis functions and the natural frequencies
# associated with the basis functions are determined.

sphara_basis = sb.SpharaBasis(simple_mesh, 'fem')
basis_functions, natural_frequencies = sphara_basis.basis()

######################################################################
# The set of SPHARA basis functions can be used for spatial Fourier
# analysis of the spatially irregularly sampled data.
#
# The first 15 spatially low-frequency SPHARA basis functions are
# shown below, starting with DC at the top left.

# sphinx_gallery_thumbnail_number = 2
figsb1, axes1 = plt.subplots(nrows=5,
                             ncols=3,
                             figsize=(8, 12),
                             subplot_kw={'projection': '3d'})
for i in range(np.size(axes1)):