View Javadoc
1   // ******************************************************************************
2   //
3   // Title:       Force Field X.
4   // Description: Force Field X - Software for Molecular Biophysics.
5   // Copyright:   Copyright (c) Michael J. Schnieders 2001-2025.
6   //
7   // This file is part of Force Field X.
8   //
9   // Force Field X is free software; you can redistribute it and/or modify it
10  // under the terms of the GNU General Public License version 3 as published by
11  // the Free Software Foundation.
12  //
13  // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16  // details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA 02111-1307 USA
21  //
22  // Linking this library statically or dynamically with other modules is making a
23  // combined work based on this library. Thus, the terms and conditions of the
24  // GNU General Public License cover the whole combination.
25  //
26  // As a special exception, the copyright holders of this library give you
27  // permission to link this library with independent modules to produce an
28  // executable, regardless of the license terms of these independent modules, and
29  // to copy and distribute the resulting executable under terms of your choice,
30  // provided that you also meet, for each linked independent module, the terms
31  // and conditions of the license of that module. An independent module is a
32  // module which is not derived from or based on this library. If you modify this
33  // library, you may extend this exception to your version of the library, but
34  // you are not obligated to do so. If you do not wish to do so, delete this
35  // exception statement from your version.
36  //
37  // ******************************************************************************
38  package ffx.numerics.math;
39  
40  import static java.lang.System.arraycopy;
41  
42  /**
43   * Convenience class for working with 3D double vectors.
44   *
45   * @author Michael J. Schnieders
46   * @since 1.0
47   */
48  public class Double3 {
49  
50    /** Internal storage for the vector. */
51    private final double[] a;
52  
53    /** Construct a Double3 at (0.0, 0.0, 0.0). */
54    public Double3() {
55      a = new double[] {0.0, 0.0, 0.0};
56    }
57  
58    /**
59     * Construct a Double3 at (x, y, z).
60     *
61     * @param x X value.
62     * @param y Y value.
63     * @param z Z value.
64     */
65    public Double3(double x, double y, double z) {
66      a = new double[] {x, y, z};
67    }
68  
69    /**
70     * Construct a Double3 at a.
71     *
72     * @param a Double3 to initialize from (the data is copied).
73     */
74    public Double3(double[] a) {
75      this.a = new double[] {a[0], a[1], a[2]};
76    }
77  
78    /**
79     * Compute <code>this * b + c</code> and return the result in a new Double3.
80     *
81     * @param b Scalar.
82     * @param c Double3.
83     * @return Returns the FMA of <code>this * b + c</code> in a new Double3.
84     */
85    public Double3 fma(double b, Double3 c) {
86      Double3 ret = new Double3();
87      DoubleMath.fma(a, b, c.get(), ret.get());
88      return ret;
89    }
90  
91    /**
92     * Compute <code>this * b + c</code> and return the result in a new Double3.
93     *
94     * @param b Scalar.
95     * @param c Double3.
96     * @return Returns the FMA of <code>this * b + c</code> in this Double3.
97     */
98    public Double3 fmaI(double b, Double3 c) {
99      DoubleMath.fma(a, b, c.get(), a);
100     return this;
101   }
102 
103   /**
104    * Cross product of this Double3 with b.
105    *
106    * @param b Vector b.
107    * @return Returns the cross product in a new Double3.
108    */
109   public Double3 X(Double3 b) {
110     Double3 ret = new Double3();
111     DoubleMath.X(a, b.get(), ret.get());
112     return ret;
113   }
114 
115   /**
116    * In-place Cross product of this Double3 with b.
117    *
118    * @param b Vector b.
119    * @return Returns the cross product in this Double3.
120    */
121   public Double3 XI(Double3 b) {
122     return set(X(b));
123   }
124 
125   /**
126    * Finds the sum of this Double3 with b.
127    *
128    * @param b Second Double3.
129    * @return Returns the sum in a new Double3.
130    */
131   public Double3 add(Double3 b) {
132     Double3 ret = new Double3();
133     DoubleMath.add(a, b.get(), ret.get());
134     return ret;
135   }
136 
137   /**
138    * Finds the sum of this Double3 with b in place.
139    *
140    * @param b Second Double3.
141    * @return Returns the sum in this Double3.
142    */
143   public Double3 addI(Double3 b) {
144     DoubleMath.add(a, b.get(), a);
145     return this;
146   }
147 
148   /**
149    * Angle of this Double3 with b.
150    *
151    * @param b Vector b.
152    * @return Returns the angle.
153    */
154   public double angle(Double3 b) {
155     return DoubleMath.angle(a, b.get());
156   }
157 
158   /**
159    * Returns a new copy of this Double3.
160    *
161    * @return Returns a copy of this Double3.
162    */
163   public Double3 copy() {
164     return new Double3(a);
165   }
166 
167   /**
168    * Finds the Euclidean distance between two positions.
169    *
170    * @param b Second vector.
171    * @return Returns the distance between this Double3 and b.
172    */
173   public double dist(Double3 b) {
174     return DoubleMath.dist(a, b.get());
175   }
176 
177   /**
178    * Finds the square of the Euclidean distance between two positions.
179    *
180    * @param b Second vector.
181    * @return Returns the squared distance between this Double3 and b.
182    */
183   public double dist2(Double3 b) {
184     return DoubleMath.dist2(a, b.get());
185   }
186 
187   /**
188    * Finds the dot product between two vectors.
189    *
190    * @param b Second vector.
191    * @return Returns the dot product of this Double3 and b.
192    */
193   public double dot(Double3 b) {
194     return DoubleMath.dot(a, b.get());
195   }
196 
197   /**
198    * Returns a reference to the internal double array that stores this Double3.
199    *
200    * @return A reference to the internal double array.
201    */
202   public double[] get() {
203     return a;
204   }
205 
206   /**
207    * Returns the coordinate at position i.
208    *
209    * @param i The coordinate index.
210    * @return The coordinate.
211    */
212   public double get(int i) {
213     return a[i];
214   }
215 
216   /**
217    * Finds the length of this Double3.
218    *
219    * @return Length of vector this Double3.
220    */
221   public double length() {
222     return DoubleMath.length(a);
223   }
224 
225   /**
226    * Finds the length of this Double3 squared.
227    *
228    * @return Length of vector this Double3 squared.
229    */
230   public double length2() {
231     return DoubleMath.length2(a);
232   }
233 
234   /** Log this Double3. */
235   public void log() {
236     DoubleMath.log(a);
237   }
238 
239   /**
240    * Normalize this Double3.
241    *
242    * @return Returns a new Double3.
243    */
244   public Double3 normalize() {
245     Double3 ret = new Double3();
246     DoubleMath.normalize(a, ret.get());
247     return ret;
248   }
249 
250   /**
251    * Normalize this Double3 in place.
252    *
253    * @return Returns a reference to this Double3 normalized.
254    */
255   public Double3 normalizeI() {
256     DoubleMath.normalize(a, a);
257     return this;
258   }
259 
260   /**
261    * Scales a Double3.
262    *
263    * @param d A scalar value.
264    * @return Returns a new scaled Double3.
265    */
266   public Double3 scale(double d) {
267     Double3 ret = new Double3();
268     DoubleMath.scale(a, d, ret.get());
269     return ret;
270   }
271 
272   /**
273    * Scales a Double3 in place.
274    *
275    * @param d A scalar value.
276    * @return Returns a reference to this Double3 scaled.
277    */
278   public Double3 scaleI(double d) {
279     DoubleMath.scale(a, d, a);
280     return this;
281   }
282 
283   /**
284    * Squares values in Double3.
285    *
286    * @return Returns a reference to this Double3 squared.
287    */
288   public Double3 square() {
289     Double3 ret = new Double3();
290     DoubleMath.square(a, ret.get());
291     return ret;
292   }
293 
294   /**
295    * Squares values in Double3 in place.
296    *
297    * @return Returns a reference to this Double3 squared.
298    */
299   public Double3 squareI() {
300     DoubleMath.square(a, a);
301     return this;
302   }
303 
304   /**
305    * Square roots values in Double3.
306    *
307    * @return Returns a reference to this Double3 square rooted.
308    */
309   public Double3 sqrt() {
310     Double3 ret = new Double3();
311     DoubleMath.squareRoot(a, ret.get());
312     return ret;
313   }
314 
315   /**
316    * Square roots values in Double3 in place.
317    *
318    * @return Returns a reference to this Double3 square rooted.
319    */
320   public Double3 sqrtI() {
321     DoubleMath.squareRoot(a, a);
322     return this;
323   }
324 
325   /**
326    * Set the value of this Double3.
327    *
328    * @param x X-value.
329    * @param y Y-value.
330    * @param z Z-value.
331    * @return A reference to this Double3.
332    */
333   public Double3 set(double x, double y, double z) {
334     a[0] = x;
335     a[1] = y;
336     a[2] = z;
337     return this;
338   }
339 
340   /**
341    * Set the value of this Double3.
342    *
343    * @param b Double array that is copied.
344    * @return A reference to this Double3.
345    */
346   public Double3 set(double[] b) {
347     arraycopy(b, 0, a, 0, 3);
348     return this;
349   }
350 
351   /**
352    * Set the value of this Double3.
353    *
354    * @param b Double3 that is copied.
355    * @return A reference to this Double3.
356    */
357   public Double3 set(Double3 b) {
358     arraycopy(b.get(), 0, a, 0, 3);
359     return this;
360   }
361 
362   /**
363    * Finds the difference between two vectors.
364    *
365    * @param b Second vector
366    * @return Returns the difference in a new Double3.
367    */
368   public Double3 sub(Double3 b) {
369     Double3 ret = new Double3();
370     DoubleMath.sub(a, b.get(), ret.get());
371     return ret;
372   }
373 
374   /**
375    * Finds the difference between two vectors.
376    *
377    * @param b Second vector
378    * @return Returns the difference in this Double3.
379    */
380   public Double3 subI(Double3 b) {
381     DoubleMath.sub(a, b.get(), a);
382     return this;
383   }
384 
385   /**
386    * Describe this Double3 in a String.
387    *
388    * @return Returns a String description.
389    */
390   @Override
391   public String toString() {
392     return DoubleMath.toString(a);
393   }
394 
395   /**
396    * Get the value x.
397    *
398    * @return Returns x.
399    */
400   public double x() {
401     return a[0];
402   }
403 
404   /**
405    * Get the value of y.
406    *
407    * @return Returns y.
408    */
409   public double y() {
410     return a[1];
411   }
412 
413   /**
414    * Get the value of z.
415    *
416    * @return Returns z.
417    */
418   public double z() {
419     return a[2];
420   }
421 }