1 package org.djunits.value.vfloat.matrix; 2 3 import java.io.Serializable; 4 5 import org.djunits.unit.AbsoluteLinearUnit; 6 import org.djunits.unit.Unit; 7 import org.djunits.value.Absolute; 8 import org.djunits.value.FunctionsAbs; 9 import org.djunits.value.StorageType; 10 import org.djunits.value.ValueException; 11 import org.djunits.value.vfloat.scalar.AbstractFloatScalarAbs; 12 13 /** 14 * Absolute Immutable typed matrix. 15 * <p> 16 * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br> 17 * BSD-style license. See <a href="http://djunits.org/docs/license.html">DJUNITS License</a>. 18 * <p> 19 * $LastChangedDate: 2015-09-29 14:14:28 +0200 (Tue, 29 Sep 2015) $, @version $Revision: 73 $, by $Author: pknoppers $, initial 20 * version Sep 5, 2015 <br> 21 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 22 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 23 * @param <AU> the absolute unit 24 * @param <RU> the relative unit 25 * @param <A> the absolute matrix type 26 * @param <R> the relative matrix type 27 * @param <MA> the mutable absolute matrix type 28 * @param <S> the absolute scalar type 29 */ 30 abstract class AbstractFloatMatrixAbs<AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, 31 A extends AbstractFloatMatrixAbs<AU, RU, A, R, MA, S>, R extends AbstractFloatMatrixRel<RU, R, ?, ?>, 32 MA extends AbstractMutableFloatMatrixAbs<AU, RU, A, R, MA, S>, S extends AbstractFloatScalarAbs<AU, S, RU, ?>> 33 extends AbstractFloatMatrix<AU, A> implements FunctionsAbs<AU, RU, A, R>, FloatMatrixInterface<AU>, Absolute, Serializable 34 { 35 /** */ 36 private static final long serialVersionUID = 20151006L; 37 38 /** 39 * Construct a new Absolute Immutable FloatMatrix. 40 * @param values float[][]; the values of the entries in the new Absolute Immutable FloatMatrix 41 * @param unit AU; the unit of the new Absolute Immutable FloatMatrix 42 * @param storageType the data type to use (e.g., DENSE or SPARSE) 43 * @throws ValueException when values is null 44 */ 45 AbstractFloatMatrixAbs(final float[][] values, final AU unit, final StorageType storageType) throws ValueException 46 { 47 super(unit, FloatMatrixData.instantiate(ensureRectangularAndNonEmpty(values), unit.getScale(), storageType)); 48 49 } 50 51 /** 52 * Construct a new Absolute Immutable FloatMatrix. 53 * @param values S[][]; the values of the entries in the new Absolute Immutable FloatMatrix 54 * @param storageType the data type to use (e.g., DENSE or SPARSE) 55 * @throws ValueException when values has zero entries 56 */ 57 AbstractFloatMatrixAbs(final S[][] values, final StorageType storageType) throws ValueException 58 { 59 super(checkUnit(values), FloatMatrixData.instantiate(values, storageType)); 60 } 61 62 /** 63 * Construct a new Relative Immutable FloatMatrix. 64 * @param data an internal data object 65 * @param unit the unit 66 */ 67 AbstractFloatMatrixAbs(final FloatMatrixData data, final AU unit) 68 { 69 super(unit, data.copy()); 70 } 71 72 /** 73 * Create a mutable version of this FloatMatrix. <br> 74 * The mutable version is created with a shallow copy of the data and the internal copyOnWrite flag set. The first operation 75 * in the mutable version that modifies the data shall trigger a deep copy of the data. 76 * @return MA; mutable version of this FloatMatrix 77 */ 78 public MA mutable() 79 { 80 return instantiateMutableType(getData(), getUnit()); 81 } 82 83 /** 84 * Construct a new Absolute Immutable FloatMatrix of the right type. Each extending class must implement this method. 85 * @param dmd an internal data object 86 * @param unit the unit 87 * @return M the Mutable FloatMatrix of the right type 88 */ 89 protected abstract A instantiateTypeAbs(FloatMatrixData dmd, AU unit); 90 91 /** 92 * Construct a new Relative Immutable FloatMatrix of the right type. Each extending class must implement this method. 93 * @param dmd an internal data object 94 * @param unit the unit 95 * @return M the Mutable FloatMatrix of the right type 96 */ 97 protected abstract R instantiateTypeRel(FloatMatrixData dmd, RU unit); 98 99 /** 100 * Construct a new Absolute Mutable FloatMatrix of the right type. Each extending class must implement this method. 101 * @param dmd an internal data object 102 * @param unit the unit 103 * @return M the Mutable FloatMatrix of the right type 104 */ 105 protected abstract MA instantiateMutableType(FloatMatrixData dmd, AU unit); 106 107 /** 108 * Construct a new Absolute Immutable FloatScalar of the right type. Each extending class must implement this method. 109 * @param value the value 110 * @param unit the unit 111 * @return S the Immutable FloatScalar of the right type 112 */ 113 protected abstract S instantiateScalar(float value, AU unit); 114 115 /** 116 * Return the Scalar value at the index position. 117 * @param row the row position 118 * @param column the column position 119 * @return S the scalar 120 * @throws ValueException when index out of bounds 121 */ 122 @SuppressWarnings("checkstyle:designforextension") 123 public final S get(final int row, final int column) throws ValueException 124 { 125 checkIndex(row, column); 126 return instantiateScalar(getInUnit(row, column, getUnit()), getUnit()); 127 } 128 129 /**********************************************************************************/ 130 /**************************** TYPED CALCULATION METHODS ***************************/ 131 /**********************************************************************************/ 132 133 /** {@inheritDoc} */ 134 @Override 135 public final A plus(final R rel) throws ValueException 136 { 137 return instantiateTypeAbs(this.getData().plus(rel.getData()), getUnit()); 138 } 139 140 /** {@inheritDoc} */ 141 @Override 142 public final A minus(final R rel) throws ValueException 143 { 144 return instantiateTypeAbs(this.getData().minus(rel.getData()), getUnit()); 145 } 146 147 /** {@inheritDoc} */ 148 @Override 149 public final R minus(final A abs) throws ValueException 150 { 151 return instantiateTypeRel(this.getData().minus(abs.getData()), getUnit().getRelativeUnit()); 152 } 153 154 /* ============================================================================================ */ 155 /* ============================= STATIC CONSTRUCTOR HELP METHODS ============================== */ 156 /* ============================================================================================ */ 157 158 /** 159 * Check that a provided array can be used to create some descendant of a FloatMatrix, and return the Unit. 160 * @param dsArray the array to check and get the unit for 161 * @param <AU> the absolute unit 162 * @param <RU> the corresponding relative unit 163 * @param <S> the scalar type 164 * @return the unit of the object 165 * @throws ValueException when the array is null, has length equal to 0, or has first entry with length equal to 0 166 */ 167 static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, 168 S extends AbstractFloatScalarAbs<AU, S, RU, ?>> AU checkUnit(final S[][] dsArray) throws ValueException 169 { 170 ensureRectangularAndNonEmpty(dsArray); 171 return dsArray[0][0].getUnit(); 172 } 173 174 /** 175 * Check that a 2D array of FloatScalar<?> is rectangular; i.e. all rows have the same length and is non empty. 176 * @param values FloatScalar<?>[][]; the 2D array to check 177 * @param <AU> the absolute unit 178 * @param <RU> the corresponding relative unit 179 * @param <S> the scalar type 180 * @throws ValueException when values is not rectangular, or contains no data 181 */ 182 protected static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, 183 S extends AbstractFloatScalarAbs<AU, S, RU, ?>> void ensureRectangularAndNonEmpty(final S[][] values) 184 throws ValueException 185 { 186 if (null == values) 187 { 188 throw new ValueException("Cannot create a FloatVector or MutableFloatVector from an empty array of FloatScalar"); 189 } 190 if (0 == values.length || 0 == values[0].length) 191 { 192 throw new ValueException("Creating FloatVector or MutableFloatVector: " 193 + "Cannot determine unit for FloatMatrix from an empty array of FloatScalar"); 194 } 195 for (int row = values.length; --row >= 1;) 196 { 197 if (values[0].length != values[row].length) 198 { 199 throw new ValueException("Creating FloatVector or MutableFloatVector: Lengths of rows are not all the same"); 200 } 201 } 202 } 203 }