def ufrac_to_ucart(A, cell, uvals): """ #>>> uvals = [0.07243, 0.03058, 0.03216, -0.01057, -0.01708, 0.03014] #>>> Ucart = Matrix([[ 0.0754483395556807, 0.030981701122469, -0.0194466522033868], [ 0.030981701122469, 0.03058, -0.01057], [-0.0194466522033868, -0.01057, 0.03216] ]) #>>> cell = (10.5086, 20.9035, 20.5072, 90, 94.13, 90) #>>> from shelxfile.dsrmath import OrthogonalMatrix #>>> A = OrthogonalMatrix(*cell) #>>> ufrac_to_ucart(A, cell, uvals) #TODO: test if this is right: | 0.0740 0.0310 -0.0299| | 0.0302 0.0306 -0.0148| |-0.0171 -0.0106 0.0346| <BLANKLINE> """ U11, U22, U33, U23, U13, U12 = uvals U21 = U12 U32 = U23 U31 = U13 Uij = Matrix([[U11, U12, U13], [U21, U22, U23], [U31, U32, U33]]) a, b, c, alpha, beta, gamma = cell V = vol_unitcell(*cell) # calculate reciprocal lattice vectors: astar = (b * c * sin(radians(alpha))) / V bstar = (c * a * sin(radians(beta))) / V cstar = (a * b * sin(radians(gamma))) / V # matrix with the reciprocal lattice vectors: N = Matrix([[astar, 0, 0], [0, bstar, 0], [0, 0, cstar]]) # Finally transform Uij values from fractional to cartesian axis system: Ucart = A * N * Uij * N.T * A.T return Ucart
def test_cholesky(self): m = Matrix([[25, 15, -5], [15, 18, 0], [-5, 0, 11]]) self.assertEqual( "| 5.0000 0.0000 0.0000|\n" "| 3.0000 3.0000 0.0000|\n" "|-1.0000 1.0000 3.0000|\n", m.cholesky().__repr__())
def test_matrix_multiply2(self): m = Matrix([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) m2 = Matrix([[2, 2, 2], [0.5, 0.5, 0.5], [2, 2, 1]]) x = m * m2 self.assertEqual( "| 6.0000 1.5000 5.0000|\n" "| 6.0000 1.5000 5.0000|\n" "| 6.0000 1.5000 5.0000|\n", x.__repr__()) self.assertEqual( "| 1.0000 1.0000 1.0000|\n" "| 1.0000 1.0000 1.0000|\n" "| 1.0000 1.0000 1.0000|\n", m.__repr__())
def test_foo(self): m = Matrix([[1, 2, 300], [4.1, 4.2, 4.3], [5, 6, 7]]) x = m + m self.assertEqual( "| 2.0000 4.0000 600.0000|\n" "| 8.2000 8.4000 8.6000|\n" "|10.0000 12.0000 14.0000|\n", x.__repr__()) m *= 3 self.assertEqual( "| 3.0000 6.0000 900.0000|\n" "|12.3000 12.6000 12.9000|\n" "|15.0000 18.0000 21.0000|\n", m.__repr__())
def transform_uvalues(self, uvals: (list, tuple), symm_num: int): """ Transforms the Uij values according to local symmetry. R. W. Grosse-Kunstleve, P. D. Adams (2002). J. Appl. Cryst. 35, 477–480. http://dx.doi.org/10.1107/S0021889802008580 U(star) = N * U(cif) * N.T U(star) = R * U(star) * R^t U(cif) = N^-1 * U(star) * (N^-1).T U(cart) = A * U(star) * A.T U(frac) = A^1 * U(cart) * (A^1).t U(star) = A^-1 * U(cart) * A^-1.t R is the rotation part of a given symmetry operation [ [U11, U12, U13] [U12, U22, U23] [U13, U23, U33] ] # Shelxl uses U* with a*,b*c*-parameterization atomname sfac x y z sof[11] U[0.05] or U11 U22 U33 U23 U13 U12 Read: X-Ray Analysis and the Structure of Organic Molecules Second Edition, Dunitz, P240 """ U11, U22, U33, U23, U13, U12 = uvals U21 = U12 U32 = U23 U31 = U13 Ucif = Matrix([[U11, U12, U13], [U21, U22, U23], [U31, U32, U33]]) # matrix with the reciprocal lattice vectors: N = Matrix([[self.astar, 0, 0], [0, self.bstar, 0], [0, 0, self.cstar]]) R = self.shx.symmcards[symm_num].matrix R_t = self.shx.symmcards[symm_num].matrix.transposed A = self.shx.orthogonal_matrix # U(star) = N * U(cif) * N.T # U(cart) = A * U(star) * A.T # U(star) = R * U(star) * R^t # U(cif) = N^-1 * U(star) * (N^-1).T # U(star) = A^-1 * U(cart) * A^-1.T Ustar = N * Ucif * N.T Ustar = R * Ustar * R_t Ucif = N.inversed * Ustar * N.inversed.T uvals = Ucif upper_diagonal = uvals.values[0][0], uvals.values[1][1], uvals.values[2][2], \ uvals.values[1][2], uvals.values[0][2], \ uvals.values[0][1] return upper_diagonal
def test_matrix_add_matrix(self): m1 = Matrix([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) m2 = Matrix([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) t1 = m1 + m2 self.assertEqual( "| 2.0000 2.0000 2.0000|\n" "| 2.0000 2.0000 2.0000|\n" "| 2.0000 2.0000 2.0000|\n", t1.__repr__()) t2 = m1 + 0.5 self.assertEqual( "| 1.5000 1.5000 1.5000|\n" "| 1.5000 1.5000 1.5000|\n" "| 1.5000 1.5000 1.5000|\n", t2.__repr__())
def test_zero(self): self.assertEqual( "| 0.0000 0.0000 0.0000|\n" "| 0.0000 0.0000 0.0000|\n" "| 0.0000 0.0000 0.0000|\n" "| 0.0000 0.0000 0.0000|\n" "| 0.0000 0.0000 0.0000|\n", Matrix.zero(5, 3).__repr__())
def test_matrix_multiply_array(self): m = Matrix([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) self.assertEqual(Array([6, 6, 6]), m * Array([2, 2, 2]))
def test_matrix_multiply1(self): m = Matrix([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) * 2 self.assertEqual( "| 2.0000 2.0000 2.0000|\n" "| 2.0000 2.0000 2.0000|\n" "| 2.0000 2.0000 2.0000|\n", m.__repr__())
def test_getitem(self): m = Matrix([[2., 2., 3.], [1., 2.2, 3.], [1., 2., 3.]]) self.assertEqual(2.2, m[1, 1]) self.assertEqual(2.2, m[1][1])
def transpose_alt(self): m = Matrix([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) self.assertEqual([[1, 1, 1], [2, 2, 2], [3, 3, 3]], m.transpose_alt().values)
def test_transposed(self): m = Matrix([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) self.assertEqual([(1, 1, 1), (2, 2, 2), (3, 3, 3)], m.transposed.values)
def test_subtract_matrix_from_matrix(self): self.assertEqual([[2, 0, -2], [2, 0, -2], [2, 0, 0]], Matrix([[3, 2, 1], [3, 2, 1], [3, 2, 3]]) - Matrix([[1, 2, 3], [1, 2, 3], [1, 2, 3]]))
def test_equal2(self): m1 = Matrix([(1, 2, 3), (1, 2, 3), (1, 2, 3)]) m2 = Matrix([(1, 2, 3), (3, 2, 3), (1, 2, 3)]) self.assertEqual(False, m1 == m2)
def test_equal(self): m1 = Matrix([(1., 2., 3.), (1., 2., 3.), (1., 2., 3.)]) m2 = Matrix([(1, 2, 3), (1, 2, 3), (1, 2, 3)]) self.assertEqual(True, m1 == m2)
def test_matrix_multiply4(self): m = Matrix([(0, 1, 0), (-1, -1, 0), (0, 0, 1)]) self.assertEqual(Array([-0.666667, -0.333334, 0.45191]), Array([0.333333, 0.666667, 0.45191]) * m)
def test_det(self): m1 = Matrix([[2, 0, 0], [0, 2, 0], [0, 0, 2]]) self.assertEqual(8, m1.det)
def test_inversed(self): self.assertEqual( "|-0.8125 0.1250 0.1875|\n" "| 0.1250 -0.2500 0.1250|\n" "| 0.5208 0.1250 -0.1458|\n", Matrix([[1, 2, 3], [4, 1, 6], [7, 8, 9]]).inversed.__repr__())