// Channel.java // // This class represents an information theoretic channel // // Tom Chothia T.Chothia@cs.bham.ac.uk 16/10/2008 // // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // // Copyright 2008 Tom Chothia package info; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.Vector; public class Channel { // an array of the output action labels // outputNames[i] will be the output of the ith column of the matrix. String[] outputNames; // an array of the input action labels. For single user matrixes // inputNames[i] will be the output of the ith roe of the matrix. // for multi-access channels the row label is found via inputsPerRow String[] inputNames; // The channel matrix double[][] channelMatrix_W; // inputsPerRow is an array of Vectors where inputPerRow[i] is a Vector // of the indexes of the inputs on row i of the channel matrix @SuppressWarnings("unchecked") Vector[] inputsPerRow; // In Condition channels groupNames[i] is the group of the ith row String[] groupNames; // currently unused // This will be used later when I add multipule groups for a row @SuppressWarnings("unchecked") Vector[] groupsPerRow; // for row i: groupNames[groupForRow[i]] is its group label. int[] groupForRow; // rowsForGroup[i] is a Vector of the rows that are in group groupNames[i] @SuppressWarnings("unchecked") Vector[] rowsForGroup; // Is the channel single user, multi-access etc. int kind; public static final int BASIC = 1; public static final int MULTI = 2; public static final int COND = 3; public static final int MULTICOND = 4; public static final int NEWMULTICOND = 5; public Channel() {} public Channel(int kind, String[] inputNames, String[] outputNames, double[][] matrix) { this.kind = kind; this.inputNames = inputNames; this.outputNames = outputNames; this.channelMatrix_W = matrix; } public String[] getOutputNames () { return outputNames; } public String[] getInputNames () { return inputNames; } public String[] getGroupNames () { return groupNames; } public double[][] getMatrix () { return channelMatrix_W; } @SuppressWarnings("unchecked") public Vector[] getInputsPerRow () { return inputsPerRow; } @SuppressWarnings("unchecked") public Vector getInputRow (int i) { return inputsPerRow[i]; } @SuppressWarnings("unchecked") public Vector[] getGroupsPerRow () { return groupsPerRow; } @SuppressWarnings("unchecked") public Vector[] getRowsForGroup () { return rowsForGroup; } public int getKind () { return kind; } public int noOfInputs() { return inputNames.length; } public int noOfRows() { return channelMatrix_W.length; } public int noOfOutputs() { return outputNames.length; } public double prob(int a,int o) { return channelMatrix_W[a][o]; } public String getInputName(int i) { return inputNames[i]; } public String getOutputName(int i) { return outputNames[i]; } public void setOutputNames (String[] arg) { outputNames = arg; } public void setInputNames (String[] arg) { inputNames = arg; } public void setGroupNames (String[] arg) { groupNames = arg; } public void setMatrix (double[][] arg) { channelMatrix_W = arg; } @SuppressWarnings("unchecked") public void setInputsPerRow (Vector[] arg) { inputsPerRow = arg; } @SuppressWarnings("unchecked") public void setGroupsPerRow (Vector[] arg) { groupsPerRow = arg; } public void setGroupForRow (int[]arg) { groupForRow = arg; } public void setKind (int arg) { kind = arg; } @SuppressWarnings("unchecked") public void setRowsForGroup (Vector[] arg) { rowsForGroup = arg; } public String getRowLabel (int rowNo) { switch (kind) { case BASIC: return (inputNames[rowNo]); case COND: return (inputNames[rowNo]+":"+groupNames[groupForRow[rowNo]]); } if (kind == BASIC || kind == COND) { return (inputNames[rowNo]); } else { String result =""; if (inputsPerRow[rowNo].size() >0 ) { result = inputNames[((Integer)inputsPerRow[rowNo].get(0)).intValue()]; for (int i=1;i<inputsPerRow[rowNo].size();i++) { result = result +", "+inputNames[((Integer)inputsPerRow[rowNo].get(i)).intValue()]; } } return result; } } public String[] inputsForRow (int rowNo) { if (kind == BASIC || kind == COND) { String[] result = {inputNames[rowNo]}; return (result); } else { if (inputsPerRow[rowNo].size() >0 ) { String[] result = new String[inputsPerRow[rowNo].size()]; for (int i=0;i<inputsPerRow[rowNo].size();i++) { result[i] = inputNames[((Integer)inputsPerRow[rowNo].get(i)).intValue()]; } return result; } else { String[] result = {""}; return result; } } } // //Pretty Print functions // // prints i+1 spaces public static void addspaces(int i) { for (int j = 0;j<=i;j++) { System.out.print(" "); } } // prints the string and pads it to length i public static void printToLength(String s, int i) { System.out.print(s); for (int j = s.length();j<=i;j++) { System.out.print(" "); } } public static void printSaveToLength(BufferedWriter writer, String s, int i) { System.out.print(s); try { writer.write(s); for (int j = s.length();j<=i;j++) { System.out.print(" "); writer.write(" "); } } catch (Exception e) {System.out.print(e);} } // Print the channel to standard out public void printChannel() { // Find maximum output length int maxOutLength = 0; for (int i=0;i< outputNames.length ;i++) { maxOutLength = Math.max(maxOutLength, outputNames[i].length()); } //for (int i=0;i< channelMatrix_W.length ;i++) //{ // for (int j=0;j<channelMatrix_W[0].length;j++) // { // maxOutLength = Math.max(maxOutLength, ((new Double(channelMatrix_W[i][j]).toString()).length())); // } //} // //Rounding probs to 4 d.p. therefore all probs have length 6 maxOutLength = Math.max(maxOutLength,6); // Find the Max Input row label length int maxInLength = 0; switch (kind) { case BASIC: for (int i=0;i<inputNames.length;i++) { maxInLength = Math.max(maxInLength,inputNames[i].length()); } maxInLength = maxInLength + 2; break; case MULTI: for (int i=0;i<inputNames.length;i++) { maxInLength = maxInLength + inputNames[i].length(); } maxInLength = maxInLength + inputNames.length; break; case COND: for (int i=0;i<inputNames.length;i++) { maxInLength = Math.max(maxInLength,inputNames[i].length()); } int maxGroupLength = 0; for (int i=0;i<groupNames.length;i++) { maxGroupLength = Math.max(maxGroupLength,groupNames[i].length()); } maxInLength = maxInLength + maxGroupLength; break; } //Print the outputs names addspaces(maxInLength+2); for (int i=0;i<outputNames.length;i++) { System.out.print("| "); printToLength(outputNames[i],maxOutLength); } System.out.println(""); // Print each row for (int i=0;i<channelMatrix_W.length;i++) { printRow (i,maxInLength, maxOutLength); } } public void printRow (int RowNo,int maxInLength, int maxOutLength) { System.out.print(" "); printToLength(getRowLabel(RowNo),maxInLength+1); for (int j=0;j<outputNames.length;j++) { System.out.print("| "); printToLength(Double.toString(Stats.round(channelMatrix_W[RowNo][j],Math.max(4,maxOutLength-2))),maxOutLength); } System.out.println(""); } // Print the channel to standard out and write it to "fileName" public void printSaveChannel(String fileName) { // Find maximum output length int maxOutLength = 0; for (int i=0;i< outputNames.length ;i++) { maxOutLength = Math.max(maxOutLength, outputNames[i].length()); } for (int i=0;i< channelMatrix_W.length ;i++) { for (int j=0;j<channelMatrix_W[0].length;j++) { maxOutLength = Math.max(maxOutLength, ((new Double(channelMatrix_W[i][j]).toString()).length())); } } // Find the Max Input row label length int maxInLength = 0; switch (kind) { case BASIC: for (int i=0;i<inputNames.length;i++) { maxInLength = Math.max(maxInLength,inputNames[i].length()); } maxInLength = maxInLength + 2; break; case MULTI: for (int i=0;i<inputNames.length;i++) { maxInLength = maxInLength + inputNames[i].length(); } maxInLength = maxInLength + inputNames.length; break; case COND: for (int i=0;i<inputNames.length;i++) { maxInLength = Math.max(maxInLength,inputNames[i].length()); } int maxGroupLength = 0; for (int i=0;i<groupNames.length;i++) { maxGroupLength = Math.max(maxGroupLength,groupNames[i].length()); } maxInLength = maxInLength + maxGroupLength; break; } //Print the outputs names try { BufferedWriter writer = new BufferedWriter(new FileWriter(fileName)); //addspaces(maxInLength+2); printSaveToLength(writer,"("+inputNames.length+","+outputNames.length+")",maxInLength+2); //for (int j = 0;j<=maxInLength+2;j++) //{ // System.out.print(" "); // writer.write(" "); //} for (int i=0;i<outputNames.length;i++) { System.out.print("| "); writer.write("| "); printSaveToLength(writer,outputNames[i],maxOutLength); } System.out.println(""); writer.write("\n"); // Print each row for (int i=0;i<channelMatrix_W.length;i++) { printSaveRow (writer,i,maxInLength, maxOutLength); } writer.close(); } catch (IOException e) { System.out.println("Error opening output files:"+fileName); } } public void printSaveRow (BufferedWriter writer, int RowNo,int maxInLength, int maxOutLength) { System.out.print(" "); try { writer.write(" "); printSaveToLength(writer,getRowLabel(RowNo),maxInLength+1); for (int j=0;j<outputNames.length;j++) { System.out.print("| "); writer.write("| "); printSaveToLength(writer,Double.toString(channelMatrix_W[RowNo][j]),maxOutLength); } System.out.println(""); writer.write("\n"); } catch (Exception e) { System.out.print(e); } } }