001package squarematrix;
002
003/**
004 * Model a square matrix.
005 * 
006 * Experiment with matrix multiplication to
007 * show the convergence seen in the case study
008 * in Section 1.6 of the textbook.
009 * 
010 * <a href="http://mathworld.wolfram.com/MatrixMultiplication.html">
011 * Read more about matrix multiplication.</a>
012 * 
013 * @author Your Name
014 * @version 23 February 2015
015 */
016public class SquareMatrix {
017
018    /**
019     * The dimension is the number of rows and
020     * columns in this square matrix.
021     */
022    private final int dimension;
023    /**
024     * This matrix stores the floating point values of its
025     * elements in a two dimensional array.
026     */
027    private final double[][] elements;
028
029    /**
030     * Create a square matrix that has a given number of
031     * rows and columns, with all elements equal to zero.
032     * 
033     * @param dimension is the number of rows and columns.
034     */
035    public SquareMatrix(int dimension) {
036        this.dimension = dimension;
037        this.elements = new double[dimension][dimension];
038        for (int i = 0; i < dimension; i++) {
039            for (int j = 0; j < dimension; j++) {
040                this.setElement(i, j, 0.0);
041            } // for
042        } // for
043    } // SquareMatrix( int )
044
045    /**
046     * Retrieve the dimension of this matrix.
047     * 
048     * @return the number of rows and columns that
049     * this square matrix has.
050     */
051    public final int getDimension() {
052        // Need more code here.
053        // (Replace 0 in return statement with something else.)
054        return 0;
055    } // getDimension();
056
057    /**
058     * Retrieve the value of the element of this
059     * matrix that is at the specified position.
060     * 
061     * @param row
062     * @param column
063     * @return the value at (row, column).
064    */
065    public final double getElement(int row, int column) {
066        // Need more code here.
067        // (Replace 0.0 in return statement with something else.)
068        return 0.0;
069    } // getElement( int, int )
070
071    /**
072     * Change the value of a specified element of this
073     * matrix.
074     * 
075     * @param row
076     * @param column
077     * @param value is the new value to be assigned to the element
078     * at (row, column).
079     */
080    public final void setElement(int row, int column, double value) {
081        // Need more code here.
082    } // setElement( int, int, double )
083
084    /**
085     * Create a printable representation of this matrix.
086     * 
087     * @return a string that contains newline characters
088     * at the end of each row.
089     */
090    @Override
091    public String toString() {
092        StringBuilder result = new StringBuilder();
093        for( int i = 0; i < this.getDimension(); i++ ) {
094            for( int j = 0; j < this.getDimension(); j++ ) {
095                String formattedString = String.format( "%6.2f ", 
096                        this.getElement(i,j));
097                result.append( formattedString );
098            } // for
099            result.append( "\n" );
100        } // for
101        return result.toString();
102    } // toString()
103    
104    /**
105     * Create another matrix that is equal to this one.
106     * 
107     * "Equal" means that for every row i and column j
108     * the elements at (i,j) in each matrix are equal.
109     * 
110     * @return a copy of this matrix 
111     */
112    public SquareMatrix copy() {
113        SquareMatrix result = new SquareMatrix( this.getDimension() );
114        for( int i = 0; i < this.getDimension(); i++ ) {
115            for( int j = 0; j < this.getDimension(); j++ ) {
116                result.setElement(i, j, this.getElement(i,j));
117            } // for
118        } // for
119        return result;
120    } // copy()
121    
122    /**
123     * Set the values of the elements of this matrix
124     * to make an identity matrix.
125     * 
126     * In an identity matrix, the values of all elements
127     * that are on the main diagonal (upper left to lower right)
128     * are one and the values of all other elements are zero.
129     */
130    public void setToIdentity() {
131       // Need more code here.
132    } // setToIdentity()
133    
134    /**
135     * Set the values of the elements of this matrix
136     * to make rows that represent PDFs.
137     * 
138     * A row represents a PDF if all values within
139     * the row are in the interval [0,1) and the sum
140     * of all values is 1.0.
141     */
142    public void setToPDFs() {
143        for (int i = 0; i < this.getDimension(); i++) {
144            // fill row with random numbers between 0.0 and 1.0
145            for (int j = 0; j < this.dimension; j++) {
146                this.setElement(i, j, Math.random());
147            } // for
148
149            // find sum of numbers in row i
150            double sum = 0.0;
151            for (int j = 0; j < this.getDimension(); j++) {
152                sum += this.getElement(i, j);
153            } // for
154
155            // divide each number in row i by sum
156            for (int j = 0; j < this.getDimension(); j++) {
157                double e = this.getElement(i, j);
158                this.setElement(i, j, e / sum);
159            } // for
160        } // for
161    } // setToPDFs()
162
163    /**
164     * Create a new matrix that is the product
165     * of this matrix and another given matrix.
166     * 
167     * @param m is the other matrix.
168     * @return the product of this matrix and m.
169     */
170    public SquareMatrix multiply(SquareMatrix m) {
171        int n = this.getDimension();
172        if (n != m.getDimension()) {
173            String message = "Matrices must have the same dimension.";
174            throw new IllegalArgumentException(message);
175        } // if
176
177        SquareMatrix productOfMatrices = new SquareMatrix(n);
178
179        for (int i = 0; i < n; i++) {
180            for (int j = 0; j < n; j++) {
181                double sumOfProducts = 0.0;
182                for (int k = 0; k < n; k++) {
183                    // Need more code here.
184                } // for
185                productOfMatrices.setElement(i, j, sumOfProducts);
186            } // for
187        } // for
188        return productOfMatrices;
189    } // multiply( SquareMatrix, SquareMatrix )
190
191    /**
192     * Compute the product of this matrix with itself.
193     * 
194     * @return the square of this matrix. 
195     */
196    public SquareMatrix square() {
197        return this.multiply(this);
198    } // square()
199    
200    /**
201     * Compute a matrix that is equal to this matrix
202     * raised to a given integer power.
203     * 
204     * @param exponent is the power to which the method
205     * raises this matrix.
206     * @return the product of this matrix multiplied times itself
207     * the specified number of times.
208     */
209    public SquareMatrix power( int exponent ) {
210        SquareMatrix result = new SquareMatrix( this.getDimension() );
211        
212        if( exponent == 0 ) {
213            result.setToIdentity();
214        } // if
215        else if( exponent == 1 ) {
216            result = this.copy();
217        } // else if
218        else {
219            SquareMatrix smallerPower = this.power(exponent/2);
220            result = smallerPower.square();
221            if( exponent % 2 == 1 ) {
222                result = result.multiply(this);
223            } // if
224        } // else 
225
226        return result;
227    } // power( int )
228    
229    public static void main(String[] args) {
230        SquareMatrix m = new SquareMatrix(4);
231        //m.setToPDFs();
232        System.out.println( m );
233        
234        SquareMatrix m2 = m.power(2);
235        System.out.println( m2 );
236        
237        SquareMatrix m4 = m.power(4);
238        System.out.println( m4 );
239        
240        SquareMatrix m8 = m.power(8);
241        System.out.println( m8 );
242    } // main( String [] )
243
244} // SquareMatrix