MultiplexerGroup.java

/*
 * Created on 2007/08/03
 * Copyright (C) 2007 Koga Laboratory. All rights reserved.
 *
 */
package org.mklab.tool.control.system.math;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.RealNumericalScalar;


/**
 * 多重器のグループを表すクラスです。
 * 
 * @author Koga Laboratory
 * @version $Revision: 1.2 $, 2007/08/03
  * @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 class MultiplexerGroup<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>> {

  /** グループに属する多重器 */
  private Map<Integer, Multiplexer<RS,RM,CS,CM>> multiplexers = new TreeMap<>();

  /**
   * 多重器をグループに追加します。
   * 
   * @param multiplexer グループに追加する多重器
   */
  @SuppressWarnings("boxing")
  public void add(final Multiplexer<RS,RM,CS,CM> multiplexer) {
    this.multiplexers.put(multiplexer.getInputNumber(), multiplexer);
  }

  /**
   * グループに属する多重器を返します。
   * 
   * @return グループに属する多重器
   */
  public List<Multiplexer<RS,RM,CS,CM>> getMultiplexers() {
    return new ArrayList<>(this.multiplexers.values());
  }

  /**
   * 指定された多重器をグループから削除します。
   * 
   * @param multiplexer グループから削除する多重器
   */
  @SuppressWarnings("boxing")
  public void remove(final Multiplexer<RS,RM,CS,CM> multiplexer) {
    this.multiplexers.remove(multiplexer.getInputNumber());
  }

  /**
   * グループ内の多重器の出力ベクトル内でのオフセットが決定されているか判定します。
   * 
   * @return グループ内の多重器の出力ベクトル内でのオフセットが決定されていればtrue、そうでなければfalse
   */
  private boolean isOffsetDefined() {
    for (final Multiplexer<RS,RM,CS,CM> mux : new ArrayList<>(this.multiplexers.values())) {
      if (mux.getInputSize() == -1) {
        return false;
      }
    }

    return true;
  }

  /**
   * グループに属する多重器の入力数の変化に対応して、各多重器の出力ベクトル内でのオフセットを変更します。
   */
  public void multiplexerChanged() {
    if (isOffsetDefined() == false) {
      return;
    }

    for (final Multiplexer<RS,RM,CS,CM> multiplexer : new ArrayList<>(this.multiplexers.values())) {
      multiplexer.setOffset(getOffset(multiplexer));
    }
  }

  /**
   * 多重器の出力ベクトル内でのオフセットを返します。
   * 
   * @param multiplexer 対象となる多重器
   * @return 多重器の出力ベクトル内でのオフセット
   */
  public int getOffset(final Multiplexer<RS,RM,CS,CM> multiplexer) {
    if (this.multiplexers.containsValue(multiplexer) == false) {
      return -1;
    }

    int offset = 0;
    for (final Multiplexer<RS,RM,CS,CM> mux : new ArrayList<>(this.multiplexers.values())) {
      if (mux == multiplexer) {
        break;
      }
      if (mux.getInputSize() == -1) {
        return -1;
      }

      offset += mux.getInputSize();
    }
    return offset;
  }
}