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

umontreal.ssj.hups.DigitalNetFromFile Maven / Gradle / Ivy

There is a newer version: 3.3.2
Show 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 Universite de Montreal
 * Organization: DIRO, Universite de Montreal
 * @author
 * @since
 *
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package umontreal.ssj.hups;

import java.io.*;
import java.util.*;
import java.net.URL;
import java.net.MalformedURLException;
import umontreal.ssj.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
 * @ref umontreal.ssj.hups.DigitalNet. The format of the data files must be
 * the following:
 *  (see the format in guidehups.pdf)
 *
 * 
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Any number of comment lines starting with * //
@f$b@f$// @f$\mbox{Base}@f$
@f$k@f$// Number of columns
@f$r@f$// Maximal number of rows
@f$n@f$// Number of points = @f$b^k@f$
@f$s@f$// Maximal dimension of points
// dim = 1
@f$c_{11}@f$@f$c_{21}@f$@f$\cdots@f$@f$c_{r1}@f$
@f$c_{12}@f$@f$c_{22}@f$@f$\cdots@f$@f$c_{r2}@f$
@f$\vdots@f$
@f$c_{1k}@f$@f$c_{2k}@f$@f$\cdots@f$@f$c_{rk}@f$
// dim = 2
@f$\vdots@f$
// dim = @f$s@f$
@f$c_{11}@f$@f$c_{21}@f$@f$\cdots@f$@f$c_{r1}@f$
@f$c_{12}@f$@f$c_{22}@f$@f$\cdots@f$@f$c_{r2}@f$
@f$\vdots@f$
@f$c_{1k}@f$@f$c_{2k}@f$@f$\cdots@f$@f$c_{rk}@f$
*
*
* * 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 * @f$k\times r@f$ matrix of integers in @f$\{0, 1, …, b-1\}@f$ (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://simul.iro.umontreal.ca/ssj/data](http://simul.iro.umontreal.ca/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](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/ssj/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://simul.iro.umontreal.ca/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` @f$\ge@f$ `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 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/ssj/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/ssj/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