mailr26611 - in /trunk: pipe_control/align_tensor.py user_functions/align_tensor.py


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by edward on November 18, 2014 - 11:54:
Author: bugman
Date: Tue Nov 18 11:54:21 2014
New Revision: 26611

URL: http://svn.gna.org/viewcvs/relax?rev=26611&view=rev
Log:
Implemented a new default basis set for the align_tensor.matrix_angles user 
function.

This is uses standard definition of the inter-matrix angle using the 
Euclidean inner product of the
two matrices divided by the product of the Frobenius norm of each matrix.  As 
this is a linear map,
it should produce the most correct definition of inter-tensor angles.


Modified:
    trunk/pipe_control/align_tensor.py
    trunk/user_functions/align_tensor.py

Modified: trunk/pipe_control/align_tensor.py
URL: 
http://svn.gna.org/viewcvs/relax/trunk/pipe_control/align_tensor.py?rev=26611&r1=26610&r2=26611&view=diff
==============================================================================
--- trunk/pipe_control/align_tensor.py  (original)
+++ trunk/pipe_control/align_tensor.py  Tue Nov 18 11:54:21 2014
@@ -24,8 +24,8 @@
 
 # Python module imports.
 from copy import deepcopy
-from math import pi, sqrt
-from numpy import arccos, dot, float64, linalg, zeros
+from math import acos, pi, sqrt
+from numpy import arccos, dot, float64, inner, linalg, zeros
 from numpy.linalg import norm
 import sys
 from warnings import warn
@@ -907,7 +907,8 @@
         tensor_num = tensor_num + 1
 
     # Create the matrix which contains the 5D vectors.
-    matrix = zeros((tensor_num, 5), float64)
+    matrix_3D = zeros((tensor_num, 3, 3), float64)
+    matrix_5D = zeros((tensor_num, 5), float64)
 
     # Loop over the tensors.
     i = 0
@@ -919,24 +920,29 @@
         # Unitary basis set.
         if basis_set == 0:
             # Pack the elements.
-            matrix[i, 0] = tensor.Sxx
-            matrix[i, 1] = tensor.Syy
-            matrix[i, 2] = tensor.Sxy
-            matrix[i, 3] = tensor.Sxz
-            matrix[i, 4] = tensor.Syz
+            matrix_5D[i, 0] = tensor.Sxx
+            matrix_5D[i, 1] = tensor.Syy
+            matrix_5D[i, 2] = tensor.Sxy
+            matrix_5D[i, 3] = tensor.Sxz
+            matrix_5D[i, 4] = tensor.Syz
 
         # Geometric basis set.
         elif basis_set == 1:
             # Pack the elements.
-            matrix[i, 0] = tensor.Szz
-            matrix[i, 1] = tensor.Sxxyy
-            matrix[i, 2] = tensor.Sxy
-            matrix[i, 3] = tensor.Sxz
-            matrix[i, 4] = tensor.Syz
+            matrix_5D[i, 0] = tensor.Szz
+            matrix_5D[i, 1] = tensor.Sxxyy
+            matrix_5D[i, 2] = tensor.Sxy
+            matrix_5D[i, 3] = tensor.Sxz
+            matrix_5D[i, 4] = tensor.Syz
+
+        # Full matrix.
+        elif basis_set == 2:
+            matrix_3D[i] = tensor.A
 
         # Normalisation.
-        norm = linalg.norm(matrix[i])
-        matrix[i] = matrix[i] / norm
+        if basis_set in [0, 1]:
+            norm_5D = linalg.norm(matrix_5D[i])
+            matrix_5D[i] = matrix_5D[i] / norm_5D
 
         # Increment the index.
         i = i + 1
@@ -945,12 +951,15 @@
     cdp.align_tensors.angles = zeros((tensor_num, tensor_num), float64)
 
     # Header printout.
-    sys.stdout.write("\nData pipe: " + repr(pipes.cdp_name()) + "\n")
-    sys.stdout.write("\n5D angles in deg between the vectors ")
     if basis_set == 0:
+        sys.stdout.write("5d angles in deg between the vectors ")
         sys.stdout.write("{Sxx, Syy, Sxy, Sxz, Syz}")
     elif basis_set == 1:
+        sys.stdout.write("5d angles in deg between the vectors ")
         sys.stdout.write("{Szz, Sxx-yy, Sxy, Sxz, Syz}")
+    elif basis_set == 2:
+        sys.stdout.write("Angles in deg between the matrices ")
+        sys.stdout.write("(using the Euclidean inner product and Frobenius 
norm)")
     sys.stdout.write(":\n")
 
     # Initialise the table of data.
@@ -974,15 +983,35 @@
 
         # Second loop over the columns.
         for j in range(tensor_num):
-            # Dot product.
-            delta = dot(matrix[i], matrix[j])
-
-            # Check.
-            if delta > 1:
-                delta = 1
-
-            # The angle (in rad).
-            cdp.align_tensors.angles[i, j] = arccos(delta)
+            # The 5D angles.
+            if basis_set in [0, 1]:
+                # Dot product.
+                delta = dot(matrix_5D[i], matrix_5D[j])
+
+                # Check.
+                if delta > 1:
+                    delta = 1
+
+                # The angle.
+                theta = arccos(delta)
+
+            # The full matrix angle.
+            elif basis_set in [2]:
+                # The Euclidean inner product.
+                nom = inner(matrix_3D[i].flatten(), matrix_3D[j].flatten())
+
+                # The Frobenius norms.
+                denom = norm(matrix_3D[i]) * norm(matrix_3D[j])
+
+                # The angle.
+                ratio = nom / denom
+                if ratio <= 1.0:
+                    theta = arccos(nom / denom)
+                else:
+                    theta = 0.0
+
+            # Store the angle (in rad).
+            cdp.align_tensors.angles[i, j] = theta
 
             # Add to the table as degrees.
             table[i+1].append("%8.1f" % (cdp.align_tensors.angles[i, 
j]*180.0/pi))

Modified: trunk/user_functions/align_tensor.py
URL: 
http://svn.gna.org/viewcvs/relax/trunk/user_functions/align_tensor.py?rev=26611&r1=26610&r2=26611&view=diff
==============================================================================
--- trunk/user_functions/align_tensor.py        (original)
+++ trunk/user_functions/align_tensor.py        Tue Nov 18 11:54:21 2014
@@ -297,18 +297,18 @@
 
 # The align_tensor.matrix_angles user function.
 uf = uf_info.add_uf('align_tensor.matrix_angles')
-uf.title = "Calculate the 5D angles between all alignment tensors."
+uf.title = "Calculate the angles between all alignment tensors."
 uf.title_short = "Alignment tensor angle calculation."
 uf.display = True
 uf.add_keyarg(
     name = "basis_set",
-    default = 0,
+    default = 2,
     py_type = "int",
     desc_short = "basis set",
     desc = "The basis set to operate with.",
     wiz_element_type = "combo",
-    wiz_combo_choices = ["{Sxx, Syy, Sxy, Sxz, Syz}", "{Szz, Sxxyy, Sxy, 
Sxz, Syz}"],
-    wiz_combo_data = [0, 1]
+    wiz_combo_choices = ["{Sxx, Syy, Sxy, Sxz, Syz}", "{Szz, Sxxyy, Sxy, 
Sxz, Syz}", "Full matrix angles using the Euclidean inner product"],
+    wiz_combo_data = [0, 1, 2]
 )
 uf.add_keyarg(
     name = "tensors",
@@ -322,11 +322,23 @@
 )
 # Description.
 uf.desc.append(Desc_container())
-uf.desc[-1].add_paragraph("This will calculate the angles between all loaded 
alignment tensors for the current data pipe.  The matrices are first 
converted to a 5D vector form and then then angles are calculated.  The 
angles are dependent on the basis set.  If the basis set is set to the 
default of 0, the vectors {Sxx, Syy, Sxy, Sxz, Syz} are used.  If the basis 
set is set to 1, the vectors {Szz, Sxxyy, Sxy, Sxz, Syz} are used instead.")
+uf.desc[-1].add_paragraph("This will calculate the angles between all loaded 
alignment tensors for the current data pipe.  Depending upon the basis set, 
the matrices are first converted to a 5D vector form and then then angles are 
calculated.  The angles are dependent upon the basis set:")
+uf.desc[-1].add_item_list_element("0", "The basis set {Sxx, Syy, Sxy, Sxz, 
Syz},")
+uf.desc[-1].add_item_list_element("1", "The basis set {Szz, Sxxyy, Sxy, Sxz, 
Syz} of the Pales standard notation,")
+uf.desc[-1].add_item_list_element("2", "The full matrix angle via the 
Euclidean inner product of the alignment matrices together with the Frobenius 
norm ||A||_F.")
+uf.desc[-1].add_paragraph("The full matrix angle via the Euclidean inner 
product is defined as:")
+uf.desc[-1].add_verbatim("""
+                   /   <A1 , A2>   \ 
+    theta = arccos | ------------- | ,
+                   \ ||A1|| ||A2|| /
+""")
+uf.desc[-1].add_paragraph("where <a,b> is the Euclidean inner product and 
||a|| is the Frobenius norm of the matrix.")
+uf.desc[-1].add_paragraph("Note that the inner product solution is a linear 
map which hence preserves angles, whereas the {Sxx, Syy, Sxy, Sxz, Syz} and 
{Szz, Sxxyy, Sxy, Sxz, Syz} basis sets are non-linear maps which do not 
preserve angles.  Therefore the angles from all three basis sets will be 
different.")
 uf.backend = align_tensor.matrix_angles
 uf.menu_text = "&matrix_angles"
 uf.gui_icon = "oxygen.categories.applications-education"
-uf.wizard_size = (800, 600)
+uf.wizard_height_desc = 500
+uf.wizard_size = (1000, 700)
 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
 
 




Related Messages


Powered by MHonArc, Updated Tue Nov 18 14:00:03 2014