//MassCenter centers in in the center of mass of oref. Mass must be //A column vector. Returns the centered matrix and the displacement matrix. func MassCenter(in, oref *v3.Matrix, mass *mat64.Dense) (*v3.Matrix, *v3.Matrix, error) { or, _ := oref.Dims() ir, _ := in.Dims() if mass == nil { //just obtain the geometric center tmp := ones(or) mass = mat64.NewDense(or, 1, tmp) //gnOnes(or, 1) } ref := v3.Zeros(or) ref.Copy(oref) gnOnesvector := gnOnes(1, or) f := func() { ref.ScaleByCol(ref, mass) } if err := gnMaybe(gnPanicker(f)); err != nil { return nil, nil, CError{err.Error(), []string{"v3.Matrix.ScaleByCol", "MassCenter"}} } ref2 := v3.Zeros(1) g := func() { ref2.Mul(gnOnesvector, ref) } if err := gnMaybe(gnPanicker(g)); err != nil { return nil, nil, CError{err.Error(), []string{"v3.gOnesVector", "MassCenter"}} } ref2.Scale(1.0/mass.Sum(), ref2) returned := v3.Zeros(ir) returned.Copy(in) returned.SubVec(returned, ref2) /* for i := 0; i < ir; i++ { if err := returned.GetRowVector(i).Subtract(ref2); err != nil { return nil, nil, err } } */ return returned, ref2, nil }
//CenterOfMass returns the center of mass the atoms represented by the coordinates in geometry //and the masses in mass, and an error. If mass is nil, it calculates the geometric center func CenterOfMass(geometry *v3.Matrix, mass *mat64.Dense) (*v3.Matrix, error) { if geometry == nil { return nil, CError{"goChem: nil matrix to get the center of mass", []string{"CenterOfMass"}} } gr, _ := geometry.Dims() if mass == nil { //just obtain the geometric center tmp := ones(gr) mass = mat64.NewDense(gr, 1, tmp) //gnOnes(gr, 1) } tmp2 := ones(gr) gnOnesvector := mat64.NewDense(1, gr, tmp2) //gnOnes(1, gr) ref := v3.Zeros(gr) ref.ScaleByCol(geometry, mass) ref2 := v3.Zeros(1) ref2.Mul(gnOnesvector, ref) ref2.Scale(1.0/mass.Sum(), ref2) return ref2, nil }