DoubleVector.java
package org.djunits.value.vdouble.vector.base;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import org.djunits.unit.SIUnit;
import org.djunits.unit.Unit;
import org.djunits.unit.scale.IdentityScale;
import org.djunits.unit.util.UnitRuntimeException;
import org.djunits.value.ValueRuntimeException;
import org.djunits.value.storage.StorageType;
import org.djunits.value.vdouble.scalar.base.DoubleScalarInterface;
import org.djunits.value.vdouble.vector.SIVector;
import org.djunits.value.vdouble.vector.data.DoubleVectorData;
/**
* DoubleVector utility methods, e.g., for creating DoubleVectors from different types of data.
* <p>
* Copyright (c) 2015-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
* BSD-style license. See <a href="https://djunits.org/docs/license.html">DJUNITS License</a>.
* <p>
* @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
* @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a>
*/
public final class DoubleVector
{
/** The cache to make the lookup of the constructor for a Immutable Vector belonging to a unit faster. */
private static final Map<Unit<?>, Constructor<? extends DoubleVectorInterface<?, ?, ?>>> CACHE_DATA = new HashMap<>();
/** Do not instantiate. */
private DoubleVector()
{
// Utility class.
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler.
* @param valuesInUnit double[]; the values in the given unit
* @param unit U; the unit in which the values are expressed and displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiate(final double[] valuesInUnit, final U unit,
final StorageType storageType)
{
return instantiateAnonymous(DoubleVectorData.instantiate(valuesInUnit, unit.getScale(), storageType), unit);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler. The class for the vector is
* explicitly provided, e.g., for user-defined vector classes.
* @param valuesInUnit double[]; the values in the given unit
* @param unit U; the unit in which the values are expressed and displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiate(final double[] valuesInUnit, final U unit,
final StorageType storageType, final Class<V> vectorClass)
{
return instantiateAnonymous(DoubleVectorData.instantiate(valuesInUnit, unit.getScale(), storageType), unit,
vectorClass);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler.
* @param valuesSI double[]; the values in the SI unit
* @param displayUnit U; the unit in which the values will be displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateSI(final double[] valuesSI, final U displayUnit,
final StorageType storageType)
{
return instantiateAnonymous(DoubleVectorData.instantiate(valuesSI, IdentityScale.SCALE, storageType), displayUnit);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler. The class for the vector is
* explicitly provided, e.g., for user-defined vector classes.
* @param valuesSI double[]; the values in the SI unit
* @param displayUnit U; the unit in which the values will be displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateSI(final double[] valuesSI, final U displayUnit,
final StorageType storageType, final Class<V> vectorClass)
{
return instantiateAnonymous(DoubleVectorData.instantiate(valuesSI, IdentityScale.SCALE, storageType), displayUnit,
vectorClass);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler.
* @param values S[]; the values
* @param displayUnit U; the unit in which the values will be displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiate(final S[] values, final U displayUnit,
final StorageType storageType)
{
return instantiateAnonymous(DoubleVectorData.instantiate(values, storageType), displayUnit);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler. The class for the vector is
* explicitly provided, e.g., for user-defined vector classes.
* @param values S[]; the values
* @param displayUnit U; the unit in which the values will be displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiate(final S[] values, final U displayUnit,
final StorageType storageType, final Class<V> vectorClass)
{
return instantiateAnonymous(DoubleVectorData.instantiate(values, storageType), displayUnit, vectorClass);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler.
* @param valueListInUnit List<Double>; the values in the given unit
* @param unit U; the unit in which the values are expressed and displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @throws ValueRuntimeException on vector init error
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiate(final List<Double> valueListInUnit, final U unit,
final StorageType storageType) throws ValueRuntimeException
{
return instantiateAnonymous(DoubleVectorData.instantiate(valueListInUnit, unit.getScale(), storageType), unit);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler. The class for the vector is
* explicitly provided, e.g., for user-defined vector classes.
* @param valueListInUnit List<Double>; the values in the given unit
* @param unit U; the unit in which the values are expressed and displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @throws ValueRuntimeException on vector init error
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiate(final List<Double> valueListInUnit, final U unit,
final StorageType storageType, final Class<V> vectorClass) throws ValueRuntimeException
{
return instantiateAnonymous(DoubleVectorData.instantiate(valueListInUnit, unit.getScale(), storageType), unit,
vectorClass);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler.
* @param valueListSI List<Double>; the values in the SI unit
* @param displayUnit U; the unit in which the values will be displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @throws ValueRuntimeException on vector init error
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateSI(final List<Double> valueListSI, final U displayUnit,
final StorageType storageType) throws ValueRuntimeException
{
return instantiateAnonymous(DoubleVectorData.instantiate(valueListSI, IdentityScale.SCALE, storageType), displayUnit);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler. The class for the vector is
* explicitly provided, e.g., for user-defined vector classes.
* @param valueListSI List<Double>; the values in the SI unit
* @param displayUnit U; the unit in which the values will be displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @throws ValueRuntimeException on vector init error
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateSI(final List<Double> valueListSI, final U displayUnit,
final StorageType storageType, final Class<V> vectorClass) throws ValueRuntimeException
{
return instantiateAnonymous(DoubleVectorData.instantiate(valueListSI, IdentityScale.SCALE, storageType), displayUnit,
vectorClass);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler.
* @param valueList List<S>; the value list
* @param displayUnit U; the unit in which the values will be displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateList(final List<S> valueList, final U displayUnit,
final StorageType storageType)
{
return instantiateAnonymous(DoubleVectorData.instantiateList(valueList, storageType), displayUnit);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler. The class for the vector is
* explicitly provided, e.g., for user-defined vector classes.
* @param valueList List<S>; the value list
* @param displayUnit U; the unit in which the values will be displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateList(final List<S> valueList, final U displayUnit,
final StorageType storageType, final Class<V> vectorClass)
{
return instantiateAnonymous(DoubleVectorData.instantiateList(valueList, storageType), displayUnit, vectorClass);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler.
* @param valueMapInUnit SortedMap<Integer, Double>; the values in the given unit
* @param length int; the size of the vector
* @param unit U; the unit in which the values are expressed and displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiate(final SortedMap<Integer, Double> valueMapInUnit,
final int length, final U unit, final StorageType storageType)
{
return instantiateAnonymous(DoubleVectorData.instantiate(valueMapInUnit, length, unit.getScale(), storageType), unit);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler. The class for the vector is
* explicitly provided, e.g., for user-defined vector classes.
* @param valueMapInUnit SortedMap<Integer, Double>; the values in the given unit
* @param length int; the size of the vector
* @param unit U; the unit in which the values are expressed and displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiate(final SortedMap<Integer, Double> valueMapInUnit,
final int length, final U unit, final StorageType storageType, final Class<V> vectorClass)
{
return instantiateAnonymous(DoubleVectorData.instantiate(valueMapInUnit, length, unit.getScale(), storageType), unit,
vectorClass);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler.
* @param valueMapSI SortedMap<Integer, Double>; the values in the SI unit
* @param length int; the size of the vector
* @param displayUnit U; the unit in which the values are displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateSI(final SortedMap<Integer, Double> valueMapSI,
final int length, final U displayUnit, final StorageType storageType)
{
return instantiateAnonymous(DoubleVectorData.instantiate(valueMapSI, length, IdentityScale.SCALE, storageType),
displayUnit);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler. The class for the vector is
* explicitly provided, e.g., for user-defined vector classes.
* @param valueMapSI SortedMap<Integer, Double>; the values in the SI unit
* @param length int; the size of the vector
* @param displayUnit U; the unit in which the values are displayed
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateSI(final SortedMap<Integer, Double> valueMapSI,
final int length, final U displayUnit, final StorageType storageType, final Class<V> vectorClass)
{
return instantiateAnonymous(DoubleVectorData.instantiate(valueMapSI, length, IdentityScale.SCALE, storageType),
displayUnit, vectorClass);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler.
* @param valueMap SortedMap<Integer, S>; the value map
* @param displayUnit U; the unit in which the values will be displayed
* @param length int; the size of the vector
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateMap(final SortedMap<Integer, S> valueMap, final int length,
final U displayUnit, final StorageType storageType)
{
return instantiateAnonymous(DoubleVectorData.instantiateMap(valueMap, length, storageType), displayUnit);
}
/**
* Instantiate the DoubleVector based on its unit. Rigid check on types for the compiler. The class for the vector is
* explicitly provided, e.g., for user-defined vector classes.
* @param valueMap SortedMap<Integer, S>; the value map
* @param displayUnit U; the unit in which the values will be displayed
* @param length int; the size of the vector
* @param storageType StorageType; whether the vector is SPARSE or DENSE
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateMap(final SortedMap<Integer, S> valueMap, final int length,
final U displayUnit, final StorageType storageType, final Class<V> vectorClass)
{
return instantiateAnonymous(DoubleVectorData.instantiateMap(valueMap, length, storageType), displayUnit, vectorClass);
}
/**
* Instantiate the Mutable DoubleVector based on its unit. Rigid check on types for the compiler.
* @param values DoubleVectorData; the values
* @param unit U; the unit in which the values are expressed
* @return V; an instantiated mutable DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiate(final DoubleVectorData values, final U unit)
{
return instantiateAnonymous(values, unit);
}
/**
* Instantiate the Mutable DoubleVector based on its unit. Rigid check on types for the compiler. The class for the vector
* is explicitly provided, e.g., for user-defined vector classes.
* @param values DoubleVectorData; the values
* @param unit U; the unit in which the values are expressed
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated mutable DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiate(final DoubleVectorData values, final U unit,
final Class<V> vectorClass)
{
return instantiateAnonymous(values, unit, vectorClass);
}
/**
* Instantiate the Immutable DoubleVector based on its unit. Loose check for types on the compiler. This allows the unit to
* be specified as a Unit<?> type.<br>
* <b>Note</b> that it is possible to make mistakes with anonymous units.
* @param values DoubleVectorData; the values
* @param unit Unit<?>; the unit in which the values are expressed
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
@SuppressWarnings("unchecked")
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateAnonymous(final DoubleVectorData values, final Unit<?> unit)
{
try
{
Constructor<? extends DoubleVectorInterface<?, ?, ?>> vectorConstructor = CACHE_DATA.get(unit);
if (vectorConstructor == null)
{
if (!unit.getClass().getSimpleName().endsWith("Unit"))
{
throw new ClassNotFoundException("Unit " + unit.getClass().getSimpleName()
+ " name does not end with 'Unit'. Cannot find corresponding vector");
}
Class<? extends DoubleVectorInterface<?, ?, ?>> vectorClass;
if (unit instanceof SIUnit)
{
vectorClass = SIVector.class;
}
else
{
vectorClass = (Class<DoubleVectorInterface<?, ?, ?>>) Class.forName("org.djunits.value.vdouble.vector."
+ unit.getClass().getSimpleName().replace("Unit", "") + "Vector");
}
vectorConstructor = vectorClass.getDeclaredConstructor(DoubleVectorData.class, unit.getClass());
CACHE_DATA.put(unit, vectorConstructor);
}
return (V) vectorConstructor.newInstance(values, unit);
}
catch (SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | ClassNotFoundException | NoSuchMethodException exception)
{
throw new UnitRuntimeException("Cannot instantiate DoubleVectorInterface of unit " + unit.toString() + ". Reason: "
+ exception.getMessage());
}
}
/**
* Instantiate the Immutable DoubleVector based on its unit. Loose check for types on the compiler. This allows the unit to
* be specified as a Unit<?> type. The class for the vector is explicitly provided, e.g., for user-defined vector
* classes.<br>
* <b>Note</b> that it is possible to make mistakes with anonymous units.
* @param values DoubleVectorData; the values
* @param unit Unit<?>; the unit in which the values are expressed
* @param vectorClass Class<V>; the class of the vector to instantiate
* @return V; an instantiated DoubleVector with the values expressed in their unit
* @param <U> the unit type
* @param <S> the corresponding scalar type
* @param <V> the corresponding vector type
*/
@SuppressWarnings("unchecked")
public static <U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
V extends DoubleVectorInterface<U, S, V>> V instantiateAnonymous(final DoubleVectorData values, final Unit<?> unit,
final Class<V> vectorClass)
{
try
{
Constructor<? extends DoubleVectorInterface<?, ?, ?>> vectorConstructor = CACHE_DATA.get(unit);
if (vectorConstructor == null)
{
vectorConstructor = vectorClass.getDeclaredConstructor(DoubleVectorData.class, unit.getClass());
CACHE_DATA.put(unit, vectorConstructor);
}
return (V) vectorConstructor.newInstance(values, unit);
}
catch (SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException exception)
{
throw new UnitRuntimeException("Cannot instantiate DoubleVectorInterface of unit " + unit.toString() + ". Reason: "
+ exception.getMessage());
}
}
}