All Downloads are FREE. Search and download functionalities are using the official Maven repository.

umontreal.iro.lecuyer.hups.DigitalNetFromFile Maven / Gradle / Ivy

Go to download

SSJ is a Java library for stochastic simulation, developed under the direction of Pierre L'Ecuyer, in the Département d'Informatique et de Recherche Opérationnelle (DIRO), at the Université de Montréal. It provides facilities for generating uniform and nonuniform random variates, computing different measures related to probability distributions, performing goodness-of-fit tests, applying quasi-Monte Carlo methods, collecting (elementary) statistics, and programming discrete-event simulations with both events and processes.

The newest version!


/*
 * Class:        DigitalNetFromFile
 * Description:  read the parameters defining a digital net from a file
                 or from a URL address
 * Environment:  Java
 * Software:     SSJ 
 * Copyright (C) 2001  Pierre L'Ecuyer and Université de Montréal
 * Organization: DIRO, Université de Montréal
 * @author       
 * @since

 * SSJ is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License (GPL) as published by the
 * Free Software Foundation, either version 3 of the License, or
 * any later version.

 * SSJ 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.

 * A copy of the GNU General Public License is available at
   GPL licence site.
 */

package umontreal.iro.lecuyer.hups;

import java.io.*;
import java.util.*;
import java.net.URL;
import java.net.MalformedURLException;
import umontreal.iro.lecuyer.util.PrintfFormat;


/**
 * This class allows us to read the parameters defining a digital net either
 * from a file, or from a URL address on the World Wide Web.
 * The parameters used in building the net are those defined in class
 * {@link umontreal.iro.lecuyer.hups.DigitalNet DigitalNet}.
 * The format of the data files must be the following:
 * (see the format in guidehups.pdf)
 * 
* \begin{figure}\begin{center}
 * \tt
 * \fbox{
 * \begin {tabular}{llll}
 * \multicolumn{4}{...
 * ... $c_{2k}$\ & $\cdots$\ & $c_{rk}$\ \\
 * \end {tabular}
 * }
 * \end{center}\end{figure} *
* *

* The figure above gives the general format of the data file * needed by DigitalNetFromFile. * The values of the parameters on the left must appear in the file * as integers. On the right of each parameter, there is an optional * comment that is disregarded by the reader program. In general, the * Java line comments // are accepted anywhere and will * ensure that the rest of the line is dropped by the reader. Blank lines * are also disregarded by the reader program. For each dimension, there must * be a k×r matrix of integers in * {0, 1,…, b - 1} (note that * the matrices must appear in transposed form). * *

* The predefined files of parameters are kept in different directories, * depending on the criteria used in the searches for the parameters defining * the digital net. These files have all been stored at the address * http://www.iro.umontreal.ca/~simardr/ssj/data. * Each file contains the parameters for a specific digital net. * The name of the files gives information about the main parameters of * the digital net. For example, the file named Edel/OOA2/B3S13R9C9St6 * contains the parameters for a digital net proposed by Yves Edel * (see http://www.mathi.uni-heidelberg.de/~yves/index.html) based * on ordered orthogonal arrays; the digital net has base B = 3, * dimension S = 13, the generating matrices have R = 9 rows * and C = 9 columns, and the strength of the net is St = 6. * */ public class DigitalNetFromFile extends DigitalNet { private String filename; private void readMatrices (StreamTokenizer st, int r, int k, int dim) throws IOException, NumberFormatException { // Read dim matrices with r rows and k columns. // dim is the dimension of the digital net. genMat = new int[dim * k][r]; for (int i = 0; i < dim; i++) for (int c = 0; c < k; c++) { for (int j = 0; j < r; j++) { st.nextToken (); genMat[i*numCols + c][j] = (int) st.nval; } // If we do not use all the rows, drop the unused ones. for (int j = r; j < numRows; j++) { st.nextToken (); } } } void readData (StreamTokenizer st) throws IOException, NumberFormatException { // Read beginning of data file, but do not read the matrices st.eolIsSignificant (false); st.slashSlashComments (true); int i = st.nextToken (); if (i != StreamTokenizer.TT_NUMBER) throw new NumberFormatException(" readData: cannot read base"); b = (int) st.nval; st.nextToken (); numCols = (int) st.nval; st.nextToken (); numRows = (int) st.nval; st.nextToken (); numPoints = (int) st.nval; st.nextToken (); dim = (int) st.nval; if (dim < 1) throw new IllegalArgumentException (" dimension dim <= 0"); } static BufferedReader openURL (String filename) throws MalformedURLException, IOException { try { URL url = new URL (filename); BufferedReader input = new BufferedReader ( new InputStreamReader ( url.openStream())); return input; } catch (MalformedURLException e) { System.err.println (e + " Invalid URL address: " + filename); throw e; } catch (IOException e) { // This can receive a FileNotFoundException System.err.println (e + " in openURL with " + filename); throw e; } } static BufferedReader openFile (String filename) throws IOException { try { BufferedReader input; File f = new File (filename); // If file with relative path name exists, read it if (f.exists()) { if (f.isDirectory()) throw new IOException (filename + " is a directory"); input = new BufferedReader (new FileReader (filename)); } else { // else read it from ssj.jar String pseudo = "umontreal/iro/lecuyer/hups/data/"; StringBuffer pathname = new StringBuffer (pseudo); for (int ci = 0; ci < filename.length(); ci++) { char ch = filename.charAt (ci); if (ch == File.separatorChar) pathname.append ('/'); else pathname.append (ch); } InputStream dataInput = DigitalNetFromFile.class.getClassLoader().getResourceAsStream ( pathname.toString()); if (dataInput == null) throw new FileNotFoundException(); input = new BufferedReader (new InputStreamReader (dataInput)); } return input; } catch (FileNotFoundException e) { System.err.println (e + " *** cannot find " + filename); throw e; } catch (IOException e) { // This will never catch FileNotFoundException since there // is a catch clause above. System.err.println (e + " cannot read from " + filename); throw e; } } /** * Constructs a digital net after reading its parameters from file * filename. If a file named filename * can be found relative to the program's directory, then the parameters * will be read from this file; otherwise, they will be read from the file * named filename in the ssj.jar archive. * If filename is a URL string, it will be read on * the World Wide Web. * For example, to construct a digital net from the parameters in file * B3S13R9C9St6 in the current directory, one must give the string * "B3S13R9C9St6" as argument to the constructor. * As an example of a file read from the WWW, one may give * as argument to the constructor the string * * "http://www.iro.umontreal.ca/˜simardr/ssj/data/Edel/OOA3/B3S13R6C6St4". * Parameter w gives the number of digits of resolution, r1 is * the number of rows, and s1 is the dimension. * Restrictions: s1 must be less than the maximal dimension, and * r1 less than the maximal number of rows in the data file. * Also w  >=  r1. * * @param filename Name of the file to be read * * @param r1 Number of rows for the generating matrices * * @param w Number of digits of resolution * * @param s1 Number of dimensions * * */ public DigitalNetFromFile (String filename, int r1, int w, int s1) throws MalformedURLException, IOException { super (); BufferedReader input = null; StreamTokenizer st = null; try { if (filename.startsWith("http:") || filename.startsWith("ftp:")) input = openURL(filename); else input = openFile(filename); st = new StreamTokenizer (input); readData (st); } catch (MalformedURLException e) { System.err.println (" Invalid URL address: " + filename); throw e; } catch (FileNotFoundException e) { System.err.println (" Cannot find " + filename); throw e; } catch (NumberFormatException e) { System.err.println (" Cannot read number from " + filename); throw e; } catch (IOException e) { System.err.println (" IOException: " + filename); throw e; } if (b == 2) { System.err.println (" base = 2, use DigitalNetBase2FromFile"); throw new IllegalArgumentException ("base = 2, use DigitalNetBase2FromFile"); } if ((double)numCols * Math.log ((double)b) > (31.0 * Math.log (2.0))) throw new IllegalArgumentException ("DigitalNetFromFile: too many points" + PrintfFormat.NEWLINE); if (r1 > numRows) throw new IllegalArgumentException ("DigitalNetFromFile: One must have r1 <= Max num rows" + PrintfFormat.NEWLINE); if (s1 > dim) throw new IllegalArgumentException ("DigitalNetFromFile: One must have s1 <= Max dimension" + PrintfFormat.NEWLINE); if (w < 0) { r1 = w = numRows; s1 = dim; } if (w < numRows) throw new IllegalArgumentException ("DigitalNetFromFile: One must have w >= numRows" + PrintfFormat.NEWLINE); try { readMatrices (st, r1, numCols, s1); } catch (NumberFormatException e) { System.err.println (e + " cannot read matrices from " + filename); throw e; } catch (IOException e) { System.err.println (e + " cannot read matrices from " + filename); throw e; } input.close(); this.filename = filename; numRows = r1; dim = s1; outDigits = w; int x = b; for (int i=1; i(filename, r, r, s) where * s is the dimension and r is given in data file filename. * * @param filename Name of the file to be read * * @param s Number of dimensions * */ public DigitalNetFromFile (String filename, int s) throws MalformedURLException, IOException { this (filename, -1, -1, s); } DigitalNetFromFile () { super (); } public String toString() { StringBuffer sb = new StringBuffer ("File: " + filename + PrintfFormat.NEWLINE); sb.append (super.toString()); return sb.toString(); } /** * Writes the parameters and the generating matrices of this digital net * to a string. This is useful to check that the file parameters have been * read correctly. * */ public String toStringDetailed() { StringBuffer sb = new StringBuffer (toString()); sb.append (PrintfFormat.NEWLINE + "n = " + numPoints + PrintfFormat.NEWLINE); sb.append ("dim = " + dim + PrintfFormat.NEWLINE); for (int i = 0; i < dim; i++) { sb.append (PrintfFormat.NEWLINE + " // dim = " + (1 + i) + PrintfFormat.NEWLINE); for (int c = 0; c < numCols; c++) { for (int r = 0; r < numRows; r++) sb.append (genMat[i*numCols + c][r] + " "); sb.append (PrintfFormat.NEWLINE); } } return sb.toString (); } static class NetComparator implements Comparator { // Used to sort list of nets. Sort first by base, then by dimension, // then by the number of rows. Don't forget that base = 4 are in files // named B4_2* and that the computations are done in base 2. public int compare (Object o1, Object o2) { DigitalNetFromFile net1 = (DigitalNetFromFile) o1; DigitalNetFromFile net2 = (DigitalNetFromFile) o2; if (net1.b < net2.b) return -1; if (net1.b > net2.b) return 1; if (net1.filename.indexOf("_") >= 0 && net2.filename.indexOf("_") < 0 ) return 1; if (net2.filename.indexOf("_") >= 0 && net1.filename.indexOf("_") < 0 ) return -1; if (net1.dim < net2.dim) return -1; if (net1.dim > net2.dim) return 1; if (net1.numRows < net2.numRows) return -1; if (net1.numRows > net2.numRows) return 1; return 0; } } private static List getListDir (String dirname) throws IOException { try { String pseudo = "umontreal/iro/lecuyer/hups/data/"; StringBuffer pathname = new StringBuffer (pseudo); for (int ci = 0; ci < dirname.length(); ci++) { char ch = dirname.charAt (ci); if (ch == File.separatorChar) pathname.append ('/'); else pathname.append (ch); } URL url = DigitalNetFromFile.class.getClassLoader().getResource ( pathname.toString()); File dir = new File (url.getPath()); if (!dir.isDirectory()) throw new IllegalArgumentException ( dirname + " is not a directory"); File[] files = dir.listFiles(); List alist = new ArrayList (200); if (!dirname.endsWith (File.separator)) dirname += File.separator; for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) continue; if (files[i].getName().endsWith ("gz") || files[i].getName().endsWith ("zip")) continue; DigitalNetFromFile net = new DigitalNetFromFile(); BufferedReader input = net.openFile(dirname + files[i].getName()); StreamTokenizer st = new StreamTokenizer (input); net.readData (st); net.filename = files[i].getName(); alist.add (net); } if (alist != null && !files[0].isDirectory()) Collections.sort (alist, new NetComparator ()); return alist; } catch (NullPointerException e) { System.err.println ("getListDir: cannot find directory " + dirname); throw e; } catch (NumberFormatException e) { System.err.println (e + "*** cannot read number "); throw e; } catch (IOException e) { System.err.println (e); throw e; } } private static String listFiles (String dirname) { try { String pseudo = "umontreal/iro/lecuyer/hups/data/"; StringBuffer pathname = new StringBuffer (pseudo); for (int ci = 0; ci < dirname.length(); ci++) { char ch = dirname.charAt (ci); if (ch == File.separatorChar) pathname.append ('/'); else pathname.append (ch); } URL url = DigitalNetFromFile.class.getClassLoader().getResource ( pathname.toString()); File dir = new File (url.getPath()); File[] list = dir.listFiles(); List alist = new ArrayList (200); final int NPRI = 3; StringBuffer sb = new StringBuffer(1000); for (int i = 0; i < list.length; i++) { if (list[i].isDirectory()) { sb.append (PrintfFormat.s(-2, list[i].getName())); sb.append (File.separator + PrintfFormat.NEWLINE); } else { sb.append (PrintfFormat.s(-25, list[i].getName())); if (i % NPRI == 2) sb.append (PrintfFormat.NEWLINE); } } if (list.length % NPRI > 0) sb.append (PrintfFormat.NEWLINE); return sb.toString(); } catch (NullPointerException e) { System.err.println ("listFiles: cannot find directory " + dirname); throw e; } } /** * Lists all files (or directories) in directory dirname. Only relative * pathnames should be used. The files are parameter files used in defining * digital nets. For example, calling listDir("") will give the list * of the main data directory in SSJ, while calling listDir("Edel/OOA2") * will give the list of all files in directory Edel/OOA2. * */ public static String listDir (String dirname) throws IOException { try { List list = getListDir (dirname); if (list == null || list.size() == 0) return listFiles (dirname); StringBuffer sb = new StringBuffer(1000); sb.append ("Directory: " + dirname + PrintfFormat.NEWLINE + PrintfFormat.NEWLINE); sb.append (PrintfFormat.s(-25, " File") + PrintfFormat.s(-15, " Base") + PrintfFormat.s(-10, "Dimension") + PrintfFormat.s(-10, " numRows") + PrintfFormat.s(-10, "numColumns" + PrintfFormat.NEWLINE)); int base = 0; for (int i = 0; i < list.size(); i++) { DigitalNet net = (DigitalNet) list.get(i); int j = ((DigitalNetFromFile)net).filename.lastIndexOf (File.separator); if (net.b != base) { sb.append ( "----------------------------------------------------------------------" + PrintfFormat.NEWLINE); base = net.b; } String name = ((DigitalNetFromFile)net).filename.substring(j+1); sb.append (PrintfFormat.s(-25, name) + PrintfFormat.d(10, net.b) + PrintfFormat.d(10, net.dim) + PrintfFormat.d(10, net.numRows) + PrintfFormat.d(10, net.numCols) + PrintfFormat.NEWLINE); } return sb.toString(); } catch (NullPointerException e) { System.err.println ( "formatPlain: cannot find directory " + dirname); throw e; } } /** * Creates a list of all data files in directory dirname and writes * that list in format HTML in output file filename. * Each data file contains the parameters required to build a digital net. * The resulting list contains a line for each data file giving the * name of the file, the base, the dimension, the number of rows and * the number of columns of the corresponding digital net. * */ public static void listDirHTML (String dirname, String filename) throws IOException { String list = listDir(dirname); StreamTokenizer st = new StreamTokenizer (new StringReader(list)); st.eolIsSignificant(true); st.ordinaryChar('/'); st.ordinaryChar('_'); st.ordinaryChar('-'); st.wordChars('-', '-'); st.wordChars('_', '_'); st.slashSlashComments(false); st.slashStarComments(false); PrintWriter out = new PrintWriter ( new BufferedWriter ( new FileWriter (filename))); out.println ("" + PrintfFormat.NEWLINE + "" + PrintfFormat.NEWLINE + ""); while (st.nextToken () != st.TT_EOL) ; out.println ( PrintfFormat.NEWLINE + "" + PrintfFormat.NEWLINE + ""); // out.println (""); out.println (""); out.println ("

"); out.println (""); st.nextToken(); st.nextToken(); while (st.sval.compareTo ("File") != 0) st.nextToken(); out.print (""); while (st.nextToken () != st.TT_EOL) { out.print ("" ); } out.println ("" + PrintfFormat.NEWLINE); while (st.nextToken () != st.TT_EOF) { switch(st.ttype) { case StreamTokenizer.TT_EOL: out.println (""); break; case StreamTokenizer.TT_NUMBER: out.print ("" ); break; case StreamTokenizer.TT_WORD: if (st.sval.indexOf ("---") >= 0) { st.nextToken (); continue; } out.print (""); break; default: out.print (st.sval); break; } } out.println ("
Directory: " + dirname + "
" + st.sval + "" + st.sval + "
" + (int) st.nval + "
" + st.sval + "
"); out.println ("" + PrintfFormat.NEWLINE + ""); out.close(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy