Deadline: end of this semester
Ellipsoidal tubes are difficult to interpolate using the convential methods because a few properties very specific to ellipsoidal tubes, especially tight
ellipsoidal tubes have to be preserved. These properties are
- E_1[t] belongs E_2[t] at all times
- E_1[t] touches E_2[t] along l(t)
The property 1) is easy to satisfy even by using a linear interpolation. However given that both E_1 and E_2 tubes are known on a certain time grid {t_i}
a linear interpolation cannot guarantee that an interpolated tube (which is based on linearly interpolated shape matrix of an ellipsoid) satisfies property 2).
This is because EllTube.interp method is based on nearest interpolation which is not suitable for control-synthesis problems. The goal is to implement
a proper interpolation that doesn't break both properties. Luckily such interpolation does exist and has been implemented at 70%. Thus we need just to finish
the implementation glueing loose ends here and there. The interpolation is based on ODE solution via Runge-Kutta 45 algorithm by Dormand Prince (see
articles in https://drive.google.com/open?id=0B5OqL4IVOIC8elN4MHpfbHhTWFU). The idea is that Dormand Prince suggested an interpolation that uses the same
coefficients as ODE solver so that this interpolation has the same level of precision as ODE solution. Actually this interpolation is already used by ode45 solver.
According to Mathworks Dormand and Prince have sent this interpolation via an email. There is no any theoretical proof that I was able to find though but this is
the best that we have. The fact that this interpolation is implemented in an official ode45 solver gives it a certain level of credability.
Anyways, branch "issue_10" contains a partial implementation of the task. I suggest you create a copy of this branch and merge your changes back to issue_10 fromtime to
time. Kirill Aksenov will be helping your with this task by implementing a comparison functionality for matrix functions so he will also be merging to issue_10.
Once issue_10 is ready you will merge it to master branch. You are responsible for issue_10, not Kirill but your task depend on his work.
Step I: study what has been already done, namely
- A few classes in gras.ode package. These classes allow to generate a special interpolation object from ode45 solver so that this object can be used
for interpolating solution of any ODE.
products+gras+ode+test+mlunit\SuiteBasic.m
products+gras+ode+test+mlunit\SuiteOde45Reg.m
products+gras+ode\IMatrixSysInterp.m
products+gras+ode\MatrixODE45InterpFunc.m
products+gras+ode\MatrixODE45ScalarTimeInterpFunc.m
products+gras+ode\MatrixSysNearestInterp.m
products+gras+ode\MatrixSysODERegInterpSolver.m
products+gras+ode\MatrixSysODESolver.m
products+gras+ode\MatrixSysReshapeOde45RegInterp.m
products+gras+ode\VecOde45RegInterp.m
products+gras+ode\ode45reg.m
You need to understand what these classes do by studying tests for them in SuiteBasic and SuiteOde45Reg test classes.
- Changes to MatrixFunctions in
products+gras+mat
products+gras+mat+fcnlib
packages. Matrix function object is an entity that is responsible for a delayed calculation (symbolic). The idea of an
ellipsoidal tube interpolation is that instead of calculating ellipsoidal matrices at certain time grid {t_i} we "remember" the formulas themselves
in a symbolic form. This way we can then calculate the shape matrix at any given t, not just at time moments from {t_i}. For instance, if you
need to multiply matrix A by vector b you write A*b but in our case we do something different, we do
opFactory=gras.mat.CompositeMatrixOperations();
aMatrixFunc=... (comes from somewhere, isa(aMatrixFunc,'gras.mat.IMatrixFunction')=true
bVecFunc=...(comes from somewhere , isa(bVecFunc,'gras.mat.IMatrixFunction')=true)
multResultFunc=opFactory.rMultiplyByVec(aMatrixFunc, bVecFunc);
then we can calculate a result of A*b on a certain time grid timeVec just by calling multResultFunc.evaluate(timeVec). So all those
new matrix function classes added in issue_10 branch to gras.mat and gras.mat.fcnlib package are responsible for different kinds
of operations (like *, /, indexing etc).
- Changes to ellipsoidal tube calculation classes.
products+gras+ellapx+lreachuncert+probdyn\LReachProblemLTIDynamics.m (this class and many others are responsible
for calculating things like A(t), B(t), B(t)P(t)B'(t), C(t)Q(t)C'(t), B(t)p(t), C(t)q(t) as well as a center of ellipsoidal tubes
that are solutions to \dot(x)=A(t)x(t)+B(t)p(t), C(t)q(t). In master branch this solution to this ODE is obtained on a certain
time grid and then interpolated via a cubic spline. In issue_10 LReachProblemLTIDynamics has been changed to use an interpolated
object returned by ODE solver itself. This way cube interpolation is replaced by the interpolation by Dormand-Prince that has the same
level of precision as the solution itself. You need to change LReachProblemDynamicsInterp so that it uses the same approach as
LReachProblemLTIDynamics. Also please avoid copy-pasting, if you can place the common functionality in LReachProblemDynamicsInterp
and LReachProblemLTIDynamics in a new base class - please do so.
products+gras+ellapx+lreachplain\AGoodDirs.m (a base class for calculating a transition matrix X(s,t) and l(t))
products+gras+ellapx+lreachplain\GoodDirsContinuousGen.m (implementations of X(t,s) and l(t) calculations for a generic continuous time systems
products+gras+ellapx+lreachplain\GoodDirsContinuousLTI.m (same for time-independent systems)
products+gras+ellapx+lreachplain\GoodDirsDiscrete.m (same for discrete-time systems)
The changes to these classes are very similar to the changes to LReachProblemLTIDynamics - a spline-based interpolation is either replaced
or complemented with Dormand-Prince interpolation.
An important thing to remember here is that GoodDirs classes do not operate with X(t,s) directly, instead they calculate an normalized X(t,s)
denoted as R(s,t) (R(s,t)=X(s,t)/||X(s,t)||). R is suitable for calculating good directions l(t) to the same extent as X because for good directions
their norm doesn't matter. But at the same time R has a few advantages - its norm is kept around 1 which gives l(t) with norm also around 1 (more or less).
If we use X then for certain A a norm of l_s(t) = X(s,t)'l_s can grow or drop down to zero with an exponential speed.
products+gras+ellapx+lreachuncert\ExtIntEllApxBuilder.m (this class is responsible for calculating both external and internal approximations
and building ellipsoidal tubes. In issue_10 branch tube constructors require a few additional inputs associated with an interpolation objects).
For instance, if previously it was sufficient to provide QArray:double[nDims,nDims,nTime](- Q%28t%29), aMat:double[nDims,nTimes](- a%28t%29)
along with a few additional inputs to build E(t)=E(Q(t),a(t)) tube, now we also need interpolation objects for both Q(t) and a(t) so that
we can calculate E(t) at any arbitrary t \in [t_0,t_1].
Changes to
products+gras+ellapx+smartdb+rels\EllTube.m
products+gras+ellapx+smartdb+rels\EllTubeBasic.m
introduced in issue_10 reflect that.
Step II: Finish the implementation.
-
Finish changes to problem dynamics classes (see above). Right now only a class for LTI system has been changed.
-
Finish changes to GoodDirs classes. Changes have been introduced by none of the changes have been thoroughly tested.
There are a few tests in products+gras+ellapx+lreachplain+test but you need to extend the coverage by
verifying these classes one a few simple linear systems and comparing the results with ethalon results (calculated
analytically on a piece of paper).
-
Finish changes to EllTube clases in gras.ellapx.smartdb.rels classes and make sure the tests in gras.ellapx.smartdb.test pass.
A potential challenge is a comparison of ellipsoidal tubes. When tube objects do not contain
any interpolation objects as properties (like in master branch) comparing tubes is easy and this is successfully done.
However in issue_10 branch ellipsoidal tubes contain interpolation object that have dependencies on a lot of interpolation objects.
Thus we need to be able to compare interpolation objects with a certain precision. For that purpose we need to be able to
compare any object imlpemented in gras.mat and gras.mat.fcnlib package.
I suggest we approach this problem in two steps:
a) implementing a stub comparison code that can recognize as equal objects
that are 100% equal and not equal otherwise. This can be done via inheriting gras.mat.AMatrixFunctionComparable from
modgen.common.obj.HandleObjectCloner object which provides all necessary comparison functionality. All you need to do is
overriding isEqualScalarInternal in AMatrixFunctionComparable so that it calls isEqualScalarAsBlobInternal method.
This way all matrix function objects will be compared as BLOBs which should be sufficient for fixing all existing tests
in gras.ellapx.smartdb.test package.
b) A correct implementation of matrix function comparison will require providing a matrix function class-specific implementation
of isEqualScalarInternal method. This will be done by Kirill Aksenov.
Please note that some of the tests that fail in issue_10 right now are because of getRGoodDirCurveInterpObj method missing in AGoodDirs.
(R stands for R(s,t) - normalized transition matrix, see above). Instead of getRGoodDirCurveInterpObj you need to use getRGoodDirOneCurveInterpList
that you need to implement. Here is an explanation why and how.
fromQArraysInternal in products+gras+ellapx+smartdb+rels\EllTubeBasic.m
generates interpolation objects for good curves using subarray method of CompositeMatrixOperations factory:
line 331:
STubeData.ltGoodDirInterpObjList{iLDir} = ...
compositeMatrixOperationsObj.subarray(...
ltGoodDirInterObj,[{1:nRows} {iLDir}]);
This needs to be changed by implementing a method AGoodDirections in analogous to getRGoodDirOneCurveSplineList
but returning a list of interpolation objects for each l_i. This method needs to be called
getRGoodDirOneCurveInterpList and EllTubeBasic.fromQArraysInternal should accept a list of these interpolation objects
returned by getRGoodDirOneCurveInterpList method instead of a single ltGoodDirInterObj. Once this is done the transformation
performed on line 331 won't be needed and STubeData.ltGoodDirInterpObjList can be taken directly from the input.
AGoodDirs.getRGoodDirOneCurveInterpList should be implemented based directly on getRstTransInterpObj method that returns an
interpolation objects for R(s,t)' - normalized X(s,t)' matrix. A normalized l(t) could then be taken directly
by multiplying R(s,t)' by l_i. This can be done via gras.mat.CompositeMatrixOperations.rMultiplyByVec.
- Re-cache regression tests in gras.ellapx.uncertcalc.test package. Most of the tests from this package use the calculation
results stored in mat files as ethalons Since you have a new structure of EllTube classes comparison won't work so you need to re-cache the results
(update ethalons on disk).
Assuming you are fixed all the bugs in ExtIntEllApxBuilder the test re-caching can be done via
gras.ellapx.uncertcalc.test.regr.run_regr_tests('reCache',true)
gras.ellapx.uncertcalc.test.regr.run_regr_tests('reCache',true,'nParallelProcesses',8) (for 4-core processor with hyper-threading like i7 4790k for instance)
Note: cache files are located in \products+gras+ellapx+uncertcalc+test+regr+mlunit\TestData\SuiteRegression\testRegression_out
- Enable the following tests for elltool.reach.ReachContinuos class that are currently disabled because "interp" method of EllTube class doesn't
work correctly (it uses a nearest interpolation while it should provide a "true" interpolation).
products+elltool+reach+test+mlunit\ContinuousIsEqualTestCase.m
DISABLED_testIsEqualEnclosedTimeVecs
DISABLED_testIsEqualNotEnclosedTimeVecs
products+elltool+reach+test+mlunit\ContinuousReachTestCase.m
DISABLE_testEvolve
DISABLE_testCut
Once the test are disable you can make sure that all tests for ReachContinuos pass via running elltool.reach.test.run_cont_tests
- Remove matrix function that are not used anywhere (some were added just in case and we might not need them any longer).
An example of such matrix function is the one build via gras.mat.CompositeMatrixOperations.subarrayInit