1 package org.djunits.value.vdouble.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.vdouble.scalar.AbstractDoubleScalarAbs; 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 AbstractDoubleMatrixAbs<AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, 31 A extends AbstractDoubleMatrixAbs<AU, RU, A, R, MA, S>, R extends AbstractDoubleMatrixRel<RU, R, ?, ?>, 32 MA extends AbstractMutableDoubleMatrixAbs<AU, RU, A, R, MA, S>, S extends AbstractDoubleScalarAbs<AU, S, RU, ?>> 33 extends AbstractDoubleMatrix<AU, A> implements FunctionsAbs<AU, RU, A, R>, Absolute, Serializable 34 { 35 /** */ 36 private static final long serialVersionUID = 20151006L; 37 38 /** 39 * Construct a new Absolute Immutable DoubleMatrix. 40 * @param values double[][]; the values of the entries in the new Absolute Immutable DoubleMatrix 41 * @param unit AU; the unit of the new Absolute Immutable DoubleMatrix 42 * @param storageType the data type to use (e.g., DENSE or SPARSE) 43 * @throws ValueException when values is null 44 */ 45 AbstractDoubleMatrixAbs(final double[][] values, final AU unit, final StorageType storageType) throws ValueException 46 { 47 super(unit, DoubleMatrixData.instantiate(ensureRectangularAndNonEmpty(values), unit.getScale(), storageType)); 48 } 49 50 /** 51 * Construct a new Absolute Immutable DoubleMatrix. 52 * @param values S[][]; the values of the entries in the new Absolute Immutable DoubleMatrix 53 * @param storageType the data type to use (e.g., DENSE or SPARSE) 54 * @throws ValueException when values has zero entries 55 */ 56 AbstractDoubleMatrixAbs(final S[][] values, final StorageType storageType) throws ValueException 57 { 58 super(checkUnit(values), DoubleMatrixData.instantiate(values, storageType)); 59 } 60 61 /** 62 * Construct a new Relative Immutable DoubleMatrix. 63 * @param data an internal data object 64 * @param unit the unit 65 */ 66 AbstractDoubleMatrixAbs(final DoubleMatrixData data, final AU unit) 67 { 68 super(unit, data.copy()); 69 } 70 71 /** 72 * Create a mutable version of this DoubleMatrix. <br> 73 * The mutable version is created with a shallow copy of the data and the internal copyOnWrite flag set. The first operation 74 * in the mutable version that modifies the data shall trigger a deep copy of the data. 75 * @return MA; mutable version of this DoubleMatrix 76 */ 77 public MA mutable() 78 { 79 return instantiateMutableType(getData(), getUnit()); 80 } 81 82 /** 83 * Construct a new Absolute Immutable DoubleMatrix of the right type. Each extending class must implement this method. 84 * @param dmd an internal data object 85 * @param unit the unit 86 * @return M the Mutable DoubleMatrix of the right type 87 */ 88 protected abstract A instantiateTypeAbs(DoubleMatrixData dmd, AU unit); 89 90 /** 91 * Construct a new Relative Immutable DoubleMatrix of the right type. Each extending class must implement this method. 92 * @param dmd an internal data object 93 * @param unit the unit 94 * @return M the Mutable DoubleMatrix of the right type 95 */ 96 protected abstract R instantiateTypeRel(DoubleMatrixData dmd, RU unit); 97 98 /** 99 * Construct a new Absolute Mutable DoubleMatrix of the right type. Each extending class must implement this method. 100 * @param dmd an internal data object 101 * @param unit the unit 102 * @return M the Mutable DoubleMatrix of the right type 103 */ 104 protected abstract MA instantiateMutableType(DoubleMatrixData dmd, AU unit); 105 106 /** 107 * Construct a new Absolute Immutable DoubleScalar of the right type. Each extending class must implement this method. 108 * @param value the value 109 * @param unit the unit 110 * @return S the Immutable DoubleScalar of the right type 111 */ 112 protected abstract S instantiateScalar(double value, AU unit); 113 114 /** {@inheritDoc} */ 115 @Override 116 @SuppressWarnings("checkstyle:designforextension") 117 public final S get(final int row, final int column) throws ValueException 118 { 119 checkIndex(row, column); 120 return instantiateScalar(getInUnit(row, column, getUnit()), getUnit()); 121 } 122 123 /**********************************************************************************/ 124 /**************************** TYPED CALCULATION METHODS ***************************/ 125 /**********************************************************************************/ 126 127 /** {@inheritDoc} */ 128 @Override 129 public final A plus(final R rel) throws ValueException 130 { 131 return instantiateTypeAbs(this.getData().plus(rel.getData()), getUnit()); 132 } 133 134 /** {@inheritDoc} */ 135 @Override 136 public final A minus(final R rel) throws ValueException 137 { 138 return instantiateTypeAbs(this.getData().minus(rel.getData()), getUnit()); 139 } 140 141 /** {@inheritDoc} */ 142 @Override 143 public final R minus(final A abs) throws ValueException 144 { 145 return instantiateTypeRel(this.getData().minus(abs.getData()), getUnit().getRelativeUnit()); 146 } 147 148 /* ============================================================================================ */ 149 /* ============================= STATIC CONSTRUCTOR HELP METHODS ============================== */ 150 /* ============================================================================================ */ 151 152 /** 153 * Check that a provided array can be used to create some descendant of a DoubleMatrix, and return the Unit. 154 * @param dsArray the array to check and get the unit for 155 * @param <AU> the absolute unit 156 * @param <RU> the corresponding relative unit 157 * @param <S> the scalar type 158 * @return the unit of the object 159 * @throws ValueException when the array is null, has length equal to 0, or has first entry with length equal to 0 160 */ 161 static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, 162 S extends AbstractDoubleScalarAbs<AU, S, RU, ?>> AU checkUnit(final S[][] dsArray) throws ValueException 163 { 164 ensureRectangularAndNonEmpty(dsArray); 165 return dsArray[0][0].getUnit(); 166 } 167 168 /** 169 * Check that a 2D array of DoubleScalar<?> is rectangular; i.e. all rows have the same length and is non empty. 170 * @param values DoubleScalar<?>[][]; the 2D array to check 171 * @param <AU> the absolute unit 172 * @param <RU> the corresponding relative unit 173 * @param <S> the scalar type 174 * @throws ValueException when values is not rectangular, or contains no data 175 */ 176 protected static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, 177 S extends AbstractDoubleScalarAbs<AU, S, RU, ?>> void ensureRectangularAndNonEmpty(final S[][] values) 178 throws ValueException 179 { 180 if (null == values) 181 { 182 throw new ValueException("Cannot create a DoubleVector or MutableDoubleVector from an empty array of DoubleScalar"); 183 } 184 if (0 == values.length || 0 == values[0].length) 185 { 186 throw new ValueException("Creating DoubleVector or MutableDoubleVector: " 187 + "Cannot determine unit for DoubleMatrix from an empty array of DoubleScalar"); 188 } 189 for (int row = values.length; --row >= 1;) 190 { 191 if (values[0].length != values[row].length) 192 { 193 throw new ValueException("Creating DoubleVector or MutableDoubleVector: Lengths of rows are not all the same"); 194 } 195 } 196 } 197 198 }