Hist.java

/*
 * $Id: Hist.java,v 1.23 2008/03/26 14:31:23 koga Exp $
 * 
 * Copyright (C) 2004 Koga Laboratory. All rights reserved.
 */
package org.mklab.tool.matrix;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.IntMatrix;
import org.mklab.nfc.scalar.DoubleNumber;


/**
 * ヒストグラムを描画するためのデータを求めるクラスです。
 * 
 * <p> Data for histograms-plot
 * 
 * @author koga
 * @version $Revision: 1.23 $
 * @see org.mklab.tool.matrix.Bar
 */
public class Hist {

  /**
   * もし<code>y</code>がベクトルなら、<code>y</code>の最小値と 最大値の間を10分割して、ヒストグラムを描画するためのデータを返します。
   * 
   * @param Y データ
   * @return ヒストグラムを描画するためのデータ (data for histgrams-plot)
   */
  public static List<DoubleMatrix> hist(DoubleMatrix Y) {
    return histRowWise(Y.reshape(1, Y.getRowSize() * Y.getColumnSize()));
  }

  /**
   * <code>size</code>分割にします。
   * 
   * @param Y データ
   * @param size 分割数
   * @return ヒストグラムを描画するためのデータ (data for histgrams-plot)
   */
  public static List<DoubleMatrix> hist(DoubleMatrix Y, int size) {
    return histRowWise(Y.reshape(1, Y.getRowSize() * Y.getColumnSize()), size);
  }

  /**
   * もし<code>y</code>が行列なら、列毎に計算します。
   * 
   * @param Y_ データ
   * @return ヒストグラムを描画するためのデータ (data for histgrams-plot)
   */
  public static List<DoubleMatrix> histColumnWise(DoubleMatrix Y_) {
    int n = 10;
    return histColumnWise(Y_, n);
  }

  /**
   * <code>size</code>分割にします。
   * 
   * @param Y_ データ
   * @param size 分割数
   * @return ヒストグラムを描画するためのデータ (data for histgrams-plot)
   */
  public static List<DoubleMatrix> histColumnWise(DoubleMatrix Y_, int size) {
    DoubleMatrix Y;
    if (Y_.getRowSize() == 1 && Y_.getColumnSize() != 1) {
      Y = Makecolv.makecolv(Y_);
    } else {
      Y = Y_;
    }

    DoubleMatrix X = Y.createZero(size, Y.getColumnSize());
    DoubleMatrix N = Y.createZero(size, Y.getColumnSize());
    for (int i = 1; i <= Y.getColumnSize(); i++) {
      DoubleMatrix y = Y.getSubMatrix(1, Y.getRowSize(), i, i);

      DoubleNumber y_min = y.min();
      DoubleNumber y_max = y.max();
      DoubleNumber bw = y_max.subtract(y_min).divide(size);
      DoubleMatrix x = new DoubleMatrix(IntMatrix.series(0, size)).multiply(bw).addElementWise(y_min).transpose();
      x.setElement(x.length(), y_max);

      DoubleMatrix nn = Y.createZero(size + 1, 1);
      for (int j = 2; j <= size + 1; j++) {
        nn.setElement(j, 1, y.compareElementWise(".<=", x.getElement(j)).find().length()); //$NON-NLS-1$
      }

      N.setColumnVector(i, nn.getSubMatrix(2, size + 1, 1, 1).subtract(nn.getSubMatrix(1, size, 1, 1)));
      X.setColumnVector(i, x.getSubVector(1, x.length() - 1).addElementWise(bw.divide(2)));
    }

    if (Y_.getRowSize() == 1 && Y_.getColumnSize() != 1) {
      N = N.transpose();
      X = X.transpose();
    }

    return new ArrayList<>(Arrays.asList(new DoubleMatrix[] {N, X}));
  }

  /**
   * もし<code>y</code>が行列なら、行毎に計算します。
   * 
   * @param Y データ
   * @return ヒストグラムを描画するためのデータ (data for histgrams-plot)
   */
  public static List<DoubleMatrix> histRowWise(DoubleMatrix Y) {
    List<DoubleMatrix> tmp = histColumnWise(Y.transpose());
    DoubleMatrix N = tmp.get(0);
    DoubleMatrix X = tmp.get(1);
    N = N.transpose();
    X = X.transpose();
    return new ArrayList<>(Arrays.asList(new DoubleMatrix[] {N, X}));
  }

  /**
   * <code>size</code>分割にします。
   * 
   * @param Y データ
   * @param size 分割数
   * @return ヒストグラムを描画するためのデータ (data for histgrams-plot)
   */
  public static List<DoubleMatrix> histRowWise(DoubleMatrix Y, int size) {
    List<DoubleMatrix> tmp = histColumnWise(Y.transpose(), size);
    DoubleMatrix N = tmp.get(0);
    DoubleMatrix X = tmp.get(1);
    N = N.transpose();
    X = X.transpose();
    return new ArrayList<>(Arrays.asList(new DoubleMatrix[] {N, X}));
  }

}