001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.openimaj.math.matrix;
031
032import ch.akuhn.matrix.Matrix;
033import ch.akuhn.matrix.Vector;
034
035/**
036 * @author Sina Samangooei (ss@ecs.soton.ac.uk)
037 *
038 */
039public class DiagonalMatrix extends Matrix{
040
041        private double[] vals;
042
043        /**
044         * New empty matrix with 0s down the diagonals
045         * @param rowcol
046         */
047        public DiagonalMatrix(int rowcol) {
048                this.vals = new double[rowcol];
049        }
050        
051        /**
052         * New empty matrix with val down the diagonals
053         * @param rowcol
054         * @param val 
055         */
056        public DiagonalMatrix(int rowcol, double val) {
057                this.vals = new double[rowcol];
058                for (int i = 0; i < vals.length; i++) {
059                        vals[i] = val;
060                }
061        }
062
063        /**
064         * Diagonal version of the matrix handed
065         * @param arr
066         */
067        public DiagonalMatrix(double[][] arr) {
068                this(Math.min(arr.length, arr[0].length));
069                for (int i = 0; i < vals.length; i++) {
070                        this.vals[i] = arr[i][i];
071                }
072        }
073        
074        /**
075         * @param mat
076         */
077        public DiagonalMatrix(Matrix mat) {
078                this(Math.min(mat.rowCount(), mat.columnCount()));
079                for (int i = 0; i < vals.length; i++) {
080                        this.vals[i] = mat.get(i, i);
081                }
082        }
083        
084        @Override
085        public Vector mult(Vector x) {
086                double[] y = new double[this.columnCount()];
087                for (int i = 0; i < y.length; i++) {
088                        y[i] = this.vals[i] * x.get(i);
089                }
090                return Vector.wrap(y);
091        }
092        
093        @Override
094        public Vector transposeMultiply(Vector x) {
095                return mult(x);
096        }
097        
098        @Override
099        public Vector transposeNonTransposeMultiply(Vector x) {
100                double[] y = new double[this.columnCount()];
101                for (int i = 0; i < y.length; i++) {
102                        y[i] = this.vals[i] * this.vals[i] * x.get(i);
103                }
104                return Vector.wrap(y);
105        }
106        
107        @Override
108        public int columnCount() {
109                return this.vals.length;
110        }
111
112        @Override
113        public double get(int row, int column) {
114                if(row!=column) return 0;
115                else return vals[row];
116        }
117
118        @Override
119        public double put(int row, int column, double value) {
120                if(row == column)
121                        return vals[row] = value;
122                return 0;
123        }
124
125        @Override
126        public int rowCount() {
127                return vals.length;
128        }
129
130        @Override
131        public int used() {
132                return vals.length;
133        }
134
135
136        /**
137         * @param rowcol
138         * @return a matrix of ones in the diagonal
139         */
140        public static DiagonalMatrix zeros(int rowcol) {
141                return fill(rowcol,0.);
142        }
143
144        /**
145         * @param rowcol
146         * @return a matrix of ones in the diagonal
147         */
148        public static DiagonalMatrix ones(int rowcol) {
149                return fill(rowcol,1.);
150        }
151
152        /**
153         * @param rowcol
154         * @param d
155         * @return a matrix with d in the diagonal
156         */
157        public static DiagonalMatrix fill(int rowcol, double d) {
158                DiagonalMatrix ret = new DiagonalMatrix(rowcol);
159                for (int i = 0; i < rowcol; i++) {
160                        ret.vals[i] = d;
161                }
162                return ret;
163        }
164
165        /**
166         * @return the diagonals
167         */
168        public double[] getVals() {
169                return this.vals;
170        }
171
172        @Override
173        public Matrix newInstance(int rows, int cols) {
174                return new DiagonalMatrix(rows);
175        }
176}