I am trying to fill a RealVector (from Apache Commons Math) with values. I tried using the class’s append method, but that didn’t actually add anything. So now I’m using a double[], which works fine, except I don’t know in advance how big the array needs to be.
private void runAnalysis() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Double attr;
double[] data = new double[100]; // TODO: bad.
int i = 0;
for (Method m : ParseTree.class.getMethods()) {
if (m.isAnnotationPresent(Analyze.class)) {
attr = (Double) m.invoke(this);
analysis.put(m.getAnnotation(Analyze.class).name(), attr);
data[i++] = attr * m.getAnnotation(Analyze.class).weight();
}
}
weightedAnalysis = new ArrayRealVector(data);
}
How can I deal with this issue? Here are my ideas:
-
Iterate through the class and count the methods with the annotation, then use that size to initialize the array. However, this will require an extra loop, and reflection is performance-intensive. (right?)
-
Pick an arbitrary size for the array, doubling it if space runs out. Downside: requires more lines of code
-
Use a
List<Double>, then somehow weasel theDoubleobjects back intodoublesso they can be put in theRealVector. Uses more memory for the list. -
Just pick a huge size for the starting array, and hope that it never overflows. Downside: this is begging for arrayindexoutofbound errors.
-
Or am I just using
append(double d)wrong?private void runAnalysis() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Double attr;
weightedAnalysis = new ArrayRealVector(data);for (Method m : ParseTree.class.getMethods()) { if (m.isAnnotationPresent(Analyze.class)) { attr = (Double) m.invoke(this); analysis.put(m.getAnnotation(Analyze.class).name(), attr); weightedAnalysis.append(attr * m.getAnnotation(Analyze.class).weight()); } }}
RealVector.append() doesn’t modify the vector, but rather constructs a new vector:
The [Java doc of RealVector.append()](http://commons.apache.org/math/apidocs/org/apache/commons/math/linear/RealVector.html#append(double)) explains:
Please note that using
RealVectorto construct the vector is quite an expensive operation, as append() would need to copy the elements over and over (i.e. constructing the array in the way you explained runs inO(n^2)time.I would recommend simply using java’s
ArrayList<Double>during construction, and then simply converting toRealVectoror any other data abstraction you like.