Synthia
Generic and flexible data structure generator
HyperspherePicker.java
Go to the documentation of this file.
1 /*
2  Synthia, a data structure generator
3  Copyright (C) 2019-2021 Laboratoire d'informatique formelle
4  Université du Québec à Chicoutimi, Canada
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 package ca.uqac.lif.synthia.vector;
20 
21 import ca.uqac.lif.synthia.Picker;
23 
24 /**
25  * Generates <i>n</i>-dimensional vectors with a given modulus. This
26  * picker does so by taking a positive value <i>r</i> and <i>n</i>-1 pickers
27  * providing angles &theta;<sub>1</sub>, &hellip; &theta;<sub><i>n</i>-1</sub>
28  * (in radians). These values are taken as the <i>n</i>-dimensional polar
29  * coordinates of a point, which is then turned into an <i>n</i>-dimensional
30  * vector in Euclidean coordinates, as is defined in this paper:
31  * <blockquote>
32  * A. Muleshkov, T. Nguyen. (2013). Easy proof of the Jacobian for the n-dimensional
33  * polar coordinates. (<a href="http://muleshko.faculty.unlv.edu/am_papers_pdf/n_d_polarcoordinates_note1.pdf">Paper</a>)
34  * </blockquote>
35  * The end result is that this picker generates vectors corresponding
36  * to points that lie on the surface of an <i>n</i>-dimensional
37  * hypersphere of some radius <i>r</i>.
38  *
39  * @ingroup API
40  *
41  */
42 public class HyperspherePicker implements VectorPicker
43 {
44  /**
45  * The pickers for the radius and each polar angle
46  */
48 
49  /**
50  * Creates a new hypersphere picker.
51  * @param dimensions The pickers used to generate values for
52  * each of the dimensions of the vector. The first corresponds
53  * to the radius, and the others to each polar angle.
54  */
55  @SuppressWarnings("unchecked")
56  public HyperspherePicker(Picker<? extends Number> ... dimensions)
57  {
58  super();
59  m_dimensions = dimensions;
60  }
61 
62  /**
63  * Creates a new hypershpere picker.
64  * @param modulus The modulus of the vectors to generate
65  * @param dimensions The pickers used to generate values for
66  * each polar angle.
67  */
68  @SuppressWarnings("unchecked")
69  public HyperspherePicker(float modulus, Picker<? extends Number> ... dimensions)
70  {
71  super();
72  m_dimensions = new Picker[dimensions.length + 1];
73  m_dimensions[0] = new Constant<Number>(modulus);
74  for (int i = 0; i < dimensions.length; i++)
75  {
76  m_dimensions[i + 1] = dimensions[i];
77  }
78 
79  }
80 
81 
82  /**
83  * Puts the hypersphere picker back into its initial state. This means that the
84  * sequence of calls to {@link #pick()} will produce the same values
85  * as when the object was instantiated.
86  */
87  @Override
88  public void reset()
89  {
90  for (Picker<?> p : m_dimensions)
91  {
92  p.reset();
93  }
94  }
95 
96  @Override
97  public float[] pick()
98  {
99  float r = m_dimensions[0].pick().floatValue();
100  int n = m_dimensions.length;
101  float[] v = new float[n];
102  float sin_prod = 1;
103  float last_theta = m_dimensions[n - 1].pick().floatValue();
104  v[n - 1] = r * (float) Math.cos(last_theta);
105  for (int i = n - 2; i > 1; i--)
106  {
107  sin_prod *= Math.sin(last_theta);
108  last_theta = m_dimensions[i].pick().floatValue();
109  v[i] = r * (float) Math.cos(last_theta);
110  }
111  //last_theta = m_dimensions[1].pick().floatValue();
112  v[0] = r * (float) Math.sin(last_theta) * sin_prod;
113  return v;
114  }
115 
116  /**
117  * Creates a copy of the hypersphere picker.
118  * @param with_state If set to <tt>false</tt>, the returned copy is set to
119  * the class' initial state (i.e. same thing as calling the picker's
120  * constructor). If set to <tt>true</tt>, the returned copy is put into the
121  * same internal state as the object it is copied from.
122  * @return The copy of the hypersphere picker
123  */
124  @SuppressWarnings("unchecked")
125  @Override
126  public HyperspherePicker duplicate(boolean with_state)
127  {
128  Picker<? extends Number>[] dimensions = new Picker[m_dimensions.length];
129  for (int i = 0; i < m_dimensions.length; i++)
130  {
131  dimensions[i] = m_dimensions[i].duplicate(with_state);
132  }
133  return new HyperspherePicker(dimensions);
134  }
135 
136  @Override
137  public int getDimension()
138  {
139  return m_dimensions.length;
140  }
141 
142  @Override
143  public String toString()
144  {
145  return "HyperspherePicker";
146  }
147 }
ca.uqac.lif.synthia.Picker
Picks an object.
Definition: Picker.java:36
ca.uqac.lif.synthia.vector.HyperspherePicker.reset
void reset()
Puts the hypersphere picker back into its initial state.
Definition: HyperspherePicker.java:88
ca.uqac.lif.synthia.vector.HyperspherePicker.toString
String toString()
Definition: HyperspherePicker.java:143
ca.uqac.lif.synthia.util
Miscellaneous pickers performing various functions.
Definition: ArrayPicker.java:19
ca.uqac.lif.synthia.vector.HyperspherePicker.pick
float[] pick()
Picks an object.
Definition: HyperspherePicker.java:97
ca.uqac
ca.uqac.lif.synthia
Definition: Bounded.java:19
ca.uqac.lif.synthia.util.Constant
Picker that returns the same object every time.
Definition: Constant.java:37
ca.uqac.lif.synthia.vector.HyperspherePicker
Generates n-dimensional vectors with a given modulus.
Definition: HyperspherePicker.java:42
ca.uqac.lif.synthia.vector.VectorPicker
Interface for pickers that generate arrays of floating-point numbers.
Definition: VectorPicker.java:29
ca.uqac.lif
ca.uqac.lif.synthia.vector.HyperspherePicker.m_dimensions
Picker<? extends Number >[] m_dimensions
The pickers for the radius and each polar angle.
Definition: HyperspherePicker.java:47
ca
ca.uqac.lif.synthia.Picker.pick
T pick()
Picks an object.
ca.uqac.lif.synthia.vector.HyperspherePicker.HyperspherePicker
HyperspherePicker(Picker<? extends Number > ... dimensions)
Creates a new hypersphere picker.
Definition: HyperspherePicker.java:56
ca.uqac.lif.synthia.vector.HyperspherePicker.getDimension
int getDimension()
Returns the dimension of the picker, i.e.
Definition: HyperspherePicker.java:137
ca.uqac.lif.synthia.Picker.duplicate
Picker< T > duplicate(boolean with_state)
Creates a copy of the picker.
ca.uqac.lif.synthia.vector.HyperspherePicker.duplicate
HyperspherePicker duplicate(boolean with_state)
Creates a copy of the hypersphere picker.
Definition: HyperspherePicker.java:126