I am sure this is relatively straightforward, but I feel like I am missing some basic knowledge to let me find the answer.

I have a list of 3D vectors not (necessarily) originating at the origin.

First question: What is the best way to represent this? My gut would say {{{x1,y1,z1},{vx1,vy1,vz1}},...}, where {{1,1,1},{1,0,0}} would be a vector originating at point {1,1,1} and pointing with magnitude 1 in the positive x direction, but I'm not sure if that's the easiest convention to use (maybe the second component should be the end point rather than the direction?). The answers to the following questions may influence the answer to this question.

Second question: What is the best way to perform transformations on this list of vectors? I am particularly interested in the various symmetry operations from group theory. So, for example, if I have a C4 rotation axis, and I have defined a matrix for that transformation, how do I apply it so that both the origin and the direction are appropriately transformed for each element in my list? I am interested in rotations, reflection planes, improper rotations, and centers of inversion.

Third question: If my system is set up such that each list element transforms into another list element when the above transformations are performed (within some tolerance, because the locations of the points may have some level of imprecision), is there a way to identify which element has transformed into which other element?

Bonus question: If the system is NOT set up so that each element transforms into another one, but rather into a linear combination of some of the other ones (where the basis for that linear combination will all originate at the same point), is there a way to find that linear combination? Example: a regular hexagon transforming by a C6 rotation, but where the basis is the three Cartesian axes centered on each vertex. If the z is perpendicular to the plane of the hexagon, then the x axis on one vertex will transform to a linear combination of x and y on another vertex.

Edited to add:

So it looks like I can just do the transforms straight. Given the {{{x1,y1,z1},{vx1,vy1,vz1}},...} structure, it looks like I can perform something like:


It looks like this is generalizable to all of the symmetry operations I am trying to apply. So that seems to answer questions 1 and 2. For question 3 I have made some progress, but it's not fully working. So I tried this:

basisElement[[Flatten[Map[Position[basisVectors, #] &, 
    ((Nearest[basisVectors] /@ C4A)[[1 ;; Length[basisVectors], 1]])]]]]

Here basisElement gives labels for the basis vectors. For example {{1,1,1},{0,0,1}} might be labeled pxA and {{1,1,-1},{0,0,1}} might be labeled pxB. But this doesn't correctly deal with an inversion of a basis element (for example, if pxA turns into {{1,1,-1},{0,0,-1}}, I want to return -pxB).

Further edited to add:

Ok, so my specific case has the direction vectors all as {0,0,0}, {1,0,0}, {0,1,0}, or {0,0,1}. So here is my kludge:

expandedBasisVectors = Join[basisVectors, 
     Cases[basisVectors, {x_, {y___, 1, z___}} -> {x, {y, -1, z}}]];
expandedBasisElements = Join[basisOrbitals, 
     -basisElements[[Position[basisVectors, #][[1,1]] & /@ 
     (Cases[basisVectors, {x_, {y___, 1, z___}} -> {x, {y, 1, z}}])]]];

That adds some extra entries that specifically lay out the negative directions of the basis elements. Then:

expandedBasisOrbitals[[Flatten[Map[Position[expandedBasisVectors, #] &,
     ((Nearest[expandedBasisVectors] /@ C4A)
     [[1 ;; Length[basisVectors], 1]])]]]]

So this works for the simple case, which may be good enough for me, but I feel like there must be a more elegant approach. And it also doesn't address the bonus question at all.

  • $\begingroup$ Take a look at TransformationFunction and see how it works. This may influence the way you choose to represent your data. $\endgroup$ – bill s Nov 9 '18 at 0:06
  • $\begingroup$ Thank you; I have glanced at it, and I see how it operates on a coordinate point or on a vector originating at the origin (since those are basically the same thing), but am unclear on how it can operate on a vector centered elsewhere (so that it has both 3D origin and 3D direction). Can you provide any insight? $\endgroup$ – Kevin Ausman Nov 9 '18 at 19:26

So I think I have finally figured out the rest of this. I modified my last set of trials above into:

expandedBasisVectors = Join[basisVectors, 
       Cases[basisVectors, {x_, Except[{0, 0, 0}, y_]} -> {x, -y}]];
expandedBasisElements = Join[basisOrbitals, 
       -basisOrbitals[[Position[basisVectors, #][[1, 1]] & /@ 
       (Cases[basisVectors, {x_, Except[{0, 0, 0}, y_]} -> {x, y}])]]];

This way any non-zero directional vector gets reversed. So that now fully answers my third question. My bonus question, it seems, is obviated by dropping the requirement that the element definitions be based on an external reference frame. If instead they are based on an element-specific reference frame, and those reference frames are chosen carefully based on the symmetry of the system, we should never have a case that requires any symmetry operation to convert a basis element into anything other than another basis element. Ok, maybe never is too strong... perhaps nearly never. Regardless, I have enough to work with now. Cheers, all!

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.