Erf.java

/*
 * $Id: Erf.java,v 1.21 2008/07/16 15:40:00 koga Exp $
 * 
 * Copyright (C) 2004 Koga Laboratory. All rights reserved.
 */
package org.mklab.tool.matrix;

import org.mklab.nfc.matrix.DoubleMatrix;


/**
 * 誤差関数を計算するクラスです。
 * 
 * <p> Error function
 * 
 * @author koga
 * @version $Revision: 1.21 $
 * @see org.mklab.tool.matrix.Gammac
 * @see org.mklab.tool.matrix.Gammaf
 * @see org.mklab.tool.matrix.Gammai
 * @see org.mklab.tool.matrix.Inverf
 */
public class Erf {

  /**
   * ベクトル<code>x</code>の成分の誤差関数を計算します。
   * 
   * <p> 誤差関数は、正規分布の確率分布関数を <code>0</code>から<code>X</code>まで積分した
   * 
   * <pre><code> erf(x) = 2/sqrt(PI) integral(0,x) exp(-t&circ;2) </code></pre>
   * 
   * です。
   * 
   * @param x1_ データ
   * @return 誤差関数 (error function)
   */
  public static DoubleMatrix erf(DoubleMatrix x1_) {
    DoubleMatrix x1 = x1_.createZero(x1_.getRowSize(), x1_.getColumnSize());
    DoubleMatrix x2 = x1_;

    return erf(x1, x2);
  }

  /**
   * <code>x1</code>から<code>x2</code>まで積分した誤差関数
   * 
   * <pre><code> erf(x1,x2) = 2/sqrt(PI) integral(x1,x2) exp(-t&circ;2) </code></pre>
   * 
   * の値を返します。 <code>x1</code>と<code>x2</code>が行列の場合、全ての成分について 関数が評価されます。
   * 
   * @param x1_ データ1
   * @param x2_ データ2
   * @return 誤差関数 (error function)
   */
  public static DoubleMatrix erf(DoubleMatrix x1_, DoubleMatrix x2_) {
    DoubleMatrix x1 = x1_;
    DoubleMatrix x2 = x2_;

    int m1 = x1.getRowSize();
    int n1 = x1.getColumnSize();
    int m2 = x2.getRowSize();
    int n2 = x2.getColumnSize();

    if (m1 != m2 || n1 != n2) {
      if (m1 == 1 && n1 == 1) {
        x1 = x1.createOnes(x2.getRowSize(), x2.getColumnSize()).multiply(x1.getElement(1, 1));
      } else if (m2 == 1 && n2 == 1) {
        x2 = x1.createOnes(x1.getRowSize(), x1.getColumnSize()).multiply(x2.getElement(1, 1));
      } else {
        throw new IllegalArgumentException(Messages.getString("Erf.0")); //$NON-NLS-1$
      }
    }

    DoubleMatrix x = x1.appendRight(x2);
    DoubleMatrix er = x.signumElementWise().multiply(Gammaf.gammaf(new DoubleMatrix(new double[] {0.5}), x.powerElementWise(2)));
    int n = x.getColumnSize() / 2;
    er = er.getSubMatrix(1, er.getRowSize(), n + 1, 2 * n).subtract(er.getSubMatrix(1, er.getRowSize(), 1, n));
    return er;
  }

}