144 if strcmpi(this.
Mode,
" rel ")
145 target_dim = ceil(min(size(data))*this.
Value);
146 elseif strcmpi(this.
Mode,
" abs ")
147 target_dim = this.
Value;
149 if ~isempty(target_dim) && target_dim > min(size(data))
150 warning(
" KerMor:general:POD ",
" Targeted reduced space dimension (%d) has to be <= the smallest matrix dimension (%d). Using size %d. ",...
151 target_dim,min(size(data)),min(size(data)));
152 target_dim = min(size(data));
156 if isa(data,
" data.ABlockedData ")
157 if ~any(strcmpi(this.
Mode,[
" abs ",
" rel "]))
158 target_dim = min(size(data));
159 if max(size(data)) > 10000
160 warning(
" POD on data.ABlockedData with dimension %d and mode '%s' is possibly very very slow. Try to use "" abs "" or "" rel "" modes. ",max(size(data)),this.
Mode);
165 fprintf(
" Starting POD on ABlockedData(%s, %dx%d, %d blocks) with mode "" %s "" and value %g\n ",...
166 class(data),n,m,data.getNumBlocks,
this.Mode,
this.Value);
168 [podvec, s] = data.getSVD(target_dim, Vexclude, targetdims);
171 sig = 1:size(podvec,2);
172 if strcmpi(this.
Mode,
" sign ")
173 sig = s >= s(1)*this.
Value;
174 elseif strcmpi(this.
Mode,
" eps ")
175 sig = s >= this.
Value;
177 podvec = podvec(:,sig);
182 data = data(targetdims,:);
185 if ~isempty(Vexclude)
186 data = data - Vexclude*(Vexclude^
t*data);
187 target_dim = min(target_dim, min(size(data))-size(Vexclude,2));
194 nonzero = find(sum(abs(data),2) ~= 0);
198 fprintf(
" Reducing data dimension from %d to %d as sparse matrix is given. ",...
199 size(data,1),length(find(nonzero)));
201 fulldim = size(data,1);
202 data = full(data(nonzero,:));
207 fprintf(
" Starting POD on %dx%d matrix with mode "" %s "" and value %g (UseSVDS=%d) ... ",...
213 if any(strcmpi(this.
Mode,[
" sign ",
" eps "]))
214 [u,s] = svd(data,
" econ ");
216 if strcmpi(this.
Mode,
" sign ")
217 sig = s >= s(1)*this.
Value;
218 elseif strcmpi(this.
Mode,
" eps ")
219 sig = s >= this.
Value;
222 fprintf(
" selecting %d singular values ... ",length(find(sig)));
228 rerr = 100*err/sum(s);
238 if this.
UseSVDS || issparse(data)
239 [u, s] = svds(data, target_dim);
242 [u,s] = svd(data,
" econ ");
244 err = sum(s(target_dim+1:end));
245 rerr = 100*err/sum(s);
246 u(:,target_dim+1:end) = [];
250 fprintf(
" error %g (%g%% relative)\n ",err,rerr);
254 z = find(s(1:size(u,2)) == 0);
256 warning(
" KerMor:POD ",
" %d of %d selected singular values are zero. Assuming output size %d ",...
257 length(z),length(s),length(s)-length(z));
270 if any(any(round(podvec^
t*podvec) ~= eye(size(podvec,2))))
271 warning(
" KerMor:POD ",[
" Resulting POD vectors not " ...
272 " sufficiently orthogonal. Orthonormalizing. "]);
275 o = general.Orthonormalizer;
276 podvec = o.orthonormalize(podvec);
308 #if 0 //mtoc++: 'set.UseSVDS'
320 #if 0 //mtoc++: 'set.Mode'
321 function
Mode(value) {
322 if ~any(strcmpi(value, [
" sign ",
" eps ",
" abs ",
" rel "]))
323 error([" Unknown
POD reduction mode: " value " \nAllowed: sign, eps, abs, rel "]);
325 this.
Mode= lower(value);
332 #if 0 //mtoc++: 'set.Value'
333 function
Value(value) {
334 if ~isreal(value) || ~isscalar(value)
335 error("
Value property must be a positive real scalar. ");
352 res = res && general.POD.internalPODTest(pod, vec);
353 res = res && general.POD.internalPODTest(pod, vec, 1:30);
354 res = res && general.POD.internalPODTest(pod, vec, 30:50);
358 res = res && general.POD.internalPODTest(pod, vec);
359 res = res && general.POD.internalPODTest(pod, vec, 1:300);
360 res = res && general.POD.internalPODTest(pod, vec, 800:900);
367 static function res = internalPODTest(pod,vec,selection) {
374 V = pod.computePOD(vec,[],selection);
375 res = res && isequal(round(V^
t*V),eye(size(V,2)));
379 V = pod.computePOD(vec,[],selection);
380 res = res && isequal(round(V^
t*V),eye(size(V,2)));
384 V = pod.computePOD(vec,[],selection);
385 res = res && isequal(round(V^
t*V),eye(size(V,2)));
388 o = general.Orthonormalizer;
390 exclu = o.orthonormalize(rand(length(vec(selection,1)),round(pod.Value/2)));
391 Vex = pod.computePOD(vec,exclu,selection);
392 res = res && isequal(round(Vex^
t*Vex),eye(size(Vex,2)));
393 res = res && norm(exclu^
t*Vex) < 1e-12;
397 Vf = pod.computePOD(data.FileMatrix(vec),[],selection);
398 res = res && isequal(round(Vf
" *Vf),eye(size(Vf,2))) && norm(abs(V)-abs(Vf), "fro^
t) < 1e-10;
402 V = pod.computePOD(vec,[],selection);
403 res = res && isequal(round(V^t*V),eye(size(V,2)));
407 Vf = pod.computePOD(data.FileMatrix(vec),[],selection);
408 res = res && isequal(round(Vf
" *Vf),eye(size(Vf,2))) && norm(abs(V)-abs(Vf), "fro^t) < 1e-10;
static function res = test_POD()
Base class for any KerMor class.
static function Asparse = toSparse(matrix< double > A,rowvec< integer > rowidx, n)
Converts a full matrix A to a sparse matrix, where the entries of A are split up to the row indices s...
function registerProps(varargin)
Call this method at any class that defines DPCM observed properties.
function [ matrix< double > podvec , rowvec< double > s ] = computePOD(matrix< double > data,matrix< double > Vexclude,colvec< integer > targetdims)
Computes the POD vectors according to the specified settings.
KerMorObject()
Constructs a new KerMor object.
Value
The value associated with the selected Mode.
Mode
The modus used to generate the reduced space.
UseSVDS
Flag whether to use the svds routine rather than svd. Applies only for the Modes abs and rel...
MatUtils: Matrix utility functions.
POD: Implements proper orthogonal decomposition.
Global configuration class for all KerMor run-time settings.
static function KerMor theinstance = App()
The singleton KerMor instance.