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
BaseFullModel.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 models.BaseModel,
20  public IParallelizable {
117  public:
118 
134  .export.JKerMorExport JKerMorExport;
148  public: /* ( setObservable ) */
149 
345  logical AutoSave = false;
365  char SaveTag = "";
385  public: /* ( Dependent, setObservable ) */
386 
426  public: /* ( Dependent ) */
427 
442  public:
443 
477  private:
478 
479  fTrainingInputs = "[]";
480 
481  fTrainingParams = "[]";
482 
483  ftcold = struct;
484 
485 
486  public:
487 
488 
489  BaseFullModel(char name) {
490  this = this@models.BaseModel;
491 
492  /* Register name change listener (might not have the name set
493  * already now) */
494  this.addlistener(" Name "," PostSet ", @this.nameChanged);
495 
496  /* Set name if given */
497  if nargin == 1
498  this.Name= name;
499  end
500 
501  /* Setup default values for the full model's components */
502  this.Sampler= sampling.RandomSampler;
503 
504  this.SpaceReducer= spacereduction.PODGreedy;
505 
506  this.Data= data.ModelData(this);
507 
508  /* Set default dynamical system */
509  this.System= models.BaseFirstOrderSystem(this);
510 
511  /* Register default properties */
512  this.registerProps(" Sampler "," SpaceReducer "," Approx ",...
513  " preApproximationTrainingCallback "," postApproximationTrainingCallback ",...
514  " Data "," TrainingInputs "," AutoSave ");
515 
516  /* Create a listener for the */
517  this.addlistener(" T "," PreSet ", @this.intTimeChanging);
518  this.addlistener(" dt "," PreSet ", @this.intTimeChanging);
519  this.addlistener(" T "," PostSet ", @this.intTimeChanged);
520  this.addlistener(" dt "," PostSet ", @this.intTimeChanged);
521  }
531  function delete() {
532  this.Sampler= [];
533  this.SpaceReducer= [];
534  this.Approx= [];
535  this.System= [];
536  /* Clean up data at last (other instances might still have data inside DataDirectory
537  * folder) */
538  this.Data= [];
539 
540  delete@models.BaseModel(this);
541  }
542 
543 
545 
546  /* Sampling */
547  time = tic;
548  if ~isempty(this.Sampler)
549  this.Data.ParamSamples= this.Sampler.generateSamples(this);
550  elseif this.System.ParamCount > 0
551  error(" No parameter sampler set for a parameterized system. See package sampling and the Sampler property of the BaseFullModel class. ");
552  end
553  this.OfflinePhaseTimes(1) = toc(time);
554  this.autoSave;
555  }
562  function off2_genTrainingData() {
563  time = tic;
564 
565  num_s = max(1,this.Data.SampleCount);
566  num_in = max(1,this.TrainingInputCount);
567 
568  completed = zeros(3,num_s*num_in);
569  tlen = length(this.Times);
570 
571  /* Clear old trajectory data. */
573  this.RealTimePlotting= false;
574 
575  oldv = this.EnableTrajectoryCaching;
576  this.EnableTrajectoryCaching= false;
577 
578  /* Automatically use the default input if exists and no others
579  * are set. */
580  if isempty(this.TrainingInputs) && ~isempty(this.DefaultInput)
581  this.TrainingInputs= this.DefaultInput;
582  end
583 
584  /* % Parallel - computation */
585  if this.ComputeParallel
586  told = [];
587  if ~isa(this.Data.TrajectoryData," data.FileTrajectoryData ")
588  told = this.Data.TrajectoryData;
590  end
591  idxmat = Utils.createCombinations(1:num_s,this.TrainingInputs);
592 
593  fprintf(" Starting parallel projection training data computation of %d trajectories on %d workers...\n ",size(idxmat,2),matlabpool(" size "));
594  /* Iterate through all param/input combinations */
595  paridx = idxmat(1,:); /* Use sliced variables here */
596 
597  inidx = idxmat(2,:);
598  clear idxmat;
599 
600  /* Notation switch to be reminded that the remote variable will not
601  * exist in the local context outside the parfor! */
602  remote = this;
603  n = size(paridx,2);
604  parfor idx = 1:n
605  /* Check for parameters */
606  mu = [];
607  if remote.Data.SampleCount > 0 /* #ok<*PFBNS> */
608 
609  mu = remote.Data.getParams(paridx(idx));
610  end
611  /* Check for inputs */
612  inputidx = [];
613  if remote.TrainingInputCount > 0
614  inputidx = inidx(idx);
615  end
616 
617  /* Get trajectory */
618  [t, x, ctime] = remote.computeTrajectory(mu, inputidx);
619 
620  /* Assign snapshot values */
621  remote.Data.TrajectoryData.addTrajectory(x, mu, inputidx, ctime);
622 
623  /* Evaluate fxi on current values if required */
625  hlp = tic;
626  fx = this.System.f.evaluateMulti(x, t, mu);
627  ctime = toc(hlp);
628  this.Data.TrajectoryFxiData.addTrajectory(fx, mu, inputidx, ctime);
629  end
630  completed(:,idx) = [inidx(idx); paridx(idx); size(x,2) == tlen];
631  end
632  /* Build the hash map for the local FileTrajectoryData (parfor
633  * add them to remotely instantiated FileTrajectoryDatas and does
634  * not sync them (not generically possible) */
635 
636  td = this.Data.TrajectoryData;
637  td.consolidate(this);
638  if ~isempty(told)
639  told.transferFrom(td);
640  td.clearTrajectories;
641  this.Data.TrajectoryData= [];
642  this.Data.TrajectoryData= told;
643  end
644 
645  if ~isempty(this.Data.TrajectoryFxiData) && isa(this.Data.TrajectoryFxiData," data.FileTrajectoryData ")
646  this.Data.TrajectoryFxiData.consolidate(this);
647  end
648 
649  /* % Non-parallel computation */
650  else
651  /* Assume no parameters or inputs */
652  mu = [];
653  inputidx = [];
654 
655  if KerMor.App.Verbose > 0
656  pi = ProcessIndicator(sprintf(" Generating projection training data (%d trajectories)... ",num_in*num_s),num_in*num_s);
657  end
658 
659  completed = double.empty(3,0);
660  /* Iterate through all input functions */
661  for inidx = 1:num_in
662  /* Iterate through all parameter samples */
663  for pidx = 1:num_s
664  /* Check for parameters */
665  if this.Data.SampleCount > 0
666  mu = this.Data.getParams(pidx);
667  end
668  /* Check for inputs */
669  if this.TrainingInputCount > 0
670  inputidx = this.TrainingInputs(inidx);
671  end
672 
673  /* Get trajectory */
674  try
675  [t, x, ctime, cache] = this.computeTrajectory(mu, inputidx);
676  /* Store snapshot values, only if not already from trajectory data */
677  if cache ~= 1
678  if size(x,2) == tlen
679  this.Data.TrajectoryData.addTrajectory(x, mu, inputidx, ctime);
680  elseif size(x,2) ~= tlen
681  this.Data.TrajectoryIncompleteData.addTrajectory(x, mu, inputidx, ctime);
682  end
683  end
684 
685  /* Evaluate fxi on current values if required */
687  hlp = tic;
688  fx = this.System.f.evaluateMulti(x, t, mu);
689  ctime = toc(hlp);
690  this.Data.TrajectoryFxiData.addTrajectory(fx, mu, inputidx, ctime);
691  end
692  ok = size(x,2) == tlen;
693  catch ME
694  ok = 0;
695  warning(ME.identifier," Failed to compute trajectory:\n%s ",ME.message);
696  end
697  completed(:,end+1) = [inidx; pidx; ok]; /* #ok */
698 
699 
700  if KerMor.App.Verbose > 0
701  pi.step;
702  end
703  end
704  end
705  if KerMor.App.Verbose > 0
706  pi.stop;
707  end
708  end
709 
710  this.EnableTrajectoryCaching= oldv;
711  this.TrajectoriesCompleted= completed;
712 
713  /* delete parameters of incomplete trajectories */
714  incomplete = find(completed(3,:)==0);
715  this.Data.ParamSamples(:,incomplete) = [];
716 
717  /* Input space span computation (if spacereduction is used) */
718  if ~isempty(this.SpaceReducer) && any([this.SpaceReducer(:).IncludeBSpan])
719  if KerMor.App.Verbose > 0
720  fprintf(" Computing input space span... ");
721  end
722  B = this.System.B;
723  this.Data.InputSpaceSpan= [];
724  if isempty(B)
725  warning(" KerMor:BaseFullModel "," Cannot compute B span, no System.B set. ");
726  return;
727  end
728  if isa(B," dscomponents.LinearInputConv ")
729  o = general.Orthonormalizer;
730  this.Data.InputSpaceSpan= o.orthonormalize(B.B);
731  elseif isa(B," dscomponents.AffLinInputConv ")
732  o = general.Orthonormalizer;
733  tmp = [];
734  for k = 1:B.N
735  tmp = [tmp B.getMatrix(k)];/* #ok */
736 
737  end
738  this.Data.InputSpaceSpan= o.orthonormalize(tmp);
739  else
740  warning(" KerMor:BaseFullModel "," B span computation: Case %s not yet implemented ",class(B));
741  end
742  if KerMor.App.Verbose > 0
743  fprintf(" dimension %d.\n ",size(this.Data.InputSpaceSpan,2));
744  end
745  end
746 
747  this.OfflinePhaseTimes(2) = toc(time);
748  this.autoSave;
749  }
757  time = tic;
758  this.Data.ProjectionSpaces= [];
759  if ~isempty(this.SpaceReducer)
760  ns = length(this.SpaceReducer);
761  /* % Sanity checks */
762  dim = this.System.NumTotalDofs;
763  numalgdofs = this.System.NumAlgebraicDofs;
764  for k = 1:ns
765  td = this.SpaceReducer(k).TargetDimensions;
766  if strcmp(td," : ")
767  if numalgdofs > 0
768  this.SpaceReducer(k).TargetDimensions = 1:dim-numalgdofs;
769  fprintf(" Adjusting TargetDimensions of space reducer#%d: Selection "" : "" invalid when having algebraic constraints.\n ",k);
770  end
771  elseif any(td > dim-numalgdofs)
772  disp(td(td > dim-numalgdofs));
773  error(" Cannot select algebraic constraints for reduction (Check System.AlgebraicConditionDoF and SpaceReducer.TargetDimensions) ! Conflicting DoF indices above. ");
774  end
775  end
776  /* % Actual computation */
777  fprintf(" Computing %d projection space(s)...\n ",ns);
778  for k = 1:ns
779  s = this.SpaceReducer(k);
780  [V, W] = s.generateReducedSpace(this);
781  this.Data.addProjectionSpace(V,W,s.TargetDimensions);
782  end
783  end
784  this.OfflinePhaseTimes(3) = toc(time);
785  this.autoSave;
786  }
794  t = tic;
795  if ~isempty(this.Approx)
796  this.Data.ApproxTrainData= data.ApproxTrainData.computeFrom(this, ...
797  this.System.f, this.Approx.TrainDataSelector, this.ComputeParallel);
798  end
799  this.OfflinePhaseTimes(4) = toc(t);
800  this.autoSave;
801  }
814  time = tic;
815 
816  if ~isempty(this.Approx)
817  if isempty(this.Data.ApproxTrainData.xi)
818  error(" No approximation training data available. Called off4_genApproximationTrainData? ");
819  end
820 
821  if ~isempty(this.preApproximationTrainingCallback)
823  end
824 
825  if KerMor.App.Verbose > 0
826  fprintf(" Starting approximation process for %d dimensions ...\n ",size(this.Data.ApproxTrainData.fxi,1));
827  end
828 
829  /* warning off MATLAB:nearlySingularMatrix;
830  *% Approximate core function (is parallelizable for its own)
831  * Compile necessary data */
833  /* warning on MATLAB:nearlySingularMatrix; */
834 
835  if ~isempty(this.postApproximationTrainingCallback)
837  end
838  end
839 
840  this.OfflinePhaseTimes(5) = toc(time);
841  this.autoSave;
842  }
852  t = tic;
853  e = this.ErrorEstimator;
854  if ~isempty(e)
855  if KerMor.App.Verbose > 0
856  fprintf(" Starting error estimator offline computations...\n ");
857  end
858  e.offlineComputations(this);
859  end
860  this.OfflinePhaseTimes(6) = toc(t);
861  this.autoSave;
862  }
869  function offlineGenerations() {
870  this.OfflinePhaseTimes= [];
871 
878  }
892  function [models.ReducedModelreduced , doubletime ] = buildReducedModel(varargin) {
893  tic;
894  reduced = models.ReducedModel(this);
895  reduced.build(varargin[:]);
896  time = toc;
897  }
926  function [t , x , time , cache ] = computeTrajectory(colvec<double> mu,inputidx) {
927 
928  if KerMor.App.UseDPCM
929  DPCM.criticalsCheck(this);
930  end
931  if ~isempty(this.System.f) && (isempty(this.System.f.xDim) || isempty(this.System.f.fDim))
932  error(" Nonlinarity properties fDim and xDim not set. See dscomponents.ACoreFun ");
933  end
934 
935  /* Try local model data first */
936  cache = 1;
937  [x, time] = this.Data.TrajectoryData.getTrajectory(mu, inputidx);
938  if isempty(x) && this.EnableTrajectoryCaching
939  cache = 2;
940  [x, time] = this.Data.SimCache.getTrajectory([this.T; this.dt; mu], inputidx);
941  end
942  if ~isempty(x)
943  t = this.scaledTimes;
944  if size(x,2) < length(t)
945  warning(" Inconsistent trajectory data: Cached trajectory shorter than current time-steps. Using matching subarray of model.scaledTimes ");
946  t = t(1:size(x,2));
947  elseif size(x,2) > length(t)
948  error(" Inconsistent trajectory data: More trajectory samples than time-steps in current model. Please fix. ");
949  end
950  /* Also set the current mu config for output mapping &
951  * plotting to work correctly. */
952  this.System.setConfig(mu, inputidx);
953  else
954  st = tic;
955 
956  /* Preparation call to approximation, if present */
957  if ~isempty(this.Approx)
958  this.Approx.prepareSimulation(mu);
959  end
960 
961  if this.isStatic
962  [t, x] = solveStatic(this, mu, inputidx);
963  else
964  [t, x] = computeTrajectory@models.BaseModel(this, mu, inputidx);
965  end
966  time = toc(st);
968  if size(x,2) == length(this.Times)
969  this.Data.SimCache.addTrajectory(x, [this.T; this.dt; mu], inputidx, time);
970  else
971  warning(" KerMor:InconsistentTrajectoryData ",...
972  " Not caching trajectory: Returned result size differs from simulation times. ");
973  end
974  end
975  cache = 0;
976  end
977  }
997  function [doublet , matrix<double>y , colvec<double>mu , in , ct ] = getSimCacheTrajectory(nr) {
998  [y,mu,in,ct] = this.Data.SimCache.getTrajectoryNr(nr);
999  this.T= mu(1);
1000  this.dt= mu(2);
1001  mu = mu(3:end);
1002  t = this.Times;
1003  this.System.setConfig(mu,in);
1004  }
1005 
1006 
1007  function plotTrajectoryNr(nr) {
1008  [y,mu,in] = this.Data.TrajectoryData.getTrajectoryNr(nr);
1009  this.System.setConfig(mu,in);
1010  this.plot(this.Times,y);
1011  }
1012 
1013 
1014  function [V , W ] = assembleProjectionMatrices(target_dim) {
1015  fd = this.Data;
1016  if isempty(fd.ProjectionSpaces)
1017  V = [];
1018  else
1019  if nargin < 2
1020  /* Default: create a reduced model 10th the size of the full
1021  * one */
1022  target_dim = max(1,floor(this.System.NumTotalDofs/10));
1023  end
1024  if target_dim > size(fd.ProjectionSpaces(1).V,2)
1025  warning(" Target dimension %d too large, using max value of %d. ",...
1026  target_dim,size(fd.ProjectionSpaces(1).V,2));
1027  target_dim = size(fd.ProjectionSpaces(1).V,2);
1028  end
1029  V = fd.ProjectionSpaces(1).V(:,1:target_dim);
1030  end
1031  /* We do */
1032  W = V;
1033  /* % Old code for multiple projection spaces (not currently used anywhere)
1034  * md = this.Data;
1035  * ps = md.ProjectionSpaces;
1036  * ns = length(ps);
1037  *
1038  * % If no target dimension(s) are given, assume full size (for
1039  * % each subspace)
1040  * if nargin < 2 || isempty(target_dim)
1041  * for k = 1:ns
1042  * target_dim(k) = ps(k).Size;
1043  * end
1044  * % If only a scalar is given, assume a total desired size of
1045  * % target_dim and equally split sizes for each subspace
1046  * elseif isscalar(target_dim)
1047  * target_dim = ones(ns,1)*floor(target_dim/ns);
1048  * end
1049  * for k = 1:ns
1050  * if target_dim(k) > ps(k).Size
1051  * warning('Target size %d for subspace %d too large! Using max value of %d',...
1052  * target_dim(k),k,ps(k).Size);
1053  * target_dim(k) = ps(k).Size;
1054  * end
1055  * % Store the currently used effective size of that subspace
1056  * % for use by other components upon projection
1057  * ps(k).LastEffectiveSize = target_dim(k);
1058  * end
1059  *
1060  * %% Compute the effective projection matrix
1061  * % As we might have multiple projection subspaces, we need to
1062  * % assemble a global projection matrix (block-like if separate
1063  * % subspace dimensions are "sorted" in full model).
1064  * % Any not-projected DoFs are forwarded as-is by identity.
1065  * % DAE constraints are treated outside of this method - this is
1066  * % purely dof-related.
1067  * V = []; W = []; %#ok<*PROP>
1068  * if ns > 0
1069  * dim = this.System.NumTotalDofs;
1070  * V = zeros(dim,sum(target_dim));
1071  * W = V;
1072  * offset = 0;
1073  * done = false(dim,1);
1074  * for k=1:ns
1075  * s = ps(k);
1076  * sel = 1:target_dim(k);
1077  * V(s.Dimensions,offset + sel) = s.V(:,sel);
1078  * if ~isempty(s.W)
1079  * W(s.Dimensions,offset + sel) = s.W(:,sel);
1080  * end
1081  * offset = offset + target_dim(k);
1082  * done(s.Dimensions) = true;
1083  * end
1084  * % % Insert identity for any remaining dimensions (corresponds
1085  * % % to algebraic constraint DoFs
1086  * % unreduced = find(~done);
1087  * % nunred = length(unreduced);
1088  * % V(unreduced,end+(1:nunred)) = eye(nunred);
1089  * % W(unreduced,end+(1:nunred)) = eye(nunred);
1090  * end */
1091  }
1092 
1093 
1094  function file = save(char directory,char filename) {
1095  if nargin < 3
1096  if ~isempty(this.SaveTag)
1097  filename = this.SaveTag;
1098  else
1099  warning(" KerMor:NoSaveTag "," No SaveTag set. Using default 'model.mat' ");
1100  filename = " model.mat ";
1101  end
1102  end
1103  if nargin < 2
1104  directory = this.Data.DataDirectory;
1105  end
1106  file = fullfile(directory,filename);
1107  m = this; /* #ok (renaming */
1108 
1109  save(file," m ");
1110  }
1128  private:
1129 
1130  function intTimeChanging(src,unused1) {
1131  this.ftcold.(src.Name) = this.(src.Name);
1132  }
1133 
1134 
1135  function intTimeChanged(src,unused1) {
1136  if this.ftcold.(src.Name) ~= this.(src.Name)
1137  md = this.Data.TrajectoryData;
1138  if md.getNumTrajectories > 0
1139  /* md.clearTrajectories;
1140  *fprintf(2,'Deleted all old trajectories for %s=%f\n',src.Name,this.ftcold.(src.Name)); */
1141  end
1142  /* this.Data.SimCache.clearTrajectories; */
1143  end
1144  }
1145 
1146 
1147  function nameChanged(unused1,unused2) {
1148  if isempty(this.SaveTag)
1149  this.SaveTag= regexprep(...
1150  strrep(strtrim(this.Name)," "," _ ")," [^\d\w~-] ",);
1151  end
1152  }
1153 
1154 
1155  function autoSave() {
1156  if this.AutoSave
1157  save(fullfile(this.Data.DataDirectory," model_autosave.mat ")," this ");
1158  end
1159  }
1166  /* % Getter & Setter */
1167  public:
1168 
1169 
1170 #if 0 //mtoc++: 'set.Sampler'
1171 function Sampler(value) {
1172  this.checkType(value, " sampling.BaseSampler ");
1173  this.Sampler= value;
1174  }
1175 
1176 #endif
1177 
1178 
1179 
1180 #if 0 //mtoc++: 'set.Data'
1181 function Data(value) {
1182  this.checkType(value, " data.ModelData ");
1183  if ~isequal(this.Data, value)
1184  this.Data= [];
1185  this.Data= value;
1186  end
1187  }
1188 
1189 #endif
1190 
1191 
1192 
1193 #if 0 //mtoc++: 'set.SpaceReducer'
1194 function SpaceReducer(value) {
1195  this.checkType(value, " spacereduction.BaseSpaceReducer ");
1196  this.SpaceReducer= value;
1197  }
1198 
1199 #endif
1200 
1201 
1202 
1203 #if 0 //mtoc++: 'set.Approx'
1204 function Approx(value) {
1205  this.checkType(value, " approx.BaseApprox ");
1206  this.Approx= value;
1207  }
1208 
1209 #endif
1210 
1211 
1212 
1213 #if 0 //mtoc++: 'set.preApproximationTrainingCallback'
1214 function preApproximationTrainingCallback(value) {
1215  if ~isempty(value) && ~isa(value, " function_handle ")
1216  error(" Value must be a function handle taking the current model instance ");
1217  end
1219  }
1220 
1221 #endif
1222 
1223 
1224 
1225 #if 0 //mtoc++: 'set.postApproximationTrainingCallback'
1226 function postApproximationTrainingCallback(value) {
1227  if ~isempty(value) && ~isa(value, " function_handle ")
1228  error(" Value must be a function handle taking the current model instance ");
1229  end
1231  }
1232 
1233 #endif
1234 
1235 
1236 
1237 #if 0 //mtoc++: 'set.TrainingInputs'
1238 function TrainingInputs(value) {
1239  if ~isempty(value)
1240  if any(value < 1)
1241  error(" Value may only contain valid indices for the Inputs cell array. ");
1242  elseif any(value > this.System.InputCount) || any(value < 1)
1243  error(" Invalid indices for Inputs. ");
1244  elseif isempty(this.System.B)
1245  error(" You must set the system "" s property B when using training inputs. ");
1246  end
1247  end
1248  this.fTrainingInputs= value;
1249  }
1250 
1251 #endif
1252 
1253 
1254 
1255 #if 0 //mtoc++: 'set.TrainingParams'
1256 function TrainingParams(value) {
1257  if ~isempty(value)
1258  if any(value < 1)
1259  error(" Value may only contain valid indices for the parameter array. ");
1260  elseif any(value > this.System.ParamCount) || any(value < 1)
1261  error(" Invalid indices for Inputs. ");
1262  end
1263  end
1264  this.fTrainingParams= value;
1265  }
1266 
1267 #endif
1268 
1269 
1270 
1271 #if 0 //mtoc++: 'set.ProjectApproxTrainingData'
1272 function ProjectApproxTrainingData(value) {
1273  if ~islogical(value) || ~isscalar(value)
1274  error(" ProjectApproxTrainingData must be a flag (scalar logical) ");
1275  end
1276  this.ProjectApproxTrainingData= value;
1277  }
1278 
1279 #endif
1280 
1281 
1282 
1283 #if 0 //mtoc++: 'set.EnableTrajectoryCaching'
1284 function EnableTrajectoryCaching(value) {
1285  if ~islogical(value) || ~isscalar(value)
1286  error(" EnableTrajectoryCaching must be a flag (scalar logical) ");
1287  end
1288  this.EnableTrajectoryCaching= value;
1289  }
1290 
1291 #endif
1292 
1293 
1294 
1295 #if 0 //mtoc++: 'set.AutoSave'
1296 function AutoSave(value) {
1297  if ~islogical(value) || ~isscalar(value)
1298  error(" AutoSave must be a flag (scalar logical) ");
1299  end
1300  this.AutoSave= value;
1301  }
1302 
1303 #endif
1304 
1305 
1306 
1307 #if 0 //mtoc++: 'get.TrainingInputs'
1308 function rowvec<double>ti = TrainingInputs() {
1309  ti = this.fTrainingInputs;
1310  }
1311 
1312 #endif
1313 
1314 
1315 
1316 #if 0 //mtoc++: 'get.TrainingParams'
1317 function rowvec<double>ti = TrainingParams() {
1318  ti = this.fTrainingParams;
1319  }
1320 
1321 #endif
1322 
1323 
1324 
1325 #if 0 //mtoc++: 'get.TrainingInputCount'
1326 function c = TrainingInputCount() {
1327  c = length(this.TrainingInputs);
1328  }
1329 
1330 #endif
1331 
1332 
1333  protected: /* ( Static ) */
1334 
1335  static function this = loadobj(this,sobj) {
1336  if ~isa(this," models.BaseFullModel ") && nargin < 2
1337  error(" The model class has changed but the loadobj method does not implement backwards-compatible loading behaviour.\nPlease implement the loadobj-method in your subclass and pass the loaded object struct as second argument. ");
1338  end
1339  if nargin == 2
1340  this = loadobj@models.BaseModel(this, sobj);
1341  this.SpaceReducer= sobj.SpaceReducer;
1342  this.Approx= sobj.Approx;
1343  this.JKerMorExport= sobj.JKerMorExport;
1344  this.Sampler= sobj.Sampler;
1345  this.EnableTrajectoryCaching= sobj.EnableTrajectoryCaching;
1346  this.preApproximationTrainingCallback= sobj.preApproximationTrainingCallback;
1347  this.postApproximationTrainingCallback= sobj.postApproximationTrainingCallback;
1348  this.ErrorEstimator= sobj.ErrorEstimator;
1349  this.ComputeTrajectoryFxiData= sobj.ComputeTrajectoryFxiData;
1350  this.SaveTag= sobj.SaveTag;
1351  this.fTrainingInputs= sobj.fTrainingInputs;
1352  this.OfflinePhaseTimes= sobj.OfflinePhaseTimes;
1353  this.ftcold= sobj.ftcold;
1354  if isfield(sobj," AutoSave ")
1355  this.AutoSave= logical(sobj.AutoSave);
1356  end
1357  if isfield(sobj," TrajectoriesCompleted ")
1358  this.TrajectoriesCompleted= sobj.TrajectoriesCompleted;
1359  end
1360  /* Load data class at last; any other components that might
1361  * make use of stuff inside the model folder should be able
1362  * to clean up */
1363  this.Data= sobj.Data;
1364  else
1365  this = loadobj@models.BaseModel(this);
1366  end
1367  this.addlistener(" T "," PreSet ", @this.intTimeChanging);
1368  this.addlistener(" dt "," PreSet ", @this.intTimeChanging);
1369  this.addlistener(" T "," PostSet ", @this.intTimeChanged);
1370  this.addlistener(" dt "," PostSet ", @this.intTimeChanged);
1371  this.addlistener(" Name "," PostSet ", @this.nameChanged);
1372  }
1373 
1374 
1375  public: /* ( Static ) */
1376 
1377 
1378  static function test_BaseModels() {
1379  m = models.BaseFullModel;
1380  af = dscomponents.AffLinCoreFun(m.System);
1381  af.addMatrix(" 1 ", rand(4,4));
1382  af.addMatrix(" sum(mu)*5 ", rand(4,4)*3);
1383 
1384  m.System.f= af;
1385  m.System.x0= dscomponents.ConstInitialValue(sin(1:4)^t);
1386  m.System.addParam(" test ",.5," Range ",[0 1]," Desired ",10);
1387  m.System.MaxTimestep= m.dt/2;
1388 
1389  m.offlineGenerations;
1390  red = m.buildReducedModel;
1391  /* Test simulations */
1392  m.simulate(m.getRandomParam);
1393  red.simulate(m.getRandomParam);
1394 
1395  /* dont forget to free resources! (static handles seem to
1396  * persist over several method calls) */
1397  clear af m red;
1398  }
1399 
1400 
1401  static function res = test_BareModel() {
1402  m = models.BaseFullModel;
1403  m.SpaceReducer= [];
1404  m.Approx= [];
1405  m.Sampler= [];
1406  A = rand(2,2);
1407  m.System= models.BaseFirstOrderSystem(m);
1408  m.System.f= dscomponents.PointerCoreFun(@(x,t,mu)A*x,2);
1409  m.System.x0= dscomponents.ConstInitialValue(sin(1:2)^t);
1410  m.simulate();
1411  m.offlineGenerations;
1412  res = false;
1413  try
1414  m.buildReducedModel;
1415  catch ME/* #ok */
1416 
1417  res = true;
1418  end
1419 
1420  /* dont forget to free resources! (static handles seem to
1421  * persist over several method calls) */
1422  clear af m;
1423  }
1424 
1425 
1426  static function test_LinearModel() {
1427  ts = testing.testsettings;
1428  m = ts.m;
1429  m.Approx.Algorithm.ExpConfig.ParamConfig= [];
1430  s = m.System;
1431  s.f= dscomponents.PointerCoreFun(ts.flin,ts.testdim);
1432  s.x0= ts.x0;
1433  m.simulate();
1434  m.offlineGenerations;
1435  r = m.buildReducedModel;
1436  r.simulate();
1437  clear s m r;
1438  }
1439 
1440 
1441  static function test_LinearModelNoProj() {
1442  ts = testing.testsettings;
1443  m = ts.m;
1444  m.Approx.Algorithm.ExpConfig.ParamConfig= [];
1445  m.SpaceReducer= [];
1446  s = m.System;
1447  s.f= dscomponents.PointerCoreFun(ts.flin,ts.testdim);
1448  s.x0= ts.x0;
1449  m.simulate();
1450  m.offlineGenerations;
1451  r = m.buildReducedModel;
1452  r.simulate();
1453  clear s m r;
1454  }
1455 
1456 
1457  static function test_LinearModelNoApprox() {
1458  ts = testing.testsettings;
1459  m = ts.m;
1460  m.Approx= [];
1461  s = m.System;
1462  s.f= dscomponents.PointerCoreFun(ts.flin,ts.testdim);
1463  s.x0= ts.x0;
1464  m.simulate();
1465  m.offlineGenerations;
1466  r = m.buildReducedModel;
1467  r.simulate();
1468  clear s m r;
1469  }
1470 
1471 
1472  static function test_LinearModelParams() {
1473  ts = testing.testsettings;
1474  m = ts.m;
1475  m.Approx.Expansion.ParamKernel= ts.ParamKernel;
1476  s = m.System;
1477  s.f= dscomponents.PointerCoreFun(ts.flin_p,ts.testdim);
1478  s.x0= ts.x0_p;
1479  for idx = 1:length(ts.params)
1480  p = ts.params(idx);
1481  s.addParam(p.Name, p.Default, " Range ", [p.MinVal p.MaxVal], " Desired ", p.Desired);
1482  end
1483  m.simulate(m.getRandomParam);
1484  m.offlineGenerations;
1485  r = m.buildReducedModel;
1486  r.simulate(r.getRandomParam);
1487  clear s m r;
1488  }
1489 
1490 
1491  static function test_LinearModelInputs() {
1492  ts = testing.testsettings;
1493  m = ts.m;
1494  m.Approx.Algorithm.ExpConfig.ParamConfig= [];
1495  s = m.System;
1496  s.B= dscomponents.PointerInputConv(ts.B);
1497  s.f= dscomponents.PointerCoreFun(ts.flin,ts.testdim);
1498  s.x0= ts.x0;
1499  s.Inputs= ts.Inputs;
1500  m.simulate([],1);
1501  m.TrainingInputs= 1:ts.testinputs;
1502  m.offlineGenerations;
1503  r = m.buildReducedModel;
1504  r.simulate([],1);
1505  clear s m r;
1506  }
1507 
1508 
1509  static function test_LinearModelParamsInput() {
1510  ts = testing.testsettings;
1511  m = ts.m;
1512  s = m.System;
1513  s.f= dscomponents.PointerCoreFun(ts.flin_p, ts.testdim);
1514  s.B= dscomponents.PointerInputConv(ts.B_p);
1515  s.x0= ts.x0_p;
1516  for idx = 1:length(ts.params)
1517  p = ts.params(idx);
1518  s.addParam(p.Name, p.Default, " Range ", [p.MinVal p.MaxVal], " Desired ", p.Desired);
1519  end
1520  s.Inputs= ts.Inputs;
1521  m.simulate(m.getRandomParam, 1);
1522  m.TrainingInputs= 1:ts.testinputs;
1523  m.offlineGenerations;
1524  r = m.buildReducedModel;
1525  r.simulate(r.getRandomParam, 1);
1526  clear s m r;
1527  }
1528 
1529 
1530  static function test_NonlinearModel() {
1531  ts = testing.testsettings;
1532  m = ts.m;
1533  s = m.System;
1534  s.f= dscomponents.PointerCoreFun(ts.fnlin,ts.testdim);
1535  s.x0= ts.x0;
1536  m.Approx.Algorithm.ExpConfig.ParamConfig= [];
1537  m.simulate();
1538  m.offlineGenerations;
1539  r = m.buildReducedModel;
1540  r.simulate();
1541  clear s m r;
1542  }
1543 
1544 
1545  static function test_NonlinearModelParams() {
1546  ts = testing.testsettings;
1547  m = ts.m;
1548  s = m.System;
1549  s.f= dscomponents.PointerCoreFun(ts.fnlin_p,ts.testdim);
1550  s.x0= ts.x0_p;
1551  for idx = 1:length(ts.params)
1552  p = ts.params(idx);
1553  s.addParam(p.Name, p.Default, " Range ", [p.MinVal p.MaxVal], " Desired ", p.Desired);
1554  end
1555  m.simulate(m.getRandomParam);
1556  m.offlineGenerations;
1557  r = m.buildReducedModel;
1558  r.simulate(r.getRandomParam);
1559  clear s m r;
1560  }
1561 
1562 
1563  static function test_NonlinearModelInputs() {
1564  ts = testing.testsettings;
1565  m = ts.m;
1566  m.Approx.Algorithm.ExpConfig.ParamConfig= [];
1567  s = m.System;
1568  s.B= dscomponents.PointerInputConv(ts.B);
1569  s.f= dscomponents.PointerCoreFun(ts.fnlin,ts.testdim);
1570  s.x0= ts.x0;
1571  s.Inputs= ts.Inputs;
1572  m.simulate([],1);
1573  m.offlineGenerations;
1574  r = m.buildReducedModel;
1575  r.simulate([],1);
1576  clear s m r;
1577  }
1578 
1579 
1581  ts = testing.testsettings;
1582  m = ts.m;
1583  m.Approx.Expansion.ParamKernel= ts.ParamKernel;
1584  s = m.System;
1585  s.f= dscomponents.PointerCoreFun(ts.fnlin_p,ts.testdim);
1586  s.B= dscomponents.PointerInputConv(ts.B_p);
1587  s.x0= ts.x0_p;
1588  for idx = 1:length(ts.params)
1589  p = ts.params(idx);
1590  s.addParam(p.Name, p.Default, " Range ", [p.MinVal p.MaxVal], " Desired ", p.Desired);
1591  end
1592  s.Inputs= ts.Inputs;
1593  m.simulate(m.getRandomParam,1);
1594  m.offlineGenerations;
1595  r = m.buildReducedModel;
1596  r.simulate(r.getRandomParam,1);
1597  clear s m r;
1598  }
1599 
1600 
1601  static function test_TimeDependentOutput() {
1602  ts = testing.testsettings;
1603  m = ts.m;
1604  m.Approx.Algorithm.ExpConfig.ParamConfig= [];
1605  s = m.System;
1606  s.f= dscomponents.PointerCoreFun(ts.flin,ts.testdim);
1607  s.x0= ts.x0;
1608  s.C= dscomponents.PointerOutputConv(@(t,mu)t,true);
1609  m.simulate();
1610  m.offlineGenerations;
1611  r = m.buildReducedModel;
1612  r.simulate();
1613  clear s m r;
1614  }
1615 
1616 
1617  static function res = test_FileSystemTidyness() {
1618  m = models.circ.RCLadder(10);
1619  m.offlineGenerations;
1620  dir = m.Data.DataDirectory;
1621 
1622  /* Plain small model with FileData */
1623  m = models.circ.RCLadder(10);
1624 
1625  /* Overwrite test: old m instance isnt needed anywhere else */
1626  res = exist(dir," file ") == 0;
1627 
1628  /* Test with FileTrajectoryData, FileTrajectoryFxiData and nonempty SimCache */
1629  m.Data.useFileTrajectoryData;
1630  m.ComputeTrajectoryFxiData= true;
1631  m.TrainingInputs= [2 3];
1632  m.offlineGenerations;
1633  m.simulate([],4);
1634 
1635  /* "Tweak" atd FileMatrices to contain more than one block */
1636  atd = m.Data.ApproxTrainData;
1637  atd.xi= atd.xi.copyWithNewBlockSize(0.1);
1638  atd.fxi= atd.fxi.copyWithNewBlockSize(0.1);
1639 
1640  dir = m.Data.DataDirectory;
1641  clear atd;
1642  clear m;
1643  res = res && exist(dir," file ") == 0;
1644  }
1701 };
1702 }
1703 
1704 
function file = save(char directory,char filename)
Saves this instance inside the data.ModelData.DataDirectory folder using the model's SaveTag if set o...
char Name
The name of the Model.
Definition: BaseModel.m:117
Collection of generally useful functions.
Definition: Utils.m:17
static function test_LinearModel()
integer fDim
The current output dimension of the function.
Definition: ACoreFun.m:171
varargin TargetDimensions
This property determines which dimensions are to be reduced. It is possible to reduce the entire numb...
data.FileMatrix xi
The state space samples , stored row-wise in a data.FileMatrix instance.
static function res = test_FileSystemTidyness()
Plain small model.
static function comb = createCombinations(ranges, varargin)
Creates the cartesian product of the vectors passed as a matrix containing elements of each vector pe...
Definition: Utils.m:114
data.FileMatrix fxi
The evaluations of , stored row-wise in a data.FileMatrix.
function useFileTrajectoryData(logical overwrite)
Sets the TrajectoryData and TrajectoryFxiData classes to filesystem based versions.
Definition: ModelData.m:349
BaseModel: Base class for both full and reduced models.
Definition: BaseModel.m:18
virtual function [ colvec< double > x , double ctime ] = getTrajectory(colvec< double > mu,integer inputidx)
Gets the traejctory for the given parameter and input index.
matrix< double > InputSpaceSpan
The orthonormalized vectors spanning the space of the input components.
Definition: ModelData.m:97
logical isStatic
Determines if the model is time dependent or static.
Definition: BaseModel.m:174
error.BaseEstimator ErrorEstimator
The associated error estimator for this model.
virtual function approximateSystemFunction(model)
Computes the approximation according to the concrete approximation strategy.
function [ models.ReducedModel reduced , double time ] = buildReducedModel(varargin)
Builds a reduced model from a full model.
The base class for any KerMor detailed model.
Definition: BaseFullModel.m:18
function off6_prepareErrorEstimator()
Prepares offline data for a possible error estimator.
double dt
The desired time-stepsize for simulations.
Definition: BaseModel.m:291
integer TrainingInputs
The indices of inputs to use for training data generation. Uses the DefaultInput if not set (and Defa...
sampling.BaseSampler Sampler
The sampling strategy the Model uses.
static function test_TimeDependentOutput()
models.BaseFirstOrderSystem System
The actual dynamical system used in the model.
Definition: BaseModel.m:102
dscomponents.AInputConv B
The input conversion.
Times
Evaluation points of the model.
Definition: BaseModel.m:206
SampleCount
The number of samples contained in the model data.
Definition: ModelData.m:167
function prepareSimulation(colvec< double > mu)
A method that allows parameter-dependent computations to be performed before a simulation using this ...
Definition: ACoreFun.m:380
virtual function clearTrajectories()
Clears all stored trajectory data.
function setConfig(mu, inputidx)
Sets the dynamical system's configuration.
A MatLab cell array or matrix.
static function test_LinearModelNoProj()
colvec< data.ProjectionSpace > ProjectionSpaces
Array of ProjectionSpace instances that contains all the separate linear projection spaces computed d...
Definition: ModelData.m:133
function off3_computeReducedSpace()
Offline phase 3: Generate state space reduction.
function registerProps(varargin)
Call this method at any class that defines DPCM observed properties.
Definition: DPCMObject.m:125
virtual function addTrajectory(colvec< double > x,colvec< double > mu,integer inputidx,double ctime)
Adds a trajectory to the ModelData instance.
logical RealTimePlotting
Determines if the simulation should plot intermediate steps during computation.
Definition: BaseModel.m:335
function_handle postApproximationTrainingCallback
Advanced property. Must be a function handle taking the current model instance.
matrix ParamSamples
A Model's parameter samples as column vector collection.
Definition: ModelData.m:53
An integer value.
function transferFrom(data.ATrajectoryData source)
Transfers the data from one ATrajectoryData instance to another.
data.FileDataCollection TrajectoryFxiData
Evaluations of the system's nonlinearity on the trajectoriy data.
Definition: ModelData.m:85
function [ double t , matrix< double > y , colvec< double > mu , in , ct ] = getSimCacheTrajectory(nr)
A MatLab function handle.
static function test_LinearModelInputs()
JKerMorExport: Export class for JaRMoS model generation from KerMor models.
Definition: JKerMorExport.m:17
Matlab's base handle class (documentation generation substitute)
function off4_genApproximationTrainData()
Generates the training data for the -approximation and precomputes values.
BaseSampler Basis class for parameter sampling classes.
Definition: BaseSampler.m:18
static function test_NonlinearModelInputs()
DPCM: Default property change monitoring for MatLab class properties.
Definition: DPCM.m:17
A boolean value.
static function test_LinearModelParams()
ComputeParallel
Flag whether the code should be run in parallel or not.
Base class for all error estimators.
Definition: BaseEstimator.m:18
function [ V , W ] = assembleProjectionMatrices(target_dim)
A variable number of input arguments.
integer xDim
The current state space dimension of the function's argument .
Definition: ACoreFun.m:151
BaseFullModel(char name)
Creates a new instance of a full model.
static function test_NonlinearModel()
ApproxTrainData(matrix< double > xi,rowvec< double > ti,matrix< double > mui)
Creates a new approx train data instance.
logical ProjectApproxTrainingData
Flag to determine if the data collected by the approx.Approx.TrainDataSelector should be projected in...
integer DefaultInput
The default input to use if none is given.
Definition: BaseModel.m:189
export.JKerMorExport JKerMorExport
Export instance for possible export of this model to JKerMor.
rowvec< integer > TrainingParams
The indices of the model parameters to use for training data generation.
function plotTrajectoryNr(nr)
logical ComputeTrajectoryFxiData
Flag that determines whether fxi data should be computed along with the trajectories or not...
static function res = test_BareModel()
approx.BaseApprox Approx
The approximation method for the CoreFunction.
disp
Handle object disp method which is called by the display method. See the MATLAB disp function...
double T
The final timestep up to which to simulate.
Definition: BaseModel.m:271
function addProjectionSpace(V, W, dims)
Adds a new projection space to the model data instance.
Definition: ModelData.m:224
data.ModelData Data
The full model's data container. Defaults to an empty container.
function off5_computeApproximation()
Offline phase 5: Core function approximation.
function off2_genTrainingData()
Offline phase 2: Snapshot generation for subspace computation.
char DataDirectory
The root folder where the FileData's files are saved.
Definition: FileData.m:56
spacereduction.BaseSpaceReducer SpaceReducer
The reduction algorithm for subspaces.
function_handle preApproximationTrainingCallback
Advanced property. Must be a function handle taking the current model instance.
static function this = loadobj(this, sobj)
integer TrainingInputCount
Gets the number of inputs used for training.
static function test_BaseModels()
function off1_createParamSamples()
Offline phase 1: Sample generation.
ModelData(varargin)
Creates a new container for large full model data.
Definition: ModelData.m:180
Abstract base class for all core function approximations inside dynamical systems.
Definition: BaseApprox.m:18
function [ t , x , time , cache ] = computeTrajectory(colvec< double > mu, inputidx)
Computes a solution/trajectory for the given mu and inputidx in the SCALED state space.
function checkType(obj, type)
Object typechecker.
Definition: KerMorObject.m:122
logical EnableTrajectoryCaching
Flag that enables caching of computed trajectories in a simulation cache stored in KerMor's TempDirec...
IParallelizable Interface to indicate parallel computation capability of the implementing classes...
dscomponents.ACoreFun f
The core f function from the dynamical system.
function [ double t , colvec< double > x , double ctime ] = solveStatic(colvec< double > mu,integer inputidx)
Solves the linear system . Spatial dependence of f is neglected in the current implementation (since ...
Definition: BaseModel.m:634
function samples = generateSamples(models.BaseFullModel model)
Definition: BaseSampler.m:44
function offlineGenerations()
Performs all large offline computations for model reduction.
function fx = evaluateMulti(colvec< double > x,double t,colvec< double > mu)
Evaluates this function on multiple locations and maybe multiple times and parameters.
Definition: ACoreFun.m:335
ParamCount
The number of the system's parameters.
rowvec< double > scaledTimes
The time steps Times in scaled time units .
Definition: BaseModel.m:218
rowvec< double > OfflinePhaseTimes
The computation times for all phases of the last offline generation.
static function criticalsCheck(DPCMobj)
This is a shorthand method that runs the DPCM but only for critical properties.
Definition: DPCM.m:192
virtual function [ colvec< double > x , colvec< double > mu , integer inputidx , double ctime ] = getTrajectoryNr(nr)
Gets the trajectory with the number nr.
function [ handle f , handle ax ] = plot(rowvec< double > t,matrix< double > y, varargin)
Plots the results of the simulation. Override in subclasses for a more specific plot if desired...
Definition: BaseModel.m:539
Data class that contains a model's large data, including subspace matrices, trajectories and approxim...
Definition: ModelData.m:18
Global configuration class for all KerMor run-time settings.
Definition: KerMor.m:17
static function test_NonlinearModelParams()
function matrix< double > mu = getParams(rowvec< int32 > idx)
Returns parameters for given indices.
Definition: ModelData.m:245
logical AutoSave
Flag to enable automatic saving of the model after each individual offline phase step and at other lo...
BaseFirstOrderSystem(models.BaseFullModel model)
Creates a new base dynamical system class instance.
TrajectoriesCompleted
Contains a flag for each input/parameter combination which has been successfully computed completely ...
static function KerMor theinstance = App()
The singleton KerMor instance.
Definition: KerMor.m:910
addlistener
Creates a listener for the specified event and assigns a callback function to execute when the event ...
data.ApproxTrainData ApproxTrainData
Training data for the core function approximation.
Definition: ModelData.m:110
A MatLab character array.
Base class for all space reduction algorithms.
static function test_LinearModelNoApprox()
static function test_NonlinearModelParamsInput()
data.ATrajectoryData TrajectoryIncompleteData
The incomplete trajectory training data for the full model is saved separately.
Definition: ModelData.m:74
ProcessIndicator: A simple class that indicates process either via waitbar or text output...
data.ATrajectoryData TrajectoryData
The trajectory training data for the full model (only complete trajectories!)
Definition: ModelData.m:63
char SaveTag
A custom tag that can be used as a prefix to files for corresponding model identification.
static function test_LinearModelParamsInput()