// This may look like C code, but it is really -*- C++ -*-
// RTSS --- Railway Total System Simulator
// (c) TAKAGI Ryo (at Prof. SONE's Laboratory, the Univ. of Tokyo.)
// feed_y.hh --- class feed_y calculating Y matrix from bran_node data
// $Id: feed_y.hh,v 2.4 1994/12/27 12:03:47 rt Exp $

#include "matrix.hh"
#include <vector>
#include <stdexcept>


using std :: vector ;



#ifndef ___FEED_Y_HH
#define ___FEED_Y_HH		// こうしておくと2度インクルードしても大丈夫！

// ブランチデータ
struct bran_node
{
  int nfline ;		// このブランチに対応する饋電線番号
  int startnode ;	// ブランチ始点
  double startpos ;
  int endnode ;		// ブランチ終点
  double endpos ;
  double impedance ;	// ブランチインピーダンス
} ;



class _BN_Container
  : private vector < bran_node >
{

public :

  _BN_Container () : vector < bran_node > () {}
  _BN_Container ( _BN_Container const & x ) : vector < bran_node > ( x ) {}
  _BN_Container & operator= ( _BN_Container const & x ) ;
  
  typedef size_type bn_size_type ;
  typedef iterator bn_iterator ;

  bn_iterator bn_begin () { return begin () ; }
  bn_iterator bn_end () { return end () ; }
  bn_size_type bn_size () { return size () ; }
  void bn_push_back ( bran_node x ) { push_back ( x ) ; }

  bran_node & getElement ( bn_size_type i )
  { try { return at ( i ) ; } catch ( std :: out_of_range )
    { cerr << "Error: subscript out of range (_BN_Container)" << endl ;
      exit ( 26 ) ; } }
  
  bran_node const & getElement ( bn_size_type i ) const
  { try { return at ( i ) ; } catch ( std :: out_of_range )
    { cerr << "Error: subscript out of range (_BN_Container)" << endl ;
      exit ( 26 ) ; } }

  void renew () { clear () ; }
  _BN_Container & operator+= ( _BN_Container const & ) ;
  _BN_Container & operator+= ( bran_node const & ) ;

} ;

  

// feedline クラスの提供する情報によりＹ行列を作成
class feed_y
  : public _BN_Container
{

  matrix hh ;		// 節点−枝接続行列, h(int) により作成
  matrix ht ;
  diagmatrix dy ;	// ブランチアドミタンス行列, diag_y() により作成

  matrix & h ( int ) ;		// 節点−枝接続行列, 引数: ncss, y(int) が呼ぶ
  diagmatrix & diag_y () ;	// ブランチアドミタンス行列

public :

  feed_y () : _BN_Container () {}		// default constructor
  ~feed_y () {}					// destructor
  feed_y ( feed_y const & x ) ;			// X(X&)
  feed_y & operator= ( feed_y const & ) ;	// 代入
  int branch () { return bn_size () ; }	// ブランチ数を返す

  matrix & h () { hh . transpose ( ht ) ; return ht ; }
	// hh の転置: y(int) の後呼ぶこと

  diagmatrix & branchadmittance () { return dy ; }
	// ブランチアドミタンス行列: y(int) の後呼ぶこと

  void y ( int , matrix & ) ;	// Ｙ行列, 引数: ncss, ymtx

} ;

#endif /* ! ___FEED_Y_HH */
