/* Copyright (C) 2003 Univ. of Massachusetts Amherst, Computer Science Dept. This file is part of "MALLET" (MAchine Learning for LanguagE Toolkit). http://www.cs.umass.edu/~mccallum/mallet This software is provided under the terms of the Common Public License, version 1.0, as published by http://www.opensource.org. For further information, see the file `LICENSE' included with this distribution. */ package cc.mallet.types; // Generated package name /** * Implementation of Matrix that allows arbitrary * number of dimensions. This implementation * simply uses a flat array. * * This also provides static utilities for doing * arbitrary-dimensional array indexing (see * {@link #singleIndex}, {@link #singleToIndices}). * * Created: Tue Sep 16 14:52:37 2003 * * @author <a href="mailto:casutton@cs.umass.edu">Charles Sutton</a> * @version $Id: Matrixn.java,v 1.1 2007/10/22 21:37:39 mccallum Exp $ */ public class Matrixn extends DenseMatrix implements Cloneable { int numDimensions; int[] sizes; /** * Create a 1-d matrix with the given values. */ public Matrixn(double[] vals) { numDimensions = 1; sizes = new int[1]; sizes [0] = vals.length; values = (double[]) vals.clone(); } /** * Create a matrix with the given dimensions. * * @param szs An array containing the maximum for * each dimension. */ public Matrixn (int szs[]) { numDimensions = szs.length; // sizes = (int[])szs.clone(); sizes = szs; int total = 1; for (int j = 0; j < numDimensions; j++) { total *= sizes [j]; } values = new double [total]; } /** * Create a matrix with the given dimensions and * the given values. * * @param szs An array containing the maximum for * each dimension. * @param vals A flat array of the entries of the * matrix, in row-major order. */ public Matrixn (int[] szs, double[] vals) { numDimensions = szs.length; sizes = (int[])szs.clone(); values = (double[])vals.clone(); } public int getNumDimensions () { return numDimensions; }; public int getDimensions (int [] szs) { for ( int i = 0; i < numDimensions; i++ ) { szs [i] = this.sizes [i]; } return numDimensions; } public double value (int[] indices) { return values [singleIndex (indices)]; } public void setValue (int[] indices, double value) { values [singleIndex (indices)] = value; } public ConstantMatrix cloneMatrix () { /* The Matrixn constructor will clone the arrays. */ return new Matrixn (sizes, values); } public Object clone () { return cloneMatrix(); } public int singleIndex (int[] indices) { return singleIndex (sizes, indices); } // This is public static so it will be useful as a general // dereferencing utility for multidimensional arrays. public static int singleIndex (int[] szs, int[] indices) { int idx = 0; for ( int dim = 0; dim < indices.length; dim++ ) { idx = (idx * szs[dim]) + indices [dim]; } return idx; } // NOTE: Cut-n-pasted to other singleToIndices method!! public void singleToIndices (int single, int[] indices) { /* must be a better way to do this... */ int size = 1; for (int i = 0; i < numDimensions; i++) { size *= sizes[i]; } for ( int dim = 0; dim < numDimensions; dim++) { size /= sizes [dim]; indices [dim] = single / size; single = single % size; } } /** Just a utility function for arbitrary-dimensional matrix * dereferencing. */ // NOTE: Cut-n-paste from other singleToIndices method!! public static void singleToIndices (int single, int[] indices, int[] szs) { int numd = indices.length; assert numd == szs.length; /* must be a better way to do this... */ int size = 1; for (int i = 0; i < numd; i++) { size *= szs[i]; } for ( int dim = 0; dim < numd; dim++) { size /= szs [dim]; indices [dim] = single / size; single = single % size; } } public boolean equals (Object o) { if (o instanceof Matrixn) { /* This could be extended to work for all Matrixes. */ Matrixn m2 = (Matrixn) o; return (numDimensions == m2.numDimensions) && (sizes.equals (m2.sizes)) && (values.equals (m2.values)); } else { return false; } } /** * Returns a one-dimensional array representation of the matrix. * Caller must not modify the return value. * @return An array of the values where index 0 is the major index, etc. */ public double[] toArray () { return values; } /* Test array referencing and dereferencing */ public static void main(String[] args) { double m1[] = new double[] { 1.0, 2.0, 3.0, 4.0 }; int idx1[] = new int[1]; Matrixn a = new Matrixn (m1); System.out.println("Checking 1-D case"); a.singleToIndices (3, idx1); System.out.println(idx1[0]); System.out.println (a.singleIndex (idx1)); System.out.println ("Checking 2-D case"); int sizes[] = new int[] { 2, 3 }; m1 = new double [6]; for (int i = 0; i < 6; i++) { m1 [i] = 2.0 * i; } a = new Matrixn (sizes, m1); idx1 = new int [2]; a.singleToIndices (5, idx1); System.out.println("5 => (" + idx1[0] + ", " + idx1[1] + ") => " + a.singleIndex (idx1) ); System.out.println(a.value (idx1)); System.out.println("Checking 3-D case"); sizes = new int[] { 2, 3, 4 }; idx1 = new int[3]; m1 = new double [24]; for (int i = 0; i < 24; i++) { m1 [i] = 2.0 * i; } a = new Matrixn (sizes, m1); a.singleToIndices (21, idx1); System.out.println ("21 => (" + idx1[0] + " " + idx1[1] + " " + idx1[2] + ") =>" + a.singleIndex (idx1)); System.out.println(a.value (idx1)); } // serialization garbage private static final long serialVersionUID = 7963668115823191655L; }