/*--------------- D i s p l a y P w l F c n ( ) --------------- PURPOSE Display a pwlFcn from beginning to end. INPUT PARAMETERS pwlFcn -- the pwlFcn to be displayed. */ void DisplayPwlFcn(DblLinkedList &pwlFcn) { double x; double y; //Check if empty if(pwlFcn.Empty()) { cout<<"The pwlFcn is empty."<<endl; return; } //Start at the beginning and print everything pwlFcn.Rewind(); cout<<"PIECEWISE LINEAR FUNCTION DEFINITION"<<endl; while(!pwlFcn.AtEnd()) { x = pwlFcn.CurrentItem().X(); y = pwlFcn.CurrentItem().Y(); cout<<"("<<x<<","<<y<<")"<<endl; pwlFcn.Forward(); } //Reset to beginning pwlFcn.Rewind(); }
/*--------------- W r i t e P w l F c n F i l e ( ) --------------- PURPOSE Write out a pwlFcn file. INPUT PARAMETERS cmdLine -- the execute command command line. pwlFcn -- the pwlFcn list. */ void WritePwlFcnFile(string cmdLine, DblLinkedList &pwlFcn) { ofstream pwlFcnStream; // The output stream string pwlFcnFile; // The output file name // Ask for the file name and then open the file. pwlFcnFile = GetFileName(cmdLine); if (pwlFcnFile.length() == 0) return; pwlFcnStream.open(pwlFcnFile.c_str()); if (!pwlFcnStream.is_open()) { cout << "*** ERROR: Failed to open file " << pwlFcnFile << endl; return; } // Write out the entire pwlFcn. pwlFcn.Rewind(); while (!pwlFcn.AtEnd()) { pwlFcnStream << pwlFcn.CurrentItem().X() <<" " << pwlFcn.CurrentItem().Y() << endl; pwlFcn.Forward(); } pwlFcnStream.close(); pwlFcn.Rewind(); }
/*--------------- I n t e r p o l a t e ( ) --------------- PURPOSE Determine the value of the waveform at time t by linear interpolation. INPUT PARAMETERS pwlFcn -- the pwlFcn list t -- the time at which the waveform value is to be obtained */ double Interpolate(DblLinkedList &pwlFcn, double t) { double lowerBound; double upperBound; Point low; Point high; lowerBound = pwlFcn.FirstItem().X(); upperBound = pwlFcn.LastItem().X(); //modulate t to be in the period of the wave while(t<lowerBound) { t+=upperBound; } while(t>upperBound) { t-=upperBound; } t=fmod(t,upperBound); //find the upper and lower points to use to interp pwlFcn.Rewind(); while(!pwlFcn.AtEnd()) { if(t>pwlFcn.CurrentItem().X()) { low = pwlFcn.CurrentItem(); } else { high = pwlFcn.CurrentItem(); break; } pwlFcn.Forward(); } //calculate line double m = (high.Y()-low.Y())/(high.X()-low.X()); //slope double b = (high.Y())-(m*high.X()); //offset return (m*t+b); //Compute and return y }
//------------------- DblLinkedList::DeepCopy() ------------------- // Deep copy source to this object void DblLinkedList::DeepCopy(DblLinkedList &source) { Node *tempNode; assert(tempNode = new(nothrow) Node()); tempNode = source.current; //Delete the old list this->~DblLinkedList(); //Rewind the source list source.Rewind(); //Copy that linked list. while (source.current != 0) { InsertItem(source.CurrentItem()); source.Forward(); } source.current = tempNode; current = tempNode; tempNode = 0; delete tempNode; }
/*--------------- C o u n t P o i n t s ( ) --------------- PURPOSE Count the number of points in the pwlFcn. The list is passed by value to invoke the copy constructor. The destructor is executed upon return when the parameter is destroyed. */ void CountPoints(DblLinkedList pwlFcn) { unsigned numPts = 0; // Number of points in the pwlFcn // Display the current entry. cout << "\nCURRENT ENTRY\n" << pwlFcn.CurrentItem() << endl << endl; // Rewind to the beginning. pwlFcn.Rewind(); // Add 1 point and move forward until reaching the end of the pwlFcn. while (!pwlFcn.AtEnd()) { ++numPts; pwlFcn.Forward(); } // Rewind on the way out. pwlFcn.Rewind(); // Display the count. cout << "Number of Points: " << numPts << endl; }
/*--------------- E x e c u t e ( ) --------------- PURPOSE Execute a command stream, either from cin of from a command file INPUT PARAMETERS cmdStream -- the stream from which commands are to be read pwlFcn -- the pwlFcn list. */ void Execute(istream &cmdStream, DblLinkedList &pwlFcn) { string cmdLine; // The current command line // Repeatedly get a command from the keyboard and // execute it. do { cmdLine = GetCmd(cmdStream, pwlFcn); if (cmdLine.length() != 0) { switch (toupper(cmdLine[0])) { // Execute a command file. case ExecuteCmd: DoExecute(cmdLine, pwlFcn); break; // Determine which command to execute. case InsertCmd: // Insert a new point. InsertPoint(cmdLine, pwlFcn); break; case ClearCmd: // Clear the pwlFcn. pwlFcn.~DblLinkedList(); // Explicit destructor function call break; case DeleteCmd: // Delete the current point. if (!pwlFcn.AtEnd()) pwlFcn.DeleteItem(); if (pwlFcn.Empty()) cout << "The pwlFcn is empty." << endl; break; case PrintCmd: // Display the pwlFcn. DisplayPwlFcn(pwlFcn); break; case OpenCmd: // Read in a pwlFcn file. ReadPwlFcnFile(cmdLine, pwlFcn); break; case SaveAsCmd: // Write out a pwlFcn file. WritePwlFcnFile(cmdLine, pwlFcn); break; case ForwardCmd: // Advance to the next point. if (!pwlFcn.AtEnd()) pwlFcn.Forward(); if (pwlFcn.AtEnd()) cout << "The pwlFcn is at the end." << endl; break; case BackwardCmd: // Go back to the previous point. pwlFcn.Backward(); break; case RewindCmd: // Rewind to the first point in the pwlFcn. pwlFcn.Rewind(); break; case GenerateCmd: // Generate waveform. { DblLinkedList pwlFcnCopy(pwlFcn); // Invokes copy constructor Generate(cmdLine, pwlFcnCopy); } break; case NumPtsCmd: { DblLinkedList pwlFcnCopy; // A copy of the pwlFcn pwlFcnCopy = pwlFcn; // Invokes overloaded assignment CountPoints(pwlFcnCopy); // Pass by value invokes the copy constructor. } break; case QuitCmd: // Terminate execution. break; default: // Bad command cout << "*** Error: Unknown Command" << endl; break; } } } while (cmdLine.length() > 0 && toupper(cmdLine[0]) != QuitCmd); }