/* * 文件名:SparseMatrix.java * 版权:Copyright 2008-20012 复旦大学 All Rights Reserved. * 描述:程序总入口 * 修改人:xpqiu * 修改时间:2009 Jul 29, 2009 2:49:41 PM * 修改内容:新增 * * 修改人:〈修改人〉 * 修改时间:YYYY-MM-DD * 跟踪单号:〈跟踪单号〉 * 修改单号:〈修改单号〉 * 修改内容:〈修改内容〉 */ package edu.fudan.ml.types.sv; import gnu.trove.iterator.TLongFloatIterator; import gnu.trove.map.hash.TLongFloatHashMap; import java.util.Random; /** * 类似于matlab的多维稀疏矩阵 * 列向量优先 * @author xpqiu * @version 1.0 * SparseMatrix * package edu.fudan.ml.types */ public class SparseMatrix { /** * 每一维的大小 */ private int[] dim; /** * 内部为向量表示 */ public TLongFloatHashMap vector = null; public SparseMatrix(){ vector = new TLongFloatHashMap(100,0.8f); } public SparseMatrix(int[] dim){ this(); this.dim = dim; } public void set(int[] indices, float val){ long idx = getIdx(indices); set(idx,val); } public void set(long index, float value) { vector.put(index, value); } public float elementAt(int[] indices) { long idx = getIdx(indices); return vector.get(idx); } public float elementAt(long index) { return vector.get(index); } public int[] size() { return dim; } public SparseMatrix mutiplyMatrix(SparseMatrix a){ int m = this.size()[0]; int n = a.size()[1]; int dim[]={m,n}; SparseMatrix matrix = new SparseMatrix(dim); TLongFloatIterator it = this.vector.iterator(); TLongFloatIterator ita = a.vector.iterator(); for (int i = this.vector.size(); i-- > 0;) { it.advance(); ita = a.vector.iterator(); for(int j = a.vector.size(); j-- > 0;) { ita.advance(); if(this.getIndices(it.key())[1]==a.getIndices(ita.key())[0]) { int []indices = {this.getIndices(it.key())[0],a.getIndices(ita.key())[1]}; matrix.set(indices, matrix.elementAt(indices)+it.value()*ita.value()); } } } return matrix; } /** * 将多维索引转换为列排序索引 * @param indices * @return * Jul 29, 2009 */ public long getIdx(int[] indices){ long idx=0; int i=indices.length-1; for(int j=0;i>0&&j<indices.length-1;i--,j++) idx += indices[i]*dim[j]; idx += indices[0]; return idx; } /** * long型索引转换为int[]索引 * @param idx * @return 索引 */ public int[] getIndices(long idx) { int xIndices = (int)idx%this.size()[0]; int yIndices = (int)(idx-xIndices)/this.size()[0]; int []Indices = {xIndices,yIndices}; return Indices; } public SparseMatrix clone(){ SparseMatrix mat = new SparseMatrix(); mat.dim = this.dim; mat.vector = new TLongFloatHashMap(vector); return mat; } /** * 生成大小为int[]dim的随机矩阵 * @param dim * @return 矩阵 */ public static SparseMatrix random(int[] dim) { Random r = new Random(); SparseMatrix matrix = new SparseMatrix(dim); for(int i=0;i<dim[0];i++) for(int j=0;j<dim[1];j++) { int []indices={i,j}; matrix.set(indices, r.nextFloat()); } return matrix; } /** * @param mat * Sep 6, 2009 */ public void minus(SparseMatrix mat) { TLongFloatIterator it = mat.vector.iterator(); for (int i = mat.vector.size(); i-- > 0;) { it.advance(); vector.put(it.key(),vector.get(it.key()) - it.value()); } } public void add(SparseMatrix mat) { TLongFloatIterator it = mat.vector.iterator(); for (int i = mat.vector.size(); i-- > 0;) { it.advance(); vector.put(it.key(),vector.get(it.key()) + it.value()); } } public float l1Norm() { float norm = 0; TLongFloatIterator it = vector.iterator(); for (int i = vector.size(); i-- > 0;) { it.advance(); norm += Math.abs(it.value()); } return norm; } public float l2Norm() { float norm = 0; TLongFloatIterator it = vector.iterator(); for (int i = vector.size(); i-- > 0;) { it.advance(); norm += it.value()*it.value(); } return (float) Math.sqrt(norm); } public float infinityNorm() { float norm = 0; TLongFloatIterator it = vector.iterator(); for (int i = vector.size(); i-- > 0;) { it.advance(); if (Math.abs(it.value()) > norm) norm = Math.abs(it.value()); } it=null; return norm; } /** * @return * Sep 6, 2009 */ public SparseMatrix trans() { int []newdim = {dim[1],dim[0]}; SparseMatrix newmat = new SparseMatrix(newdim); TLongFloatIterator itW = vector.iterator(); for (int i = vector.size(); i-- > 0;) { itW.advance(); int x = getIndices(itW.key())[0]; int y = getIndices(itW.key())[1]; int []TranWIndices = {y,x}; newmat.set(TranWIndices,itW.value()); } return newmat; } }