//BestPlane returns a row vector that is normal to the plane that best contains the molecule //if passed a nil Masser, it will simply set all masses to 1. func BestPlane(coords *v3.Matrix, mol Masser) (*v3.Matrix, error) { var err error var Mmass []float64 cr, _ := coords.Dims() if mol != nil { Mmass, err = mol.Masses() if err != nil { return nil, errDecorate(err, "BestPlane") } if len(Mmass) != cr { return nil, CError{fmt.Sprintf("Inconsistent coordinates(%d)/atoms(%d)", len(Mmass), cr), []string{"BestPlane"}} } } moment, err := MomentTensor(coords, Mmass) if err != nil { return nil, errDecorate(err, "BestPlane") } evecs, _, err := v3.EigenWrap(moment, appzero) if err != nil { return nil, errDecorate(err, "BestPlane") } normal, err := BestPlaneP(evecs) if err != nil { return nil, errDecorate(err, "BestPlane") } //MomentTensor(, mass) return normal, err }
//A very basic analysis of the moment of inertia tensor. func main() { mol, err := chem.XYZFileRead("../sample.xyz") if err != nil { panic(err.Error()) } mass, err := mol.Masses() if err != nil { mass = nil //MomentTensor will simply assign 1 to all masses } coords := mol.Coords[0] moment, err := chem.MomentTensor(coords, mass) if err != nil { panic(err.Error()) } eigvectors, eigvalues, err := v3.EigenWrap(moment, -1) if err != nil { panic(err.Error()) } main := eigvectors.VecView(2) //The last is the widest. fmt.Printf("Widest eigenvector: %v Corresponding eigenvalue: %4.1f\n", main, eigvalues[2]) }