public boolean valid() { // Checks if this is a control matrix Complex[][] data = new Complex[][] { {new Complex(Tools.CONTROL_VALUE), new Complex(0)}, {new Complex(0), new Complex(1)} }; FieldMatrix<Complex> control = new Array2DRowFieldMatrix<Complex>(data); if (mat.equals(control)) return true; final boolean is_dimension_power_of_2 = (mat.getColumnDimension() & (mat.getColumnDimension() - 1)) == 0; if (!mat.isSquare() || !is_dimension_power_of_2) return false; // Computes dagger of mat FieldMatrix<Complex> dagger = mat.transpose(); dagger.walkInOptimizedOrder(new MatrixConjugator()); // Checks if dagger * mat = identity matrix FieldMatrix<Complex> result = mat.multiply(dagger); Complex is_identity = result.walkInOptimizedOrder(new UnitaryChecker()); // 1+0i if true, 0+0i if false return is_identity.equals(new Complex(1)); }
private static FieldMatrix<Complex> kronecker(FieldMatrix<Complex> lhs, FieldMatrix<Complex> rhs) { FieldMatrix<Complex> result = new Array2DRowFieldMatrix<Complex>(ComplexField.getInstance(), lhs.getRowDimension() * rhs.getRowDimension(), lhs.getColumnDimension() * rhs.getColumnDimension()); for (int i = 0; i < lhs.getRowDimension(); i++) for (int j = 0; j < lhs.getColumnDimension(); j++) for (int k = 0; k < rhs.getRowDimension(); k++) for (int l = 0; l < rhs.getColumnDimension(); l++) { int row = i * rhs.getRowDimension() + k, col = j * rhs.getColumnDimension() + l; // The control value alters Kronecker product's behavior to create controlled gates if (lhs.getEntry(i, j).getReal() == Tools.CONTROL_VALUE) if (row == col) result.setEntry(row, col, new Complex(Tools.CONTROL_VALUE)); else result.setEntry(row, col, new Complex(0)); else result.setEntry(row, col, lhs.getEntry(i, j).multiply(rhs.getEntry(k, l))); } return result; }
/** * Calculates the exact value of {@code P(D_n < d)} using method described * in [1] and {@link org.apache.commons.math3.fraction.BigFraction} (see * above). * * @param d statistic * @return the two-sided probability of {@code P(D_n < d)} * @throws MathArithmeticException if algorithm fails to convert {@code h} * to a {@link org.apache.commons.math3.fraction.BigFraction} in expressing * {@code d} as {@code (k - h) / m} for integer {@code k, m} and * {@code 0 <= h < 1}. */ private double exactK(double d) throws MathArithmeticException { final int k = (int) FastMath.ceil(n * d); final FieldMatrix<BigFraction> H = this.createH(d); final FieldMatrix<BigFraction> Hpower = H.power(n); BigFraction pFrac = Hpower.getEntry(k - 1, k - 1); for (int i = 1; i <= n; ++i) { pFrac = pFrac.multiply(i).divide(n); } /* * BigFraction.doubleValue converts numerator to double and the * denominator to double and divides afterwards. That gives NaN quite * easy. This does not (scale is the number of digits): */ return pFrac.bigDecimalValue(20, BigDecimal.ROUND_HALF_UP).doubleValue(); }
/** Build the P matrix. * <p>The P matrix general terms are shifted (j+1) (-i)<sup>j</sup> terms * with i being the row number starting from 1 and j being the column * number starting from 1: * <pre> * [ -2 3 -4 5 ... ] * [ -4 12 -32 80 ... ] * P = [ -6 27 -108 405 ... ] * [ -8 48 -256 1280 ... ] * [ ... ] * </pre></p> * @param rows number of rows of the matrix * @return P matrix */ private FieldMatrix<BigFraction> buildP(final int rows) { final BigFraction[][] pData = new BigFraction[rows][rows]; for (int i = 1; i <= pData.length; ++i) { // build the P matrix elements from Taylor series formulas final BigFraction[] pI = pData[i - 1]; final int factor = -i; int aj = factor; for (int j = 1; j <= pI.length; ++j) { pI[j - 1] = new BigFraction(aj * (j + 1)); aj *= factor; } } return new Array2DRowFieldMatrix<BigFraction>(pData, false); }
/** Build the P matrix. * <p>The P matrix general terms are shifted (j+1) (-i)<sup>j</sup> terms * with i being the row number starting from 1 and j being the column * number starting from 1: * <pre> * [ -2 3 -4 5 ... ] * [ -4 12 -32 80 ... ] * P = [ -6 27 -108 405 ... ] * [ -8 48 -256 1280 ... ] * [ ... ] * </pre></p> * @param rows number of rows of the matrix * @return P matrix */ private FieldMatrix<T> buildP(final int rows) { final T[][] pData = MathArrays.buildArray(field, rows, rows); for (int i = 1; i <= pData.length; ++i) { // build the P matrix elements from Taylor series formulas final T[] pI = pData[i - 1]; final int factor = -i; T aj = field.getZero().add(factor); for (int j = 1; j <= pI.length; ++j) { pI[j - 1] = aj.multiply(j + 1); aj = aj.multiply(factor); } } return new Array2DRowFieldMatrix<T>(pData, false); }
/** * Calculates the exact value of {@code P(D_n < d)} using the method described in [1] (reference * in class javadoc above) and {@link org.apache.commons.math3.fraction.BigFraction} (see * above). * * @param d statistic * @param n sample size * @return the two-sided probability of \(P(D_n < d)\) * @throws MathArithmeticException if algorithm fails to convert {@code h} to a * {@link org.apache.commons.math3.fraction.BigFraction} in expressing {@code d} as \((k * - h) / m\) for integer {@code k, m} and \(0 \le h < 1\). */ private double exactK(double d, int n) throws MathArithmeticException { final int k = (int) Math.ceil(n * d); final FieldMatrix<BigFraction> H = this.createExactH(d, n); final FieldMatrix<BigFraction> Hpower = H.power(n); BigFraction pFrac = Hpower.getEntry(k - 1, k - 1); for (int i = 1; i <= n; ++i) { pFrac = pFrac.multiply(i).divide(n); } /* * BigFraction.doubleValue converts numerator to double and the denominator to double and * divides afterwards. That gives NaN quite easy. This does not (scale is the number of * digits): */ return pFrac.bigDecimalValue(20, BigDecimal.ROUND_HALF_UP).doubleValue(); }
/** Build the P matrix. * <p>The P matrix general terms are shifted j (-i)<sup>j-1</sup> terms: * <pre> * [ -2 3 -4 5 ... ] * [ -4 12 -32 80 ... ] * P = [ -6 27 -108 405 ... ] * [ -8 48 -256 1280 ... ] * [ ... ] * </pre></p> * @param nSteps number of steps of the multistep method * (excluding the one being computed) * @return P matrix */ private FieldMatrix<BigFraction> buildP(final int nSteps) { final BigFraction[][] pData = new BigFraction[nSteps][nSteps]; for (int i = 0; i < pData.length; ++i) { // build the P matrix elements from Taylor series formulas final BigFraction[] pI = pData[i]; final int factor = -(i + 1); int aj = factor; for (int j = 0; j < pI.length; ++j) { pI[j] = new BigFraction(aj * (j + 2)); aj *= factor; } } return new Array2DRowFieldMatrix<BigFraction>(pData, false); }
/** verifies that two matrices are equal */ public static void assertEquals(FieldMatrix<? extends FieldElement<?>> expected, FieldMatrix<? extends FieldElement<?>> observed) { Assert.assertNotNull("Observed should not be null",observed); if (expected.getColumnDimension() != observed.getColumnDimension() || expected.getRowDimension() != observed.getRowDimension()) { StringBuilder messageBuffer = new StringBuilder(); messageBuffer.append("Observed has incorrect dimensions."); messageBuffer.append("\nobserved is " + observed.getRowDimension() + " x " + observed.getColumnDimension()); messageBuffer.append("\nexpected " + expected.getRowDimension() + " x " + expected.getColumnDimension()); Assert.fail(messageBuffer.toString()); } for (int i = 0; i < expected.getRowDimension(); ++i) { for (int j = 0; j < expected.getColumnDimension(); ++j) { FieldElement<?> eij = expected.getEntry(i, j); FieldElement<?> oij = observed.getEntry(i, j); Assert.assertEquals(eij, oij); } } }
public FieldVector<Complex> calculate(FieldVector<Complex> input) throws SeviException{ this.layerResults.clear(); LayerResult result = new LayerResult(); result.setInput(input); for(int i = 0; i < net.getLayers().size() -1; i++) { Layer l = net.getLayers().get(i); FieldMatrix<Complex> matrix = l.getMatrixtoNextLayer(); FieldVector<Complex> output = matrix.operate(result.getInput()); output = activationFunction(output, l); result.setOutput(output); this.layerResults.add(result); result = new LayerResult(); result.setInput(output); } return result.getInput(); }
@Test public void calcWeightDeltaTest() { double eta = 0.1; Complex[] d = {new Complex(0.1),new Complex(0.2)}; Complex[] in = {new Complex(0.1),new Complex(0.2), new Complex(0.3)}; FieldVector<Complex> delta = MatrixUtils.createFieldVector(d); FieldVector<Complex> input = MatrixUtils.createFieldVector(in); FieldMatrix<Complex> weightDiff = this.calcWeightDelta(delta,input,eta); assertEquals(2,weightDiff.getRowDimension()); assertEquals(3,weightDiff.getColumnDimension()); assertEquals(0.001,weightDiff.getEntry(0,0).getReal(),0.00001); assertEquals(0.002,weightDiff.getEntry(0,1).getReal(),0.00001); assertEquals(0.003,weightDiff.getEntry(0,2).getReal(),0.00001); assertEquals(0.002,weightDiff.getEntry(1,0).getReal(),0.00001); assertEquals(0.004,weightDiff.getEntry(1,1).getReal(),0.00001); assertEquals(0.006, weightDiff.getEntry(1, 2).getReal(), 0.00001); }
@Test public void getMatrixToNextLayerTest() throws Exception{ Layer l1 = new Layer(2, ActivationFunction.Sigmoid); Layer l2 = new Layer(3, ActivationFunction.Sigmoid); l1.connectTo(l2); //Set weights manually l1.getNeurons().get(0).getOutputs().get(0).setWeight(new Complex(1)); l1.getNeurons().get(0).getOutputs().get(1).setWeight(new Complex(2)); l1.getNeurons().get(0).getOutputs().get(2).setWeight(new Complex(3)); l1.getNeurons().get(1).getOutputs().get(0).setWeight(new Complex(4)); l1.getNeurons().get(1).getOutputs().get(1).setWeight(new Complex(5)); l1.getNeurons().get(1).getOutputs().get(2).setWeight(new Complex(6)); FieldMatrix<Complex> matrix = l1.getMatrixtoNextLayer(); //out(matrix); assertEquals(1, matrix.getEntry(0, 0).getReal(), 0.0001); assertEquals(4, matrix.getEntry(0, 1).getReal(), 0.0001); assertEquals(2,matrix.getEntry(1, 0).getReal(), 0.0001); assertEquals(5,matrix.getEntry(1, 1).getReal(), 0.0001); assertEquals(3,matrix.getEntry(2, 0).getReal(), 0.0001); assertEquals(6,matrix.getEntry(2, 1).getReal(), 0.0001); }
@Test public void setMatrixToNextLayerTest() throws SeviException{ Layer l1 = new Layer(2, ActivationFunction.Sigmoid); Layer l2 = new Layer(3, ActivationFunction.Sigmoid); l1.connectTo(l2); FieldMatrix<Complex> matrix1 = l1.getMatrixtoNextLayer(); l1.setMatrixtoNextLayer(matrix1); FieldMatrix<Complex> matrix2 = l1.getMatrixtoNextLayer(); for(int x = 0; x < matrix1.getRowDimension(); x++) { for(int y = 0; y < matrix1.getColumnDimension(); y++) { assertTrue(matrix1.getEntry(x, y).equals(matrix2.getEntry(x, y))); } } }
/** * Calculates the exact value of {@code P(D_n < d)} using method described * in [1] and {@link org.apache.commons.math3.fraction.BigFraction} (see * above). * * @param d statistic * @return the two-sided probability of {@code P(D_n < d)} * @throws MathArithmeticException if algorithm fails to convert {@code h} * to a {@link org.apache.commons.math3.fraction.BigFraction} in expressing * {@code d} as {@code (k - h) / m} for integer {@code k, m} and * {@code 0 <= h < 1}. */ private double exactK(double d) throws MathArithmeticException { final int k = (int) Math.ceil(n * d); final FieldMatrix<BigFraction> H = this.createH(d); final FieldMatrix<BigFraction> Hpower = H.power(n); BigFraction pFrac = Hpower.getEntry(k - 1, k - 1); for (int i = 1; i <= n; ++i) { pFrac = pFrac.multiply(i).divide(n); } /* * BigFraction.doubleValue converts numerator to double and the * denominator to double and divides afterwards. That gives NaN quite * easy. This does not (scale is the number of digits): */ return pFrac.bigDecimalValue(20, BigDecimal.ROUND_HALF_UP).doubleValue(); }
public Gate(final String id, double angle_x, double angle_y, double angle_z, final Tools.AngleType angle_type) { this.id = id; this.IO_ports = 1; if (angle_type == Tools.AngleType.DEGREES) { angle_x = Math.toRadians(angle_x); angle_y = Math.toRadians(angle_y); angle_z = Math.toRadians(angle_z); } Complex[][] data_x_rot = new Complex[][] { {new Complex(Tools.round(Math.cos(angle_x / 2))), new Complex(0.0, Tools.round(-Math.sin(angle_x / 2)))}, {new Complex(0.0, Tools.round(-Math.sin(angle_x / 2))), new Complex(Tools.round(Math.cos(angle_x / 2)))} }; FieldMatrix<Complex> x_rot = new Array2DRowFieldMatrix<Complex>(data_x_rot); Complex[][] data_y_rot = new Complex[][] { {new Complex(Tools.round(Math.cos(angle_y / 2))), new Complex(Tools.round(-Math.sin(angle_y / 2)))}, {new Complex(Tools.round(Math.sin(angle_y / 2))), new Complex(Tools.round(Math.cos(angle_y / 2)))} }; FieldMatrix<Complex> y_rot = new Array2DRowFieldMatrix<Complex>(data_y_rot); Complex[][] data_z_rot = new Complex[][] { {new Complex(Tools.round(Math.cos(angle_z / 2)), Tools.round(-Math.sin(angle_z / 2))), new Complex(0.0)}, {new Complex(0.0), new Complex(Tools.round(Math.cos(angle_z / 2)), Tools.round(Math.sin(angle_z / 2)))} }; FieldMatrix<Complex> z_rot = new Array2DRowFieldMatrix<Complex>(data_z_rot); mat = z_rot.multiply(y_rot).multiply(x_rot); if (!valid()) throw new RuntimeException( "Matrix is not a valid quantum gate in Gate rotation constructor"); }
public Gate(final String id, final FieldMatrix<Complex> mat) { this.id = id; this.IO_ports = (int) (Math.log(mat.getColumnDimension()) / Math.log(2)); // Get base-2 logarithm of mat.getColumnDimension() this.mat = mat; if (!valid()) throw new IllegalArgumentException( "Provided matrix is not a valid quantum gate"); }
/** * Calculates {@code P(D_n < d)} using method described in [1] and doubles * (see above). * * @param d statistic * @return the two-sided probability of {@code P(D_n < d)} * @throws MathArithmeticException if algorithm fails to convert {@code h} * to a {@link org.apache.commons.math3.fraction.BigFraction} in expressing * {@code d} as {@code (k - h) / m} for integer {@code k, m} and * {@code 0 <= h < 1}. */ private double roundedK(double d) throws MathArithmeticException { final int k = (int) FastMath.ceil(n * d); final FieldMatrix<BigFraction> HBigFraction = this.createH(d); final int m = HBigFraction.getRowDimension(); /* * Here the rounding part comes into play: use * RealMatrix instead of FieldMatrix<BigFraction> */ final RealMatrix H = new Array2DRowRealMatrix(m, m); for (int i = 0; i < m; ++i) { for (int j = 0; j < m; ++j) { H.setEntry(i, j, HBigFraction.getEntry(i, j).doubleValue()); } } final RealMatrix Hpower = H.power(n); double pFrac = Hpower.getEntry(k - 1, k - 1); for (int i = 1; i <= n; ++i) { pFrac *= (double) i / (double) n; } return pFrac; }