GithubHelp home page GithubHelp logo

systemanalysisdpt-cmc-msu / ellipsoids Goto Github PK

View Code? Open in Web Editor NEW
18.0 22.0 7.0 349.44 MB

Ellipsoidal Toolbox for MATLAB is a standalone set of easy-to-use configurable MATLAB routines and classes to perform operations with ellipsoids and hyperplanes of arbitrary dimensions

Home Page: http://systemanalysisdpt-cmc-msu.github.io/ellipsoids

License: Other

MATLAB 95.54% M 0.65% Objective-C 0.20% C++ 0.24% Fortran 2.47% Batchfile 0.16% Shell 0.17% Java 0.12% C 0.01% HTML 0.01% Perl 0.17% Python 0.27%
ellipsoid control

ellipsoids's Introduction

ellipsoids

Ellipsoidal Toolbox (ET) is a standalone set of easy-to-use configurable MATLAB routines and classes to perform operations with ellipsoids and hyperplanes of arbitrary dimensions. It computes the external and internal ellipsoidal approximations of geometric (Minkowski) sums and differences of ellipsoids, intersections of ellipsoids and intersections of ellipsoids with halfspaces and polytopes; distances between ellipsoids, between ellipsoids and hyperplanes, between ellipsoids and polytopes; and projections onto given subspaces.

Ellipsoidal methods are used to compute forward and backward reach sets of continuous- and discrete-time piecewise affine systems. Forward and backward reach sets can be also computed for piecewise linear systems ith disturbances. It can be verified if computed reach sets intersect with given ellipsoids, hyperplanes, or polytopes.

For more information please refer to Ellipsoidal Toolbox website

Contact / Support

  • Found ET useful for something?
  • Found a bug and wish to report it?
  • Have questions, suggestions or feature requests?
  • Wish to contribute to the ET development?

Please, contact Peter Gagarinov, Alex Kurzhanskiy or report an issue.

ellipsoids's People

Contributors

23-shephard avatar alextim27 avatar arturlu avatar asemenova avatar axellkir avatar chist avatar dimamih avatar dkanatnikov avatar ekaterinashevchenko avatar eshcherbakova avatar ezilonova avatar heartofmars avatar ifshirokikh avatar irublev avatar iukinpavel avatar koviashev avatar luxenia avatar nikolaytrusov avatar pgagarinov avatar rguliev avatar sdrozhzhin avatar shalnovyar avatar shaludinalexandr avatar sstis avatar timchenko-alexandr avatar vadimdanilov93 avatar vault-guy avatar vitbaranov avatar vlazareva avatar zmargarita avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ellipsoids's Issues

ellipsoid.plot very slow compared to V1

Nice to see the toolbox is still being actively developed. I just upgraded from version 1 to version 2 and am wondering about one thing: Is it a bug or to be expected that the plot command is much slower than on version 1? With much I mean that version 1 was more than 100 times faster.
It takes seconds instead of milliseconds. I am only doing 2D plots.
It seems that somehow a lot of time is spent in plotgeombodyarr:
https://dl.dropboxusercontent.com/u/17406199/elltool2.png

Currently, I use work around the problem by using the first two outputs of the cylinder command of matlab translate/scale it to do my 2d plots. However, if the speed is not a bug but to be expected, I guess I'll downgrade to version 1 again.

Anyways, thanks in advanance for any information concerning this issue and thanks a lot for having created this incredible toolbox.

Refactor content of multiobj package

Multiobj functionality is removed in master until the following tasks are completed. Please refer to tag "issue_1" for latest multiobj source code

  1. Remove all comments in russian
  2. Get rid of copy-pasting
  3. Get rid of unused code inherited from old program that operated with files
  4. Get rid of meaningless status messages produced by mexPrintf
  5. Documentation in Russia should be replaced with a section in ETB manual written in English

Make it possible to plot 2d and 3d ellipsoids from the same array

Right now a call like this

ellVec=[ellipsoid(eye(2)),ellipsoid(eye(3))];

is not supported. One needs to make it possible. Most of the points from issue #22 are useful here as well.

  1. The implemented functionality should be covered with tests implemented in the following test pack.
    +elltool+core+test+mlunit\GenEllipsoidPlotTestCase. In the test one needs to consider different combinations of input parameters and array sizes. Negative tests are also required. See Wiki for an example of a negative test (mlunitext.test_case.runAndCheckError).

  2. No copy-pasting, compliance with the coding style (see Wiki) and presence of code comments.
    No commented out code, no blank lines, no long lines.

Add support for state constraints in the ellipsoidal approximations

By a user request:

Hi Peter,

Do you have plan to incorporate the state constraints in the the reachability analysis of the toolbox? The related paper was published by Prof. AB Kurzhanskiy in 2003. It would be particular useful for hybrid system.

Thanks,
Yuchen Zhou

Finish implementation of interpolation for ellipsoidal tubes

This task includes finishing items 4) and 5) from https://code.google.com/p/ellipsoids/issues/detail?id=126

The task includes at least the following sub-tasks

1)[Anton Lesnichiy] Finish the tests for the modified versions of GoodDir ΠΈ ProbDynamics classes
2)[Ekaterina Markova] Make all MatrixFunction classes from products+gras+mat comparable via implementing MatrixFunctionComparamble super class with its isEqualInternal and toStruct methods (covered with unit tests). Apart from these methods this super class should implement getCopy method for building a copy of an object. The code of getCopy should look like this:

function otherObj=getCopy(self)
otherObj=getArrayFromByteStream(getByteStreamFromArray(self)
end

see
http://undocumentedmatlab.com/blog/serializing-deserializing-matlab-data

for details.

3){Andrew Zanochkin] Make mlunitext.runtestcase('gras.ellapx.smartdb.test.mlunit.SuiteEllTube','testInterpAdvanced') pass and fix EllTubeProjBasic.getInterpDataInternal (and potentially EllTubeBasic.projectInternal)

  1. [To be decided by the group] Find and fix all the problems with the blind copy-pasting of all matrix calculations from master on a symbolic level.
    5)[Anton Lesnichiy] Remove prefix "А" from the names of non-abstract classes in products+gras+mat
  2. [Andrew Zanochkin] - make sure that getInterpDataInternal and other methods that are ultimately used for building a copy of the original object (in interp or cut methods for instance) do not just copy interpolation objects via "=". Instead of writing SData.interpAMatObj=self.interpASMatObj we need to write SData.interpAMatObj=self.interpASMatObj.getCopy();

Preparing an animation of ell tube evolution takes forever

Deadline - 1st of November, by that time both the changes and all the tests should be integrated into "master" branch

elltool.demo.test.control.anim6 seems to work very slowly, thanks to performance of EllTube.cut method and some others. We need to do a major performance optimization. One needs to use a profiler (profile on; run calculation... ; profile viewer) to find the performance bottlenecks and fix them. It can be that some portions of the code need to be refactored for better performance.

As part of this task one needs to write a few performance tests in +gras+ellapx+smartdb+test+mlunit\SuiteEllTube.m for the methods that will be optimized. The idea for writing the performance test can be as follows: we perform an animation of already calculated tube in two different ways: a) ugly but fast via extracting the ellipsoidal matrices from the tube and doing the plotting manually via low-level functions from gras.geom.* packages. b) via EllTube.cut. Then we compare the runtimes of these two methods and check that the difference is less than x% where x% is fixed in the test. The goal is to make the overhead x less than at least 25%.

Once the optimization is done we will uncomment a call to elltool.demo.test.run_demo_tests from

in +elltool+demo+test\run_tests.m. Run now this call is commented out so that the test pack for ellipsoids takes under 2 hours to run.

Make ReachContinuous and ReachDiscrete handle nTimeGridPoints property correctly

Deadline - 30th of October, by that time all changes and tests should be merged into "master" branch

  1. elltool.reach.ReachContinuous class doesn't seem to take nTimeGrindPoints property into account - in elltool.demo.test.control.anim6 function for instance calling elltool.conf.Properties.setNTimeGridPoints(135); doesn't change a number of time points in returned ellipsoidal tube (100). That is because nTimeGridPoints is not passed into the low-level EllTube builder class.
  2. For discrete systems this property seems to be ignored altogether though it should be set based on time limits.

One needs to fix these two problems and write tests in a test case class located inproducts+elltool+reach+test+mlunit package. The tests should check explicitly that these properties are not ignored for a few different systems (both discrete and continous) in both direct and opposite time, for projections and not projections. One can either create a separate test case class and put the tests in one of the existing test cases.

Get rid of dependency on Symbolic toolbox

Deadline is 3rd of November

Symbolic toolbox is currently used by Ellipsoidal Toolbox for a variable replacement when we need to transform
an equation \dot{x}=A(t)x(t)+... for a solvability problem into an equation for a rachability problem. This is done in
\products+elltool+reach\ReachContinuous.m 216 t = sym('t');

Also there is a function
\products+gras+mat+fcnlib\iscellofstringconst.m

that is used for checking if matrix function doesn't depent on time i.e. constant.

The goal is to get rid of dependency on symbolic math by writing a new function

gras.sym.varreplace that does a replacement in an expression of a specified named variable with another expression.
Examples:
sin(t): t -> 10-t: sin(10-t)
[(sin(t)+t)/tt]^att: t -> 10-t: [(sin(10-t)+10-t)/tt]^att
sin(s): s->s/10 : sin(s/10)

These are just a few examples to show that it is not as trivial as replacing one symbol. You should think of more tricky cases.
This function should be coreved with tests (that test this function on each tricky example) placed into gras.sym.test.mlunit.BasicTC test case.

Once this function is implemented please implement one more function: gras.sym.isdepdendent which does the same as iscellofstringconst from
above but via gras.sym.varreplace this time. gras.sym.isdepdendent also needs to be covered with tests in the same test case.

Finally remove iscellofstringconst and replace all calls to iscellofstringconst with calls to isdepdendent. Also please refactor code that
uses sym function from Matlab toolbox with varreplace function. Then re-install Matlab without Symbolic toolbox and make sure that
all tests still pass after your changes.

Mac Support?

Am I correct in understanding that this toolbox is only compatible with Windows machines? I have a Mac and wanted to confirm that I cannot use this toolbox on it.

Implement elltool.core.AGenEllipsoid.getScalarPolar and use it everywhere instead of inline code for polar calculation

Deadline is 28th of October, by that time all the chagnes and the new tests should be in "master" branch

fSinglePolar in ellipsoid.polar and getPolar in doesContainPoly contain approximately the same code responsible for calculating polar of a single ellipsoid. Though similar the algorithms are a bit different so please implement both in a new protected elltool.core.AGenEllipsoid.getScalarPolar method. This method should have the following parameters:

  1. self - the object itself (can only be scalar - check that first using isscalar and modgen.common.checkvar - see help header for checkvar and Wiki for more details).
  2. isRobustMethod - if true then the algorithm from fSinglePolar should be used, otherwise - the algorithm from doesContainPoly.

Then replace the explicit formulas with the calls to the newly created method. Also please check all methods of ellipsoid class to see if there are some other places where this method can be used instead of explicit formulas. If there are any - make the replacement. And make sure that all the existing tests pass i.e. that you didn't break anything.

Locate existing tests for getPolar and doesContainPoly methods in elltool.core.test.mlunit package and study them.

Then figure out a test for ellipsoids with such matrices that the not-robust method (isRobustMethod =false) used in doesContainPoly doesn't work while the robust method works. Then make doesContainPoly use the robust method also and check that this makes the test pass. Most probably the test should operate with ill-conditioned matrices of high dimensions. The test should be implemented in a separate test case class named elltool.core.test.mlunit.PolarIllCondTC

Make matrix function classes derived from gras.mat.AMatrixFunctionComparable comparable

Deadline: end of the semester

The goal of this task is to make all subclasses of gras.mat.AMatrixFunctionComparable class comparable. This is needed for issue #39
so that ellipsoidal tubes with built-in Dormand-Prince interpolation can be compared with any given precision.

  1. Please read a description for issue #39 and make sure you fully understand it.

  2. Investigate gras.mat.AMatrixFunctionComparable class. Current implementation of this class needs to be slightly changed by
    a) inheriting it from modgen.common.obj.HandleObjectCloner (which automatically adds isEqual and re-defines isequal,isequaln, eq,ge,le etc).
    b) Re-defining isEqualScalarInternal method of HandleObjectCloner using the current code from AMatrixFunctionComparable.isEqual method
    (with a few simplifications - after all isEqualScalarInternal is only for comparing scalar objects). This way any vectorial object (isEqual inherited from
    HandleObjectCloner as well as other comparison methods inherited from this class can handle vectorial objects by comparing them element-wise and using isEqualScalarInternal
    method that can be re-defined in derived classes) inherited
    AMatrixFunctionComparable can be comparable as long as it implements an abstract AMatrixFunctionComparable.toStructInternal.

  3. Study all functions from gras.mat and gras.mat.fcnlib packages. Then implement toStructInternal for each of them in a way that makes possible an
    adequate comparison. By adequate comparison I mean that comparing structures should be equivalent to comparing functions themselves.
    For instace comparing objects of ConstMatrixFunction class is easy - you just compare constant matrices because the function is not time-dependent.
    However for the most functions (except for a few functions that are very simple or/and similar to ConstMatrixFunction) it is not that easy because all you have is "evaluate" method and no analytical formula. Given a comparison precision absTol and two matrix functions M_1(t) and M_2(t)
    the problem you need to solve then is finding t^{} such that ||M_1(t) - M_2(t)||>absTol. If no such t^{} if found M_1 and M_2 are considered equal and
    not equal otherwise. Of course this is not that simple for a least two reasons:
    a) in addition to absTol and also have relTol - relative precision and comparison should be performed using both precision levels.
    The rough idea behind comparing a and b with both relative and absolute precision is as follows:
    if ||a-b|| <absTol - cosider a and b as equal, otherwise check if 2_||a-b||/(||a||+||b||)< relTol. If positive - a and b are still equal and not equal otherwise.
    But in reality this is a bit more complex than this - see modgen.common.absrelcompare for an exact algorithm.
    b) in practice it is often impossible to find an exact value of t^{_} or prove that it doesn't exist because neither M_1 nor M_2 is not specified in an analytical form.

Assuming you investigated AMatrixFunctionComparable.isEqual method it should be clear that this method uses modgen.struct.structcomparevec to compare structures. structcomparevec in its turn uses absrelcompare function. For simple functions like ConstMatrixFunction for instance
AMatrixFunctionComparable.toStructInternal should generate a single structure with something that is equivalent to comparing the function itself. For ConstMatrixFunction representing a function M=M(t) it would be a structure like struct ('ConstantMatrix',M). However for "complex| functions this approach might not
work well. Why might? Because I suggest we try it as the first step and generate a vector of M(t) values for a certain time grid and put this vector into the resulting
structure generated by toStructInternal method. This way we will at least have something to compare with later in term of both performance and precision. Thus the next step
4) Implement toStructInternal for simple functions based on their internal structure and for "complex" functions - by putting 3d-array of M(t) values into the structure with a single field and then letting isEqualScalarInternal compare these structures with single-field 3d arrays via structcompare. Time grids for which M(t)
is calculated should be specified in isEqual as an additional property "timeGridVec". For this purpose you need to override isEqual in AMatrixFunctionApxComparable class using the same approach as the one used in \products+gras+ellapx+smartdb+rels\ATypifiedAdjustedRel.isEqual method. AMatrixFunctionApxComparable should be inherited from AMatrixFunctionComparable and should be used as base class for comparing all "complex" functions. "timeGridVec" property should be obligatory for now.
"Simple" functions should be inherited from
AMatrixFunctionComparable directly. Also please make sure that your implementation of isEqualScalarInternal just calls "isEqualScalarAsBlobInternal" when both absTol=0 and relTol=0 (when we need to do comparison with absolute precision we can just compare a BLOB representation of an object)
5) Write tests that show that
a) "simple" functions are compared correctly and that both absTol and relTol precisions are treated adequatly.
b) "complex" functions can be compared correctly for sufficiently dense time grids (specified as additional properties to isEqual).

All tests should be written in a "parameterized way" - a few test case that are parameterized with a factory generating instances of different matrix funciton classes. See how this is done in elltool.reach.test.run_cont_tests.

Note: you should work in a branch derived from "issue_10" and merge back to issue_10 as it were master. This is because you will work in parallel with Nikitua Zuyanov who also uses issue_10 as "master" branch. Once you both finish your work "issue_10" will be merged to master.

Implement ellipsoid.intersectTightIa method that builds a series of tight internal approximations based on Andrew Vazhentsev's thesis

Deadline is the end of this semester

Here is the thesis: https://drive.google.com/open?id=0B5OqL4IVOIC8SnlFeGVPVjNfdzA

  1. Read the thesis first
  2. Suggest a sensible way of parameterization
  3. Implement the method
  4. Cover this method with tests in 2d and 3d space
  5. Write a demo that demonstrates this method at work in 2d and 3d space products\elltoolboxcore\demo subfolder.
  6. Write a few tests for higher-dimensional ellipsoids.

More details will follow.

Allow for small imaginary parts in input matrices for a number of methods/functions in ET

Deadline is 3rd of November 2015

  1. Implement resMat=gras.la.trytreatasreal(inpMat,tolVal) function where tolVal is optional argument with a default value = eps
    (floating-point relative accuracy in Matlab, type "doc eps" for more details). The function should do the following:
    a) check if inpMat is real - if positive - resMat = inpMat, else - calculate an imaginary part of inpMat: imagInpMat=imag(inpMat) and compare its norm(x,Inf) with tolVal.
    if norm(imagInpMat,Inf)<tolVal then return resMat= real(inpMat); otherwise - throw an exception (use modgen.common.throwerror) that says something like
    "input matrix cannot be considered real as a 1.3233e-10 (norm of imaginary part) > (tolVal)1e-18"

This function should also work for vectors.

  1. Write a few tests (both positive and negative) that check that this function works correctly.

  2. In all the places below replace check that use "isreal" with calls to resMat=gras.la.trytreatasreal(inpMat) with a single input argument.
    The idea is to let all these functions(methods) accept matrices with very small imaginary parts just as if they were real matrices (imaginary part is thrown away).

(especially if function/method can be called with different number/combination of input arguments) of passing a matrix,vector
products+gras+la\orthtransl.m 21 if ~isreal(srcVec)
products+gras+la\orthtransl.m 25 if ~isreal(dstVec)
products+gras+la\orthtranslqr.m 20 if ~isreal(srcVec)
products+gras+la\orthtranslqr.m 24 if ~isreal(dstVec)
products+gras+la\regmat.m 20 'isscalar(x)&&isreal(x)&&isnumeric(x)&&(x>0)');
products+gras+la\regposdefmat.m 19 'isscalar(x)&&isreal(x)&&isnumeric(x)&&(x>0)');
\products\elltoolboxcore@ellipsoid\ellipsoid.m 217 checkvar(regParamList{1},@(x) isa(x,'double')&&isreal(x),...
\products\elltoolboxcore@ellipsoid\ellipsoid.m 235 isreal(x) && isreal(y),2,regParamList{1},regParamList{2},...
\products\elltoolboxcore@ellipsoid\fromRepMat.m 65 checkvar(sizeVec,@(x) isa(x,'double')&&all(isreal(x(:)))&&...
\products\elltoolboxcore@hyperplane\fromRepMat.m 58 checkvar(sizeVec,@(x) isa(x,'double')&&all(isreal(x(:)))&&...

  1. For all these functions/functions from the list above write test that check every case of passing matrices with very small imaginary parts and make sure that
    everything works as planned i.e. if matrix has an imaginary part that is less or equalthan eps (eps/2 or eps for instance) then these functions work as if the matrix was real.
    Otherwise the exception is thrown (negative tests for such case should also be written). Please note that each test should be written in a corresponding test case located next to the function it tests.

Comparison of ellipsoidal objects is done only based on relative precision, absolute precision is ignored

Deadline - 28th of October, by that time all changes and tests should be merged into "master" branch.

Comparison of ellipsoid objects doesn't take into account an absolute precision, see elltool.core.AGenEllipsoid.isEqualInternal:

Line 31: [~, tolerance] = ellFirstArr.getRelTol;

Line 60-62:

            [isEqualArr, reportStr] =...
                modgen.struct.structcomparevec(SEll1Array,...
                SEll2Array, tolerance);

This needs to be fixed by using absolute precision along with relative precision (modgen.struct.structcomparevec can actually accept both).

The first step should be writing the tests that "capture" this incorrect behavior. To do that study modgen.common.absrelcompare function and the way it works. The best ways to do that - study its code and the tests for the function (look at "testAbsRelCompare" test in modgen.common.test.mlunit.mlunit_test_common test case).

Once you understand the way absrelcompare works you can create tests by constructing ellipsoids with different precisions of calculation (this can be done via passing additional properties to "ellipsoid" constructor like this ellObj=ellipsoid(centVec,shapeMat,'absTol',1e-4,'relTol',1-3')) and calling isEqual to compare the constructed ellipsoid objects. The tests should be constructed in a such way that they would pass if the logic were correct.
The tests should be put into elltool.core.test.mlunit.EllipsoidTestCase. All the tests should fail.

After that you make the fix to isEqualInternal method and make sure that all the tests start to pass. If you change the tests to make them pass - roll back the change in isEqualInternal and make sure once again that they fail prior to the change. Thus the tests should all fail prior the change and should all pass after the change.

Fix doesIntersectionContain for mode="i"

Deadline is 25th of October

doesIntersectionContain method uses qcqp subfunction for the intersection case (mode = 'i')
qcqp function uses minimization of quadratic form

minimize(xVec'invQMat_xVec + 2(-invQMat_qVec)'_xVec + ...
(qVec'_invQMat*qVec - 1))

which is incorrect and contradicts the function description in the help header.

All this means that there are no any tests right now neither in
C:\Users\Administrator\Documents_Ellipsoids\ellipsoids\products+elltool+core+test+mlunit\EllSecTCMultiDim.m
nor in any other test case that check this particular case of intersection.

Please

  1. Write a few non-trivial tests that check that particular case and make sure that they fail. Or, if you find some existing tests from
    EllSecTCMultiDim (or any other test case) that can be slightly tweaked/enhanced to capture this problem - do that instead of writing completely new tests.
  2. Change minimize to maximize and make sure that all the tests pass (old and new).

Regularization error in ReachContinuous

I have been trying reachablility set computation for some aircraft dynamics. I kept on getting strange errors in the regularization process. The code is attached test.txt

The errors when runing "rsObj_A = elltool.reach.ReachContinuous(lsys, x0EllObj, dirsMat, timeVec, 'isRegEnabled', true, 'isJustCheck', false, 'regTol', 1e-7);" are the following.

"
Error using modgen.common.checkvar (line 69)
matrix must be symmetric.

Error in gras.la.regposdefmat (line 20)
modgen.common.checkvar(inpMat, 'gras.la.ismatsymm(x)',...

Error in gras.mat.MatrixPosReg>@(x)gras.la.regposdefmat(x,self.regTol) (line 28)
@(x) gras.la.regposdefmat(x, self.regTol), resArray,...

Error in gras.gen.MatVector.evalMFunc (line 68)
resArray(:,:,iElem)=fHandle(dataArray(:,:,iElem));

Error in gras.mat.MatrixPosReg/evaluate (line 27)
resArray = gras.gen.SquareMatVector.evalMFunc(...

Error in gras.ellapx.lreachplain.ExtEllApxBuilder/calcEllApxMatrixDeriv (line 12)
BPBTransMat=BPBTransDynamics.evaluate(t);

Error in
gras.ellapx.lreachplain.ExtEllApxBuilder/getEllApxMatrixDerivFunc/@(t,y)calcEllApxMatrixDeriv(self,self.getProblemDef().getAtDynamics,self.getProblemDef.getBPBTransDynamics,self.getGoodDirSet.getRGoodDirOneCurveSpline(iGoodDir),t,y)

Error in gras.ode.MatrixODESolver>@(t,y)(reshape(fDerivFunc(t,reshape(y,reshapeSizeVec)),[],1)) (line 30)
fMatrixDerivFunc=@(t, y)(reshape(fDerivFunc(t, ...

Error in odearguments (line 87)
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.

Error in ode45 (line 113)
[neq, tspan, ntspan, next, t0, tfinal, tdir, y0, f0, odeArgs, odeFcn, ...

Error in gras.ode.MatrixODESolver/solve (line 32)
[timeVec, xResMat] = ...

Error in gras.ellapx.lreachplain.ATightEllApxBuilder/build (line 54)
[~,data_Q_star]=solverObj.solve(fHandle,...

Error in gras.ellapx.lreachplain.ATightEllApxBuilder/getEllTubes (line 110)
self.build();

Error in gras.ellapx.gen.EllApxCollectionBuilder/getEllTubes (line 43)
ellTubeTempRel=self.builderList{iBuilder}.getEllTubes();

Error in elltool.reach.ReachContinuous/auxMakeEllTubeRel (line 136)
extEllTubeRel = extellTubeBuilder.getEllTubes();

Error in elltool.reach.ReachContinuous/internalMakeEllTubeRel (line 168)
[ellTubeRel,goodDirSetObj] = self.auxMakeEllTubeRel(...

Error in elltool.reach.AReach/makeEllTubeRel (line 657)
[ellTubeRel, goodDirSetObj] = self.internalMakeEllTubeRel(...

Error in elltool.reach.AReach (line 767)
[self.ellTubeRel,goodDirSetObj,probDynObj] =...

Error in elltool.reach.ReachContinuous (line 298)
self=[email protected](varargin{:});

Software Version:
ET Version 2.1
CVX and MPT is the ones included in the toolbox
MATLAB Version: 8.5.0.197613 (R2015a)
Operating System: Microsoft Windows 7 Enterprise Version 6.1 (Build 7601: Service Pack 1)
Java Version: Java 1.7.0_60-b19 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
MATLAB Version 8.5 (R2015a)
Simulink Version 8.5 (R2015a)
Bioinformatics Toolbox Version 4.5.1 (R2015a)
Communications System Toolbox Version 6.0 (R2015a)
Computer Vision System Toolbox Version 6.2 (R2015a)
Control System Toolbox Version 9.9 (R2015a)
Curve Fitting Toolbox Version 3.5.1 (R2015a)
DSP System Toolbox Version 9.0 (R2015a)
Data Acquisition Toolbox Version 3.7 (R2015a)
Database Toolbox Version 5.2.1 (R2015a)
Datafeed Toolbox Version 5.1 (R2015a)
Fixed-Point Designer Version 5.0 (R2015a)
Fuzzy Logic Toolbox Version 2.2.21 (R2015a)
Global Optimization Toolbox Version 3.3.1 (R2015a)
Image Acquisition Toolbox Version 4.9 (R2015a)
Image Processing Toolbox Version 9.2 (R2015a)
Instrument Control Toolbox Version 3.7 (R2015a)
MATLAB Coder Version 2.8 (R2015a)
MATLAB Compiler Version 6.0 (R2015a)
MATLAB Compiler SDK Version 6.0 (R2015a)
MATLAB Report Generator Version 4.1 (R2015a)
Mapping Toolbox Version 4.1 (R2015a)
Model Predictive Control Toolbox Version 5.0.1 (R2015a)
Multi-Parametric Toolbox Version 3.1 (R2011a)
Neural Network Toolbox Version 8.3 (R2015a)
OPC Toolbox Version 3.3.3 (R2015a)
Optimization Toolbox Version 7.2 (R2015a)
Parallel Computing Toolbox Version 6.6 (R2015a)
Partial Differential Equation Toolbox Version 2.0 (R2015a)
Robust Control Toolbox Version 5.3 (R2015a)
Signal Processing Toolbox Version 7.0 (R2015a)
SimEvents Version 4.4 (R2015a)
SimMechanics Version 4.6 (R2015a)
Simscape Version 3.13 (R2015a)
Simulink 3D Animation Version 7.3 (R2015a)
Simulink Coder Version 8.8 (R2015a)
Simulink Control Design Version 4.2 (R2015a)
Simulink Design Optimization Version 2.7 (R2015a)
Spreadsheet Link EX Version 3.2.3 (R2015a)
Stateflow Version 8.5 (R2015a)
Statistics and Machine Learning Toolbox Version 10.0 (R2015a)
Symbolic Math Toolbox Version 6.2 (R2015a)
System Identification Toolbox Version 9.2 (R2015a)
Wavelet Toolbox Version 4.14.1 (R2015a)

Finish implementation of control synthesis for regularized discrete systems with uncertainty

Deadline: end of the semester

Existing implementation of control synthesis for discrete systems in issue_73_alim_komarov is implemented for the systems without uncertainty
and covered with tests that can be run via elltool.control.test.run_disc_tests. All tests basically check that a point that is within a solvability
domain is driven to a terminal set. A number of different systems is tested, each specified via a separate pair of xml file that stores a system configuration.
All system configurations are stored in products+elltool+control+test+conf\confrepo_templates and products+elltool+control+test+sysdef+conf\confrepo_templates where a system parameters are stored in the second folder while other parameters like a set of good directions, time interval etc are stored in the first folder. Configurations from the first folder reference configurations from the second folder via
systemDefinitionConfName parameter of configuration. The tests can be run either for all configurations or for a subset of configurations (see a help header for elltool.control.test.run_disc_tests for examples).

Not all implemented tests pass, particularly

a) Tests for configurations
demo3thirdTest
uosc8
ltisys
x2dtest

doesn't pass because of error "undefined function or variable AtDefCMat". This problem needs to be investigated and fixed.

b) Configuration demo3fourthTest doesn't pass because of error "timeVec is expected to contain integer values".

This problem also needs to be investigated and fixed.

c) Tests for configuration osc8 doesn't pass because of mismatch of matrix dimensions, this also needs to be fixed.

d) Some other tests doesn't pass because a system trajectory doesn't end up exactly in the terminal set.

There are two reasons for these problems:

  1. Programmatic errors in the implementation of control synthesis for systems without uncertainty
  2. Not implemented control synthesis for regularized systems with uncertainty. Some of the configurations include both uncertainty and regularization enabled. The regularization parameters are
    specified in regularizationProps section of configuration:
        <regularizationProps type="struct" >
            <isEnabled type="boolean" >0</isEnabled>
           <isJustCheck type="boolean" >0</isJustCheck>
                <regTol type="double" >1e-05</regTol>
        </regularizationProps>

where isEnabled=true and isJustCheck means that reachability tube is dynamically regularized with epsilon=regTol in formula 36 from
https://drive.google.com/open?id=0B5OqL4IVOIC8NTZCZmpBVTU3ODA

All this means that control constraint is no longer E(p(t),P(t)) but E(p(t),P(t)+M(t)) where M(t) is stored in MArray field of ellipsoidal tube returned
by getEllTubeRel method of elltool.reach.ReachDiscrete class.

For additional information about control synthesis for discrete systems under uncertainty please refer to
https://drive.google.com/open?id=0B5OqL4IVOIC8VzdaQzR3LVZ0ZDg

Here is what you need to do step by step

  1. Read https://drive.google.com/open?id=0B5OqL4IVOIC8VzdaQzR3LVZ0ZDg
  2. In parallel with 1) - study
    a) existing implementation of control synthesis for discrete systems in package elltool.control.
    b) tests for control synthesis launched via elltool.control.test.run_disc_tests. You need to understand how tests work and how to run tests for a specific system.
  3. Compare tests for discrete systems (elltool.control.test.run_disc_tests) and continuous systems (elltool.control.test.run_cont_tests). You will see that 4th column in
    confCMat for continous systems is not empty and empty for discrete systems. This column contains a list of external points that are not expected to be driven by control
    synthesis into a terminal set. The thing is that these points are not defined in the tests for discrete systems and you need to add such points for each configuration. External (outer) points are the points that are located outside of solvability domain and are expected to stay outside of solvability domain for all times. Since exact reachability domain
    is not known we can use a simple rule to generate points that are guaranteed to be outer: we just take a good direction l(t) at time t, for a point of contact between ellipsoidal
    approximation E(t) and exact X(t) along l(t) i.e. a maximizer x^{}(t) such that (l(t),x^{}(t)) rho(l(t)|E(t)) and then use x^{_}(t)+eps_l(t) as an outer point where eps is small.
    You should generate at least 3 points for each cofiguration for different l_i=l(t_s) where s usually equals t_0 (depends on configuration). At the end of this step there should
    be at least 3 outer points defined for each configuration in elltool.control.test.run_disc_tests.
  4. fix problems a,b,c,d listed above for those configurations (systems) that contain no uncertainty. After this step all tests for systems without uncertainty should pass.
  5. Study https://drive.google.com/open?id=0B5OqL4IVOIC8NTZCZmpBVTU3ODA paying a special attention to a regularization schema and the way M(t) is used in ellipsoidal approximation schema. Then modify control synthesis for discrete systems in elltool.control by using E(p(t),P(t)+M(t)) as a control constraint instead of just E(p(t),P(t)) where M(t) is stored in MArray field of ellipsoidal tube returned by getEllTubeRel method of elltool.reach.ReachDiscrete class. After this modification make sure that tests for systems with uncertainty pass.

Refactor linear problem dynamics-related code in ReachContinuous/ReachDiscrete classes and provide a dense test coverage

Deadline - end of the semester

  1. Create an abstract protected method in AReach called "getProbDynamicsBuilder" that accepts two logica inputs: isDisturbance and isBackward and returns
    a problem definition constructor. The Constructor should be returned as function handles, for instance for
    ReachDiscrete, isBackward=true, isDisturbance=false the output would be
    @(varargin)gras.ellapx.lreachplain.probdyn.LReachDiscrBackwardDynamics(gras.ellapx.lreachplain.probdef.LReachContProblemDef(varargin{:})) and for ReachContinous for the
    same type of system - @gras.ellapx.lreachuncert.probdyn.LReachProblemDynamicsFactory.createByParams.
    This is because these calls correspond to the existing logic in ReachDiscrete.getProbDynamics and elltool.reach.ReachContinuous.getProbDynamics.
    Once getProbDynamicsBuilder is implemented in both ReachContinous and ReachDiscrete merge the implementation of getProbDynamics methods from ReachContinous
    and ReachDiscrete by placing its code in AReach and making it call getProbDynamicsBuilder. This way the code getProbDynamics will be common for both ReachContinous
    and ReachDiscrete while getProbDynamicsBuilder will contain all the difference between continuous and discrete systems.

  2. Now, once getProbDynamics is in AReach replace calcPrecision input argument with two separate arguments - relTol and absTol, make sure that whereever
    getProbDynamics is calls both relTol and absTol are passed as inputs. Right now only relTol is passed - taken
    from self.relTol field, you should also pass self.absTol. Please note that getProbDynamicsBuilder should return such builders for Discrete systems that
    can accept both relTol and absTol even for Discrete systems. However for Discrete systems relTol and absTol should not be passed any further (i.e. ignored).
    Here is an example of ignoring input argument in an anonymous function that should help to understand:
    fBuild=@(varargin)constructDiscrete(varargin{1:end-2}); In this example last two arguments (relTol and absTol) are ignored. Thus, to keep things simple it is better
    to make relTol and absTol last input arguments in builders returned by getProbDynamicsBuilder. For continuous systems all the classes that previously
    accepted calcPrecision should now accept relTol and absTol. One of this classes is
    +gras+ellapx+lreachplain+probdyn\LReachProblemDynamicsInterp.m (line 30).

    function odePropList=getOdePropList(self,calcPrecision)
        odePropList={'NormControl',self.ODE_NORM_CONTROL,'RelTol',...
            calcPrecision*self.CALC_PRECISION_FACTOR,...
            'AbsTol',calcPrecision*self.CALC_PRECISION_FACTOR};
    end

defined in C:\Users\Administrator\Documents_Git\ellipsoids\products+gras+ellapx+lreachplain+probdyn\AReachProblemDynamics.m
should be changed so that it looks like this:

    function odePropList=getOdePropList(self,relTol, absTol)
        odePropList={'NormControl',self.ODE_NORM_CONTROL,'RelTol',...
            relTol*self.REL_TOL_FACTOR,...
            'absTol',absTol*self.ABS_TOL_FACTOR};
    end

where REL_TOL_FACTOR and ABS_TOL_FACTOR constant have the same value as CALC_PRECISION_FACTOR for now. CALC_PRECISION_FACTOR constant need to be removed.

  1. Add one more optional input to gras+ellapx+lreachuncert+probdyn\LReachProblemDynamicsFactory.createByParams called "isDiscrete", if not specified assume
    that isDiscrete=false. Then make createByParams a bit smarter by implementing an ability to construct discrete systems in the same way
    as getSysWithDisturb and getSysWithoutDisturb did that in ReachDiscrete that prior to implementation of step 1) above.
    Then get rid of getProblemDynamics call in both AReach constructor and evolveApprox and use
    gras+ellapx+lreachuncert+probdyn\LReachProblemDynamicsFactory.createByParams instead. Please note that there is no need to pass isDisturbance into createByParams
    as it is capable to determining if the system contains disturbance in the same way as AReach can. This means that isDisturbance method in AReach
    should be removed as well as the following call on line 564:
        isDisturbance = LReachProblemDynamicsFactory.getIsDisturbance(...
            ctStrCMat, qtStrCMat);
  1. Cover problem dynamics and problem definition classes from the following packages with tests
    \products+gras+ellapx+lreachplain+probdef
    \products+gras+ellapx+lreachplain+probdyn
    \products+gras+ellapx+lreachuncert+probdef
    \products+gras+ellapx+lreachuncert+probdyn

the test cases should be located in the following packages

\products+gras+ellapx+lreachplain+probdef+test+mlunit
\products+gras+ellapx+lreachplain+probdyn+test+mlunit
\products+gras+ellapx+lreachuncert+probdef+test+mlunit
\products+gras+ellapx+lreachuncert+probdyn+test+mlunit

functions run_tests should be located in each +test subpackage.
and their calls should be added to \products+gras+ellapx+test\run_tests function.

For the problem definition classes (in probdef packages) the tests should construct the problem definition objects on a few simple systems
and verify that all methods return a correct result. Please note that there should be no copy-pasting in the tests - you should parameterize them
with tested calsses so that the same test case can be applied to different problem definition classes. This approach is very well demonstrated
in elltool.reach.test.run_cont_tests - please use this function as a reference.

For problem dynamics classes the approach should be similar - create problem dynamics for a few simple systems and make sure that the values returned by
its methods (by getAtDynamics method responsible for returning a matrix function for A(t)) match the expected result on a certain time grid. For A(t) it means that
you need to check that A(t_i) matches the expected result for all t_i from the time grid.

After each step (and actually during the implementation of the steps) you need to make sure that ALL tests pass. Implementation without all the tests passing = zero result.

Introduce a parameter that would make evolution of reachability tubes along all the "good" directions optional

Right now AReach.evole methods builds tight ellipsoidal approximations for each terminal ellipsoid along each good direction. Thus for two good directions at time t_1 would get 2 tubes, at time t_2 (after the first evolve) - 4 tubes etc. This might not be the best approach in all the cases as sometimes we might be better off with just 2 ellipsoidal tubes after each evole. The solution would be creating an optional parameter in evolve method to specify whether we need use all good directions for each terminal ellipsoidal ellipsoid or just 1 direction for which the ellipsoid in question is a tight one.

Make ReachContinous return an original system dynamics even for a system in a backward time (for a attainability domains)

Deadline - 1st of November, by that date the code with all the tests should be in "master" branch.

Currently evaluating an solvability tube as per the following example

aMat = {'2_sin(t)' '0'; '0' '2_sin(t)'}; bMat = eye(2);
SUBounds = struct();
SUBounds.center = {'0'; 't/10'};
SUBounds.shape = [.1 0; 0 .1];
sys = elltool.linsys.LinSysContinuous(aMat, bMat, SUBounds);
x0EllObj = ell_unitball(2);
timeVec = [2 0];
dirsMat = [1 0; 0 1]';
rsObj = elltool.reach.ReachContinuous(sys, x0EllObj, dirsMat, timeVec);
rsObj.evolve(-1,sys);

would result into modifying the system parameters so that A(0) is no longer [2 0;0 2]:

pdl = rsObj.getIntProbDynamicsList;
pdl1 = pdl{1}{1};
at = pdl1.getAtDynamics();
at.evaluate(0)

ans =
-1.8186 0
0 -1.8186

This is because "prepareSysParam" method in ReachContinous transforms the system parameters in a such way that a reachability tube for the modified system equals a solvability domain for the original system in an opposite time.

One needs to make sure that modifying the system parameters becomes an internal business of ReachContinous while the system dynamics returned by getIntProbDynamicsList method (and others) corresponds to the original (non-modified) system.

The way to implement this is to create a class that would be a "wrapper" system for any system in forward time. This way instead of manually modifying each system matrix (A(t), C(t), B(t) etc) in prepareSysParam we would just create an instance of the wrapper system like this

backTimeWrapperSysObj=BackwardTimeWrapSystem(sysDynObj);

and then would use this backTimeWrapperSysObj internally while externally getIntProbDynamicsList method and others would return the original dynamics no matter what.

The new wrapper class needs to be placed into products+elltool+linsys package next to other LinSys classes and separately covered with tests in a new test case placed into products+elltool+linsys+test+mlunit package.

Obviously we will have to have 2 different wrapper classes for both discrete and continuous systems.

Also the correct behavior of ReachContinuous and ReachDiscrete classes needs to be covered with
a few tests
\products+elltool+reach+test+mlunit

Finally all the existing tests need to be fixed because in some places it is currently assumed that the getIntProbDynamicsList works the way it works now so those places will have to be fixed so that all the tests pass.

Refactor comparison methods of GenEllipsid, ellipsoid and hyperplane via inheriting these classes from modgen.common.obj.HandleObjectCloner

Deadline: end of the semester

GenEllipsoid, ellipsoid and hyperplane classes are all inherited from elltool.core.AGenEllipsoid class that implements isEqualInternal method
that is designed for an element-wise comparison of two object arrays. HandleObjectCloner in its turn takes this even futher by introducing
separate methods for element-wise comparison, pair-wise comparison of multiple arrays and even supporting gt,le,lt,ge and sort operators based on
lexicographical comparison of BLOB sequences. The goal of this task is to get rid of isEqualInternal method by replacing it with the methods
inherited from HandleObjectCloner class. Doing so will cause the following changes in the way some of the comparison methods work:

I) isEqual method implemented in AGenEllipsoid now returns a logical array isEqualArr that contains a result of element-wise comparison of corresponding
object elements while isEqual implemented in HandleObjectCloner returns a scalar logical output that contains a result of comparison of multiple inputs (type
edit modgen.common.obj.HandleObjectCloner.isEqual to see for yourself). However HandleObjectCloner.isEqualElem does the same as AGenEllipsoid.isEqual. This means
that after inheriting AGenEllipsoid from HandleObjectCloner all tests (and other code) that used AGenEllipsoid.isEqual to do element-wise comparison will have to be
changed to use isEqualElem. The good thing however is that most of the code while calling isEqual did it solely for scalar objects which means this code expected
an output of isEqual to be scalar. Thus most of the code won't have to be changed.

II) AGenEllipsoid uses Matlab built-in implementation of isequal, isequaln and isequalwithequalnans which is based on comparing objects as binary sequences. HandleObjectCloner
however changes that by redirecting calls to these 3 methods to either isEqualScalarInternal or isEqualScalarAsBLOBInternal depending on what HandleObjectCloner.getComparisonMode
method returns (if asBLOB property is not specified). There is asHandle flag that can also be specified, if true then calls to isequal, isequaln and isequalwithequalnans are redirected to eq with asHandle=true flag and objects are compared as handles.

III) HandleObjectCloner also re-defines >=, <=,>,< == and ~= operators (same as ge, le,gt, lt,eq,ne). Since ellipsoid overrides <=,>=,<,> based on its own ellipsoid-based logic an implementation of this operators in ellipsoid class should not be touched. However, ne operator in ellipsoid class needs to be removed since HandleObjectCloner's implementation of the same operator is more correct.

IV) Some tests for ellipsoid, hyperplane and GenEllipsid classes use eq,==, isequal, isequaln and isequalwithequalnans methods to compare ellipsoids. There can be two reasons for that
a) a need to compare objects as binary sequences (this is the way the built-in implementation of isequal* methods work) i.e. with absolute precision using all content of the object including the fields like "absTol" that ordinary "isEqual" method does not compare.
b) Just a human error - a developer could have used isEqual but used isequal instead just because it looked more familiar.
These two case need to be treated separately - in case a) you need to replace calls with isEqual with "asBlob" flag while in b) you need to use just "isEqual" without asBlob.

The complete functionality of HandleObjectCloner can be easily studied by looking at the tests of this class in +modgen+common+obj+test+mlunit\HandleObjectClonerTC.m
test case.

Here is what you need to do step by step

  1. Remove implementation of isEqualInternal method in AGenEllipsoid and add inheritance from modgen.common.obj.HandleObjectCloner.
  2. Go through all tests for ellipsoid, GenEllipsid and hyperplane classes in elltool.core.test. package and make a method replacement based on items I)-IV) and Make sure all
    tests from elltool.core.test package pass.
  3. Make sure that all ET tests pass.
  4. Implement additional tests in a separate test case class in elltool.core.test.mlunit package for isEqualElem, isequal, isequaln,isequalwithequalnans, ne and eq methods.
    These tests should be made common for ellipsoid, hyperplane and GenEllipsid i.e. parametrized by these objects factory (i.e. one test case class should test all 3 classes).
    When doing so please refer to elltool+core+test+mlunit\HyperplaneDispStructTC and elltool+core+test+mlunit\EllipsoidDispStructTC test cases as example (both these test cases
    are inherited from elltool.core.test.mlunit.ADispStructTC class that contain the tests while sub-classes define certain methods that contain all the differences between
    of hyperplanes and ellipsoids).

Refactor and optimize ellipsoid.toPolytope

Deadline is October 28th, by that time the changes and all the tests should be in "master" branch

ellipsoid.toPolytope method is currently based on elltool.exttbx.mpt.gen.tri2polytope function. This function uses "null" and "cross" functions which is an overkill for 2d and 3d cases. These functions should be replaced with a exact highly-efficient formulas. Once this is done one needs to write a few performance tests that make sure that toPolytope performs x% slower comparing to a performance of ellipsoid.getBoundary method (also called internally from toPolytope) where x is assumingly around 10-20%. The idea is that tri2polytope should only take a small portion of toPolytope's runtime.

The performance tests should run getBoundary and getPolytope multiple times, compare their runtimes and make sure that the difference is percentage terms is less than x where x is a constant specified in the test. The tests should be implemented in +elltool+core+test+mlunit\MPTIntegrationTestCase.m test case. The total runtime of all newly added tests should not be large though (minutes at max).

Make ellipsoid.plot create axes labels

Deadline - 16th of November, by that time the changes and the new tests should be in "master branch

Right now ellipsoid.plot doesn't create any axis labels neither for 2d nor for 3d case.
We need to make "plot" method create labels in "x_i" format where i is the axis number.
When creating a label one needs to keep in mind that
a) plot method can be called for an array of ellipsoids like this

ellVec=[ellipsoid(eye(2)),ellipsoid(eye(2)*2)];
ellVec.plot

in which case all ellipsoids are created on the same axes unless "newFigure" property is specified.
So one needs to make sure that labels are only created once for each axes in both cases.
Also, when creating a label one should use the following approach:

% hAxes is some axes handle
set(get(hAxes,'XLabel'),'String','x_1','Interpreter','tex');

get(hAxes,'XLabel') will return a non-empty axes handle even when the axes didn't have any labels prior to the call.

b) plot has a few input properties including 'relDataPlotter'. This property is used to pass in a RelationDataPlotter object that is a container for all future graphical objects. See the tests for RelationDataPlotter in \lib+smartdb+disp+test\mlunit_test_disp.m for more
details. Anyways, if RelationDataPlotter is not specified it is created internally so that all plotting is performed by an internal
RelationDataPlotter object. This object makes sure that there are no any untracked graphical objects (text labels are also graphical objects)
and throws an exception ("no all handles are tracked") if this is not the case. To avoid such exceptions one needs to return handles for all newly created graphical objects from internal plotting functions like

function hVec=axesSetPropDoNothingFunc(hAxes,)
axis(hAxes,'on');
axis(hAxes,'auto');
grid(hAxes,'on');
hold(hAxes,'on');
hVec=[];
end
%
function hVec=axesSetPropDoNothing2Func(hAxes,
)
axis(hAxes,'on');
axis(hAxes,'auto');
grid(hAxes,'on');
hold(hAxes,'off');
hVec=[];
end

subfunctions in +elltool+plot\plotgeombodyarr.m function.

Presumably adding labels will require changing one (or both) of these functions and replacing an empty list of properties (column names in a relation) for these functions in the following code (line 147 from plotgeombodyarr)

if isObj
rel=smartdb.relations.DynamicRelation(SData);
if (nDim==2)||(nDim == 1)
plObj.plotGeneric(rel,@figureGetGroupNameFunc,{'figureNameCMat'},...
@figureSetPropFunc,{},...
@axesGetNameSurfFunc,{'axesNameCMat','axesNumCMat'},...
@axesSetPropDoNothingFunc,{},...
@plotCreateFillPlotFunc,...
{'xCMat','faceCMat','clrVec','fill','shadVec', ...
'widVec','plotPatch'},...
'axesPostPlotFunc',postFun,...
'isAutoHoldOn',false);
elseif (nDim==3)
plObj.plotGeneric(rel,@figureGetGroupNameFunc,{'figureNameCMat'},...
@figureSetPropFunc,{},...
@axesGetNameSurfFunc,{'axesNameCMat','axesNumCMat'},...
@axesSetPropDoNothingFunc,{},...
@plotCreatePatchFunc,...
{'verCMat','faceCMat','faceVertexCDataCMat',...
'shadVec','clrVec','plotPatch',...
},'axesPostPlotFunc',postFun,...
'isAutoHoldOn',false);
end

with some information that can be used to determine a dimensionality of axis.

  1. One needs to account for potential cases when 3d and 2d ellipsoids are displayed on the same axes. Surely,
    a call like this ellVec=[ellipsoid(eye(2)),ellipsoid(eye(3))]; is not supported right now but one can specify relation data plotter containing some 2d ellipsoids to plot 3d ellipsoids. This should not result into axes being renamed (x_2 becoming x_1 when we add 3d ellipsoid to 2d plot)

4)The implemented functionality should be covered with tests implemented in the following test pack.
+elltool+core+test+mlunit\GenEllipsoidPlotTestCase. In the test one needs to consider different combinations of input parameters and array sizes. Negative tests are also required. See Wiki for an example of a negative test (mlunitext.test_case.runAndCheckError).

  1. No copy-pasting, compliance with the coding style (see Wiki) and presence of code comments.
    No commented out code, no blank lines, no long lines.

Finish implementation of control synthesis classes almost finished by Yurij Komarov and Damir Alimov

Below (under the line) is the old task description. It is a bit out of date and not very detailed. A new much more detailed description and references to the articles wll be added within 1-2 days.

Estimated time: whole semester, this will be your only task.


The task is analogous to Issue #3 (branch Issue_74_asemenova) but for discrete systems. Issue 3 introduces classes

ContControlBuilder,Control

In this task one needs to

  1. Rename Control class into ContContrTrajectoryBuilder (continuous control).
  2. Create DiscrControlBuilder and DiscrControl classes having the same interface (and some common internal code located in abstract AControlBuilder and AControl classes).
  3. The logic of DiscrControlBuilder and DiscrControl classes should be covered with the regression tests in exactly the same manner as it was done in Issue #3 by Anastasia Semenova.

Implement control synthesis for systems with uncertainty

Deadline: end of the semester

  1. Classes for control synthesis have been implemented for systems without disturbance as per
    issue #7. The classes have not yet been merged into master because of a few issues with performance and structure - see details in issue 7 (last comments, items >=13, both high and low priority items). The goal of this step is to have control synthesis classes without any major bottlenecks and test failures. After this step there should be a merge to master branch.

Please use the following articles as a reference
https://drive.google.com/open?id=0B5OqL4IVOIC8eU1VWjFyVVhzTzA
https://drive.google.com/open?id=0B5OqL4IVOIC8VzdaQzR3LVZ0ZDg

and contact Yurij Komarov and Damir Alimov if you have questions concerting the source code of the control synthesis classes (their emails are available in the help headers for those classes).

  1. In the classes responsible for control synthesis for discrete systems please implement a check that throws an exception in case those classes are used for systems with uncertainty. The message should be "Control synthesis for discrete systems with uncertainty is not yet supported". Then please write a negative test for that check in a separate test case in elltool.control.test package.

  2. Study the way gras.ellapx.uncertmixcalc.run function works. This function returns an ellipsoidal tube and a list of the tube projections on a few subspaces.
    The tube is build via a mixing procedure described in this article https://drive.google.com/open?id=0B5OqL4IVOIC8ektZbGZCMFIwX2s.
    System parameters, good directions l(t) and subspaces for projections are all part of xml configuration that is specified as
    the first input to gras.ellapx.uncertmixcalc.run function.
    You can
    a) Show a list of existing system definitions via running gras.ellapx.uncertmixcalc.listsysconf()
    b) Show details of an existing definition via gras.ellapx.uncertcalc.editsysconf(sysName)
    gras.ellapx.uncertmixcalc.editsysconf('default') for instance
    c) Copy an existing definition via running gras.ellapx.uncertmixcalc.copysysconf('default','testsys');
    d) Edit the copied system definition: gras.ellapx.uncertmixcalc.editsysconf('testsys'); If you want to define a system with the matrices not-depending on t - make
    sure that definitions of matrices A,B etc do not depend on it.

Apart from a system definition configuration there is a configuration that specifies parameters of calculation. For these configurations the same set of
utility functions is available:
a) Show list of configurations: gras.ellapx.uncertmixcalc.listconf
b) Show details of an existing configuration - gras.ellapx.uncertmixcalc.editconf(confName)
c) Copy an existing configuration configuration gras.ellapx.uncertmixcalc.copyconf('default','testconf');
d) Edit the copied configuration - gras.ellapx.uncertmixcalc.editconf('testconf');. Please make sure to put a correct system name into
'systemDefinitionConfName' section. I.e. to refer to the system 'testsys' you need to write 'testsys'.

Once both the system and calculation configurations are set up type gras.ellapx.uncertmixcalc('testconf') to run the calculation of reachability tube.

All configurations are stored as xml files in

\products+gras+ellapx+uncertmixcalc+conf\confrepo_default
\products+gras+ellapx+uncertmixcalc+conf+sysdef\confrepo_default

  1. Implement a class elltool.reach.ReachRelaxedContinuous by using the same approach as ReachContinuous uses for the tight approximations but for
    the relaxed approximations based on the tube mixing. ReachContinuous uses internal pieces of gras.ellapx.uncertcalc.run while the new class
    ReachRelaxedContinuous should use the internal pieces of gras.ellapx.uncertmixcalc.run.

Both ReachRelaxedContinuous and ReachContinuous should both be inherited from AReachRelaxed which in its turn should be inherited from AReach. AReachRelaxed should contain continuous systems-specific code that is common for both relaxed and tight approximations. Also please copy elltool.reach.

  1. Modify elltool.reach.ReachFactory so that it can return instances of ReachRelaxedContinuous. Then study tests from elltool.reach.test.run_cont_tests, copy a portion of tests that can be run for both ReachRelaxedContinuous and ReachContinuous into run_cont_generic_tests and make run_cont_tests call run_cont_generic_tests with ReachFactory that returns instances of ReachContinuous objects. Then create run_contrelax_tests that calls run_cont_generic_tests with ReachFactory returning ReachRelaxedContinuous objects. This way you will cover ReachRelaxedContinuous using the tests already written fro ReachContinuous.

After that please make a merge into master

  1. Once ReachRelaxedContinuos is implemented please create configurations in
    products+elltool+control+test+conf+sysdef\confrepo_templates
    products+elltool+control+test+conf\confrepo_templates

for an oscillating system described in https://drive.google.com/open?id=0B5OqL4IVOIC8c3FQTHk4V1RyYnc

  1. Make sure that the system is stabilized using the control synthesis classes described in item 1)

Cover GenEllipsoid, ellipsoid and hyperplane with parameterized test cases and make them use common code where possible

Deadline: end of the semester

The goal of this task is to finish the re-factoring of different classes representing ellipsoids, hyperplanes and make the tests for
them parametrized by ellipsoid object factories. Such parametrization allows for running the same number of tests against different kinds
of ellipsoids (both generalized and plain) and hyperplanes. Of course not all tests can be so universal but many can. For instance if a test
checks a behaviour of "rho" method responsible for support function calculation this test doesn't need to know which object it tests.
All this test really needs is a factory that can create objects. This factory can then be passed into the test cases using the approach described
here: https://github.com/SystemAnalysisDpt-CMC-MSU/ellipsoids/wiki/MLUNITEXT-unit-testing-framework-description#writing-parameterized-tests.

Branch issue_8_vert_svart implements the described ideas but only partially. The main problem with implementing a test parameterization was not
having many methods in GenEllipsoid class that are present in ellipsoid class. This didn't allow for the tests intended for testing ellipsoid
methods to run for generalized ellipsoid objects (GenEllipsoid class). The solution was to implement all missing methods but this task was not
finished. Now there is an understanding that we need to approach this problem in two steps.

  1. The very first step should be
    a) creating a copy of issue_8_vert_svart for your task (i.e. you should branch from issue_8_vert_svart, not from master).
    b) rebasing your branch to master and making sure that tests are successfully run on the server. Most of the tests won't pass but the tests
    runs should not crash so that we can see the test results.

Only when this is done we should move to the next step. Please note - it will be much more easier to rebase if after creating your branch as a copy
of issue_8_vert_svart you combine all commits starting with "68fe72c9f1c98d81d91451fd0dba7b95e012cbb9" made on 08-Mar-2015 into a single commit
(open log, select all commits you want to combine, then right click - > combine to one commit). If you start rebasing without combining all commits
into one you will have to resolve much more conflicts. Yes, there will be a lot of conflicts but you need to go through the changes very carefully
and resolve each conflict manually. In 99% of cases it will be clear how to resolve them because the changes in issue_8_vert_svart branch are very
typical and similar to each other.

  1. The next step should be providing a simplified implementation of all missing methods from ellipsoid in GenEllipsoid class.

A generalized ellipsoid is a set that can be represented as sum E+L, where L - a subspace of R^n and E is some (may be degenerate) ellipsoid in
an orthogonal complement to L. A generalized ellipsoid doesn't have a configuration matrix in a common sense (by construction) but it does have
a) a basis in L and its complement.
b) a configuration matrix of E (ellipsoid in the orthogonal complement to L)

Since all tests for "ellipsoid" class (plain ellipsoid) only deal with the case of empty L it will be sufficient to implement the missing methods of GenEllipsoid
via "ellipsoid" class. Here an an example of how some hypothetical method "methodX" that is implemented in "ellipsoid" class can be implemented GenEllipsoid:

classdef GenEllipsid

methods (Access=private)
function shMat=getShapeMatIfPlan(self)
%this method returns a shape matrix of generalized ellipsoid self in case L is empty i.e. when self is "plain" ellipsoid.
%in case L is not empty getShapeMatIfPlan throws an exception.
end
end

methods

function varargout=methodX(self,varargin)
    %this is a stub method that works only in a very specific case - when self is plain ellipsoid.
    shMat=self.getShapeMatIfPlan();
    cVec=self.getCenterVec();
    tmpEllObj=ellipsoid(shMat,cVec);
    if nargout==0
        tmpEllObj.methodX(varargin{:});
    else
        varargout=cell(1,nargout);
        [varargout{:}]=tmpEllObj.methodX(varargin{:});
    end
end

end
end

Method getShapeMatIfPlan is not implemented just yet but it is very easy to implement.

As you can see such implementation of methodX is just a stub which works only when generalized is not actually a generalized
ellipsoid but a plain ellipsoid. However this is more than sufficient for making all the existing test pass for both plan and
generalized ellipsoids.

Please note that the following methods are common for both GenEllipsoid and ellipsoid so they need to be moved to AEllipsoid class:

move2origin
getAbsTol
getRelTol
gt,lt,ge,le
getShape
getMove2Origin
getNPlot2dPoints
getNPlot3dPoints
getInv

  1. The final step step is finishing test parametrization by factories. Once you are done with step 1) you may discover that
    everything is already parametrized but there is no guarantee. The goal is to have the same tests for both "ellipsoid" class,
    "GenEllipsid" class and sometimes - "hyperplane". Tests need to be partitioned into the following groups

a) tests that are specific to GenEllipsid - these tests cover generalized ellipsoid functionality and not applicable for "plan"
ellipsoids
b) tests that are specific to hyperplanes ("hyperplane" class)
c) tests that are common for both GenEllipsid and ellipsoid classes.
d) tests that are common for GenEllipsid, ellipsoid and hyperplanes. Yes, there are tests that are suitable for both
hyperplanes and ellipsoids.

Each of these groups should consist of one or more tests cases parametrized by ellipsoid/hyperplane factories. Please note that
this is almost done in the issue_8_vert_svart, you just need to finish what was started.

One more thing to keep in mind - the changes introduced in issue_8_vert_svart are very conflict-provoking which means that
even after resolving all the conflicts and fixing all the problems a single change in "master" branch can cause new conflicts.
That is because people working with master do not know about test parametrization introduced in issue_8_vert_svart so thay
continue writing new non-parametrized tests. So the sooner you finish the task - the fewer conflicts you will have to resolve.

Finally, please note that issue_8_vert_svart slightly changes a hierarchy of ellipsoid classes by introducing AEllipsoid
and ABasicEllipsoid classes. elltool.core.ABasicEllipsoid is a base class for all kinds of ellipsoids and hyperplane.

Please rename ABasicEllipsoid into AGeomBody.

AEllipsoid is inherited from ABasicEllipsoid and is a base class for both ellipsoid
and GenEllipsid, while hyperplane is inherited directly from ABasicEllipsoid.

Cover problem dynamics and problem definition classes with tests

Cover problem dynamics and problem definition classes from the following packages with tests
\products+gras+ellapx+lreachplain+probdef
\products+gras+ellapx+lreachplain+probdyn
\products+gras+ellapx+lreachuncert+probdef
\products+gras+ellapx+lreachuncert+probdyn

the test cases should be located in the following packages

\products+gras+ellapx+lreachplain+probdef+test+mlunit
\products+gras+ellapx+lreachplain+probdyn+test+mlunit
\products+gras+ellapx+lreachuncert+probdef+test+mlunit
\products+gras+ellapx+lreachuncert+probdyn+test+mlunit

functions run_tests should be located in each +test subpackage.
and their calls should be added to \products+gras+ellapx+test\run_tests function.

For the problem definition classes (in probdef packages) the tests should construct the problem definition objects on a few simple systems
and verify that all methods return a correct result. Please note that there should be no copy-pasting in the tests - you should parameterize them
with tested calsses so that the same test case can be applied to different problem definition classes. This approach is very well demonstrated
in elltool.reach.test.run_cont_tests - please use this function as a reference.

For problem dynamics classes the approach should be similar - create problem dynamics for a few simple systems and make sure that the values returned by
its methods (by getAtDynamics method responsible for returning a matrix function for A(t)) match the expected result on a certain time grid. For A(t) it means that
you need to check that A(t_i) matches the expected result for all t_i from the time grid.

Add support for Linux

As of now this is almost done, what remains is automating unit test runs on Linux and fixing some potential minor bugs

Make ode45reg work in reverse time

Deadline - 27th of October, by that time both changes and tests should be merged into "master" branch

As opposed to built-in ode45 function gras.ode.ode45reg cannot handle reverse time just yet. The solution is to replace t with -t using anonymous functions inside ode45reg and then apply fliplr just before returning the output arguments. Once this is done one needs to write a test inside products+gras+ode+test+mlunit\SuiteOde45Reg.m that iterates through a few different systems (functions for right hand side of ode equation) and compares that a solution in a direct time on [0,T] coincides with a flipped solution of the system where we substitute t with T-t. Comparison should be done with modgen.common.absrelcompare (see how existing tests in SuiteOde45Reg test case work).

I think the best way would be doing this as the following sequence of steps:

  1. rename ode45reg into ode45regdir where "dir" means "direct time"
  2. implementing a wrapper function ode45reg that
    a) if tSpanVec is in forward time - ode45regdir directly OR
    b) if tSpanVec is in opposite time - adjusts input arguments (timeVec,fOdeReg,tSpanVec,y0Vec as mentioned above), then calls ode45regdir and finally adjusts the output arguments back (this includes interpObj of gras.ode.VecOde45RegInterp class - see step 3).
  3. Define an interface gras.ode.IVecOdeReg that defines "evaluate" method with the same signature as in VecOde45RegInterp and make VecOde45RegInterp define this interface. Also please add getTStart and getTEnd methods that returns self.tBegin and self.tFinal.
  4. Create a new class VecOdeRegInverseTimeWrapper that implements the same interface. A constructor of this class should accept an object of VecOde45RegInterp class and store it in its private field "interpObj". "evaluate" method should call self.interpObj.evaluate and then adjust the outputs so that they correspond to a forward time again. This makes VecOdeRegInverseTimeWrapper a thin wrapper that just changes a direction of time. When making a transformation you will have to call self.interpObj.getTStart() and self.interpObj.getTEnd() to make a time direction adjustment (T-t -> t requires knowing T=tEnd-tStart).
  5. Make ode45reg return an object of VecOdeRegInverseTimeWrapper class in case tSpanVec corresponds to an inverse time.
  6. Write a few additional tests next to already existing tests to make sure that everything works as expected.

Make Matlab recognize ET as "supplemental software" with its own documentation just like MPT 3.1

Assuming ET is installed If we look at help browser we see that Matlab recognizes MPT 3.1 as supplemental software. Authors of MPT has made this possible by following the instructions from http://www.mathworks.com/help/matlab/matlab_prog/display-custom-documentation.html

Right now we have elltool.doc.run_helpcollector utility that scans help header for all classes and functions in ET and produces doc\chap_functions.rst. This file is in reStructured text format but it was only meant to be part of ET manual document, not interactive help. We use Sphinx to convert rst files into latex and html (there is a page in Wiki that describes how we do it).

We need to improve run_helpheader so that it produces rst that can then produce html (via Sphinx) which is much more suitable for an interactive help viewable from Matlab Help Browser. If reStructured format is too limiting - we can create a special version of run_helpheader that generates html directly (though a preferrable solution we be using rst as an intermediate format.

For functions that that produce pictures we need to write scripts (a few for each function) that demonstrate a few use cases. run_helpheader would run those scripts automatically and capture pictures (the same way it does run demo examples and generate pictures for the manual). Those pictures would then become a part of interactive help.

Once html documentation is generate we need to follow all the steps from
http://www.mathworks.com/help/matlab/matlab_prog/display-custom-documentation.html
to integrate ET into Matlab. This way Matlab will recognize ET as "supplemental software".

Fix testBackward in ContinuousReachFirstTestCase and make it pass

Test testBackward in \products+elltool+reach+test+mlunit\ContinuousReachFirstTestCase.m is not finished. The idea of the test is to use the ellipsoidal tube cut at t_1 and use the resulted ellipsoid as an initial set for calculating the reachability domain. Then compare the resulted domain with the domain in direct time.

Implement a few methods of "ellipsoid" class in "GenEllipsoid" class

Deadline: end of this semester

The goal of this task is to implement a few methods of "ellipsoid" class for "GenEllipsoid" class.

A generalized ellipsoid is a set that can be represented as sum E+L, where L - a subspace of R^n and E is some (may be degenerate) ellipsoid in
an orthogonal complement to L. A generalized ellipsoid doesn't have a configuration matrix in a common sense (by construction) but it does have
a) a basis in L and its complement.
b) a configuration matrix of E (ellipsoid in the orthogonal complement to L).

You will have to refer to the generalized ellipsoid class implementation (elltool.core.GenEllipsoid class)
and its tests in

    elltool.core.test.mlunit.GenEllipsoidTestCase
    elltool.core.test.mlunit.GenEllipsoidPlotTestCase

for a better understanding of how this class works.

Once you gain a sufficient level of confidence in your understanding of GenEllipsoid class please
implement the following methods of ellipsoid class in GenEllipsoid class.
Method names, format of input and output arguments should not be changed.

isbigger
trace
shape
getShape
mtimes
parameters
plus
minus
polar
projection
fromRepMat
volume
maxeig
mineig
empty
trace
toStruct
hpintersect

All these methods should be covered with all kinds of tests that you need to put into
elltool.core.test.mlunit.GenEllipsoidSecTC class. The test coverage should
be very dense (different dimensions, all kinds of generalized ellipsoids, different combinations of
input parameters, both negative and positive tests).

Problem with legend of plot in Ellipsoid toolbox v 2.01

I have used Ellipsoid toolbox v 2.01. After plotting the ellipsoids, I have added a legend to this plot in the same way we add legend in MATLAB. However, instead of line, each ellipsoid is represented with a rectangular box in the legend box. I would be grateful if you could advise me how can I fix this problem.

Thanks in advance.
12

Finish implementation of ellipsoidal tube interpolation

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

  1. E_1[t] belongs E_2[t] at all times
  2. 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

  1. 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.

  1. 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).

  1. 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.

  1. Finish changes to problem dynamics classes (see above). Right now only a class for LTI system has been changed.

  2. 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).

  3. 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.

  1. 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

  1. 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

  1. 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

Implement quadmat function and ellipsoid.quadFunc method and use them everywhere in the toolbox instead of explicit

Deadline - October 28th, by that time the code and all the tests should be in "master" branch

Right now quadratic functions (x-c,Q^{-1}(x-c)),(x-c,Q(x-c)),(x,Q^{-1}x),(x,Qx) are calculated in many places of the toolbox
in a different way. This needs to be changed by

  1. introducing a single Matlab function that calculates these functions
  2. replacing the exact formulas in various places across the toolbox code with the calls to this function.

This function should to be placed next to
+gras+geom+ell\rhomat.m function and covered with tests in
\products+gras+geom+ell+test+mlunit\SuiteBasic.m test case.

The function should be called quadmat and should accept the following parameters

qMat - the matrix itself
xVec - x vector
cVec - center (optional, if not specified - zero is assumed)
mode - optional regime specifier, can take the following values
'plain' - use Q
'invadv' - use Q^{-1} and calculate it using gras.geom.ell.invmat function that you also need to implement. invmat should
have the same body as ell_inv function i.e. just copy content of ell_inv into invmat, cover invmat with tests, remove ell_inv
and replace all references to ell_inv with references to gras.geom.ell.invmat
'inv' - use Q^{-1} but instead of calculating Q^{-1} use the algorithm from getPolar nested function of ellipsoid.doesContainPoly method.

quadmat should be covered with all kinds of tests that call it with different combinations of input parameters and also negative tests (calling with incorrect parameters and making sure that an excepted exception is thrown - use runAndCheckError method of mlunitext.test_case, see MLUNITEXT portion of Wiki)

Also, please compare inv and invadv modes on iil-conditioned matrices to see the difference and write a test where invadv gives a better result than inv

Finally once quadmat is fully tested replace calls in all places of the toolbox with the calls to this function.

Here are only a few such places but you need to find all of them, no need to go far - just look at the body of all methods of ellipsoid class.

elltool.core.test.mlunit.MPTIntegrationTestCase.testToPolyhedron
\products\elltoolboxcore@ellipsoid\polar.m
\products\elltoolboxcore@ellipsoid\doesContainPoly.m

Be careful when replacing the calls and make sure that all the tests still pass after the replacement. You can run only the core tests for the ellipsoid class first by calling elltool.core.test.run_tests. If all pass then run elltool.test.run_tests

Finally, create a method that uses quadMat on ellipsoid matrix itself. The name of the method should be ellipsoid.quadFunc

This method needs to be covered with tests. Once this is done again look through the toolbox code to find the places where this method
can be used instead of explicit formulas formulas.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.