⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 model_graph.cpp

📁 《无线通信系统仿真——c++使用模型》这本书的源代码
💻 CPP
字号:
//
//  File = model_graph.cpp
//

#include <stdlib.h>
#include <fstream>
#include <string.h>
#include "parmfile.h"
#include "model_graph.h"
extern ParmFile ParmInput;
extern ofstream *DebugFile;

//========================================================================

ModelGraph::ModelGraph(PracSimModel* owning_model)
{
   Max_Signals = 50;
   Owning_Model = owning_model;

   Model_Is_Multirate = false;
   Model_Is_Constant_Interval = false;

   Delta_Delay = new std::vector<double>;
   Vertex_Is_Input = new std::vector<bool>;
   Vertex_Kind = new std::vector<SignalKinds_type>;
   Node_Is_Feedback = new std::vector<bool>;
   Block_Size = new std::vector<int>;
   Samp_Intvl = new std::vector<double>;
   Resamp_Rate = new std::vector<double>;
   Const_Intvl = new std::vector<bool>;
   Sig_Dep_Graph = new DirectedGraph;

   return;
}
//=========================================================================
ModelGraph::~ModelGraph()
{
   delete Vertex_Is_Input;
   delete Vertex_Kind;
};
//=========================================================================
void ModelGraph::InsertSignal( GenericSignal *new_sig_id,
                               PracSimModel *model_ptr,
                               bool new_sig_is_input)
{
   int new_sig_num;
   //--------------------------------------------------------------
   //  Add new vertex into Signal Dependency CMSG

   new_sig_num = Sig_Dep_Graph->AddVertex(new_sig_id);

   //---------------------------------------------
   //  set node properies to default values
   //
   Vertex_Is_Input->push_back(new_sig_is_input);
   Vertex_Kind->push_back(SK_REGULAR_SIGNAL);
   Node_Is_Feedback->push_back(false);
   Block_Size->push_back(0);
   Samp_Intvl->push_back(0.0);

   //------------------------------------------------------------
   //  Loop thru existing vertices to see where edges need to be
   //  added to or from new vertex
   //
   for(int old_vtx=0; old_vtx<Sig_Dep_Graph->GetNumVerts(); old_vtx++) {
      //----------------------------------------------
      //  Don't create edges between new signal and
      //  existing signals of same input/output sense
      //  (i.e. don't make edges from input to input
      //  or from output to output)
      if(Vertex_Is_Input->at(old_vtx) != new_sig_is_input) {
          
         //----------------------------------------------
         //  add edge from input vertex to output vertex

         if(new_sig_is_input){
            // new vertex is INPUT: add edge from NEW vertex
            // to EXISTING vertex
            Sig_Dep_Graph->AddEdge( model_ptr,
                                    new_sig_num,
                                    old_vtx);
         }
         else {
            // new vertex is OUTPUT: add edge from EXISTING
            // vertex to NEW vertex
            Sig_Dep_Graph->AddEdge( model_ptr,
                                    old_vtx,
                                    new_sig_num);
         }

         //--------------------------------------
         // Set edge properties to default values
         //         
         Delta_Delay->push_back(0.0); // only used by a very few models

         //-------------------------------------------------
         //  Make Resampling_Rate undefined if model is a
         //  multirate model or if the existing vertex
         //  just connected to the new edge is a control
         //  rather than a signal

         if( Model_Is_Multirate ){
            Resamp_Rate->push_back(UNDEFINED_RATE);
         }
         else{
            Resamp_Rate->push_back(1.0);
         }

         Const_Intvl->push_back(Model_Is_Constant_Interval);

      } //end of if
   }// end of loop over old_vtx
   return;
}
//====================================================
GenericSignal* ModelGraph::GetSignalId(int vtx_num)
{
   GenericSignal* sig_id;
   sig_id = (GenericSignal*)Sig_Dep_Graph->GetVertexId(vtx_num);
   return(sig_id);
}
//====================================================
void* ModelGraph::GetVertexId(int vtx_num)
{
   void* vtx_id;
   vtx_id = Sig_Dep_Graph->GetVertexId(vtx_num);
   return(vtx_id);
}
//====================================================
void* ModelGraph::GetEdgeId(int edge_num)
{
   void* vtx_id;
   vtx_id = Sig_Dep_Graph->GetEdgeId(edge_num);
   return(vtx_id);
}
//====================================================
PracSimModel* ModelGraph::GetModelId(int edge_num)
{
   PracSimModel* model_id;
   model_id = (PracSimModel*)Sig_Dep_Graph->GetEdgeId(edge_num);
   return(model_id);
}
//====================================================
void ModelGraph::EnableMultirate()
{
   Model_Is_Multirate = true;
   return;
}
//====================================================
void ModelGraph::EnableConstantInterval()
{
   Model_Is_Constant_Interval = true;
   return;
}
//===============================================================
int ModelGraph::GetBlockSize(int vtx_num)
{
   return(Block_Size->at(vtx_num));
}
//===============================================================
int ModelGraph::GetNumVerts(void)
{
   return(Sig_Dep_Graph->GetNumVerts());
}
//===============================================================
void ModelGraph::SetSampIntvl( GenericSignal* sig_id,
                               double samp_intvl)
{
   int sig_num = Sig_Dep_Graph->GetVertexNum(sig_id->GetId());
   Samp_Intvl->at(sig_num) = samp_intvl;
}
//===============================================================
void ModelGraph::SetBlockSize( GenericSignal* sig_id,
                               int block_size)
{
   int sig_num = Sig_Dep_Graph->GetVertexNum(sig_id->GetId());
   Block_Size->at(sig_num) = block_size;
}
//===============================================================
double ModelGraph::GetSampIntvl(int vtx_num)
{
   return(Samp_Intvl->at(vtx_num));
}
//===============================================================
double ModelGraph::GetResampRate(int edge_num)
{
   return(Resamp_Rate->at(edge_num));
}
//===============================================================
bool ModelGraph::GetIsConstIntvl(int edge_num)
{
   return(Const_Intvl->at(edge_num));
}
//===============================================================
double ModelGraph::GetDelay(int edge_num)
{
   return(Delta_Delay->at(edge_num));
}
//===============================================================
bool ModelGraph::ConnIsFeedback(int vtx_num)
{
   return(false);
}
//===============================================================
SignalKinds_type ModelGraph::GetVertexKind(int vtx_num)
{
   return(Vertex_Kind->at(vtx_num));
}
//===========================================================
int ModelGraph::GetEdgeNum( int in_sig_num,
                            int out_sig_num )
{
   int edge_num;
   edge_num = Sig_Dep_Graph->GetEdgeNum(in_sig_num, out_sig_num);
   return(edge_num);
}
//===========================================================
void ModelGraph::ChangeRate( GenericSignal* in_sig_id,
                             GenericSignal* out_sig_id,
                             double resamp_rate,
                             PracSimModel* model_ptr)
{
   int in_sig_num, out_sig_num, edge_num;

   in_sig_num = Sig_Dep_Graph->GetVertexNum(in_sig_id);
   out_sig_num = Sig_Dep_Graph->GetVertexNum(out_sig_id);
   edge_num = Sig_Dep_Graph->GetEdgeNum(in_sig_num, out_sig_num);

   if(edge_num < 0) {
      //---------------------------------
      // -- ERROR -- 
      // could get this error if we try to set a rate change
      // between two inputs or between two outputs -- these 
      // combinations won't have an edge defined between them.

      //ErrorStream << "Error in ModelGraph::ChangeRate -- "
      *DebugFile << "Error in ModelGraph::ChangeRate -- "
                 << "attempt to change rate on undefined edge"
                 << endl;
      exit(1);
   }
   Resamp_Rate->at(edge_num) = resamp_rate;
   return;
}
//====================================================
void ModelGraph::Closeout( PracSimModel* model_ptr)
{
   //-------------------------------------------------------
   //  Each CMG must have at least one input signal and one
   //  output signal.  Check to see if signals in CMG are all
   //  inputs or all outputs.  If they are, augment CMG
   //  by adding a dummy source or dummy destination signal
   //  as appropriate.  (Only signals are checked -- vertices
   //  that represent controls are ignored.)

   //-----------------------------------------------
   // Find first vertex that represents a signal
   // and determine if it is an input or an output.

   int vtx_num, first_sig_idx;
   bool first_is_input;
   bool sigs_have_same_in_out_sense;
   int new_sig_num;
   GenericSignal *dummy_signal;

   int num_verts = Sig_Dep_Graph->GetNumVerts();
   if(num_verts == 0) return;
   first_sig_idx = 0;
   first_is_input = Vertex_Is_Input->at(first_sig_idx);

   //-------------------------------------------------
   // Compare first signal against all other signals

   sigs_have_same_in_out_sense = true;
   for( vtx_num = first_sig_idx+1; vtx_num < num_verts; vtx_num++) {
      if(first_is_input != Vertex_Is_Input->at(vtx_num))
         sigs_have_same_in_out_sense = false;
   }

   if(sigs_have_same_in_out_sense) {
      if(first_is_input) {
         //  all existing signals are inputs: augment
         //  CMG with a dummy destination signal

         Vertex_Is_Input->push_back(false);
         dummy_signal = new GenericSignal( "Dummy_Destination\0",
                                           model_ptr);
         new_sig_num = Sig_Dep_Graph->AddVertex( dummy_signal );
         num_verts++;

         Vertex_Kind->push_back(SK_DUMMY_DEST_SIGNAL);
         Block_Size->push_back(0);
         Samp_Intvl->push_back(0.0);

         //-------------------------------------------------------
         //  add edges from each input signal to added destination

         for( vtx_num = 0; vtx_num < new_sig_num; vtx_num++){
            if(Vertex_Is_Input->at(vtx_num) ){
               Sig_Dep_Graph->AddEdge(model_ptr, vtx_num, new_sig_num);
               Resamp_Rate->push_back(UNDEFINED_RATE);
               Delta_Delay->push_back(0.0);

               if(Model_Is_Constant_Interval){
                  Const_Intvl->push_back(true);
               }
               else {
                  Const_Intvl->push_back(false);
               }
            }
         }
      } // end of if(first_is_input)
      else {
         //--------------------------------------------
         // all existing signals are outputs: augment
         // CMSG with a dummy source signal

         Vertex_Is_Input->push_back(true);
         dummy_signal = new GenericSignal( "Dummy_Source\0",
                                           model_ptr);

         new_sig_num = Sig_Dep_Graph->AddVertex( dummy_signal );
         num_verts++;

         Vertex_Kind->push_back(SK_DUMMY_SOURCE_SIGNAL);
         Block_Size->push_back(0);
         Samp_Intvl->push_back(0.0);

         //-------------------------------------------------------
         //  add edges from added source to each output signal

         for( vtx_num = 0; vtx_num < new_sig_num; vtx_num++){
            if( ! Vertex_Is_Input->at(vtx_num) ){
               Sig_Dep_Graph->AddEdge(model_ptr, new_sig_num, vtx_num);
               Resamp_Rate->push_back(UNDEFINED_RATE);
               Delta_Delay->push_back(0.0);

               if(Model_Is_Constant_Interval){
                  Const_Intvl->push_back(true);
               }
               else {
                  Const_Intvl->push_back(false);
               }
            }
         } // end of loop over vtx_num
      } // end of else clause on if(first_is_input)
   }

   DumpSigDepGraph();

   return;
}
//====================================================
void ModelGraph::DumpSigDepGraph(void)
{
   int sig_idx, sig_idx2;
   int edge_idx;

   cout << "\nIn ModelGraph::DumpSigDepGraph" << endl;
   *DebugFile << "\nIn ModelGraph::DumpSigDepGraph" << endl;

   int num_verts = Sig_Dep_Graph->GetNumVerts();
   *DebugFile << "\nVertices: " << num_verts << endl;

   for( sig_idx = 0; sig_idx < num_verts; sig_idx++) {
      *DebugFile << Sig_Dep_Graph->GetVertexId(sig_idx) << "  "
                 << ((GenericSignal*)Sig_Dep_Graph->GetVertexId(sig_idx))->GetName()
                 << endl;
   }

   int num_edges = Sig_Dep_Graph->GetNumEdges();
   *DebugFile << "\nEdges: " << num_edges << endl;

   for( edge_idx = 0; edge_idx < num_edges; edge_idx++){
      *DebugFile << Sig_Dep_Graph->GetEdgeId(edge_idx) << "  "
                 << ((PracSimModel*)Sig_Dep_Graph->GetEdgeId(edge_idx))->GetModelName()
                 << endl;
   }

   *DebugFile << "\nAdjacency Matrix:" << endl;
   for( sig_idx = 0; sig_idx < num_verts; sig_idx++){

      for( sig_idx2 = 0; sig_idx2 < num_verts; sig_idx2++) {
         *DebugFile << Sig_Dep_Graph->GetEdgeNum(sig_idx, sig_idx2)
                    << "   ";
      }
      *DebugFile << endl;
   }
   return;
}
//==================================================================
PracSimModel* ModelGraph::GetOwningModel(void)
{
   return(Owning_Model);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -