Beispiel #1
0
  public void random3Partition(DataSet p1, DataSet p2, DataSet p3, double f1, double f2) {
    int size1 = (int) (f1 * x.rows());
    int size2 = (int) (f2 * x.rows());
    int size3 = x.rows() - size1 - size2;
    Random random = new Random(new Date().getTime());

    p1.x = newFromTemplate(p1.x, size1, x.columns());
    p1.y = new double[size1];
    p2.x = newFromTemplate(p2.x, size2, x.columns());
    p2.y = new double[size2];
    p3.x = newFromTemplate(p3.x, size3, x.columns());
    p3.y = new double[size3];

    // FIXME: Verify the uniformity of the partitioning scheme.
    int r1 = 0;
    int r2 = 0;
    int r3 = 0;
    for (int r = 0; r < x.rows(); r++) {
      double p = random.nextDouble();
      if (p < f1 && r1 < size1) {
        p1.copyInstanceTo(r1, this, r);
        r1++;
      } else if (p < f1 + f2 && r2 < size2) {
        p2.copyInstanceTo(r2, this, r);
        r2++;
      } else if (r3 < size3) {
        p3.copyInstanceTo(r3, this, r);
        r3++;
      } else {
        r--;
      }
    }
  }
  /**
   * Splits recursively the points of the graph while the value of the best cut found is less of a
   * specified limit (the alpha star factor).
   *
   * @param W the weight matrix of the graph
   * @param alpha_star the alpha star factor
   * @return an array of sets of points (partitions)
   */
  protected int[][] partition(DoubleMatrix2D W, double alpha_star) {
    numPartitions++;

    // System.out.println("!");

    // If the graph contains only one point
    if (W.columns() == 1) {
      int[][] p = new int[1][1];
      p[0][0] = 0;
      return p;
      // Otherwise
    } else {
      // Computes the best cut
      int[][] cut = bestCut(W);
      // Computes the value of the found cut
      double cutVal = Ncut(W, cut[0], cut[1], null);

      // System.out.println("cutVal = "+cutVal +"\tnumPartitions = "+numPartitions);

      // If the value is less than alpha star
      if (cutVal < alpha_star && numPartitions < 2) {

        // Recursively partitions the first one found ...
        DoubleMatrix2D W0 = W.viewSelection(cut[0], cut[0]);
        int[][] p0 = partition(W0, alpha_star);
        // ... and the second one
        DoubleMatrix2D W1 = W.viewSelection(cut[1], cut[1]);
        int[][] p1 = partition(W1, alpha_star);

        // Merges the partitions found in the previous recursive steps
        int[][] p = new int[p0.length + p1.length][];
        for (int i = 0; i < p0.length; i++) {
          p[i] = new int[p0[i].length];
          for (int j = 0; j < p0[i].length; j++) p[i][j] = cut[0][p0[i][j]];
        }

        for (int i = 0; i < p1.length; i++) {
          p[i + p0.length] = new int[p1[i].length];
          for (int j = 0; j < p1[i].length; j++) p[i + p0.length][j] = cut[1][p1[i][j]];
        }

        return p;
      } else {
        // Otherwise returns the partitions found in current step
        // w/o recursive invocation
        int[][] p = new int[1][W.columns()];
        for (int i = 0; i < p[0].length; i++) p[0][i] = i;
        return p;
      }
    }
  }
Beispiel #3
0
  /**
   * Save factorisation machine in a compressed, human readable file.
   *
   * @param out output
   * @throws IOException when I/O error
   */
  public void save(OutputStream out) throws IOException {
    int N = m.rows();
    int K = m.columns();
    try (ZipOutputStream zip = new ZipOutputStream(out)) {
      zip.putNextEntry(new ZipEntry("info"));
      PrintStream ps = new PrintStream(zip);
      ps.println(N);
      ps.println(K);
      ps.flush();
      zip.closeEntry();

      zip.putNextEntry(new ZipEntry("b"));
      ps = new PrintStream(zip);
      ps.println(b);
      ps.flush();
      zip.closeEntry();

      zip.putNextEntry(new ZipEntry("w"));
      saveDenseDoubleMatrix1D(zip, w);
      zip.closeEntry();

      zip.putNextEntry(new ZipEntry("m"));
      saveDenseDoubleMatrix2D(zip, m);
      zip.closeEntry();
    }
  }
  @Override
  public DoubleMatrix getEigenvectors() {
    DoubleMatrix2D V = myDecomposition.getV();
    int nrows = V.rows();
    int ncols = V.columns();
    DoubleMatrix dm = DoubleMatrixFactory.DEFAULT.make(nrows, ncols);

    for (int r = 0; r < nrows; r++) {
      for (int c = 0; c < ncols; c++) {
        dm.set(r, c, V.getQuick(r, c));
      }
    }

    return dm;
  }
Beispiel #5
0
  static boolean computeLogMi(
      FeatureGenerator featureGen,
      double lambda[],
      DoubleMatrix2D Mi_YY,
      DoubleMatrix1D Ri_Y,
      boolean takeExp,
      boolean reuseM,
      boolean initMDone) {

    if (reuseM && initMDone) {
      Mi_YY = null;
    } else initMDone = false;
    if (Mi_YY != null) Mi_YY.assign(0);
    Ri_Y.assign(0);
    while (featureGen.hasNext()) {
      Feature feature = featureGen.next();
      int f = feature.index();
      int yp = feature.y();
      int yprev = feature.yprev();
      float val = feature.value();
      //	    System.out.println(feature.toString());

      if (yprev < 0) {
        // this is a single state feature.
        double oldVal = Ri_Y.getQuick(yp);
        Ri_Y.setQuick(yp, oldVal + lambda[f] * val);
      } else if (Mi_YY != null) {
        Mi_YY.setQuick(yprev, yp, Mi_YY.getQuick(yprev, yp) + lambda[f] * val);
        initMDone = true;
      }
    }
    if (takeExp) {
      for (int r = Ri_Y.size() - 1; r >= 0; r--) {
        Ri_Y.setQuick(r, expE(Ri_Y.getQuick(r)));
        if (Mi_YY != null)
          for (int c = Mi_YY.columns() - 1; c >= 0; c--) {
            Mi_YY.setQuick(r, c, expE(Mi_YY.getQuick(r, c)));
          }
      }
    }
    return initMDone;
  }
Beispiel #6
0
  /**
   * Predict the value of an instance.
   *
   * @param x instance
   * @return value of prediction
   */
  public double prediction(I x) {
    double pred = b;

    DoubleMatrix1D xm = new DenseDoubleMatrix1D(m.columns());
    pred +=
        x.operate(
            (i, xi) -> {
              double wi = w.getQuick(i);
              DoubleMatrix1D mi = m.viewRow(i);

              xm.assign(mi, (r, s) -> r + xi * s);

              return xi * wi - 0.5 * xi * xi * mi.zDotProduct(mi);
            },
            (v1, v2) -> v1 + v2);

    pred += 0.5 * xm.zDotProduct(xm);

    return pred;
  }
  /**
   * Constructs a new time series data contains for the given row-major data array and the given
   * list of variables. Each row of the data, data[i], contains a measured for each variable (in
   * order) for a particular time. The series of times is in increasing order.
   */
  public TimeSeriesData(DoubleMatrix2D matrix, List<String> varNames) {
    if (matrix == null) {
      throw new NullPointerException("Data must not be null.");
    }

    if (varNames == null) {
      throw new NullPointerException("Variables must not be null.");
    }
    for (int i = 0; i < varNames.size(); i++) {
      if (varNames.get(i) == null) {
        throw new NullPointerException("Variable at index " + i + "is null.");
      }
    }
    this.data2 = matrix;
    if (varNames.size() != matrix.columns()) {
      throw new IllegalArgumentException(
          "Number of columns in the data " + "must match the number of variables.");
    }
    this.varNames = varNames;
    this.name = "Time Series Data";
  }
  /**
   * Constructs and returns a new eigenvalue decomposition object; The decomposed matrices can be
   * retrieved via instance methods of the returned decomposition object. Checks for symmetry, then
   * constructs the eigenvalue decomposition.
   *
   * @param A A square matrix.
   * @return A decomposition object to access <tt>D</tt> and <tt>V</tt>.
   * @throws IllegalArgumentException if <tt>A</tt> is not square.
   */
  public EigenvalueDecomposition(DoubleMatrix2D A) {
    Property.DEFAULT.checkSquare(A);

    n = A.columns();
    V = new double[n][n];
    d = new double[n];
    e = new double[n];

    issymmetric = Property.DEFAULT.isSymmetric(A);

    if (issymmetric) {
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          V[i][j] = A.getQuick(i, j);
        }
      }

      // Tridiagonalize.
      tred2();

      // Diagonalize.
      tql2();

    } else {
      H = new double[n][n];
      ort = new double[n];

      for (int j = 0; j < n; j++) {
        for (int i = 0; i < n; i++) {
          H[i][j] = A.getQuick(i, j);
        }
      }

      // Reduce to Hessenberg form.
      orthes();

      // Reduce Hessenberg to real Schur form.
      hqr2();
    }
  }
  /**
   * Returns the best cut of a graph w.r.t. the degree of dissimilarity between points of different
   * partitions and the degree of similarity between points of the same partition.
   *
   * @param W the weight matrix of the graph
   * @return an array of two elements, each of these contains the points of a partition
   */
  protected static int[][] bestCut(DoubleMatrix2D W) {
    int n = W.columns();
    // Builds the diagonal matrices D and D^(-1/2) (represented as their diagonals)
    DoubleMatrix1D d = DoubleFactory1D.dense.make(n);
    DoubleMatrix1D d_minus_1_2 = DoubleFactory1D.dense.make(n);
    for (int i = 0; i < n; i++) {
      double d_i = W.viewRow(i).zSum();
      d.set(i, d_i);
      d_minus_1_2.set(i, 1 / Math.sqrt(d_i));
    }
    DoubleMatrix2D D = DoubleFactory2D.sparse.diagonal(d);

    // System.out.println("DoubleMatrix2D :\n"+D.toString());

    DoubleMatrix2D X = D.copy();

    // System.out.println("DoubleMatrix2D copy :\n"+X.toString());

    // X = D^(-1/2) * (D - W) * D^(-1/2)
    X.assign(W, Functions.minus);
    // System.out.println("DoubleMatrix2D X: (D-W) :\n"+X.toString());
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        X.set(i, j, X.get(i, j) * d_minus_1_2.get(i) * d_minus_1_2.get(j));

    // Computes the eigenvalues and the eigenvectors of X
    EigenvalueDecomposition e = new EigenvalueDecomposition(X);
    DoubleMatrix1D lambda = e.getRealEigenvalues();

    // Selects the eigenvector z_2 associated with the second smallest eigenvalue
    // Creates a map that contains the pairs <index, eigenvalue>
    AbstractIntDoubleMap map = new OpenIntDoubleHashMap(n);
    for (int i = 0; i < n; i++) map.put(i, Math.abs(lambda.get(i)));
    IntArrayList list = new IntArrayList();
    // Sorts the map on the value
    map.keysSortedByValue(list);
    // Gets the index of the second smallest element
    int i_2 = list.get(1);

    // y_2 = D^(-1/2) * z_2
    DoubleMatrix1D y_2 = e.getV().viewColumn(i_2).copy();
    y_2.assign(d_minus_1_2, Functions.mult);

    // Creates a map that contains the pairs <i, y_2[i]>
    map.clear();
    for (int i = 0; i < n; i++) map.put(i, y_2.get(i));
    // Sorts the map on the value
    map.keysSortedByValue(list);
    // Search the element in the map previuosly ordered that minimizes the cut
    // of the partition
    double best_cut = Double.POSITIVE_INFINITY;
    int[][] partition = new int[2][];

    // The array v contains all the elements of the graph ordered by their
    // projection on vector y_2
    int[] v = list.elements();
    // For each admissible splitting point i
    for (int i = 1; i < n; i++) {
      // The array a contains all the elements that have a projection on vector
      // y_2 less or equal to the one of i-th element
      // The array b contains the remaining elements
      int[] a = new int[i];
      int[] b = new int[n - i];
      System.arraycopy(v, 0, a, 0, i);
      System.arraycopy(v, i, b, 0, n - i);
      double cut = Ncut(W, a, b, v);
      if (cut < best_cut) {
        best_cut = cut;
        partition[0] = a;
        partition[1] = b;
      }
    }

    // System.out.println("Partition:");
    // UtilsJS.printMatrix(partition);

    return partition;
  }
  /**
   * Gibt die Lösung x des Gleichungssystems zurück: nur eindeutige (d.h. parameterunabhängige xi)
   * werden zurückgegeben. index 0: Wert = 0 bedeutet xi unbestimmt, Wert = 1 bedeutet xi bestimmt
   * index 1: eigentlicher Wert (nur wenn xi bestimmt, dh index 0 = 1, sonst Wert 0)
   */
  public final double[][] solve() throws ArithmeticException {

    // --------------------------------------------------------------------------
    // EIGENTLICHER SOLVER für bestimmte Lösungsvariablen in unbestimmen Systemen
    // --------------------------------------------------------------------------

    int gebrauchteUnbestParam = 0;
    x =
        new double[A.columns()]
            [2 + anzUnbestParam]; // Status 1 (bestimmt), kN, alpha, beta (Parameter)

    int z = A.rows() - 1; // Zeilenvariable, beginnt zuunterst

    // Gleichungen mit lauter Nullen
    while (R.viewRow(z).cardinality() == 0 // nachfolgende Tests massgebend, dieser jedoch schnell
        || (Fkt.max(R.viewRow(z).toArray()) < TOL && Fkt.min(R.viewRow(z).toArray()) > -TOL)) {
      double cwert;
      if (z < c.rows()) cwert = c.get(z, 0);
      else cwert = 0;
      if (Math.abs(cwert) > TOL) {
        System.out.println("widersprüchliche Gleichungen im System! Zeile " + z);
        throw new ArithmeticException("Widerspruch im Gleichungssystem!");
      }
      z--;
      if (z <= 0) {
        System.out.println("lauter Nullen im GLS");
        break;
      }
    }

    // Verarbeiten der Gleichungen (von unten her)
    for (z = z; z >= 0; z--) {
      // finde erste nicht-Null in Zeile (Pivot)
      int p = -1; // Pivot: erste Zahl welche nicht null ist
      pivotfinden:
      for (int i = 0; i < R.columns(); i++) {
        if (Math.abs(R.get(z, i))
            > TOL) { // Versuch, numerische Probleme (Überbestimmtheit) zu vermeiden
          p = i;
          break pivotfinden;
        }
      }

      // Fall Kein Pivot gefunden (d.h. linker Teil der Gleichung aus lauter Nullen)
      if (p < 0) {
        if (debug) System.out.println("Warnung: kein Pivot gefunden in Zeile " + z);
        // Kontrolle, ob rechte Seite (c) auch null --> ok, sonst Widerspruch im GLS
        if (Math.abs(c.get(z, 0)) > TOL) {
          System.out.println("widersprüchliche Gleichungen im System! Zeile " + z);
          throw new ArithmeticException("Widerspruch im Gleichungssystem!");
        } else {
          if (debug)
            System.out.println("Entwarnung: Zeile " + z + " besteht aus lauter Nullen (ok)");
          continue;
        }
      }

      // kontrollieren, ob es in der Gleichung (Zeile) eine neue Unbestimmte Variable (i.d.R. Pivot)
      // hat.
      boolean alleVarBestimmt = true;
      int effPivot = p; // effektiver Pivot (1. Unbestimmte Variable der Zeile), i.d.R. Pivot
      for (int i = p; i < R.columns(); i++) {
        if (x[i][0] == 0 && Math.abs(R.viewRow(z).get(i)) > TOL) {
          alleVarBestimmt = false;
          effPivot = i; // i.d.R. effPivot=p, aber nicht immer.
          break;
        }
      }

      if (alleVarBestimmt) { // alle Variablen (inkl.Pivot) schon bestimmt!
        // CHECKEN, ob (Zeile "+z+") nicht widersprüchlich
        double[] kontrolle = new double[1 + anzUnbestParam];
        for (int j = 0; j < kontrolle.length; j++) kontrolle[j] = 0;
        for (int i = p; i < R.columns(); i++) {
          for (int j = 0; j < kontrolle.length; j++) {
            kontrolle[j] += R.viewRow(z).get(i) * x[i][j + 1];
          }
        }
        kontrolle[0] -= c.get(z, 0);

        // TODO TESTEN!
        boolean alleParamNull = true;
        int bekParam = -1; // Parameter der aus der Gleichung bestimmt werden kann.
        for (int j = kontrolle.length - 1; j > 0; j--) {
          if (Math.abs(kontrolle[j]) > TOL) {
            alleParamNull = false;
            if (bekParam < 0) bekParam = j;
          }
        }
        // Überprüfen, ob Gleichung widersprüchlich ist
        if (alleParamNull) { // TODO ev. nochmals prüfen ob alle 0 mit geringerer Toleranz (Problem
                             // fastNull*Param ≠ 0 könnte bedeuten dass Param = 0). Zumindestens
                             // wenn noch Parameter zu vergeben.
          double obnull = Math.abs(kontrolle[0]);
          if (obnull > TOL) {
            System.out.println("");
            System.out.println(
                "Widerspruch im Gleichungssystem! (Zeile "
                    + z
                    + ") "
                    + obnull
                    + " ungleich 0"); // TODO: URSPRÜNGLICH ZEILE (piv) ANGEBEN!
            System.out.println("eventuell numerisches Problem");
            throw new ArithmeticException("Widerspruch im Gleichungssystem!");
          } else continue; // nächste Gleichung
        }
        // else
        // Ein schon vergebener Parameter kann ausgerechnet werden

        // Schlaufe über bisherige Lösung
        assert bekParam > 0;
        for (int xi = 0; xi < x.length; xi++) {
          double faktor = x[xi][1 + bekParam];
          if (Math.abs(faktor) < TOL) continue;
          // Einsetzen
          assert x[xi][0] > 0; // bestimmt
          for (int j = 0; j < kontrolle.length; j++) {
            if (j != bekParam) {
              x[xi][j + 1] += -kontrolle[j] * faktor / kontrolle[bekParam];
            }
          }
        }
        for (int xi = 0; xi < x.length; xi++) {
          // Parameter nachrutschen
          if (bekParam < anzUnbestParam) { // d.h. nicht der letzte zu vergebende Parameter.
            for (int j = bekParam; j < anzUnbestParam; j++) {
              x[xi][j + 1] = x[xi][j + 2];
              x[xi][j + 2] = 0;
            }
          } else x[xi][bekParam + 1] = 0;
        }
        if (debug)
          System.err.println(
              "VORSICHT, wenig GETESTETES Modul des Solvers im Einsatz."); // TODO Warnung
                                                                           // entfernen, da
                                                                           // vermutlich i.O.
        gebrauchteUnbestParam--;
      }

      // Normalfall, unbestimmter (effektiver) Pivot vorhanden
      else {

        // unbekannte
        x[effPivot][1] = c.get(z, 0) / R.viewRow(z).get(effPivot);
        for (int i = R.columns() - 1; i >= p; i--) { // R.Spalten, da dies AnzUnbek x entspricht
          if (i == effPivot) continue;
          if (x[i][0] == 0) { // unbestimmt, aber nicht Pivot
            if (Math.abs(R.viewRow(z).get(i)) > TOL) { // TODO testen!!!
              if (gebrauchteUnbestParam >= anzUnbestParam) {
                System.err.println(
                    "Programmfehler in solver: gebrauchteUnbestParam >= anzUnbestParam");
                throw new AssertionError(
                    "Programmfehler in solver: gebrauchteUnbestParam >= anzUnbestParam");
              }
              x[i][gebrauchteUnbestParam + 2] = 1; // neuer Parameter (alpha, beta) setzen
              x[i][0] = 1; // bestimmt (auch wenn von Parameter abhängig).

              gebrauchteUnbestParam++;
            }
          }

          x[effPivot][1] += -R.viewRow(z).get(i) * x[i][1] / R.viewRow(z).get(effPivot);
          for (int j = 0; j < gebrauchteUnbestParam; j++) {
            x[effPivot][2 + j] += -R.viewRow(z).get(i) * x[i][2 + j] / R.viewRow(z).get(effPivot);
          }
        }
        x[effPivot][0] = 1;
      }
    }

    if (debug) {
      System.out.println("");
      for (int i = 0; i < x.length; i++) {
        System.out.print("x" + i + " = " + Fkt.nf(x[i][1], 3));
        for (int j = 2; j < x[i].length; j++) {
          System.out.print(", P" + (j - 1) + " = " + Fkt.nf(x[i][j], 3));
        }
        System.out.println("");
      }
    }

    // ------------------
    // Lösung zurückgeben
    // ------------------

    // Lösung x: nur eindeutige (d.h. parameterunabhängige xi) werden zurückgegeben
    // index 0: Wert = 0 bedeutet xi unbestimmt,  Wert = 1 bedeutet xi bestimmt
    // index 1: eigentlicher Wert (nur wenn xi bestimmt, dh index 0 = 1, sonst Wert 0)
    xLsg = new double[R.columns()][2];

    for (int i = 0; i < x.length; i++) {
      boolean bestimmt;
      if (x[i][0] > 0) {
        bestimmt = true;
        // schauen, ob Lösungsvariable xi bestimmt, dh unabhängig von überzähligen Parametern
        for (int j = 2; j < x[i].length; j++) {
          if (Math.abs(x[i][j]) > TOL) bestimmt = false;
        }
      } else bestimmt = false;

      if (bestimmt) {
        xLsg[i][0] = 1;
        xLsg[i][1] = x[i][1];
      } else xLsg[i][0] = 0;
    }

    solved = true;
    return xLsg;
  }