Week-1 of the program is officially over, and the learning experience had been quite fruitful. Progress of this week-
- Changed the API of
TransferFunctionandTransferFunctionMatrixto make it more beginner-friendly as well as efficient at the same time.TransferFunctionobjects can now be directly created by directly passing the rational expression instead of passing thenumanddenparameters separately. It’s backward compatible, so if users want, they can also use the old way.- Suppose there is only a single variable present in the expression. In that case, users will not be required to pass the
varparameter. - Expansion of numerator and denominator expressions passed is done by default now. This is done to preserve the general polynomial convention mentioned in the definition of the transfer function.
- Removed the
num_inputs,num_outputsandshapeproperties forTransferFunction. It was introduced, in the first place, by Naman to make things compatible with theTransferFunctionMatrixin his implementation. Since I have updated the internal structuring of theTransferFunctionMatrix, it is no longer required. Also, in my implementation, (1, 1) shapedTransferFunctionMatrixobject and aTransferFunctionobject will be treated differently. I will soon be removing the_is_Matrix()property, which used extensively inSeriesandParallelclasses. - Users can now raise
TransferFunctionobjects to any integer power (even symbolic expressions unless they are Integers). - Added a new method in
TransferFunctionclass (_to_expr()) to ease the conversion of TransferFunction instances to Expr instances. This will ease the computation ofSeries(*args).doit()andParallel(*args).doit()in later phases even if they are convoluted. TransferFunctionMatrixnow inheritsImmutableMatrix(sympy.matrices.immutable.ImmutableDenseMatrix) as its parent class. This has drastically improved the computation time for typical matrix operations. Attributes likeshapeand functionalities like determinant, submatrix extraction, accessing individual elements by indices, and lambda expression compatibility are all compatible withTransferFunctionMatrixwithout writing the redundant code again for each of them.- Creating new
TransferFunctionMatrixobjects is also eased, just likeTransferFunction. The optional parametershapeis removed now. Users can createTransferFunctionMatrixby passing a list (or list of list) of Expr or TransferFunction or even a combination of two. I also didn’t override theargsattribute. Therefore,ImmutableMatrix(*args).argsandTransferFunctionMatrix(*args).argshave a similar structure making it compatible for easy interconversion. Also,varis now a keyword argument and not a positional one. - Updated the magic method
__mul__(self, other)ofTransferFunctionMatrixas the previous implementation was wrong.A*B(A and B both beingTransferFunctionMatrixobjects) should returnSeries(B, A)and notSeries(A, B). - Added a method in
TransferFunctionMatrixclass (_to_Immutable_Matrix()) to ease the conversion toImmutableDenseMatrix. It will act as a bridge in efficient Matrix operations.
-
Changed the documentation of
TransferFunctionandTransferFunctionMatrix. Added a bit more explanation and links to resources in the docs to make it beginner-friendly. After completing this PR, I also plan to add illustrations like insympy.physics.continuum_mechanics. Here is a glimpse of the same-
-
Modified the
SeriesandParallelclass’ methods and attributes corresponding to changes in the structure ofTransferFunctionandTransferFunctionMatrixmentioned above. Although, it is not complete yet. - I have modified the unit tests corresponding to the changes mentioned above.
Most of the difficult parts of Phase-1 over now (at least in my opinion). The fundamental structure is now more robust, and building functionalities on it would be easier now. For Week-2, I have the following tasks-
- Completing the class-level docstrings and unit tests for all the classes.
- Finishing the Series and Parallel class’ implementation. I will also be benchmark testing the
Series().doit(),Parallel().doit()andTransferFunctionMatrix().doit(). I will be comparing the code execution time taken by these operations with their equivalent Matrix expression counterpart to ensure that performance is not affected. - Adding the comprehensive textbook example mentioned in the previous blogpost, in the docs of control.
- Modifying the
Feedbackclass. - And finally, after all the tests pass, removing the commented-out code (tidying up the codebase, basically).
I’m working strenuously to make sure that this PR gets merged successfully until the end of Week-2 so that I can start the work on the StateSpace class from Week-3.