KerMor  0.9
Model order reduction for nonlinear dynamical systems and nonlinear approximation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BaseFirstOrderSystem.m
Go to the documentation of this file.
1 namespace models{
2 
3 
4 /* (Autoinserted by mtoc++)
5  * This source code has been filtered by the mtoc++ executable,
6  * which generates code that can be processed by the doxygen documentation tool.
7  *
8  * On the other hand, it can neither be interpreted by MATLAB, nor can it be compiled with a C++ compiler.
9  * Except for the comments, the function bodies of your M-file functions are untouched.
10  * Consequently, the FILTER_SOURCE_FILES doxygen switch (default in our Doxyfile.template) will produce
11  * attached source files that are highly readable by humans.
12  *
13  * Additionally, links in the doxygen generated documentation to the source code of functions and class members refer to
14  * the correct locations in the source code browser.
15  * However, the line numbers most likely do not correspond to the line numbers in the original MATLAB source files.
16  */
17 
19  :public KerMorObject {
84  public: /* ( setObservable ) */
85 
204  Inputs = {""};
224  Params = data.ModelParam.empty;
324  public: /* ( Transient ) */
325 
326  mu = "[]";
339  u = "[]";
352  inputidx = "[]";
365  public:
366 
367  NumStateDofs = "[]";
368 
370 
371  NumTotalDofs = "[]";
372 
373 
374  public: /* ( Dependent ) */
375 
400  public:
401 
413  public:
414 
416  this.validateModel(model);
417  this.Model= model;
418  this.C= dscomponents.LinearOutputConv(1);
419 
420  /* Register default properties */
421  this.registerProps(" A "," f "," B "," C "," x0 "," Inputs "," Params "," MaxTimestep "," StateScaling ");
422  }
434  rsys = models.ReducedSystem(rmodel);
435  }
446  function setConfig(mu,inputidx) {
447  if isempty(mu) && ~isempty(this.Params)
448  error(" A model with parameters cannot be simulated without a parameter argument. ");
449  end
450  if size(mu,1) ~= this.ParamCount
451  error(" The mu vector size mismatches the defined parameter number. ");
452  end
453  this.mu= mu;
454 
455  if isempty(inputidx) && ~isempty(this.Inputs)
456  cprintf(" red "," Attention: Starting simulations without input, but the system has configured some.\n ");
457  /* inputidx = 1; */
458  elseif inputidx > length(this.Inputs)
459  error(" Invalid input index '%d'. There are %d possible inputs configured. ",inputidx,length(this.Inputs));
460  end
461  this.u= @(t)[];
462  this.inputidx= [];
463  if ~isempty(inputidx)
464  this.u= this.Inputs[inputidx];
465  this.inputidx= inputidx;
466  end
467  }
485  this.setConfig(mu, inputidx);
486 
487  if isempty(this.NumStateDofs)
488  this.NumStateDofs= size(this.x0.evaluate(mu),1);
489  fprintf(2," NumStateDofs not set. Guess from initial value: %d\n ",this.NumStateDofs);
490  this.updateDimensions;
491  end
492 
493  /* Forward preparation call to nonlinearity, if present */
494  if ~isempty(this.A)
495  this.A.prepareSimulation(mu);
496  end
497 
498  /* Forward preparation call to nonlinearity, if present */
499  if ~isempty(this.f)
500  this.f.prepareSimulation(mu);
501  end
502 
503  /* Forward preparation call to nonlinearity, if present */
504  if ~isempty(this.B)
505  this.B.prepareSimulation(mu);
506  end
507  }
508 
509 
510  function dx = ODEFun(double t,colvec<double> x) {
511  dx = zeros(this.NumTotalDofs,1);
512  if ~isempty(this.A)
513  dx = dx + this.A.evaluate(x, t);
514  end
515  if ~isempty(this.f)
516  dx = dx + this.f.evaluate(x, t);
517  end
518  if ~isempty(this.B) && ~isempty(this.inputidx)
519  dx = dx + this.B.evaluate(t, this.mu)*this.u(t);
520  end
521  if ~isempty(this.g)
522  dx = [dx; this.g.evaluate(x,t)];
523  end
524  }
537 
538  if nargin < 3
539  mu = this.mu;
540  end
541 
542  /* Re-scale state variable */
543  if ~isequal(this.StateScaling,1)
544  if isscalar(this.StateScaling)
545  x = this.StateScaling*x;
546  else
547  x = bsxfun(@times,x,this.StateScaling);
548  end
549  end
550  y = x;
551  if ~isempty(this.C)
552  if this.C.TimeDependent
553  /* Evaluate the output conversion at each time t
554  * Figure out resulting size of C*x evaluation */
555  t = this.Model.scaledTimes;
556  hlp = this.C.evaluate(t(1),mu)*x(:,1);
557  y = zeros(size(hlp,1),length(t));
558  y(:,1) = hlp;
559  for idx=2:length(t)
560  y(:,idx) = this.C.evaluate(t(idx),mu)*x(:,idx);
561  end
562  else
563  /* otherwise it's a constant matrix so multiplication
564  * can be preformed much faster. */
565  y = this.C.evaluate([],mu)*x;
566  end
567  end
568  }
595  td = this.NumTotalDofs;
596  sd = this.NumStateDofs;
597  JP = logical(sparse(td,td));
598  if ~isempty(this.A) && ~isempty(this.A.JSparsityPattern)
599  JP(1:sd,1:sd) = JP(1:sd,1:sd) | this.A.JSparsityPattern;
600  end
601  if ~isempty(this.f) && ~isempty(this.f.JSparsityPattern)
602  JP(1:sd,:) = JP(1:sd,:) | this.f.JSparsityPattern;
603  end
604  if ~isempty(this.g)
605  JP(sd+1:end,:) = this.g.JSparsityPattern;
606  end
607  this.SparsityPattern= JP;
608  }
609 
610 
611  function J = getJacobian(double t,xc) {
612  td = this.NumTotalDofs;
613  sd = this.NumStateDofs;
614  x = xc(1:sd);
615  J = sparse(td,td);
616  if isempty(this.g)
617  if ~isempty(this.A)
618  J = J + this.A.getStateJacobian(x, t);
619  end
620  if ~isempty(this.f)
621  J = J + this.f.getStateJacobian(xc, t);
622  end
623  else
624  if ~isempty(this.A)
625  J(1:sd,1:sd) = J(1:sd,1:sd) + this.A.getStateJacobian(x, t);
626  elseif ~isempty(this.f)
627  J(1:sd,:) = J(1:sd,:) + this.f.getStateJacobian(xc, t);
628  end
629  J(sd+1:end,:) = this.g.getStateJacobian(xc,t);
630  end
631  }
641  function matrix<double>x0 = getX0(rowvec<double> mu) {
642  ss = this.StateScaling;
643  if (size(mu,2) > 1) && ~isscalar(ss)
644  ss = repmat(ss,1,size(mu,2));
645  end
646  x0 = this.x0.evaluate(mu) ./ ss;
647 
648  /* Append DoFs for algebraic conditions below (if set) */
649  if this.NumAlgebraicDofs > 0
651  end
652  }
669  function M = getMassMatrix() {
670  M = this.M;
671  if isempty(M)
672  M = dscomponents.ConstMassMatrix(speye(this.NumStateDofs));
673  else
674  if this.NumAlgebraicDofs > 0
675  error(" First order with AlgebraicDofs not yet implemented. ");
676  end
677  end
678  }
687  function ModelParamp = addParam(char name,default,varargin) {
688  if ~isempty(this.Params) && ~isempty(find(strcmpi(name,[this.Params(:).Name]),1))
689  error(" Parameter with name %s already exists. Use setParam instead. ",name);
690  end
691  p = data.ModelParam(name, default, varargin[:]);
692  this.Params(end+1) = p;
693  }
719  function pidx = getParamIndexFromName(paramname) {
720  if ~ischar(paramname)
721  error(" Parameter paramname must be a char array ");
722  end
723  pidx = find(strcmpi(paramname,[this.Params(:).Name]),1);
724  }
734  function pt = getParamInfo(colvec<double> mu) {
735  if nargin < 2
736  mu = this.Model.DefaultMu;
737  end
738  /* str = ''; */
739  pt = PrintTable;
740  pt.HasRowHeader= true;
741  pt.HasHeader= true;
742  pt.addRow(" Parameter name "," Value "," Index ");
743  for i=1:this.ParamCount
744  /* str = sprintf('%s%d - %s: %f\n',str,i,this.Params(i).Name,mu(i)); */
745  pt.addRow(this.Params(i).Name,mu(i),i);
746  end
747  if nargout < 1
748  pt.print;
749  end
750  }
751 
752 
753  function plotInputs(pm) {
754  if nargin < 2
755  pm = PlotManager;
756  pm.LeaveOpen= true;
757  end
758  for i=1:this.InputCount
759  ui = this.Inputs[i];
760  h = pm.nextPlot(sprintf(" u%d ",i),sprintf(" u_%d = %s ",i,func2str(ui)),...
761  " t ",sprintf(" u_%d ",i));
762  plot(h,this.Model.Times,ui(this.Model.scaledTimes)," LineWidth ",2);
763  end
764  pm.done;
765  }
766 
767 
768  protected:
769 
770 
771  function updateDimensions() {
772  this.NumTotalDofs= this.NumStateDofs + this.NumAlgebraicDofs;
773  }
774 
775 
777  ad_ic = zeros(this.NumAlgebraicDofs,1);
778  }
787  if ~isa(model, " models.BaseModel ")
788  error(" The Model property has to be a child of models.BaseModel ");
789  end
790  }
803  /* % Getter & Setter */
804  public:
805 
806 
807 #if 0 //mtoc++: 'set.f'
808 function f(value) {
809  if ~isempty(value) && ~isa(value, " dscomponents.ACoreFun ")
810  error(" The property 'f' has to be a class implementing dscomponents.ACoreFun ");
811  end
812 /* if (isequal(this,value))
813  * warning('KerMor:selfReference','Careful with self-referencing classes. See BaseFullModel class documentation for details.');
814  * end */
815  this.f= value;
816  }
817 
818 #endif
819 
820 
821 
822 #if 0 //mtoc++: 'set.B'
823 function B(value) {
824  if ~isempty(value) && ~isa(value, " dscomponents.AInputConv ")
825  error(" The property 'B' has to be a class implementing dscomponents.AInputConv ");
826  end
827  this.B= value;
828  }
829 
830 #endif
831 
832 
833 
834 #if 0 //mtoc++: 'set.A'
835 function A(value) {
836  if ~isempty(value) && ~(isa(value, " dscomponents.LinearCoreFun ") || isa(value, " dscomponents.AffLinCoreFun "))
837  error(" The property 'A' has to be a LinearCoreFun or AffLinCoreFun. ");
838  end
839  this.A= value;
840  }
841 
842 #endif
843 
844 
845 
846 #if 0 //mtoc++: 'set.C'
847 function C(value) {
848  if isempty(value)
849  value = dscomponents.LinearOutputConv(1);
850  warning(" An output conversion must always exist. Choosing dscomponents.LinearOutputConv(1) for simple forwarding. ");
851  elseif ~isa(value, " dscomponents.AOutputConv ")
852  error(" The property 'C' has to be a class implementing dscomponents.AOutputConv ");
853  end
854  this.C= value;
855  }
856 
857 #endif
858 
859 
860 
861 #if 0 //mtoc++: 'set.Inputs'
862 function Inputs(value) {
863  if ~iscell(value)
864  error(" Property 'Inputs' must be a cell array. ");
865  end
866  for n=1:numel(value)
867  if ~isempty(value[n])
868  if ~isa(value[n]," function_handle ")
869  error(" Each 'Inputs' cell must contain a function handle. ");
870 /* elseif nargin(value{n}) ~= 1
871  * error('Each "Inputs" function must take exactly one (=time) parameter.'); */
872  end
873  end
874  end
875  this.Inputs= value;
876  }
877 
878 #endif
879 
880 
881 
882 #if 0 //mtoc++: 'set.Params'
883 function Params(value) {
884  if ~isa(value," data.ModelParam ")
885  error(" Params property must be a ModelParam array. ");
886  end
887  this.Params= value;
888  }
889 
890 #endif
891 
892 
893 
894 #if 0 //mtoc++: 'set.x0'
895 function x0(value) {
896  this.checkType(value," dscomponents.AInitialValue ");
897 /* if ~isa(value,'function_handle')
898  * error('x0 must be a function handle.');
899  * elseif nargin(value) ~= 1
900  * error('x0 must take exactly one argument.');
901  * end */
902 
903  this.x0= value;
904  }
905 
906 #endif
907 
908 
909 
910 #if 0 //mtoc++: 'get.ParamCount'
911 function value = ParamCount() {
912  value = length(this.Params);
913  }
914 
915 #endif
916 
917 
918 
919 #if 0 //mtoc++: 'get.InputCount'
920 function value = InputCount() {
921  value = length(this.Inputs);
922  }
923 
924 #endif
925 
926 
927 
928 #if 0 //mtoc++: 'set.MaxTimestep'
929 function MaxTimestep(value) {
930  if (~isscalar(value) || value <= 0) && ~isempty(value)
931  error(" Value must be a positive real scalar if not empty. ");
932  end
933  this.MaxTimestep= value;
934  }
935 
936 #endif
937 
938 
939 
940 #if 0 //mtoc++: 'set.StateScaling'
941 function StateScaling(value) {
942  if isempty(value)
943  error(" StateScaling must not be empty. (Set to 1 if not needed). ");
944  elseif ~isvector(value)
945  error(" StateScaling must be a vector. ");
946  end
947  this.StateScaling= value(:);
948  }
949 
950 #endif
951 
952 
1000 };
1001 }
1002 
1003 
1004 
function ad_ic = getAlgebraicDofsInitialConditions()
The default is to return all zeros.
function matrix< double > x0 = getX0(rowvec< double > mu)
Gets the initial state variable at .
function J = getStateJacobian(unused1, unused2, unused3)
Params
The parameters usable for the dynamical system.
The base class for any KerMor detailed model.
Definition: BaseFullModel.m:18
function J = getStateJacobian(x, t)
Default implementation of jacobian matrix evaluation via finite differences.
Definition: ACoreFun.m:395
dscomponents.AInputConv B
The input conversion.
function prepareSimulation(colvec< double > mu)
A method that allows parameter-dependent computations to be performed before a simulation using this ...
Definition: ACoreFun.m:380
Model
The Model this System is attached to.
function setConfig(mu, inputidx)
Sets the dynamical system's configuration.
A MatLab cell array or matrix.
AInputConv: Base class for input conversion "B". For simpler input conversions, it will be convenient...
Definition: AInputConv.m:18
A double value.
function J = getJacobian(double t, xc)
Computes the global jacobian of the current system.
Base class for any KerMor class.
Definition: KerMorObject.m:17
function rsys = getReducedSystemInstance(models.ReducedModel rmodel)
Creates a reduced system given the current system and the reduced model.
function registerProps(varargin)
Call this method at any class that defines DPCM observed properties.
Definition: DPCMObject.m:125
An integer value.
The KerMor reduced model class.
Definition: ReducedModel.m:18
virtual function x0 = evaluate(mu)
Evaluates the initial value for a given mu.
A MatLab function handle.
PlotManager: Small class that allows the same plots generated by some script to be either organized a...
Definition: PlotManager.m:17
inputidx
The current inputindex of the function .
Matlab's base handle class (documentation generation substitute)
AInitialValue: Abstract base class for dynamical systems initial values.
Definition: AInitialValue.m:18
A boolean value.
Basic interface for all dynamical system's core functions Inherits the AProjectable interface...
Definition: ACoreFun.m:18
dscomponents.AInitialValue x0
Function handle to initial state evaluation.
logical HasRowHeader
Flag that determines if there is a row header for the table.
Definition: PrintTable.m:278
logical LeaveOpen
Flag indicating if the plots should be left open once the PlotManager is deleted (as variable) ...
Definition: PlotManager.m:213
A variable number of input arguments.
function fx = evaluate(colvec< double > x, unused1, unused2)
Definition: LinearCoreFun.m:80
mu
The current parameter for simulations, [] is none used.
InputCount
The number of inputs available.
A matlab column vector.
Inputs
The system's possible input functions. A cell array of function handles, each taking a time argument ...
function dx = ODEFun(double t,colvec< double > x)
Debug variant for single evaluation. Commented in function above.
colvec StateScaling
The scaling for the state vectors.
function prepareSimulation(colvec< double > mu,integer inputidx)
function fx = evaluate(x, t)
Evaluates the f-approximation. Depending on a possible projection and the CustomProjection-property t...
Definition: ACoreFun.m:296
Linear core function for state space models (no time or parameter)
Definition: LinearCoreFun.m:18
function prepareSimulation(colvec< double > mu)
do nothing by default
Definition: AInputConv.m:63
logical TimeDependent
Flag whether the output converter actually depends on a time variable. Implemented for speed reasons ...
Definition: AOutputConv.m:44
PrintTable: Class that allows table-like output spaced by tabs for multiple rows. ...
Definition: PrintTable.m:17
integer DependentParamIndices
Indices of the parameter vector that are effectively used in the system's core function.
virtual function B = evaluate(colvec< double > mu)
Template method that evaluates the input conversion matrix at the current time and [optional] param...
function pidx = getParamIndexFromName(paramname)
Gets the index within the parameter vector for a given parameter name.
sparse< logical > JSparsityPattern
Sparsity pattern for the jacobian matrix.
Definition: ACoreFun.m:127
dscomponents.LinearOutputConv C
The output conversion Defaults to an LinearOutputConv instance using a 1-matrix, which just forwards ...
function checkType(obj, type)
Object typechecker.
Definition: KerMorObject.m:122
dscomponents.ACoreFun f
The core f function from the dynamical system.
dscomponents.ACoreFun g
The system's algebraic constraints function.
ParamCount
The number of the system's parameters.
function count = cprintf(style, format, varargin)
CPRINTF displays styled formatted text in the Command Window.
Definition: cprintf.m:17
function validateModel(models.BaseFullModel model)
Validates if the model to be set is a valid BaseModel at least. Extracting this function out of the s...
function y = computeOutput(matrix< double > x,colvec< double > mu)
Computes the output from a given state result vector , using the system's time and current mu (if gi...
SparsityPattern
The global sparsity pattern for the entire RHS.
function M = getMassMatrix()
For first order systems, only algebraic constraints need to be catered for.
function C = evaluate(double t,colvec< double > mu)
Evaluates the output conversion matrix. In this simple case this is just the projection matrix...
dscomponents.AMassMatrix M
The system's mass matrix.
BaseFirstOrderSystem(models.BaseFullModel model)
Creates a new base dynamical system class instance.
u
The current input function as function handle, [] if none used.
double MaxTimestep
The maximum timestep allowed for any ODE solvers.
function ModelParam p = addParam(char name, default, varargin)
Adds a parameter with the given values to the parameter collection of the current dynamical system...
Base class for all KerMor first-order dynamical systems.
Simple affine-linear core function "f" for a dynamical system.
Definition: AffLinCoreFun.m:18
dscomponents.LinearCoreFun A
Represents a linear or affine-linear component of the dynamical system.
Standard linear output converter.
function pt = getParamInfo(colvec< double > mu)