# Path: lib/eofs/tests/utils.py
# def sign_adjustments(eofset, refeofset):
#     """Sign adjustments for EOFs/PCs.
# 
#     Create a matrix of sign weights used for adjusting the sign of a set
#     of EOFs or PCs to the sign of a reference set.
# 
#     The first dimension is assumed to be modes.
# 
#     **Arguments:**
# 
#     *eofset*
#         Set of EOFs.
# 
#     *refeofset*
#         Reference set of EOFs.
# 
#     """
#     if eofset.shape != refeofset.shape:
#         raise ValueError('input set has different shape from reference set')
#     eofset, refeofset = __tomasked(eofset, refeofset)
#     nmodes = eofset.shape[0]
#     signs = np.ones([nmodes])
#     shape = [nmodes] + [1] * (eofset.ndim - 1)
#     eofset = eofset.reshape([nmodes, np.prod(eofset.shape[1:], dtype=np.int)])
#     refeofset = refeofset.reshape([nmodes,
#                                    np.prod(refeofset.shape[1:],
#                                            dtype=np.int)])
#     for mode in range(nmodes):
#         i = 0
#         try:
#             while _close(eofset[mode, i], 0.) or \
#                   _close(refeofset[mode, i], 0.) \
#                   or np.ma.is_masked(eofset[mode, i]) or \
#                   np.ma.is_masked(refeofset[mode, i]):
#                 i += 1
#         except IndexError:
#             i = 0
#         if np.sign(eofset[mode, i]) != np.sign(refeofset[mode, i]):
#             signs[mode] = -1
#     return signs.reshape(shape)
# 
# Path: lib/eofs/tests/reference.py
# def reference_multivariate_solution(container_type, weights):
#     """Obtain a reference multivariate EOF analysis solution.
# 
#     **Arguments:**
# 
#     *container_type*
#         Either 'standard', 'cdms', or 'iris'.
# 
#     *weights*
#         Weights method. One of 'equal', 'latitude', 'area',
#         'area_multi', or 'area_multi_mix'.
# 
#     """
#     if weights.lower() == 'area':
#         weights = 'area_multi'
#     if weights.lower() == 'none_area':
#         weights = 'area_multi_mix'
#     solution = reference_solution(container_type, weights)
#     nlon = len(solution['longitude'])
#     slice1 = slice(0, nlon // 2)
#     slice2 = slice(nlon // 2, None)
#     for var in ('longitude',
#                 'sst',
#                 'eofs',
#                 'eofscor',
#                 'eofscov',
#                 'weights',
#                 'rcon',):
#         try:
#             solution[var] = (solution[var][..., slice1],
#                              solution[var][..., slice2])
#         except TypeError:
#             solution[var] = None, None
#     return solution


import numpy as np
import pytest
import eofs.multivariate as multivariate
    from iris.cube import Cube
from eofs.tests import EofsTest
from .utils import sign_adjustments
from .reference import reference_multivariate_solution
    @pytest.mark.parametrize('vfscaled', (True, False))
    def test_northTest(self, vfscaled):
        # typical errors should match the reference solution
        errs = self.solver.northTest(neigs=self.neofs, vfscaled=vfscaled)
        error_name = 'scaled_errors' if vfscaled else 'errors'
        self.assert_array_almost_equal(errs, self.solution[error_name])

    @pytest.mark.parametrize('eofscaling', (0, 1, 2))
    def test_projectField(self, eofscaling):
        # original input projected onto the EOFs should match the reference
        # solution PCs
        pcs = self._tomasked(self.solver.projectField(self.solution['sst'],
                                                      neofs=self.neofs,
                                                      eofscaling=eofscaling))
        rpcs = self._tomasked(self.solution['pcs']).copy()
        pcs *= sign_adjustments(pcs.transpose(), rpcs.transpose()).transpose()
        reigs = self._tomasked(self.solution['eigenvalues'])
        if eofscaling == 1:
            rpcs /= np.sqrt(reigs)
        elif eofscaling == 2:
            rpcs *= np.sqrt(reigs)
        self.assert_array_almost_equal(pcs, rpcs)

    def test_projectField_temporal_subset(self):
        # projecting a temporal subset of the original input onto the EOFs
        # should match the same subset of the reference PCs
        pcs = self._tomasked(
            self.solver.projectField([x[:5] for x in self.solution['sst']],
                                     neofs=self.neofs))
        rpcs = self._tomasked(self.solution['pcs'])[:5]

# Path: lib/eofs/tests/utils.py
# def sign_adjustments(eofset, refeofset):
#     """Sign adjustments for EOFs/PCs.
# 
#     Create a matrix of sign weights used for adjusting the sign of a set
#     of EOFs or PCs to the sign of a reference set.
# 
#     The first dimension is assumed to be modes.
# 
#     **Arguments:**
# 
#     *eofset*
#         Set of EOFs.
# 
#     *refeofset*
#         Reference set of EOFs.
# 
#     """
#     if eofset.shape != refeofset.shape:
#         raise ValueError('input set has different shape from reference set')
#     eofset, refeofset = __tomasked(eofset, refeofset)
#     nmodes = eofset.shape[0]
#     signs = np.ones([nmodes])
#     shape = [nmodes] + [1] * (eofset.ndim - 1)
#     eofset = eofset.reshape([nmodes, np.prod(eofset.shape[1:], dtype=np.int)])
#     refeofset = refeofset.reshape([nmodes,
#                                    np.prod(refeofset.shape[1:],
#                                            dtype=np.int)])
#     for mode in range(nmodes):
#         i = 0
#         try:
#             while _close(eofset[mode, i], 0.) or \
#                   _close(refeofset[mode, i], 0.) \
#                   or np.ma.is_masked(eofset[mode, i]) or \
#                   np.ma.is_masked(refeofset[mode, i]):
#                 i += 1
#         except IndexError:
#             i = 0
#         if np.sign(eofset[mode, i]) != np.sign(refeofset[mode, i]):
#             signs[mode] = -1
#     return signs.reshape(shape)
# 
# Path: lib/eofs/tests/reference.py
# def reference_multivariate_solution(container_type, weights):
#     """Obtain a reference multivariate EOF analysis solution.
# 
#     **Arguments:**
# 
#     *container_type*
#         Either 'standard', 'cdms', or 'iris'.
# 
#     *weights*
#         Weights method. One of 'equal', 'latitude', 'area',
#         'area_multi', or 'area_multi_mix'.
# 
#     """
#     if weights.lower() == 'area':
#         weights = 'area_multi'
#     if weights.lower() == 'none_area':
#         weights = 'area_multi_mix'
#     solution = reference_solution(container_type, weights)
#     nlon = len(solution['longitude'])
#     slice1 = slice(0, nlon // 2)
#     slice2 = slice(nlon // 2, None)
#     for var in ('longitude',
#                 'sst',
#                 'eofs',
#                 'eofscor',
#                 'eofscov',
#                 'weights',
#                 'rcon',):
#         try:
#             solution[var] = (solution[var][..., slice1],
#                              solution[var][..., slice2])
#         except TypeError:
#             solution[var] = None, None
#     return solution


# Path: lib/eofs/tests/test_multivariate_solution.py
import numpy as np
import pytest
import eofs.multivariate as multivariate
    from iris.cube import Cube
from eofs.tests import EofsTest
from .utils import sign_adjustments
from .reference import reference_multivariate_solution

    @pytest.mark.parametrize('vfscaled', (True, False))
    def test_northTest(self, vfscaled):
        # typical errors should match the reference solution
        errs = self.solver.northTest(neigs=self.neofs, vfscaled=vfscaled)
        error_name = 'scaled_errors' if vfscaled else 'errors'
        self.assert_array_almost_equal(errs, self.solution[error_name])

    @pytest.mark.parametrize('eofscaling', (0, 1, 2))
    def test_projectField(self, eofscaling):
        # original input projected onto the EOFs should match the reference
        # solution PCs
        pcs = self._tomasked(self.solver.projectField(self.solution['sst'],
                                                      neofs=self.neofs,
                                                      eofscaling=eofscaling))
        rpcs = self._tomasked(self.solution['pcs']).copy()
        pcs *= sign_adjustments(pcs.transpose(), rpcs.transpose()).transpose()
        reigs = self._tomasked(self.solution['eigenvalues'])
        if eofscaling == 1:
            rpcs /= np.sqrt(reigs)
        elif eofscaling == 2:
            rpcs *= np.sqrt(reigs)
        self.assert_array_almost_equal(pcs, rpcs)

    def test_projectField_temporal_subset(self):
        # projecting a temporal subset of the original input onto the EOFs
        # should match the same subset of the reference PCs
        pcs = self._tomasked(
            self.solver.projectField([x[:5] for x in self.solution['sst']],
                                     neofs=self.neofs))
        rpcs = self._tomasked(self.solution['pcs'])[:5]

        pcs *= sign_adjustments(pcs.transpose(), rpcs.transpose()).transpose()