⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix.java

📁 MacroWeka扩展了著名数据挖掘工具weka
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    for (i = 0; i < s.getRowDimension(); i++)
      for (n = 0; n < s.getColumnDimension(); n++)
        s.set(i, n, StrictMath.sqrt(d.get(i, n)));

    // to calculate:
    //      result = V*S/V
    //
    //    with   X = B/A
    //    and  B/A = (A'\B')'
    //    and V=A and V*S=B
    // we get 
    //      result = (V'\(V*S)')'
    //      
    //         A*X = B
    //           X = A\B
    // which is 
    //           X = A.solve(B)
    //           
    // with A=V' and B=(V*S)' 
    // we get
    //           X = V'.solve((V*S)')
    // or
    //      result = X'
    //
    // which is in full length
    //      result = (V'.solve((V*S)'))'
    a      = v.inverse();
    b      = v.times(s).inverse();
    v      = null;
    d      = null;
    evd    = null;
    s      = null;
    result = a.solve(b).inverse();

    return result;
  }

  /**
   * Performs a (ridged) linear regression.
   *
   * @param     y the dependent variable vector
   * @param     ridge the ridge parameter
   * @return    the coefficients 
   * @throws    IllegalArgumentException if not successful
   * @author    FracPete, taken from old weka.core.Matrix class
   */
  public LinearRegression regression(Matrix y, double ridge) {
    return new LinearRegression(this, y, ridge);
  }

  /**
   * Performs a weighted (ridged) linear regression. 
   *
   * @param     y the dependent variable vector
   * @param     w the array of data point weights
   * @param     ridge the ridge parameter
   * @return    the coefficients 
   * @throws    IllegalArgumentException if the wrong number of weights were
   *            provided.
   * @author    FracPete, taken from old weka.core.Matrix class
   */
  public final LinearRegression regression(Matrix y, double[] w, double ridge) {
    return new LinearRegression(this, y, w, ridge);
  }

  /** 
   * Matrix determinant
   * @return     determinant
   */
  public double det() {
    return new LUDecomposition(this).det();
  }

  /** 
   * Matrix rank
   * @return     effective numerical rank, obtained from SVD.
   */
  public int rank() {
    return new SingularValueDecomposition(this).rank();
  }

  /** 
   * Matrix condition (2 norm)
   * @return     ratio of largest to smallest singular value.
   */
  public double cond() {
    return new SingularValueDecomposition(this).cond();
  }

  /** 
   * Matrix trace.
   * @return     sum of the diagonal elements.
   */
  public double trace() {
    double t = 0;
    for (int i = 0; i < Math.min(m,n); i++) {
      t += A[i][i];
    }
    return t;
  }

  /** 
   * Generate matrix with random elements
   * @param m    Number of rows.
   * @param n    Number of colums.
   * @return     An m-by-n matrix with uniformly distributed random elements.
   */
  public static Matrix random(int m, int n) {
    Matrix A = new Matrix(m,n);
    double[][] X = A.getArray();
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        X[i][j] = Math.random();
      }
    }
    return A;
  }

  /** 
   * Generate identity matrix
   * @param m    Number of rows.
   * @param n    Number of colums.
   * @return     An m-by-n matrix with ones on the diagonal and zeros elsewhere.
   */
  public static Matrix identity(int m, int n) {
    Matrix A = new Matrix(m,n);
    double[][] X = A.getArray();
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        X[i][j] = (i == j ? 1.0 : 0.0);
      }
    }
    return A;
  }

  /** 
   * Print the matrix to stdout.   Line the elements up in columns
   * with a Fortran-like 'Fw.d' style format.
   * @param w    Column width.
   * @param d    Number of digits after the decimal.
   */
  public void print(int w, int d) {
    print(new PrintWriter(System.out,true),w,d); 
  }

  /** 
   * Print the matrix to the output stream.   Line the elements up in
   * columns with a Fortran-like 'Fw.d' style format.
   * @param output Output stream.
   * @param w      Column width.
   * @param d      Number of digits after the decimal.
   */
  public void print(PrintWriter output, int w, int d) {
    DecimalFormat format = new DecimalFormat();
    format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
    format.setMinimumIntegerDigits(1);
    format.setMaximumFractionDigits(d);
    format.setMinimumFractionDigits(d);
    format.setGroupingUsed(false);
    print(output,format,w+2);
  }

  /** 
   * Print the matrix to stdout.  Line the elements up in columns.
   * Use the format object, and right justify within columns of width
   * characters.
   * Note that is the matrix is to be read back in, you probably will want
   * to use a NumberFormat that is set to US Locale.
   * @param format A  Formatting object for individual elements.
   * @param width     Field width for each column.
   * @see java.text.DecimalFormat#setDecimalFormatSymbols
   */
  public void print(NumberFormat format, int width) {
    print(new PrintWriter(System.out,true),format,width); 
  }

  // DecimalFormat is a little disappointing coming from Fortran or C's printf.
  // Since it doesn't pad on the left, the elements will come out different
  // widths.  Consequently, we'll pass the desired column width in as an
  // argument and do the extra padding ourselves.

  /** 
   * Print the matrix to the output stream.  Line the elements up in columns.
   * Use the format object, and right justify within columns of width
   * characters.
   * Note that is the matrix is to be read back in, you probably will want
   * to use a NumberFormat that is set to US Locale.
   * @param output the output stream.
   * @param format A formatting object to format the matrix elements 
   * @param width  Column width.
   * @see java.text.DecimalFormat#setDecimalFormatSymbols
   */
  public void print(PrintWriter output, NumberFormat format, int width) {
    output.println();  // start on new line.
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        String s = format.format(A[i][j]); // format the number
        int padding = Math.max(1,width-s.length()); // At _least_ 1 space
        for (int k = 0; k < padding; k++)
          output.print(' ');
        output.print(s);
      }
      output.println();
    }
    output.println();   // end with blank line.
  }

  /** 
   * Read a matrix from a stream.  The format is the same the print method,
   * so printed matrices can be read back in (provided they were printed using
   * US Locale).  Elements are separated by
   * whitespace, all the elements for each row appear on a single line,
   * the last row is followed by a blank line.
   * <p/>
   * Note: This format differs from the one that can be read via the
   * Matrix(Reader) constructor! For that format, the write(Writer) method
   * is used (from the original weka.core.Matrix class).
   *
   * @param input the input stream.
   * @see Matrix(Reader)
   * @see #write(Writer)
   */
  public static Matrix read(BufferedReader input) throws java.io.IOException {
    StreamTokenizer tokenizer= new StreamTokenizer(input);

    // Although StreamTokenizer will parse numbers, it doesn't recognize
    // scientific notation (E or D); however, Double.valueOf does.
    // The strategy here is to disable StreamTokenizer's number parsing.
    // We'll only get whitespace delimited words, EOL's and EOF's.
    // These words should all be numbers, for Double.valueOf to parse.

    tokenizer.resetSyntax();
    tokenizer.wordChars(0,255);
    tokenizer.whitespaceChars(0, ' ');
    tokenizer.eolIsSignificant(true);
    java.util.Vector v = new java.util.Vector();

    // Ignore initial empty lines
    while (tokenizer.nextToken() == StreamTokenizer.TT_EOL);
    if (tokenizer.ttype == StreamTokenizer.TT_EOF)
      throw new java.io.IOException("Unexpected EOF on matrix read.");
    do {
      v.addElement(Double.valueOf(tokenizer.sval)); // Read & store 1st row.
    } while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);

    int n = v.size();  // Now we've got the number of columns!
    double row[] = new double[n];
    for (int j=0; j<n; j++)  // extract the elements of the 1st row.
      row[j]=((Double)v.elementAt(j)).doubleValue();
    v.removeAllElements();
    v.addElement(row);  // Start storing rows instead of columns.
    while (tokenizer.nextToken() == StreamTokenizer.TT_WORD) {
      // While non-empty lines
      v.addElement(row = new double[n]);
      int j = 0;
      do {
        if (j >= n) throw new java.io.IOException
          ("Row " + v.size() + " is too long.");
        row[j++] = Double.valueOf(tokenizer.sval).doubleValue();
      } while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
      if (j < n) throw new java.io.IOException
        ("Row " + v.size() + " is too short.");
    }
    int m = v.size();  // Now we've got the number of rows.
    double[][] A = new double[m][];
    v.copyInto(A);  // copy the rows out of the vector
    return new Matrix(A);
  }


  /** 
   * Check if size(A) == size(B) 
   */
  private void checkMatrixDimensions(Matrix B) {
    if (B.m != m || B.n != n) {
      throw new IllegalArgumentException("Matrix dimensions must agree.");
    }
  }

  /**
   * Writes out a matrix. The format can be read via the Matrix(Reader)
   * constructor.
   *
   * @param     w the output Writer
   * @throws    Exception if an error occurs
   * @see       Matrix(Reader)
   * @author    FracPete, taken from old weka.core.Matrix class
   */
  public void write(Writer w) throws Exception {
    w.write("% Rows\tColumns\n");
    w.write("" + getRowDimension() + "\t" + getColumnDimension() + "\n");
    w.write("% Matrix elements\n");
    for(int i = 0; i < getRowDimension(); i++) {
      for(int j = 0; j < getColumnDimension(); j++)
        w.write("" + get(i, j) + "\t");
      w.write("\n");
    }
    w.flush();
  }

  /** 
   * Converts a matrix to a string
   *
   * @return    the converted string
   * @author    FracPete, taken from old weka.core.Matrix class
   */
  public String toString() {
    // Determine the width required for the maximum element,
    // and check for fractional display requirement.
    double maxval = 0;
    boolean fractional = false;
    for (int i = 0; i < getRowDimension(); i++) {
      for (int j = 0; j < getColumnDimension(); j++) {
        double current = get(i, j);
        if (current < 0)
          current *= -11;
        if (current > maxval)
          maxval = current;
        double fract = Math.abs(current - Math.rint(current));
        if (!fractional
            && ((Math.log(fract) / Math.log(10)) >= -2)) {
          fractional = true;
        }
      }
    }
    int width = (int)(Math.log(maxval) / Math.log(10) 
        + (fractional ? 4 : 1));

    StringBuffer text = new StringBuffer();   
    for (int i = 0; i < getRowDimension(); i++) {
      for (int j = 0; j < getColumnDimension(); j++)
        text.append(" ").append(Utils.doubleToString(get(i, j),
              width, (fractional ? 2 : 0)));
      text.append("\n");
    }

    return text.toString();
  } 
  
  /**
   * converts the Matrix into a single line Matlab string: matrix is enclosed 
   * by parentheses, rows are separated by semicolon and single cells by
   * blanks, e.g., [1 2; 3 4].
   * @return      the matrix in Matlab single line format
   */
  public String toMatlab() {
    StringBuffer      result;
    int               i;
    int               n;

    result = new StringBuffer();

    result.append("[");

    for (i = 0; i < getRowDimension(); i++) {
      if (i > 0)
        result.append("; ");
      
      for (n = 0; n < getColumnDimension(); n++) {
        if (n > 0)
          result.append(" ");
        result.append(Double.toString(get(i, n)));
      }
    }
    
    result.append("]");

    return result.toString();
  }

  /**
   * creates a matrix from the given Matlab string.
   * @param matlab  the matrix in matlab format
   * @return        the matrix represented by the given string
   * @see           #toMatlab()
   */
  public static Matrix parseMatlab(String matlab) throws Exception {
    StringTokenizer   tokRow;
    StringTokenizer   tokCol;
    int               rows;
    int               cols;
    Matrix            result;
    String            cells;
    
    // get content
    cells = matlab.substring(
              matlab.indexOf("[") + 1, matlab.indexOf("]")).trim();
    
    // determine dimenions
    tokRow = new StringTokenizer(cells, ";");
    rows   = tokRow.countTokens();
    tokCol = new StringTokenizer(tokRow.nextToken(), " ");
    cols   = tokCol.countTokens();
    
    // fill matrix
    result = new Matrix(rows, cols);
    tokRow = new StringTokenizer(cells, ";");
    rows   = 0;
    while (tokRow.hasMoreTokens()) {
      tokCol = new StringTokenizer(tokRow.nextToken(), " ");
      cols   = 0;
      while (tokCol.hasMoreTokens()) {
        result.set(rows, cols, Double.parseDouble(tokCol.nextToken()));
        cols++;
      }
      rows++;
    }
    
    return result;
  }
  
  /**
   * Main method for testing this class.
   */
  public static void main(String[] args) {
    Matrix        I;
    Matrix        A;
    Matrix        B;

    try {
      // Identity
      System.out.println("\nIdentity\n");
      I = Matrix.identity(3, 5);
      System.out.println("I(3,5)\n" + I);
      
      // basic operations - square
      System.out.println("\nbasic operations - square\n");
      A = Matrix.random(3, 3);
      B = Matrix.random(3, 3);
      System.out.println("A\n" + A);
      System.out.println("B\n" + B);
      System.out.println("A'\n" + A.inverse());
      System.out.println("A^T\n" + A.transpose());
      System.out.println("A+B\n" + A.plus(B));
      System.out.println("A*B\n" + A.times(B));
      System.out.println("X from A*X=B\n" + A.solve(B));

      // basic operations - non square
      System.out.println("\nbasic operations - non square\n");
      A = Matrix.random(2, 3);
      B = Matrix.random(3, 4);
      System.out.println("A\n" + A);
      System.out.println("B\n" + B);
      System.out.println("A*B\n" + A.times(B));

      // sqrt
      System.out.println("\nsqrt (1)\n");
      A = new Matrix(new double[][]{{5,-4,1,0,0},{-4,6,-4,1,0},{1,-4,6,-4,1},{0,1,-4,6,-4},{0,0,1,-4,5}});
      System.out.println("A\n" + A);
      System.out.println("sqrt(A)\n" + A.sqrt());

      // sqrt
      System.out.println("\nsqrt (2)\n");
      A = new Matrix(new double[][]{{7, 10},{15, 22}});
      System.out.println("A\n" + A);
      System.out.println("sqrt(A)\n" + A.sqrt());
      System.out.println("det(A)\n" + A.det() + "\n");

      // eigenvalue decomp.
      System.out.println("\nEigenvalue Decomposition\n");
      EigenvalueDecomposition evd = A.eig();
      System.out.println("[V,D] = eig(A)");
      System.out.println("- V\n" + evd.getV());
      System.out.println("- D\n" + evd.getD());

      // LU decomp.
      System.out.println("\nLU Decomposition\n");
      LUDecomposition lud = A.lu();
      System.out.println("[L,U,P] = lu(A)");
      System.out.println("- L\n" + lud.getL());
      System.out.println("- U\n" + lud.getU());
      System.out.println("- P\n" + Utils.arrayToString(lud.getPivot()) + "\n");

      // regression
      System.out.println("\nRegression\n");
      B = new Matrix(new double[][]{{3},{2}});
      double ridge = 0.5;
      double[] weights = new double[]{0.3, 0.7};
      LinearRegression lr = A.regression(B, ridge);
      System.out.println("A\n" + A);
      System.out.println("B\n" + B);
      System.out.println("ridge = " + ridge + "\n");
      System.out.println("weights = " + Utils.arrayToString(weights) + "\n");
      System.out.println("A.regression(B, ridge)\n" 
          + A.regression(B, ridge) + "\n");
      System.out.println("A.regression(B, weights, ridge)\n" 
          + A.regression(B, weights, ridge) + "\n");

      // writer/reader
      System.out.println("\nWriter/Reader\n");
      StringWriter writer = new StringWriter();
      A.write(writer);
      System.out.println("A.write(Writer)\n" + writer);
      A = new Matrix(new StringReader(writer.toString()));
      System.out.println("A = new Matrix.read(Reader)\n" + A);

      // Matlab
      System.out.println("\nMatlab-Format\n");
      String matlab = "[ 1   2;3 4 ]";
      System.out.println("Matlab: " + matlab);
      System.out.println("from Matlab:\n" + Matrix.parseMatlab(matlab));
      System.out.println("to Matlab:\n" + Matrix.parseMatlab(matlab).toMatlab());
      matlab = "[1 2 3 4;3 4 5 6;7 8 9 10]";
      System.out.println("Matlab: " + matlab);
      System.out.println("from Matlab:\n" + Matrix.parseMatlab(matlab));
      System.out.println("to Matlab:\n" + Matrix.parseMatlab(matlab).toMatlab() + "\n");
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -