Deconv.java

/*
 * $Id: Deconv.java,v 1.18 2008/07/16 15:40:00 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.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.RealNumericalScalar;
import org.mklab.tool.signal.Filter;


/**
 * 逆畳み込み(多項式の商と余)を求めるクラスです。
 * 
 * <p> Deconvolution
 * 
 * @author koga
 * @version $Revision: 1.18 $
 * @see org.mklab.tool.matrix.Conv
 */
public class Deconv {

  /**
   * ベクトル<code>b</code>のベクトル<code>a</code>による逆畳み込み(多項式の商と余)を返します。
   * 
   * <pre><code> b = conv(q, a) + r </code></pre>
   * 
   * を満たす、商<code>q</code>と余り<code>r</code>が返されます。
   * 
   * @param b 割られる数
   * @param a 割る数
   * @return {q, r} 逆畳み込み(多項式の商と余) deconvolution
   */
  public static List<DoubleMatrix> deconv(DoubleMatrix b, DoubleMatrix a) {
    int nb = b.length();
    int na = a.length();

    DoubleMatrix q, r;
    if (na > nb) {
      q = a.createZero(1, 1);
      r = b;
      return new ArrayList<>(Arrays.asList(new DoubleMatrix[] {q, r}));
    }

    if (a.getElement(1).isZero()) {
      throw new IllegalArgumentException(Messages.getString("Deconv.0")); //$NON-NLS-1$
    }

    List<DoubleMatrix> tmp = Filter.filter(b, a, a.createUnit(1).appendRight(a.createZero(1, nb - na)));
    q = tmp.get(0);

    if (b.getRowSize() != 1) {
      q = Makecolv.makecolv(q);
    }

    r = b.subtract(Conv.conv(q, a));
    return new ArrayList<>(Arrays.asList(new DoubleMatrix[] {q, r}));
  }

  /**
   * ベクトル<code>b</code>のベクトル<code>a</code>による逆畳み込み(多項式の商と余)を返します。
   * 
   * <pre><code> b = conv(q, a) + r </code></pre>
   * 
   * を満たす、商<code>q</code>と余り<code>r</code>が返されます。
   * 
   * @param b 割られる数
   * @param a 割る数
   * @return {q, r} 逆畳み込み(多項式の商と余) deconvolution
   * @param <RS> type of real scalar
   * @param <RM> type of real matrix
   * @param <CS> type of complex scalar
   * @param <CM> type of complex matrix
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> List<RM> deconv(
      RM b, RM a) {
    int nb = b.length();
    int na = a.length();

    RM q, r;
    if (na > nb) {
      q = a.createZero(1, 1);
      r = b;
      List<RM> qr = new ArrayList<>();
      qr.add(q);
      qr.add(r);
      return qr;
    }

    if (a.getElement(1).isZero()) {
      throw new IllegalArgumentException(Messages.getString("Deconv.0")); //$NON-NLS-1$
    }

    List<RM> tmp = Filter.filter(b, a, a.createUnit(1).appendRight(a.createZero(1, nb - na)));
    q = tmp.get(0);

    if (b.getRowSize() != 1) {
      q = Makecolv.makecolv(q);
    }

    r = b.subtract(Conv.conv(q, a));

    List<RM> qr = new ArrayList<>();
    qr.add(q);
    qr.add(r);
    return qr;
  }

}