├── Examples_gallery_2 ├── .gitattributes ├── supplementary_files │ ├── myPSD.m │ └── redblueTecplot.m ├── Cylinder_wake.m └── LIP_example.m ├── Examples_gallery_4 ├── cmap.mat ├── Cascade_example.m └── Cylinder_example.m ├── Examples_gallery_1 ├── supplementary_files │ ├── PP_Ver_2_3 │ │ ├── PPGUI.m │ │ ├── StereoS2P.m │ │ ├── zplane.m │ │ ├── zplanePP.m │ │ ├── StereoP2S.m │ │ ├── myfunction.m │ │ ├── unitcirc.m │ │ ├── zdomain.m │ │ ├── BrightenRGB.m │ │ ├── fldrect.m │ │ ├── license.txt │ │ ├── PhasePlot.m │ │ ├── PPOnSphLow.m │ │ ├── PPOnSphUp.m │ │ ├── pltphase.m │ │ ├── Contents.m │ │ ├── PPOnSphere.m │ │ └── PPDemo.m │ └── sparse-grids │ │ ├── tools │ │ ├── knots_functions │ │ │ ├── GaussianLejaPrecomputedKnotsAndWeights.mat │ │ │ ├── knots_gaussian.m │ │ │ ├── knots_gaussian_leja.m │ │ │ ├── knots_CC.m │ │ │ └── knots_uniform.m │ │ ├── lev2knots_functions │ │ │ ├── lev2knots_lin.m │ │ │ ├── lev2knots_2step.m │ │ │ ├── lev2knots_doubling.m │ │ │ └── lev2knots_kpn.m │ │ ├── idxset_functions │ │ │ ├── multiidx_box_set.m │ │ │ ├── check_set_admissibility.m │ │ │ ├── define_functions_for_rule.m │ │ │ ├── fast_TD_set.m │ │ │ └── check_index_admissibility.m │ │ ├── polynomials_functions │ │ │ ├── cheb_eval.m │ │ │ ├── lagr_eval.m │ │ │ ├── lege_eval_multidim.m │ │ │ ├── cheb_eval_multidim.m │ │ │ ├── herm_eval_multidim.m │ │ │ ├── lagr_eval_fast.m │ │ │ ├── herm_eval.m │ │ │ ├── lege_eval.m │ │ │ └── lagr_eval_multidim.m │ │ └── rescaling_functions │ │ │ └── get_interval_map.m │ │ ├── src │ │ ├── get_parallel_numworkers.m │ │ ├── close_parallel.m │ │ ├── istensor.m │ │ ├── isreduced.m │ │ ├── check_if_parallel_on.m │ │ ├── issmolyak.m │ │ ├── islexico.m │ │ ├── activate_parallel.m │ │ ├── kpn_lev_table.m │ │ ├── plot_idx_status.m │ │ ├── asreduced.m │ │ ├── detect_unsufficient_tolerance.m │ │ ├── multiidx_gen.m │ │ ├── tensor_grid.m │ │ ├── generate_pattern.m │ │ ├── find_lexicographic.m │ │ ├── quadrature_on_sparse_grid_legacy.m │ │ ├── compute_modal_tensor.m │ │ └── mysortrows.m │ │ ├── ERRORS_AND_WARNINGS_LIST.m │ │ ├── main │ │ ├── plot_sparse_grid.m │ │ ├── export_sparse_grid_to_file.m │ │ ├── derive_sparse_grid.m │ │ ├── compute_sobol_indices_from_sparse_grid.m │ │ └── quadrature_on_sparse_grid.m │ │ ├── LICENSE.txt │ │ ├── docs-examples │ │ ├── test_sparse_quadrature.m │ │ ├── test_evaluate_on_sparse_grids.m │ │ └── test_sparse_interpolation.m │ │ └── README.m ├── circle_rotation_example.m ├── Lorenz_attractor_example.m ├── CMV_example.m ├── Gauss_map_example.m ├── filter_plots_and_shift_example.m ├── pendulum_example.m ├── double_pendulum_example.m └── tent_map_example.m ├── Examples_gallery_3 ├── data_from_runs │ └── circle_data.mat └── circle_map.m ├── main_routines ├── ErgodicMoments.m ├── MomentMeas.m ├── README.md ├── kernel_ResDMD.m ├── KoopPseudoSpecQR.m ├── KoopPseudoSpec.m ├── parfor_progress.m └── IsomMeas.m ├── LICENSE ├── Duffing_example.m └── README.md /Examples_gallery_2/.gitattributes: -------------------------------------------------------------------------------- 1 | *.mat filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /Examples_gallery_4/cmap.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MColbrook/Residual-Dynamic-Mode-Decomposition/HEAD/Examples_gallery_4/cmap.mat -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/PPGUI.m: -------------------------------------------------------------------------------- 1 | GUI_PhasePlot 2 | % graphical user interface for phase plots 3 | % 4 | % Usage: GUI_PhasePlot -------------------------------------------------------------------------------- /Examples_gallery_3/data_from_runs/circle_data.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MColbrook/Residual-Dynamic-Mode-Decomposition/HEAD/Examples_gallery_3/data_from_runs/circle_data.mat -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/knots_functions/GaussianLejaPrecomputedKnotsAndWeights.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MColbrook/Residual-Dynamic-Mode-Decomposition/HEAD/Examples_gallery_1/supplementary_files/sparse-grids/tools/knots_functions/GaussianLejaPrecomputedKnotsAndWeights.mat -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/get_parallel_numworkers.m: -------------------------------------------------------------------------------- 1 | function numw = get_parallel_numworkers() 2 | 3 | if verLessThan('matlab', '8.3') 4 | numw = matlabpool('size') ; 5 | else 6 | p=gcp('nocreate'); 7 | if isempty(p); 8 | numw=0; 9 | else 10 | numw = p.NumWorkers; 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/StereoS2P.m: -------------------------------------------------------------------------------- 1 | function zz = StereoS2P(x,y,z) 2 | % stereographic projection from sphere to plane 3 | % 4 | % Usage: zz = StereoS2P(x,y,z) 5 | 6 | % Part of the phase plot package 7 | % Version 2.3, January 15, 2014 8 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 9 | 10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11 | 12 | zz = (x+1i*y)./(1-z); 13 | -------------------------------------------------------------------------------- /main_routines/ErgodicMoments.m: -------------------------------------------------------------------------------- 1 | function MU = ErgodicMoments(X,N) 2 | % Compute moments -N to N of vector X using ergodic formula 3 | X=X(:); 4 | M=length(X); 5 | MU=zeros(1,N+1); 6 | MU(1)=X'*X/(M*2*pi); 7 | % MU2=MU; 8 | 9 | w=conv(X,conj(flipud(X))); 10 | MU(2:N+1)=transpose(w(length(X)-(1:N)))./(2*pi*((M-1):(-1):M-N)); 11 | 12 | % for j=1:N 13 | % MU(j+1)=X(j+1:end)'*X(1:end-j)/(2*pi*(M-j)); 14 | % end 15 | % norm(MU-MU2) 16 | 17 | MU=[conj(fliplr(MU(2:end))),MU]; 18 | 19 | end 20 | 21 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/zplane.m: -------------------------------------------------------------------------------- 1 | function z = zplane(n) 2 | % discrete field of points covering the entire complex plane 3 | % 4 | % Usage: z = zplane(n); 5 | 6 | % Part of the phase plot package 7 | % Version 2.3, January 15, 2014 8 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 9 | 10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11 | 12 | if nargin<1, n=1200; end; 13 | 14 | [p,q,r] = sphere(n); 15 | 16 | z = StereoS2P(p,q,r); 17 | 18 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/zplanePP.m: -------------------------------------------------------------------------------- 1 | function z = zplanePP(n) 2 | % discrete field of points covering the entire complex plane 3 | % 4 | % Usage: z = zplanePP(n); 5 | 6 | % Part of the phase plot package 7 | % Version 2.3, January 15, 2014 8 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 9 | 10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11 | 12 | if nargin<1, n=1200; end; 13 | 14 | [p,q,r] = sphere(n); 15 | 16 | z = StereoS2P(p,q,r); 17 | 18 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/StereoP2S.m: -------------------------------------------------------------------------------- 1 | function [p,q,r] = StereoP2S(z) 2 | % stereographic projection from plane to sphere 3 | % 4 | % Usage: [p,q,r] = StereoP2S(z) 5 | 6 | % Part of the phase plot package 7 | % Version 2.3, January 15, 2014 8 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 9 | 10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11 | 12 | x = real(z); 13 | y = imag(z); 14 | 15 | w = x.^2 + y.^2 + 1; 16 | 17 | p = 2*x./w; 18 | q = 2*y./w; 19 | r = (w-2)./w; 20 | -------------------------------------------------------------------------------- /Examples_gallery_2/supplementary_files/myPSD.m: -------------------------------------------------------------------------------- 1 | function [ F, Pxx ] = myPSD(x,Fsampling,N) 2 | % Power Spectral Density 3 | % [ F, Pxx ] = myPSD(x, Finterest, Fsampling) 4 | 5 | x = x-mean(x); 6 | % Finterest (Hz), the lowest freq we want to resolve accurately 7 | 8 | % WindowSize = 32 * Fsampling / Finterest; 9 | % NumOfWindows = 128;%length(x)/WindowSize; 10 | 11 | WindowLength = N;%length(x) / NumOfWindows; 12 | overlap = WindowLength / 2; 13 | 14 | [pxx , f] = pwelch(x, WindowLength, overlap, Fsampling/2, Fsampling); 15 | 16 | Pxx = pxx; 17 | F = f; 18 | 19 | end 20 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/myfunction.m: -------------------------------------------------------------------------------- 1 | function w = myfunction(z) 2 | % example of complex function written as script for use with PPGUI 3 | % 4 | % this is an atomic singular inner function with atoms sitting at the 5 | % fifth root of unity 6 | 7 | % Part of the phase plot package 8 | % Version 2.3, January 15, 2014 9 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 10 | 11 | omega = exp(2i*pi/5); 12 | 13 | w = ones(size(z)); 14 | 15 | for k=0:4 16 | w = w.*exp((z+omega.^k)./(z-omega.^k)); 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/unitcirc.m: -------------------------------------------------------------------------------- 1 | function t=unitcirc(n) 2 | % uniformly distributed points on complex unit circle 3 | % 4 | % Usage: t = unitcirc(n) 5 | % n+1 uniformly distributed points on the complex unit circle, t(n+1)=t(1) 6 | 7 | % Part of the phase plot package 8 | % Version 2.3, January 15, 2014 9 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 10 | 11 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 12 | 13 | if nargin<1, n=1024; end; 14 | 15 | t = exp(1i*linspace(0,2*pi,n+1)); 16 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/lev2knots_functions/lev2knots_lin.m: -------------------------------------------------------------------------------- 1 | function [m] = lev2knots_lin(i) 2 | 3 | 4 | % relation level / number of points: 5 | % m = i 6 | % 7 | % [m] = lev2knots_lin(i) 8 | % i: level in each direction 9 | % m: number of points to be used in each direction 10 | 11 | 12 | %---------------------------------------------------- 13 | % Sparse Grid Matlab Kit 14 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 15 | % See LICENSE.txt for license 16 | %---------------------------------------------------- 17 | 18 | m = i; -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/close_parallel.m: -------------------------------------------------------------------------------- 1 | function [] = close_parallel() 2 | 3 | %CLOSE_PARALLEL closes a parallel toolbox session 4 | % 5 | % CLOSE_PARALLEL() uses the default number of parallel workers 6 | 7 | 8 | %---------------------------------------------------- 9 | % Sparse Grid Matlab Kit 10 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 11 | % See LICENSE.txt for license 12 | %---------------------------------------------------- 13 | 14 | if verLessThan('matlab', '8.3') 15 | eval('matlabpool close') 16 | else 17 | p=gcp('nocreate'); 18 | delete(p) 19 | end 20 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/istensor.m: -------------------------------------------------------------------------------- 1 | function ist = istensor(S) 2 | 3 | % ISTENSOR(S) returns 1 if S is a tensor grid. A tensor grid is a struct with fields 4 | % 'knots','weights','size','knots_per_dim','m'. 5 | 6 | 7 | %---------------------------------------------------- 8 | % Sparse Grid Matlab Kit 9 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 10 | % See LICENSE.txt for license 11 | %---------------------------------------------------- 12 | 13 | if isstruct(S) 14 | ist=isempty(setxor(fieldnames(S),{'knots','weights','size','knots_per_dim','m'})) && length(S)==1; 15 | else 16 | ist=0; 17 | end 18 | 19 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/lev2knots_functions/lev2knots_2step.m: -------------------------------------------------------------------------------- 1 | function [m] = lev2knots_2step(i) 2 | 3 | 4 | % relation level / number of points: 5 | % m = 2(i-1)+1, 6 | % 7 | % i.e. m=1,3,5,7,9,... 8 | % 9 | % [m] = lev2knots_2step(i) 10 | % i: level in each direction 11 | % m: number of points to be used in each direction 12 | 13 | 14 | %---------------------------------------------------- 15 | % Sparse Grid Matlab Kit 16 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 17 | % See LICENSE.txt for license 18 | %---------------------------------------------------- 19 | 20 | m = 2*(i-1)+1; 21 | m(i==0)=0; -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/isreduced.m: -------------------------------------------------------------------------------- 1 | function isr = isreduced(S) 2 | 3 | % ISREDUCED(S) returns 1 if S is a reduced sparse grid. A reduced sparse grid is a struct with fields 4 | % 'knots','m','weights','n','size'. 5 | 6 | 7 | %---------------------------------------------------- 8 | % Sparse Grid Matlab Kit 9 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 10 | % See LICENSE.txt for license 11 | %---------------------------------------------------- 12 | 13 | 14 | if isstruct(S) 15 | isr=isempty(setxor(fieldnames(S),{'knots','m','weights','n','size'})) && length(S)==1; 16 | else 17 | isr=0; 18 | end 19 | 20 | 21 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/check_if_parallel_on.m: -------------------------------------------------------------------------------- 1 | function is_on = check_if_parallel_on() 2 | 3 | 4 | %CHECK_IF_PARALLEL_ON checks if a parallel toolbox session is open 5 | % 6 | % IS_ON = CHECK_IF_PARALLEL_ON() returns TRUE if a parallel session is open and FALSE otherwise 7 | 8 | 9 | %---------------------------------------------------- 10 | % Sparse Grid Matlab Kit 11 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 12 | % See LICENSE.txt for license 13 | %---------------------------------------------------- 14 | 15 | 16 | if verLessThan('matlab', '8.3') 17 | is_on = logical( matlabpool('size') ); 18 | else 19 | is_on = ~isempty(gcp('nocreate')); 20 | end 21 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/issmolyak.m: -------------------------------------------------------------------------------- 1 | function iss = issmolyak(S) 2 | 3 | % ISSMOLYAK(S) returns 1 if S is a smolyak sparse grid. A smolyak sparse grid is a vector of structs with fields 4 | % 'knots','weights','size','knots_per_dim','m','coeff','idx'. 5 | 6 | 7 | %---------------------------------------------------- 8 | % Sparse Grid Matlab Kit 9 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 10 | % See LICENSE.txt for license 11 | %---------------------------------------------------- 12 | 13 | if isstruct(S) 14 | iss=isempty(setxor(fieldnames(S),{'knots','weights','size','knots_per_dim','m','coeff','idx'})) && length(S)>=1; 15 | else 16 | iss=0; 17 | end 18 | 19 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/ERRORS_AND_WARNINGS_LIST.m: -------------------------------------------------------------------------------- 1 | % -------------------------------------------- 2 | % errors 3 | % -------------------------------------------- 4 | 5 | 'SparseGKit:WrongInput' %#ok<*NOPTS> 6 | 'SparseGKit:NoOpenPar' 7 | 'SparseGKit:SetNotSorted' 8 | 'SparseGKit:OutOfTable' 9 | 'SparseGKit:ToBeCoded' 10 | 'SparseGKit:FailedSanityChk' 11 | 12 | % -------------------------------------------- 13 | % warnings 14 | % -------------------------------------------- 15 | 16 | 'SparseGKit:GridsAreEqual' 17 | 'SparseGKit:deprecated' 18 | 'SparseGKit:TolNotEnough' 19 | 'SparseGKit:uint16' 20 | 'SparseGKit:double' 21 | 'SparseGKit:KpnNonTab' 22 | 'SparseGKit:IgnoredInput' %#ok<*NOPTS> 23 | 24 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/lev2knots_functions/lev2knots_doubling.m: -------------------------------------------------------------------------------- 1 | function m = lev2knots_doubling(i) 2 | 3 | % m = lev2knots_doubling(i) 4 | % 5 | % relation level / number of points: 6 | % m = 2^{i-1}+1, for i>1 7 | % m=1 for i=1 8 | % m=0 for i=0 9 | % 10 | % i.e. m(i)=2*m(i-1)-1 11 | 12 | 13 | %---------------------------------------------------- 14 | % Sparse Grid Matlab Kit 15 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 16 | % See LICENSE.txt for license 17 | %---------------------------------------------------- 18 | 19 | 20 | m = 2.^(i-1)+1; 21 | for k=1:length(m(:)) 22 | if i(k)==1 23 | m(k) = 1; 24 | end 25 | if i(k)==0 26 | m(k) = 0; 27 | end 28 | end 29 | 30 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/idxset_functions/multiidx_box_set.m: -------------------------------------------------------------------------------- 1 | function [C_with,C_without] = multiidx_box_set(shape,min_idx) 2 | 3 | % [C_with,C_without] = MULTIIDX_BOX_SET(ii,min_idx) 4 | % 5 | % given an index ii, generates C_with, the box indeces set up to that ii. 6 | % min_idx is either 0 or 1. C_without is C_with without ii itself 7 | 8 | 9 | %---------------------------------------------------- 10 | % Sparse Grid Matlab Kit 11 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 12 | % See LICENSE.txt for license 13 | %---------------------------------------------------- 14 | 15 | 16 | 17 | N=length(shape); 18 | shape_fun=@(i) i-shape(1:length(i)); 19 | C_with=multiidx_gen(N,shape_fun,0,min_idx); 20 | 21 | C_without=C_with; 22 | C_without(end,:)=[]; 23 | 24 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/zdomain.m: -------------------------------------------------------------------------------- 1 | function z = zdomain(zll,zur,m,n) 2 | % discrete field of complex numbers, domain of function 3 | % 4 | % Usage: z = zdomain(zll,zur,m,n); 5 | % zll - complex number, lower left corner of the rectangular domain 6 | % zur - complex number, upper right corner of the rectangular domain 7 | % m,n - number of discretization points in x and y direction 8 | 9 | % part of the phase plot package - visualization of complex functions 10 | % Version 2.3, January 15, 2014 11 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 12 | 13 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14 | 15 | if nargin<1, zll=-1-1i; end; 16 | if nargin<2, zur=1+1i; end; 17 | if nargin<3, m=1000; end; 18 | if nargin<4, n=1000; end; 19 | 20 | z = fldrect(zll,zur,m,n); 21 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/islexico.m: -------------------------------------------------------------------------------- 1 | function isl = islexico(a,b) 2 | 3 | % ISLEXICO checks lexicographic order of vectors 4 | % ISLEXICO(A,B) for A and B vectors returns logical 1 (true) if A<=B in lexicographic sense, 5 | % 6 | % examples: 7 | % 8 | % islexico([1 2 3],[1 2 5]) -> true 9 | % islexico([1 2 3],[1 2 3]) -> true 10 | % islexico([1 2 3],[1 2 1]) -> false 11 | % islexico([2 2 3],[1 7 1]) -> false 12 | % islexico([1 7 3],[1 5 3]) -> false 13 | 14 | 15 | %---------------------------------------------------- 16 | % Sparse Grid Matlab Kit 17 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 18 | % See LICENSE.txt for license 19 | %---------------------------------------------------- 20 | 21 | [~,~,v]=find(a-b,1); % first nonzero element of a-b. if a==b, v is empty 22 | 23 | % return true if a==b (i.e., v is empty) or if the first component for which a and b differ is smaller in a 24 | % than in b 25 | isl = isempty(v) || v<0 ; 26 | 27 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/activate_parallel.m: -------------------------------------------------------------------------------- 1 | function [] = activate_parallel(numworkers) 2 | 3 | %ACTIVATE_PARALLEL opens a parallel toolbox session 4 | % 5 | % ACTIVATE_PARALLEL() uses the default number of parallel workers 6 | % 7 | % ACTIVATE_PARALLEL(NUMWORKERS) specifies the number of parallel workers 8 | 9 | 10 | %---------------------------------------------------- 11 | % Sparse Grid Matlab Kit 12 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 13 | % See LICENSE.txt for license 14 | %---------------------------------------------------- 15 | 16 | switch nargin 17 | case 0 18 | if verLessThan('matlab', '8.3') 19 | eval('matlabpool open local') 20 | else 21 | parpool 22 | end 23 | case 1 24 | if verLessThan('matlab', '8.3') 25 | eval(['matlabpool open local ',num2str(numworkers)]) 26 | else 27 | parpool(numworkers) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/BrightenRGB.m: -------------------------------------------------------------------------------- 1 | function RGB = BrightenRGB(RGB,bright) 2 | % modification of color scheme (internal use) 3 | 4 | % Usage: RGB = BrightenRGB(RGB,bright) 5 | % 6 | % bright - scalar or field with values between 0 and 1 for brightening 7 | 8 | % part of the Phase Plot Package 9 | % Version 2.3, January 15, 2014 10 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 11 | 12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 | 14 | if size(size(bright))==1 15 | bright = bright * ones(size(RGB(:,:,1))); 16 | end 17 | 18 | RGB(:,:,1) = (1-bright).*RGB(:,:,1) + bright.*ones(size(RGB(:,:,1))); 19 | %+ (bright<0).*((1+bright).*RGB(:,:,2)); 20 | 21 | 22 | RGB(:,:,2) = (1-bright).*RGB(:,:,2) + bright.*ones(size(RGB(:,:,2))); 23 | %+ (bright<0).*((1+bright).*RGB(:,:,2)); 24 | 25 | 26 | RGB(:,:,3) = (1-bright).*RGB(:,:,3) + bright.*ones(size(RGB(:,:,3))); 27 | %+ (bright<0).*((1+bright).*RGB(:,:,3)); 28 | 29 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/polynomials_functions/cheb_eval.m: -------------------------------------------------------------------------------- 1 | function L = cheb_eval(x,k,a,b) 2 | 3 | % L = cheb_eval(x,k,a,b) 4 | % 5 | % returns the values of the k-th Chebyshev polynomial of the first kind 6 | % on [a,b] (i.e. T_n(a)=(-1)^n, T_n(b)=1), evaluated at x (vector) 7 | 8 | 9 | %---------------------------------------------------- 10 | % Sparse Grid Matlab Kit 11 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 12 | % See LICENSE.txt for license 13 | %---------------------------------------------------- 14 | 15 | 16 | % first compute the transformation of x in (a,b) to t in (-1,1) 17 | t = ( 2*x - a - b ) / (b - a ) ; 18 | 19 | 20 | % base steps 21 | % read this as L(k-2) 22 | L_2=ones(size(t)); 23 | 24 | % and this as L(k-1) 25 | L_1=t; 26 | 27 | if k==0 28 | L=L_2; 29 | return 30 | elseif k==1 31 | L=L_1; 32 | return 33 | else 34 | % recursive step 35 | for ric=2:k 36 | L = 2 * t .* L_1 - L_2; 37 | L_2=L_1; 38 | L_1=L; 39 | end 40 | return 41 | end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/fldrect.m: -------------------------------------------------------------------------------- 1 | function z = fldrect(zll,zur,m,n) 2 | % discrete field of complex numbers covering the domain of a function 3 | 4 | % Usage: z = fldrect(zll,zur,m,n); 5 | % zll - complex number, lower left corner of the rectangular domain 6 | % zur - complex number, upper right corner of the rectangular domain 7 | % m,n - number of discretization points in x and y direction 8 | 9 | % part of the phase plot package - visualization of complex functions 10 | % Version 2.3, January 15, 2014 11 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 12 | 13 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14 | 15 | if nargin<1, zll=-1-1i; end; 16 | if nargin<2, zur=1+1i; end; 17 | if nargin<3, m=1000; end; 18 | if nargin<4, n=1000; end; 19 | 20 | a = min(real(zll),real(zur)); 21 | b = max(real(zll),real(zur)); 22 | c = min(imag(zll),imag(zur)); 23 | d = max(imag(zll),imag(zur)); 24 | 25 | x = linspace(a,b,m); 26 | 27 | y = linspace(c,d,n); 28 | 29 | z = ones(n,1)*x + 1i*y'*ones(1,m); 30 | 31 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/kpn_lev_table.m: -------------------------------------------------------------------------------- 1 | function A = kpn_lev_table(rows,cols) 2 | 3 | % A = kpn_lev_table(rows,cols) 4 | % 5 | % In the tabulated kpn knots, many levels have the same knots (with weights identical 6 | % up to 10th-11th digit. For each group of levels with same number of knots we 7 | % select 1 representative, and define a map as follows: 8 | % 9 | % MAP= 10 | % i: l: nb_knots: order: 11 | % 0 0 0 0 12 | % 1 1 1 1 13 | % 2 3 3 3 14 | % 3 8 9 15 15 | % 4 15 19 29 16 | % 5 25 35 51 17 | % 18 | % this function returns the (row,col) submatrix of M 19 | 20 | 21 | %---------------------------------------------------- 22 | % Sparse Grid Matlab Kit 23 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 24 | % See LICENSE.txt for license 25 | %---------------------------------------------------- 26 | 27 | 28 | M=[ 29 | 0 0 0 0 30 | 1 1 1 1 31 | 2 3 3 3 32 | 3 8 9 15 33 | 4 15 19 29 34 | 5 25 35 51 ]; 35 | 36 | A=M(rows,cols); 37 | 38 | end 39 | -------------------------------------------------------------------------------- /Examples_gallery_2/supplementary_files/redblueTecplot.m: -------------------------------------------------------------------------------- 1 | function c = redblueTecplot(m) 2 | %REDBLUE Shades of red and blue color map 3 | % REDBLUETecplot(M), is an M-by-3 matrix that defines a colormap. 4 | % The colors match Tecplot's Diverging Redblue plot. 5 | % REDBLUETecplot, by itself, is the same length as the current figure's 6 | % colormap. If no figure exists, MATLAB creates one. 7 | % 8 | % For example, to reset the colormap of the current figure: 9 | % 10 | % colormap(redblueTecplot) 11 | % 12 | % See also HSV, GRAY, HOT, BONE, COPPER, PINK, FLAG, 13 | % COLORMAP, RGBPLOT. 14 | % Inspired from https://www.mathworks.com/matlabcentral/fileexchange/25536-red-blue-colormap 15 | % Fernando Zigunov, 2018 16 | if nargin < 1, m = size(get(gcf,'colormap'),1); end 17 | %Colormap key colors from Tecplot 18 | rT=[33 103 209 247 253 239 178]/255; 19 | gT=[102 169 229 247 219 138 24]/255; 20 | bT=[172 207 240 247 199 98 43]/255; 21 | pos=linspace(0,1,7); 22 | %Interpolates given the colormap positions 23 | posDesired=linspace(0,1,m); 24 | r = interp1(pos,rT,posDesired); 25 | g = interp1(pos,gT,posDesired); 26 | b = interp1(pos,bT,posDesired); 27 | c = [r.' g.' b.']; end 28 | 29 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/plot_idx_status.m: -------------------------------------------------------------------------------- 1 | function plot_idx_status(G,I,idx_bin,idx) 2 | 3 | 4 | % plot_idx_status(G,I,idx_bin,idx) 5 | % 6 | % plots status of a two-dimensional adaptive sparse grid 7 | 8 | %---------------------------------------------------- 9 | % Sparse Grid Matlab Kit 10 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 11 | % See LICENSE.txt for license 12 | %---------------------------------------------------- 13 | 14 | 15 | % plot the indices used 16 | figure 17 | plot(G(:,1),G(:,2),'xr','LineWidth',2,'MarkerSize',14,'DisplayName','G -- set used to build the sparse grid '), 18 | hold on 19 | plot(I(:,1),I(:,2),'o','MarkerFaceColor','b','MarkerSize',8,'DisplayName',sprintf('I -- set of idx whose neighbour \n has been explored ')), 20 | if ~isempty(idx_bin) 21 | plot(idx_bin(:,1),idx_bin(:,2),'sk','MarkerFaceColor','none','MarkerSize',14,... 22 | 'DisplayName',sprintf('idx-bin -- set of idx whose \n neighbour has not been explored ')), 23 | end 24 | plot(idx(1),idx(2),'og','MarkerFaceColor','g','MarkerSize',8,'DisplayName','next idx to be considered'), 25 | 26 | set(gca,'FontSize',16) 27 | axis([0 12 0 12]) 28 | legend show 29 | axis square 30 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/polynomials_functions/lagr_eval.m: -------------------------------------------------------------------------------- 1 | function L = lagr_eval(current_knot,other_knots,non_grid_points) 2 | 3 | % L = LAGR_EVAL(current_knot,other_knots,non_grid_points) 4 | % 5 | % builds the lagrange function L(x) s.t. 6 | % L(current_knot)=1; 7 | % L(other_knots)=0; 8 | % 9 | % and returns L=L(non_grid_points) 10 | 11 | 12 | %---------------------------------------------------- 13 | % Sparse Grid Matlab Kit 14 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 15 | % See LICENSE.txt for license 16 | %---------------------------------------------------- 17 | 18 | 19 | 20 | % each monodim lagrange function is a product of K terms like (x-x_k)/(current_knot-x_k), 21 | % so i compute it with a for loop 22 | 23 | % this is the number of iterations 24 | K=length(other_knots); 25 | 26 | % L is the result. It is a column vector, same size as non_grid_points. It is initialized to 1, and then iteratively multiplied by 27 | % each factor 28 | L=ones(size(non_grid_points)); 29 | 30 | for k=1:K 31 | % these are the non current-knot, one at a time 32 | knots_k=other_knots(k); 33 | % here it comes the computation of the lagrangian factor (x-x_k)/(current_knot-x_k) 34 | L=L.*(non_grid_points-knots_k)/(current_knot-knots_k); 35 | end 36 | 37 | end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/asreduced.m: -------------------------------------------------------------------------------- 1 | function S = asreduced(pts_list,wgs_list) 2 | 3 | % S = ASREDUCED(pts_list) returns a reduced sparse grids structure whose "knots" field is set equal to 4 | % pts_list, "size" filed is set to the number of columns of PTS_LIST, while the other fields are []. Thus, isreduced(S)==true and 5 | % S can then be used as input to e.g. PLOT_GRID or EVALUATE_ON_SPARSE_GRID. The knots in pts_list are supposed 6 | % to be all different, i.e. the list is not checked for duplicates 7 | % 8 | % S = ASREDUCED(pts_list,wgs_list) also set the weights field of S as wgs_list. An error is thrown if the number of weights and 9 | % nodes is not identical 10 | 11 | 12 | %---------------------------------------------------- 13 | % Sparse Grid Matlab Kit 14 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 15 | % See LICENSE.txt for license 16 | %---------------------------------------------------- 17 | 18 | 19 | 20 | S.knots = pts_list; 21 | if nargin==2 22 | if length(S.weights) == size(pts_list,2) 23 | S.weights=wgs_list; 24 | S.size=length(S.weights); 25 | else 26 | error('SparseGKit:WrongInput','the number of points and of weights are different') 27 | end 28 | else 29 | S.weights=[]; 30 | S.size=size(pts_list,2); 31 | end 32 | S.n=[]; 33 | S.m=[]; 34 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/polynomials_functions/lege_eval_multidim.m: -------------------------------------------------------------------------------- 1 | function L = lege_eval_multidim(X,k,a,b) 2 | 3 | % L = LEGE_EVAL_MULTIDIM(X,k,a,b) 4 | % 5 | % evaluates the multidim Legendre polynomial order k (multi-index) orthonormal on [a,b]^N 6 | % on the list of points X (each column is a point in R^N). a,b are scalar values 7 | % 8 | % a,b may differ in each direction, so that actually the domain is not [a,b]^N, but 9 | % [a1,b1] x [a2,b2] x [a3,b3] x ... [aN,bN] 10 | % in this case, a,b are defined as vectors, each with N components 11 | 12 | 13 | %---------------------------------------------------- 14 | % Sparse Grid Matlab Kit 15 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 16 | % See LICENSE.txt for license 17 | %---------------------------------------------------- 18 | 19 | 20 | [N, nb_pts] = size(X); % N here is the number of dimensions 21 | 22 | L = zeros(1,nb_pts); 23 | 24 | % L is a product of N polynomials, one for each dim. I store the evaluation 25 | % of each of these polynomials as columns of a matrix 26 | 27 | M = 0*X; 28 | 29 | % take care of the fact that a,b may be scalar values 30 | 31 | if length(a)==1 32 | a=a*ones(1,N); 33 | b=b*ones(1,N); 34 | end 35 | 36 | for n=1:N 37 | M(n,:) = lege_eval(X(n,:),k(n),a(n),b(n)); 38 | end 39 | 40 | L = prod(M,1); -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/main/plot_sparse_grid.m: -------------------------------------------------------------------------------- 1 | function h= plot_sparse_grid(S,dims,varargin) 2 | 3 | % h = plot_sparse_grid(S,dims,varargin) 4 | % 5 | % PLOT_SPARSE_GRID(S) plots S, which is a sparse grid in 2D. S can be either reduced or not. S can also be a tensor grid 6 | % (use istensor(S) to verify, type HELP ISTENSOR for details) 7 | % 8 | % PLOT_SPARSE_GRID(S,[d1 d2]) plots the d1 and d2 components of the points in S if S is more than 2D 9 | % 10 | % PLOT_SPARSE_GRID(S,[d1,d2],varargin) defines the style of the plot, e.g. 11 | % 12 | % plot_sparse_grid(S,[],'color','g','marker','o') 13 | % 14 | % h=PLOT_SPARSE_GRID(S) 15 | % 16 | % returns the handle to the plot 17 | 18 | 19 | %---------------------------------------------------- 20 | % Sparse Grid Matlab Kit 21 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 22 | % See LICENSE.txt for license 23 | %---------------------------------------------------- 24 | 25 | 26 | 27 | if ~exist('dims','var') || isempty(dims) 28 | dims=[1 2]; 29 | end 30 | 31 | x=[S.knots]; 32 | 33 | if nargin==1 || nargin==2 34 | % use a default plot style 35 | h=plot(x(dims(1),:),x(dims(2),:),'ok','MarkerFaceColor','k'); 36 | else 37 | % use style provided 38 | h=plot(x(dims(1),:),x(dims(2),:),varargin{:},'LineStyle','none'); 39 | end 40 | grid on 41 | 42 | 43 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/polynomials_functions/cheb_eval_multidim.m: -------------------------------------------------------------------------------- 1 | function C = cheb_eval_multidim(X,k,a,b) 2 | 3 | % C = CHEB_EVAL_MULTIDIM(X,k,a,b) 4 | % 5 | % evaluates the multidim Chebyshev polynomial of the first kind of order k (multi-index) on [a,b]^N 6 | % on the list of points X (each column is a point in R^N). a,b are scalar values 7 | % 8 | % a,b may differ in each direction, so that actually the domain is not [a,b]^N, but 9 | % [a1,b1] x [a2,b2] x [a3,b3] x ... [aN,bN] 10 | % in this case, a,b are defined as vectors, each with N components 11 | 12 | 13 | %---------------------------------------------------- 14 | % Sparse Grid Matlab Kit 15 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 16 | % See LICENSE.txt for license 17 | %---------------------------------------------------- 18 | 19 | 20 | 21 | [N, nb_pts] = size(X); % N here is the number of dimensions 22 | 23 | C = zeros(1,nb_pts); 24 | 25 | % L is a product of N polynomials, one for each dim. I store the evaluation 26 | % of each of these polynomials as columns of a matrix 27 | 28 | M = 0*X; 29 | 30 | % take care of the fact that a,b may be scalar values 31 | 32 | if length(a)==1 33 | a=a*ones(1,N); 34 | b=b*ones(1,N); 35 | end 36 | 37 | for n=1:N 38 | M(n,:) = cheb_eval(X(n,:),k(n),a(n),b(n)); 39 | end 40 | 41 | C = prod(M,1); -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/detect_unsufficient_tolerance.m: -------------------------------------------------------------------------------- 1 | function is_unsuf = detect_unsufficient_tolerance(pts,tol) 2 | 3 | % is_unsuf = detect_unsufficient_tolerance(pts,tol) 4 | % 5 | % for a matrix of points (one per row, as in mysortrows or lookup_merge_and_diff), 6 | % computes an approximation of the support of the set of point in each direction 7 | % (as max - min coord in each dir) and compares it with tol. It they are "same-sized" 8 | % then tol is too large and a warning is thrown 9 | 10 | 11 | %---------------------------------------------------- 12 | % Sparse Grid Matlab Kit 13 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 14 | % See LICENSE.txt for license 15 | %---------------------------------------------------- 16 | 17 | 18 | N=size(pts,2); 19 | is_unsuf=false; 20 | 21 | for n=1:N 22 | % check one column at a time. exploit the fact that unique returns a sorted sequence 23 | uu = unique(pts(:,n)); 24 | 25 | % if the tolerance is not at least 2 order of magnitude smaller than the support on the n-th direction 26 | % throw a warning 27 | 28 | if abs(log10(uu(end)-uu(1))-log10(tol)) < 2 29 | warning('SparseGKit:TolNotEnough','tol does not seem small enough to detect identical points') 30 | is_unsuf=true; 31 | return 32 | end 33 | end 34 | 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2022, Matthew Colbrook 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Sparse Grids Matlab Kit 2 | 3 | Copyright (c) 2009-2018 L. Tamellini, F. Nobile 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 14 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 15 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 16 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 17 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 18 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Elias Wegert 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/polynomials_functions/herm_eval_multidim.m: -------------------------------------------------------------------------------- 1 | function H = herm_eval_multidim(X,k,mu,sig) 2 | 3 | % H = HERM_EVAL_MULTIDIM(X,k,mu,sig) 4 | % 5 | % evaluates the multidim Hermite polynomial order k (multi-index) orthonormal on [-inf,+inf]^N 6 | % with respect to rho=prod_i 1/sqrt(2 pi sigma_i) * e^( -(x-mi_i)^2/(2*sigma_i^2) ) 7 | % on the list of points X (each column is a point in R^N) 8 | % MU, SIGMA, can be scalar values 9 | 10 | 11 | 12 | %---------------------------------------------------- 13 | % Sparse Grid Matlab Kit 14 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 15 | % See LICENSE.txt for license 16 | %---------------------------------------------------- 17 | 18 | 19 | [N, nb_pts] = size(X); % N here is the number of dimensions 20 | 21 | % take care of the fact that mu,sigma may be scalar values 22 | 23 | if length(mu)==1 24 | mu=mu*ones(1,N); 25 | sig=sig*ones(1,N); 26 | end 27 | 28 | % H is a product of N polynomials, one for each dim. I store the evaluation 29 | % of each of these polynomials as rows of a matrix. I do not compute the 30 | % zeros though, I know already they will be 1 31 | 32 | nonzero_n = find(k~=0); 33 | if isempty(nonzero_n) 34 | H = ones(1,nb_pts); 35 | else 36 | M = zeros(length(nonzero_n),nb_pts); 37 | j=0; 38 | for n=nonzero_n 39 | j=j+1; 40 | M(j,:) = herm_eval(X(n,:),k(n),mu(n),sig(n)); 41 | end 42 | H = prod(M,1); 43 | end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/lev2knots_functions/lev2knots_kpn.m: -------------------------------------------------------------------------------- 1 | function nb_knots = lev2knots_kpn(I) 2 | 3 | % nb_knots = lev2knots_kpn(I) 4 | % 5 | % returns the number of knots corresponding to the i-level i, 6 | % via the i2l map tabulated as in kpn_lev_table 7 | 8 | 9 | 10 | %---------------------------------------------------- 11 | % Sparse Grid Matlab Kit 12 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 13 | % See LICENSE.txt for license 14 | %---------------------------------------------------- 15 | 16 | 17 | 18 | % are there non tabulated levels? 19 | non_tab=I(I>5); 20 | 21 | if isempty(non_tab) 22 | 23 | [r,c]=size(I); 24 | % nb knots is a vector after this instruction; I is understood coloumnwise as I(:) 25 | % Note that I want to access rows I+1, because minimum value for level is 0, 26 | % whose data are stored in row 1 27 | vect_nb_knots=kpn_lev_table(I+1,3)'; 28 | nb_knots=reshape(vect_nb_knots,r,c); 29 | else 30 | %error('SparseGKit:OutOfTable',strcat('levels:',num2str(non_tab),' are not tabulated')) 31 | warning('SparseGKit:KpnNonTab','asking for non tabulated levels') 32 | % put Inf for I>5 33 | [r,c]=size(I); 34 | pos=find(I>5); % pos is the linear position 35 | I(I>5)=0; % to have it pass through the table. I will change it to Inf after 36 | vect_nb_knots=kpn_lev_table(I+1,3)'; 37 | vect_nb_knots(pos)=Inf; %#ok 38 | nb_knots=reshape(vect_nb_knots,r,c); 39 | end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/polynomials_functions/lagr_eval_fast.m: -------------------------------------------------------------------------------- 1 | function L = lagr_eval_fast(current_knot,other_knots,ok_len,non_grid_points,ng_size) 2 | 3 | % L = LAGR_EVAL_FAST(current_knot,other_knots,ok_len,non_grid_points,ng_size) 4 | % 5 | % builds the lagrange function L(x) s.t. 6 | % L(current_knot)=1; 7 | % L(other_knots)=0; 8 | % 9 | % and returns L=L(non_grid_points) 10 | % 11 | % where ok_len = length(other_knots), ng_size = size(non_grid_points); 12 | % 13 | % this is essentially the same function as LAGR_EVAL, but some quantities are provided as input 14 | % instead of being computed, for speed purposes. 15 | 16 | %---------------------------------------------------- 17 | % Sparse Grid Matlab Kit 18 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 19 | % See LICENSE.txt for license 20 | %---------------------------------------------------- 21 | 22 | 23 | 24 | % each monodim lagrange function is a product of K terms like (x-x_k)/(current_knot-x_k), 25 | % so i compute it with a for loop 26 | 27 | % this is the number of iterations 28 | % ok_len=length(other_knots); 29 | 30 | % L is the result. It is a column vector, same size as non_grid_points. It is initialized to 1, and then iteratively multiplied by 31 | % each factor 32 | % L=ones(size(non_grid_points)); 33 | L=ones(ng_size); 34 | 35 | for k=1:ok_len 36 | % these are the non current-knot, one at a time 37 | knots_k=other_knots(k); 38 | % here it comes the computation of the lagrangian factor (x-x_k)/(current_knot-x_k) 39 | L=L.*(non_grid_points-knots_k)/(current_knot-knots_k); 40 | end 41 | 42 | end -------------------------------------------------------------------------------- /Examples_gallery_1/circle_rotation_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | 4 | %% 1D example for the point spectrum 5 | 6 | TRUNC=1000; 7 | omega = pi*1.4; 8 | % omega = pi*sqrt(2); 9 | 10 | 11 | f = chebfun(@(x) cos(11*x)/(sqrt(1.001+sin(x))) ,[-pi,pi],'trig'); 12 | coeffs = trigcoeffs(f,2*TRUNC+1); 13 | 14 | coeffs(abs(coeffs)<10^(-14))=0; 15 | 16 | % semilogy(abs(coeffs)) 17 | % return 18 | % Compute moments 19 | 20 | 21 | N=100; 22 | MU = zeros(2*N+1,1)'; 23 | Fc=coeffs; 24 | MU(N+1)=(coeffs'*coeffs); 25 | for j=1:N 26 | K = exp((-TRUNC:TRUNC)'*1i*omega*j); 27 | Fc=K.*coeffs; 28 | MU(N+1+j)=(Fc'*coeffs); 29 | MU(N-j+1)=(MU(N+1+j))'; 30 | end 31 | mu1=MomentMeas(MU,'filt','fejer'); % approximation with filter 32 | mu1=real(mu1)/sum(real(mu1)); 33 | K0=MomentMeas(MU*0+1,'filt','fejer'); K0=K0(0); 34 | mu1 = mu1/real(K0); 35 | 36 | N=10000; 37 | MU = zeros(2*N+1,1)'; 38 | Fc=coeffs; 39 | MU(N+1)=(coeffs'*coeffs); 40 | for j=1:N 41 | K = exp((-TRUNC:TRUNC)'*1i*omega*j); 42 | Fc=K.*coeffs; 43 | MU(N+1+j)=(Fc'*coeffs); 44 | MU(N-j+1)=(MU(N+1+j))'; 45 | end 46 | mu2=MomentMeas(MU,'filt','fejer'); % approximation with filter 47 | mu2=real(mu2)/sum(real(mu2)); 48 | K0=MomentMeas(MU*0+1,'filt','fejer'); K0=K0(0); 49 | mu2 = mu2/real(K0); 50 | 51 | 52 | 53 | figure 54 | subplot(2,1,1) 55 | semilogy(mu1,'linewidth',0.5) 56 | ax = gca; ax.FontSize = 14; 57 | ylim([10^(-10),1]) 58 | title('$N=100$','interpreter','latex','fontsize',14) 59 | 60 | subplot(2,1,2) 61 | semilogy(mu2,'linewidth',0.5) 62 | ax = gca; ax.FontSize = 14; 63 | ylim([10^(-10),1]) 64 | title('$N=10000$','interpreter','latex','fontsize',14) -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/PhasePlot.m: -------------------------------------------------------------------------------- 1 | function PP = PhasePlot(z,f,cs,pres,t,h) 2 | % phase plot of complex function f(z) 3 | % 4 | % Usage: PP = PhasePlot(z,f,cs,pres,t,h) 5 | % 6 | % z - complex field of arguments 7 | % f - complex field of values f(z) 8 | % cs - color scheme (optional) 9 | % call 'help colscheme' to see a list of available color schemes 10 | % call 'PPDemo' to see a demonstration of all color schemes 11 | % pres - number of jumps in phase (optional) 12 | % t - positions of jumps at unit circle (optional) 13 | % h - height (z-axis) in which the plot is displayed (otional) 14 | % 15 | % PP - handle to colored surface 16 | 17 | % Part of the phase plot package 18 | % Version 2.3, January 15, 2014 19 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 20 | 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | if nargin==6 24 | PP = pltphase(z,f,cs,t,pres,h); 25 | elseif nargin==5 26 | PP = pltphase(z,f,cs,t,pres); 27 | elseif nargin==4 28 | if cs=='j' 29 | PP = pltphase(z,f,cs,pres); 30 | else 31 | PP = pltphase(z,f,cs,[],pres); 32 | end 33 | elseif nargin==3 34 | PP = pltphase(z,f,cs); 35 | elseif nargin==2 36 | PP = pltphase(z,f); 37 | else 38 | disp('PhasePlot(z,f) - phase plot of complex function f(z)') 39 | disp(' call as PhasePlot(z,f,colorscheme) for changing color options'); 40 | disp(' call PPColorScheme to see a list of implemented color schemes'); 41 | disp(' call PPDemo for a demonstration'); 42 | return 43 | end 44 | 45 | axis equal 46 | view(0,90) 47 | 48 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/knots_functions/knots_gaussian.m: -------------------------------------------------------------------------------- 1 | function [x,w]=knots_gaussian(n,mi,sigma) 2 | 3 | % [x,w]=KNOTS_GAUSSIAN(n,mi,sigma) 4 | % 5 | % calculates the collocation points (x) 6 | % and the weights (w) for the gaussian integration 7 | % w.r.t to the weight function 8 | % rho(x)=1/sqrt(2*pi*sigma) *exp( -(x-mi)^2 / (2*sigma^2) ) 9 | % i.e. the density of a gaussian random variable 10 | % with mean mi and standard deviation sigma 11 | 12 | 13 | %---------------------------------------------------- 14 | % Sparse Grid Matlab Kit 15 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 16 | % See LICENSE.txt for license 17 | %---------------------------------------------------- 18 | 19 | 20 | 21 | if (n==1) 22 | % the point (traslated if needed) 23 | x=mi; 24 | % the weight is 1: 25 | w=1; 26 | return 27 | end 28 | 29 | % calculates the values of the recursive relation 30 | [a,b]=coefherm(n); 31 | 32 | % builds the matrix 33 | JacM=diag(a)+diag(sqrt(b(2:n)),1)+diag(sqrt(b(2:n)),-1); 34 | 35 | % calculates points and weights from eigenvalues / eigenvectors of JacM 36 | [W,X]=eig(JacM); 37 | x=diag(X)'; 38 | w=W(1,:).^2; 39 | [x,ind]=sort(x); %#ok 40 | w=w(ind); 41 | 42 | % modifies points according to mi, sigma (the weigths are unaffected) 43 | x=mi + sqrt(2)*sigma*x; 44 | 45 | 46 | 47 | %---------------------------------------------------------------------- 48 | function [a, b] = coefherm(n) 49 | 50 | if (n <= 1), 51 | disp(' n must be > 1 '); 52 | return; 53 | end 54 | a=zeros(n,1); 55 | b=zeros(n,1); 56 | 57 | b(1)=sqrt(pi); 58 | k=2:n; 59 | b(k)=0.5*(k-1); 60 | -------------------------------------------------------------------------------- /main_routines/MomentMeas.m: -------------------------------------------------------------------------------- 1 | function [nu] = MomentMeas(MU,varargin) 2 | % This code computes smoothed spectral measures of an isometry using the 3 | % computed moments (Fourier coefficients). Requires chebfun. 4 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 | % INPUTS 6 | % MU: vector of Fourier coefficients (-N to N) 7 | 8 | % OPTIONAL LABELLED INPUTS 9 | % filt: type of filter 10 | 11 | % OUTPUTS 12 | % nu: smoothed measure as a chebfun 13 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14 | 15 | p = inputParser; 16 | addRequired(p,'MU',@isnumeric); 17 | validFILT = {'fejer','cosine','vand','sharp_cosine'}; 18 | checkFILT = @(x) any(validatestring(x,validFILT)); 19 | addParameter(p,'filt','inft',checkFILT) 20 | 21 | p.CaseSensitive = false; 22 | parse(p,MU,varargin{:}) 23 | 24 | phi_fejer = @(x) 1-abs(x); 25 | phi_cosine = @(x) (1+cos(pi*x))/2; 26 | phi_opt4 = @(x) 1- x.^4.*(-20*abs(x).^3 + 70*x.^2 - 84*abs(x) + 35); 27 | phi_sharp_cosine = @(x) phi_cosine(x).^4.*(35-84*phi_cosine(x)+70*phi_cosine(x).^2-20*phi_cosine(x).^3); 28 | phi_inft = @(x) exp(-2./(1-abs(x)).*exp(-0.109550455106347./abs(x).^4)); 29 | 30 | N=(length(MU)-1)/2; 31 | 32 | if p.Results.filt=="fejer" 33 | FILTER=phi_fejer(abs((-N:N)/N)); 34 | elseif p.Results.filt=="cosine" 35 | FILTER=phi_cosine(abs((-N:N)/N)); 36 | elseif p.Results.filt=="vand" 37 | FILTER=phi_opt4(abs((-N:N)/N)); 38 | elseif p.Results.filt=="sharp_cosine" 39 | FILTER=phi_sharp_cosine(abs((-N:N)/N)); 40 | else 41 | FILTER=phi_inft(abs((-N:N)/N)); 42 | end 43 | FILTER(1)=0; 44 | FILTER(end)=0; 45 | 46 | nu = chebfun(FILTER(:).*MU(:),[-pi pi],'trig','coeffs'); 47 | end 48 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/knots_functions/knots_gaussian_leja.m: -------------------------------------------------------------------------------- 1 | function [x,w]=knots_gaussian_leja(n) 2 | 3 | % [x,w] = knots_gaussian_leja(n) 4 | % 5 | % returns the collocation points (x) and the weights (w) 6 | % for the weighted Leja sequence for integration 7 | % w.r.t to the weight function 8 | % 9 | % rho(x)=1/sqrt(2*pi)*exp(-x^2/2) 10 | % 11 | % i.e. the density of a gaussian random variable 12 | % with mean 0 and standard deviation 1. 13 | % 14 | % Knots and weights have been precomputed (up to 50) following the work 15 | % 16 | % A. Narayan, J. Jakeman, "Adaptive Leja sparse grid constructions for stochastic collocation and high-dimensional approximation" 17 | % SIAM Journal on Scientific Computing, Vol. 36, No. 6, pp. A2952–A2983, 2014 18 | % 19 | % an error is raised if more than 50 points are requested. 20 | % 21 | % knots are sorted increasingly before returning (weights are returned in the corresponding order) 22 | 23 | %---------------------------------------------------- 24 | % Sparse Grid Matlab Kit 25 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile, B. Sprungk 26 | % See LICENSE.txt for license 27 | %---------------------------------------------------- 28 | 29 | 30 | if n>50 31 | error('SparseGKit:OutOfTable',strcat('this number of points is not available:',num2str(n))) 32 | 33 | else 34 | 35 | % load points and weights 36 | SS = load('GaussianLejaPrecomputedKnotsAndWeights.mat'); 37 | x = SS.X(1:n); 38 | w = SS.W(1:n,n); 39 | 40 | % sort knots increasingly and weights accordingly. Weights need to be row vectors 41 | [x,sorter]=sort(x); 42 | w=w(sorter)'; 43 | 44 | end 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/idxset_functions/check_set_admissibility.m: -------------------------------------------------------------------------------- 1 | function [adm,C] = check_set_admissibility(I) 2 | 3 | % [adm,C] = CHECK_SET_ADMISSIBILITY(I) checks whether I is an admissible set. 4 | % If that is the case, adm=true and C contains I ordered in lexicographic order. 5 | % If not, adm=false and C contains I plus the multiindeces needed, again in lexicographic order 6 | 7 | 8 | %---------------------------------------------------- 9 | % Sparse Grid Matlab Kit 10 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 11 | % See LICENSE.txt for license 12 | %---------------------------------------------------- 13 | 14 | 15 | 16 | C=I; 17 | 18 | % now check amdissibility condition and add what's missing. Print a warning if needed 19 | row = 0; 20 | row_max=size(C,1); 21 | adm=true; 22 | 23 | while (row-1 || ymax<1 || ymin >-1 30 | disp(' '), disp('Warning: z does not cover unit disk'); disp(' ') 31 | end 32 | 33 | 34 | if nargin==5 35 | RGB = colscheme(w,c,tjmp,pres); 36 | elseif nargin==4 37 | RGB = colscheme(w,c,[],pres); 38 | elseif nargin==3 39 | RGB = colscheme(w,c,[],30); 40 | elseif nargin==2 41 | RGB = colscheme(w,'m'); 42 | elseif nargin<=1 43 | RGB = colscheme(w,c,[],30); 44 | end 45 | 46 | %[p,q,r] = StereoP2S(z); 47 | 48 | %% plane plot of lower hemisphere 49 | 50 | zext = (abs(z)>=1); 51 | 52 | % brighten colormap outside the unit circle 53 | 54 | RGBint = BrightenRGB(RGB,0.7*zext); 55 | 56 | h = surf(real(z),imag(z),zeros(size(z)),RGBint); 57 | 58 | set(h,'EdgeColor','none'); 59 | axis equal 60 | axis off 61 | axis tight 62 | view(0,90) 63 | 64 | ax = 1.2*[-1,1,-1,1]; 65 | axis(ax); 66 | 67 | title('lower hemisphere'); 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /main_routines/README.md: -------------------------------------------------------------------------------- 1 | Here is a high-level summary of each main routine and what they do. Full details are given in the above .m files. 2 | 3 | **ErgodicMoments:** Given a vector X of a signal and a non-negative integer N, this function computes the autocorrelations of X, or moments of the Koopman operator, from -N to N. This code uses the FFT for rapid computation. 4 | 5 | **IsomMeas:** This function computes smoothed spectral measures of an isometry using the ResDMD matrices. These ResDMD matrices are "G" corresponding to <\psi_k,\psi_j>, "A" corresponding to , "L" corresponding to . Details of how these three matrices are constructed from the data are given in the ResDMD paper, and can be seen in the various examples given (i.e., G=PSI_X'WPSI_X, A=PSI_X'WPSI_Y, L=PSI_Y'WPSI_Y). IsomMeas also takes as input the vector f, smoothing parameter epsilon, and angles theta\in[-pi,pi]. 6 | 7 | **KoopPseudoSpec:** Given the ResDMD matrices G, A, and L, and a grid of points z_pts, this function computes the minimal residuals for spectral parameters over the grid. This is used to compute pseudospectra and spectra of Koopman operators. 8 | 9 | **KoopPseudoSpecQR:** Mathematically equivalent to KoopPseudoSpec, but faster and more accurate. Watch out for the different input (raw data matrices). 10 | 11 | **MomentMeas:** Given the autocorrelations (which could be computed by ErgodicMoments, for example), this function computes a smoothed approximation of the associated spectra measure in the form of a Fourier series (represented using chebfun). The user can also specify the choice of filter function used. 12 | 13 | **kernel_ResDMD:** This implements the choice of basis that uses kernel EDMD. The inputs are X and Y (Xa and Ya) snapshots to form the dictionary and X and Y snapshots (Xb and Yb) to form the ResDMD matrices. 14 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/PPOnSphUp.m: -------------------------------------------------------------------------------- 1 | function z = PPOnSphUp(z,w,c,pres,tjmp) 2 | % phase plot of function on upper hemishphere 3 | % 4 | % Usage: function z = PPOnSphUp(z,w,c,pres,tjmp) 5 | % 6 | % z - variable on domain covering exterior of unit circle, e.g. z=0.8./zdomain; 7 | % w - values of function at points z 8 | % c - color scheme (optional) 9 | % pres - resolution of phase (optional) 10 | % tjmp - jumps of phase (optional) 11 | 12 | 13 | % Part of the phase plot package 14 | % Version 2.3, January 15, 2014 15 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 16 | 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | 19 | if nargin<2 20 | z = fldplane(1200); 21 | c = 'p'; 22 | w = (z-1)./(z.^2+z+1); 23 | end 24 | 25 | xmax = max(max(real(1./z))); xmin = min(min(real(1./z))); 26 | ymax = max(max(imag(1./z))); ymin = min(min(imag(1./z))); 27 | 28 | if xmax<1 || xmin >-1 || ymax<1 || ymin >-1 29 | disp(' '), disp('Warning: z does not cover exterior of unit circle'); disp(' ') 30 | end 31 | 32 | if nargin==5 33 | RGB = colscheme(w,c,tjmp,pres); 34 | elseif nargin==4 35 | RGB = colscheme(w,c,[],pres); 36 | elseif nargin==3 37 | RGB = colscheme(w,c,[],30); 38 | elseif nargin==2 39 | RGB = colscheme(w,'m'); 40 | elseif nargin<=1 41 | RGB = colscheme(w,c,[],30); 42 | end 43 | 44 | %[p,q,r] = StereoP2S(z); 45 | 46 | %% plane plot of upper hemisphere 47 | 48 | zext = abs(z)<=1.0; 49 | 50 | % brighten colormap outside the unit circle 51 | 52 | RGB = BrightenRGB(RGB,0.7*zext); 53 | 54 | h = surf(-real(1./z),-imag(1./z),zeros(size(z)),RGB); 55 | 56 | set(h,'EdgeColor','none'); 57 | axis equal 58 | axis off 59 | axis tight 60 | view(180,90) 61 | 62 | ax = 1.2*[-1,1,-1,1]; 63 | 64 | axis(ax); 65 | 66 | title('upper hemisphere'); 67 | 68 | 69 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/pltphase.m: -------------------------------------------------------------------------------- 1 | function PP = pltphase(z,f,cs,t,pres,height) 2 | % phase plot of complex function f(z), internal use 3 | 4 | % Usage: PP = pltphase(z,f,cs,t,pres,height) 5 | 6 | % Part of the phase plot package 7 | % Version 2.3, January 15, 2014 8 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 9 | 10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11 | 12 | %rep='a'; % standard analytic landscae 13 | %rep='l'; % logarithmic analytic landscae 14 | rep='c'; % compressed analytic landscae 15 | 16 | if nargin<6, height=0; end 17 | 18 | if nargin<5 || isempty(pres), pres=20; end 19 | 20 | if nargin<4 || isempty(t), t=exp(1i*linspace(-pi,pi,pres+1)); t=t(1:pres); end 21 | 22 | if nargin<3 || isempty(cs), cs = 'p'; end 23 | 24 | if nargin<2, z=zdomain; f=sin(5*z); end 25 | 26 | % plot 27 | 28 | if nargin<6, 29 | 30 | % the phase plot is drawn on a surface 31 | 32 | if rep=='a' 33 | % analytic landscape 34 | height=abs(f); hmin=0; hmax=5; 35 | height = height.*(height<=hmax) + hmax*(height>hmax); 36 | f = f.*(height=hmin) ... 42 | + hmax*(height>hmax)+hmin*(heighthmin); 44 | 45 | elseif rep=='c' 46 | % height such that zeros are at level 0 and poles are at level 1 47 | height=(2/pi)*atan(abs(f)); hmin=0; hmax=1; 48 | end 49 | 50 | end 51 | 52 | pres = length(t); 53 | RGB = colscheme(f,cs,t,pres); 54 | 55 | PP = surf(real(z),imag(z),height,RGB); 56 | set(PP,'EdgeColor','none'); 57 | 58 | axis equal 59 | ax = axis; 60 | axis([ax,hmin,hmax]); 61 | axis off 62 | view(30,20) 63 | axis tight 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/docs-examples/test_sparse_quadrature.m: -------------------------------------------------------------------------------- 1 | 2 | %---------------------------------------------------- 3 | % Sparse Grid Matlab Kit 4 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 5 | % See LICENSE.txt for license 6 | %---------------------------------------------------- 7 | 8 | 9 | %% 10 | clear 11 | 12 | % function to be integrate, in (-1,1)^N. input column points, out row vector 13 | 14 | f = @(x,b) prod(2*x.^2);%exp(-sum(x.^2));%prod(1./sqrt(x+b)); 15 | b=3; 16 | N = 3; 17 | % I_1d=(2*sqrt(1+b)-2*sqrt(-1+b)); 18 | I_ex = 1;%pi^(N/2);%I_1d^N; 19 | 20 | 21 | % define sparse grid 22 | [lev2knots,idxset]=define_functions_for_rule('TD',N); 23 | knots=@(n) knots_gaussian(n,0,1/sqrt(2));%knots_uniform(n,-1,1,'nonprob');%knots_new(n,-2,2);%knots_CC(n,-1,1,'nonprob');%; 24 | 25 | 26 | % for loop 27 | 28 | w_max=4; 29 | q_error=zeros(1,w_max); 30 | work=zeros(1,w_max); 31 | 32 | S_old=[]; 33 | Sr_old=[]; 34 | evals_old=[]; 35 | 36 | tic 37 | for w=w_max 38 | 39 | disp(w) 40 | 41 | % create grid 42 | [S,C]=smolyak_grid(N,w,knots,lev2knots,idxset); 43 | S 44 | Sr=reduce_sparse_grid(S); 45 | 46 | [I,evals_old]=quadrature_on_sparse_grid(@(x)f(x,b),S,Sr,evals_old,S_old,Sr_old); 47 | 48 | S_old=S; 49 | Sr_old=Sr; 50 | 51 | %compute convergence error 52 | q_error(w+1)=abs(I_ex-I); 53 | 54 | % compute work 55 | work(w+1)=Sr.size; 56 | 57 | end 58 | toc 59 | 60 | % error w.r.t. level w 61 | figure 62 | semilogy(0:w_max,q_error,'-or','DisplayName','Numerical Error, w.r.t. grid level'); 63 | hold on 64 | semilogy(0:w_max,1./exp(0:w_max),'--o','DisplayName','exp(-level)') 65 | legend show 66 | 67 | % error w.r.t. nb. points 68 | figure 69 | loglog(work,q_error,'-or','DisplayName','Numerical Error, w.r.t. #points'); 70 | legend show 71 | 72 | function [x,w]=knots_new(n,x_a,x_b) 73 | x=linspace(x_a,x_b,n); 74 | w=zeros(size(x))+(x_b-x_a)/n; 75 | end 76 | 77 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/knots_functions/knots_CC.m: -------------------------------------------------------------------------------- 1 | function [x,w] = knots_CC(nn,x_a,x_b,whichrho) 2 | 3 | % [x,w] = KNOTS_CC(nn,x_a,x_b) 4 | % 5 | % calculates the collocation points (x) 6 | % and the weights (w) for the Clenshaw-Curtis integration formula 7 | % w.r.t to the weight function rho(x)=1/(b-a) 8 | % i.e. the density of a uniform random variable 9 | % with range going from x=a to x=b. Note that for efficiency reasons 10 | % nn must an odd number 11 | % 12 | % [x,w] = KNOTS_CC(nn,x_a,x_b,'prob') 13 | % 14 | % is the same as [x,w] = KNOTS_CC(nn,x_a,x_b) above 15 | % 16 | % [x,w]=[x,w] = KNOTS_CC(nn,x_a,x_b,'nonprob') 17 | % 18 | % calculates the collocation points (x) 19 | % and the weights (w) for the Clenshaw-Curtis integration formula 20 | % w.r.t to the weight function rho(x)=1 21 | 22 | 23 | %---------------------------------------------------- 24 | % Sparse Grid Matlab Kit 25 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 26 | % See LICENSE.txt for license 27 | %---------------------------------------------------- 28 | 29 | 30 | 31 | if nargin==3 32 | whichrho='prob'; 33 | end 34 | 35 | 36 | if nn==1 37 | x=(x_a+x_b)/2; wt=1; 38 | 39 | elseif mod(nn,2)==0 40 | error('SparseGKit:WrongInput','error in knots_CC: Clenshaw-Curtis formula \n use only odd number of points') 41 | 42 | else 43 | n=nn-1; 44 | 45 | N=(1:2:n-1)'; 46 | end_N=length(N); 47 | l=length(N); 48 | m=n-l; 49 | v0=[2./N./(N-2); 1/N(end_N); zeros(m,1)]; 50 | end_v0=length(v0); 51 | v2=-v0(1:end_v0-1)-v0(end_v0:-1:2); 52 | 53 | g0=-ones(n,1); 54 | g0(1+l)=g0(1+l)+n; 55 | g0(1+m)=g0(1+m)+n; 56 | g=g0/(n^2-1+mod(n,2)); 57 | 58 | 59 | wcc=ifft(v2+g); 60 | wt=[wcc;wcc(1,1)]'/2; 61 | 62 | x=cos( (0:n)*pi/n ); 63 | x = (x_b-x_a)/2*x + (x_a+x_b)/2; 64 | end 65 | 66 | switch whichrho 67 | 68 | case 'nonprob' 69 | w=(x_b-x_a)*wt; 70 | 71 | case 'prob' 72 | w=wt; 73 | 74 | otherwise 75 | error('SparseGKit:WrongInput','4th input not recognized') 76 | 77 | end 78 | -------------------------------------------------------------------------------- /Examples_gallery_1/Lorenz_attractor_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | rng(1); 4 | 5 | %% Set parameters 6 | M=10^5; 7 | delta_t=0.05; 8 | SIGMA=10; BETA=8/3; RHO=28; 9 | ODEFUN=@(t,y) [SIGMA*(y(2)-y(1));y(1).*(RHO-y(3))-y(2);y(1).*y(2)-BETA*y(3)]; 10 | options = odeset('RelTol',1e-6,'AbsTol',1e-6); 11 | N = 100; % number of delay embeddings 12 | %% Produce the data 13 | Y0=(rand(3,1)-0.5)*4; 14 | [~,Y]=ode45(ODEFUN,[0.000001 (1:(10000+M+2+N))*delta_t],Y0,options); 15 | Y=Y(10001:end,:); % sample after when on the attractor 16 | 17 | %% Reference scalar-valued spectral measure 18 | PX1=zeros(M,N+1); PX1(:,1)=Y(1:M,1); 19 | X1=Y(1:M,1); 20 | X2=Y(1:M,2); 21 | X3=Y(1:M,3); 22 | 23 | PX2=zeros(M,N+1); PX2(:,1)=Y(1:M,2); 24 | PX3=zeros(M,N+1); PX3(:,1)=Y(1:M,3); 25 | 26 | for j=2:N+1 27 | PX1(:,j)=Y((1:M)+j,1); 28 | PX2(:,j)=Y((1:M)+j,2); 29 | PX3(:,j)=Y((1:M)+j,3); 30 | end 31 | 32 | % PX = PX3(:,1:N); 33 | PX = [PX1(:,1:N),PX2(:,1:N),PX3(:,1:N)]; 34 | % PY = PX3(:,2:(N+1)); 35 | PY = [PX1(:,2:(N+1)),PX2(:,2:(N+1)),PX3(:,2:(N+1))]; clear PX1 PX2 PX3 36 | 37 | %% 38 | 39 | G = (PX'*PX)/M; 40 | A = (PX'*PY)/M; 41 | L = (PY'*PY)/M; 42 | 43 | G = (G+L)/2; 44 | L=G; 45 | 46 | 47 | E=exp(1i*[0.008,0.019,0.05,0.072,0.099,0.31,0.404,0.499,0.78]); 48 | [~,RES,V] = KoopPseudoSpec(G,A,L,[],'z_pts2',E); 49 | 50 | %% 51 | 52 | for j=1:length(E) 53 | C=PX(1:min(2*10^4,M),:)*V(:,j); 54 | 55 | figure1=figure; 56 | axes1 = axes('Parent',figure1); 57 | hold(axes1,'on'); 58 | scatter3(X1(1:min(2*10^4,M)),X2(1:min(2*10^4,M)),X3(1:min(2*10^4,M)),3,real(C),'filled'); 59 | colormap turbo; colorbar; axis equal; view(axes1,[44.1307171302158 20.3999998682605]); 60 | grid(axes1,'on'); axis(axes1,'tight'); hold(axes1,'off'); 61 | set(axes1,'DataAspectRatio',[1 1 1]); 62 | xlabel('$X$','interpreter','latex','fontsize',14) 63 | ylabel('$Y$','interpreter','latex','fontsize',14) 64 | zlabel('$Z$','interpreter','latex','fontsize',14,'rotation',0) 65 | title(sprintf('$\\theta=$%d, $\\mathrm{res}=$%d',imag(log(E(j))),RES(j)),'interpreter','latex','fontsize',20); 66 | % saveas(gcf,sprintf('LM%d.png',j)) 67 | % close all 68 | end 69 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/docs-examples/test_evaluate_on_sparse_grids.m: -------------------------------------------------------------------------------- 1 | %---------------------------------------------------- 2 | % Sparse Grid Matlab Kit 3 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 4 | % See LICENSE.txt for license 5 | %---------------------------------------------------- 6 | 7 | %% a more complex example of recycle 8 | 9 | clc 10 | clear 11 | 12 | fs=@(x) sum(x); 13 | 14 | N=2; 15 | 16 | 17 | previous_evals=[]; 18 | S_old=[]; 19 | Sr_old=[]; 20 | 21 | 22 | for w=0:4 23 | 24 | S=smolyak_grid(N,w,@(n) knots_uniform(n,-1,1),@lev2knots_lin); 25 | Sr= reduce_sparse_grid(S); 26 | 27 | evals_rec = evaluate_on_sparse_grid(fs,S,Sr,previous_evals,S_old,Sr_old); 28 | evals_non_rec = evaluate_on_sparse_grid(fs,Sr); 29 | 30 | previous_evals=evals_rec; 31 | S_old = S; 32 | Sr_old=Sr; 33 | 34 | max(abs(evals_non_rec(:)-evals_rec(:))) 35 | 36 | end 37 | 38 | 39 | 40 | %% it is also possible to extract information about what points are new and what points are in common between to grids, 41 | % and what points are in the old sparse grid only 42 | 43 | clc 44 | clear 45 | 46 | f=@(x) sum(x); 47 | 48 | N=2; w=4; 49 | S=smolyak_grid(N,w,@(n) knots_uniform(n,-1,1),@lev2knots_lin); 50 | Sr= reduce_sparse_grid(S); 51 | 52 | w=5; 53 | T=smolyak_grid(N,w,@(n) knots_uniform(n,-1,1),@lev2knots_lin); 54 | Tr= reduce_sparse_grid(T); 55 | 56 | 57 | tol=1e-16; 58 | evals_old=evaluate_on_sparse_grid(f,Sr); 59 | [evals_par,new_points,tocomp_list,discard_points,discard_list] =evaluate_on_sparse_grid(f,T,Tr,evals_old,S,Sr); 60 | 61 | 62 | 63 | 64 | %% an extreme test: we recycle from a larger grid to a smaller 65 | 66 | clc 67 | clear 68 | 69 | f=@(x) sum(x); 70 | 71 | N=2; w=3; 72 | S=smolyak_grid(N,w,@(n) knots_uniform(n,-1,1),@lev2knots_lin); 73 | Sr= reduce_sparse_grid(S); 74 | 75 | w=4; 76 | T=smolyak_grid(N,w,@(n) knots_uniform(n,-1,1),@lev2knots_lin); 77 | Tr= reduce_sparse_grid(T); 78 | 79 | evals_nr=evaluate_on_sparse_grid(f,Sr); 80 | evals_r=evaluate_on_sparse_grid(f,S,Sr,evaluate_on_sparse_grid(f,Tr),T,Tr); 81 | 82 | %[i,j]=max(abs(evals_nr(:)-evals_r(:))) 83 | max(abs(evals_nr(:)-evals_r(:))) -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/Contents.m: -------------------------------------------------------------------------------- 1 | % Contents of the Phase Plot Package 2 | % 3 | % Phase Plot Package - Visualization of complex functions 4 | % Version 2.3, January 15, 2014 5 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 6 | % 7 | % For background information on phase portraits see 8 | % E. Wegert, Visual Complex Functions, Birkhaeuser-Springer 2012 9 | % 10 | % ----------------------------------------------------------------------------- 11 | % 12 | % Demonstrations 13 | % 14 | % PPDemo - basic demonstration of phase plots 15 | % PPGUI - graphical user interface 16 | % 17 | % ----------------------------------------------------------------------------- 18 | % 19 | % Main routines 20 | % 21 | % PhasePlot - phase plot of complex function 22 | % PPOnSphere - phase plot of function on Riemann sphere 23 | % PPOnSphLow - stereographic projection of phase plot from the lower hemisphere 24 | % PPOnSphUp - stereographic projection of phase plot from the upper hemisphere 25 | % 26 | % ----------------------------------------------------------------------------- 27 | % 28 | % auxiliary functions 29 | % 30 | % colscheme - algorithms for converting complex numbers to colors 31 | % myfunction - example of matlab routine (singular inner function) 32 | % fldrect - discrete field of complex numbers, domain of function 33 | % unitcircle - vector with discrete points on complex unit circle 34 | % zdomain - the same as fldrect 35 | % zplane - discrete field of points in the entire complex plane 36 | % zplanePP - the same as zplane (to avoid confusion with existing m-file) 37 | % 38 | % ----------------------------------------------------------------------------- 39 | % 40 | % auxiliary functions, internal use 41 | % 42 | % BrightenRGB - modification of color scheme 43 | % GUI_PhasePlot - graphical user interface 44 | % pltphase - phase plot 45 | % StereoP2S - stereographic projection from plane to sphere 46 | % StereoS2P - stereographic projection from sphere to plane 47 | % unitcirc - uniformly distributed points on the complex unit circle 48 | % 49 | % ----------------------------------------------------------------------------- 50 | % 51 | % Contents - this file -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/polynomials_functions/herm_eval.m: -------------------------------------------------------------------------------- 1 | function H = herm_eval(x,k,mi,sigma) 2 | 3 | % H = herm_eval(x,k,mi,sigma) 4 | % 5 | % returns the values of the k-th Hermite polynomial orthoNORMAL in (-inf,+inf) w.r.t to rho=1/sqrt(2 pi sigma) * e^( -(x-mi)^2/(2*sigma^2) ) in the points x 6 | % ( x can be a matrix as well) 7 | % 8 | % N.B. the polynomials start from k=0: L_0(x) = 1, L_1(x) = (x - mi)/sigma 9 | 10 | 11 | %---------------------------------------------------- 12 | % Sparse Grid Matlab Kit 13 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 14 | % See LICENSE.txt for license 15 | %---------------------------------------------------- 16 | 17 | 18 | 19 | % this function expresses H as a function of the standard Hermite "probabilistic" polynomial (i.e. orthoGONAL w.r.t. rho=1/sqrt(2 pi) * e^(-x^2/2) ), 20 | % which are recursively calculated through the function standard_herm_eval, coded below in this .m file 21 | 22 | % first compute the transformation of x (referred to N(mi,sigma^2)) to z, the standard gaussian 23 | 24 | % sigma=sqrt(sigma2); 25 | 26 | 27 | z = ( x - mi ) / sigma ; 28 | 29 | % calculate the standard legendre polynomials in t 30 | H = standard_herm_eval(z,k); 31 | % modify L to take into account normalizations. 32 | if k>1 33 | H = H / sqrt ( factorial(k) ); 34 | end 35 | 36 | 37 | 38 | 39 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 | 41 | 42 | function H = standard_herm_eval(x,k) 43 | 44 | % L = standard_herm_eval(x) 45 | % 46 | % returns the values of the k-th standard Hermite "probabilistic" polynomial (i.e. orthoGONAL w.r.t. rho=1/sqrt(2 pi) * e^(-x^2/2) ), in the points x 47 | % ( x can be a vector as well) 48 | % 49 | % N.B. the polynomials start from k=0: L_0(x) = 1, L_1(x) = x 50 | 51 | % base steps 52 | 53 | % read this as L(k-2) 54 | H_2=ones(size(x)); 55 | 56 | % and this as L(k-1) 57 | H_1=x; 58 | 59 | if k==0 60 | H=H_2; 61 | return 62 | elseif k==1 63 | H=H_1; 64 | return 65 | else 66 | % recursive step 67 | for ric=2:k 68 | H = x .* H_1 - (ric-1) * H_2; 69 | H_2=H_1; 70 | H_1=H; 71 | end 72 | return 73 | end 74 | 75 | 76 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/knots_functions/knots_uniform.m: -------------------------------------------------------------------------------- 1 | function [x,w]=knots_uniform(n,x_a,x_b,whichrho) 2 | 3 | % [x,w]=KNOTS_UNIFORM(n,x_a,x_b) 4 | % 5 | % calculates the collocation points (x) 6 | % and the weights (w) for the gaussian integration 7 | % w.r.t. to the weight function rho(x)=1/(b-a) 8 | % i.e. the density of a uniform random variable 9 | % with range going from x=a to x=b. 10 | % 11 | % 12 | % [x,w]=KNOTS_UNIFORM(n,x_a,x_b,'prob') 13 | % 14 | % is the same as [x,w]=KNOTS_UNIFORM(n,x_a,x_b) above 15 | % 16 | % 17 | % [x,w]=KNOTS_UNIFORM(n,x_a,x_b,'nonprob') 18 | % 19 | % calculates the collocation points (x) 20 | % and the weights (w) for the gaussian integration 21 | % w.r.t to the weight function rho(x)=1 22 | 23 | 24 | %---------------------------------------------------- 25 | % Sparse Grid Matlab Kit 26 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 27 | % See LICENSE.txt for license 28 | %---------------------------------------------------- 29 | 30 | 31 | if nargin==3 32 | whichrho='prob'; 33 | end 34 | 35 | if n==1 36 | 37 | x=(x_a+x_b)/2; 38 | wt=1; 39 | 40 | else 41 | 42 | % calculates the values of the recursive relation 43 | [a,b]=coeflege(n); 44 | 45 | % builds the matrix 46 | JacM=diag(a)+diag(sqrt(b(2:n)),1)+diag(sqrt(b(2:n)),-1); 47 | 48 | % calculates points and weights from eigenvalues / eigenvectors of JacM 49 | [W,X]=eig(JacM); 50 | x=diag(X)'; 51 | wt=W(1,:).^2; 52 | [x,ind]=sort(x); %#ok 53 | wt=wt(ind); 54 | 55 | % modifies points according to the distribution and its interval x_a, x_b 56 | x = (x_b-x_a)/2*x + (x_a+x_b)/2; 57 | 58 | end 59 | 60 | % finally, fix weights 61 | 62 | switch whichrho 63 | 64 | case 'nonprob' 65 | w=(x_b-x_a)*wt; 66 | 67 | case 'prob' 68 | w=wt; 69 | 70 | otherwise 71 | error('SparseGKit:WrongInput','4th input not recognized') 72 | 73 | end 74 | 75 | 76 | 77 | %---------------------------------------------------------------------- 78 | function [a, b] = coeflege(n) 79 | 80 | if (n <= 1), disp(' n must be > 1 '); 81 | return; 82 | end 83 | 84 | a=zeros(1,n); 85 | b=zeros(1,n); 86 | 87 | b(1)=2; 88 | 89 | k=2:n; 90 | b(k)=1./(4-1./(k-1).^2); -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/polynomials_functions/lege_eval.m: -------------------------------------------------------------------------------- 1 | function L = lege_eval(x,k,a,b) 2 | 3 | % L = lege_eval(x,k,a,b) 4 | % 5 | % returns the values of the k-th Legendre polynomial orthoNORMAL in a,b w.r.t to rho=1/(b-a) in the points x 6 | % ( x can be a matrix as well) 7 | % 8 | % N.B. the polynomials start from k=0: L_0(x) = 1, L_1(x) = x 9 | 10 | 11 | %---------------------------------------------------- 12 | % Sparse Grid Matlab Kit 13 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 14 | % See LICENSE.txt for license 15 | %---------------------------------------------------- 16 | 17 | 18 | % this function expresses L as a function of the standard Legendre polynomial (i.e. polynomials orthogonal in -1,1 w.r.t to rho=1 !! ), 19 | % which are recursively calculated through the function standard_lege_eval, coded below in this .m file 20 | 21 | % first compute the transformation of x in (a,b) to t in (-1,1) 22 | 23 | t = ( 2*x - a - b ) / (b - a ) ; 24 | 25 | % calculate the standard legendre polynomials in t 26 | 27 | L = standard_lege_eval(t,k); 28 | 29 | % modify L to take into account normalizations 30 | 31 | st_lege_norm = sqrt ( 2 / (2*k+1) ); 32 | 33 | % moreover, add an additional sqrt(2) to take into account a general interval (a,b) , not (-1,1) 34 | 35 | L = sqrt(2) * L / st_lege_norm; 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 46 | 47 | 48 | function L = standard_lege_eval(x,k) 49 | 50 | % L = standard_lege_eval(x) 51 | % 52 | % returns the values of the k-th standard Legendre polynomial (i.e. polynomials orthogonal and not orthonormal 53 | % in -1,1 w.r.t to rho=1 !! ) in the points x ( x can be a vector as well) 54 | % 55 | % N.B. the polynomials start from k=0: L_0(x) = 1, L_1(x) = x 56 | 57 | % base steps 58 | 59 | % read this as L(k-2) 60 | L_2=ones(size(x)); 61 | 62 | % and this as L(k-1) 63 | L_1=x; 64 | 65 | if k==0 66 | L=L_2; 67 | return 68 | elseif k==1 69 | L=L_1; 70 | return 71 | else 72 | % recursive step 73 | for ric=2:k 74 | L = (2*ric - 1) / ric * x .* L_1 - (ric-1) / ric * L_2; 75 | L_2=L_1; 76 | L_1=L; 77 | end 78 | return 79 | end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/main/export_sparse_grid_to_file.m: -------------------------------------------------------------------------------- 1 | function export_sparse_grid_to_file(Sr,filename,with_weights) 2 | 3 | % EXPORT_SPARSE_GRID_TO_FILE saves knots of a reduced sparse grid to an ASCII file. 4 | % The first line of the file shows the number of points in the grid and their dimension; 5 | % then, points are stored as lines. 6 | % 7 | % Therefore, a sparse grid with 50 points in 2 dimensions will be stored in a file that 8 | % looks as follows 9 | % 10 | % 50 2 11 | % coord1(P1) coord2(P1) 12 | % coord1(P2) coord2(P2) 13 | % coord1(P3) coord2(P3) 14 | % ... 15 | % 16 | % EXPORT_SPARSE_GRID_TO_FILE(SR) saves the points in Sr in a file called POINTS.DAT 17 | % 18 | % EXPORT_SPARSE_GRID_TO_FILE(SR,FILENAME) saves the points in Sr in a file called FILENAME 19 | % (extension should be provided in FILENAME) 20 | % 21 | % EXPORT_SPARSE_GRID_TO_FILE(SR,FILENAME,'with_weights') saves the points in Sr in a file called FILENAME 22 | % (extension should be provided in FILENAME) and adds also the corresponding weight as 23 | % last entry of the row, ie. 24 | % 25 | % 50 2 26 | % coord1(P1) coord2(P1) weight(P1) 27 | % coord1(P2) coord2(P2) weight(P2) 28 | % coord1(P3) coord2(P3) weight(P3) 29 | % ... 30 | 31 | %---------------------------------------------------- 32 | % Sparse Grid Matlab Kit 33 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 34 | % See LICENSE.txt for license 35 | %---------------------------------------------------- 36 | 37 | 38 | 39 | 40 | switch nargin 41 | case 1 42 | filename = 'points.dat'; 43 | with_weights = false; 44 | case 2 45 | with_weights = false; 46 | case 3 47 | if strcmp(with_weights,'with_weights') 48 | with_weights=true; 49 | else 50 | error('unknown second parameter') 51 | end 52 | end 53 | 54 | % first row, number of points and dimension 55 | fid = fopen(filename,'w'); 56 | fprintf(fid,'%d %d\n',fliplr(size(Sr.knots))); 57 | fclose(fid); 58 | 59 | % then add all points, one per row, and possibly weights if requested 60 | if with_weights 61 | out = [Sr.knots' Sr.weights']; %#ok<*NASGU> 62 | save(filename,'out','-ascii', '-double','-append') 63 | else 64 | out = Sr.knots'; 65 | save(filename,'out','-ascii', '-double','-append') 66 | end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/multiidx_gen.m: -------------------------------------------------------------------------------- 1 | function MULTI_IDX = multiidx_gen(N,rule,w,base,multiidx,MULTI_IDX) 2 | 3 | % MULTI_IDX = multiidx_gen(N,rule,w,base,[],[]) 4 | % 5 | % calculates all multi indexes M_I of length N with elements such that rule(M_I) <= w. 6 | % M_I's are stored as rows of the matrix MULTI_IDX 7 | % indices will start from base (either 0 or 1) 8 | 9 | 10 | %---------------------------------------------------- 11 | % Sparse Grid Matlab Kit 12 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 13 | % See LICENSE.txt for license 14 | %---------------------------------------------------- 15 | 16 | 17 | % multiidx_gen works recursively, exploring in depth the tree of all possible multiindexes. 18 | % the current multi-index is passed as 4-th input argument, and eventually stored in MULTI_IDX. 19 | % The starting point is the empty multiidx: [], and MULTI_IDX is empty at the first call of the function. 20 | % That's why the call from keyboard comes with [], [] as input argument: multiidx_gen(L,rule,w,[],[]) 21 | 22 | % disp('multiidx_fabio') 23 | 24 | if nargin==3 25 | base = 0; % default choice 26 | multiidx=[]; 27 | MULTI_IDX=[]; 28 | elseif nargin==4 29 | multiidx=[]; 30 | MULTI_IDX=[]; 31 | end 32 | 33 | 34 | if length(multiidx)~=N 35 | % recursive step: generates all possible leaves from the current node (i.e. all multiindexes with length le+1 starting from 36 | % the current multi_idx, which is of length le that are feasible w.r.t. rule) 37 | 38 | i=base; 39 | 40 | while rule([multiidx, i]) <= w 41 | % if [multiidx, i] is feasible further explore the branch of the tree that comes out from it. 42 | MULTI_IDX = multiidx_gen(N,rule,w,base,[multiidx, i],MULTI_IDX); 43 | i=i+1; 44 | end 45 | 46 | % for i=0:w 47 | % if rule([multiidx, i]) <= w 48 | % % if [multiidx, i] is feasible further explore the branch of the tree that comes out from it. 49 | % MULTI_IDX = multiidx_gen(L,rule,w,[multiidx, i],MULTI_IDX); 50 | % end 51 | % end 52 | 53 | else 54 | % base step: if the length of the current multi-index is L then I store it in MULTI_IDX (the check for feasibility was performed in the previous call 55 | MULTI_IDX=[MULTI_IDX; multiidx]; 56 | end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/tensor_grid.m: -------------------------------------------------------------------------------- 1 | function S = tensor_grid(N,m,knots) 2 | 3 | %TENSOR_GRID generates a tensor grid and computes the corresponding weights 4 | % 5 | %S = TENSOR_GRID(N,M,KNOTS) creates a tensor grid in N dimensions with M=[m1,m2,...,m_N] points 6 | % in each direction. KNOTS is either a cell array containing the functions to be used 7 | % to generate the knots in each direction, i.e. 8 | % 9 | % KNOTS={@knots_function1, @knots_function2, ... } 10 | % 11 | % or a single function, to be used to generate the 1D knots in every direction, i.e. 12 | % 13 | % KNOTS=@knots_function1 14 | % 15 | % In both cases, the header of knots_function is [x,w]=knots_function(m) 16 | % 17 | % The output S is a structure containing the information on the tensor grid: 18 | % S.knots: vector containing the tensor grid knots 19 | % S.weights: vector containing the corresponding weights 20 | % S.size: size of the tensor grid, S.size = prod(m) 21 | % S.knots_per_dim: cell array (N components), each component is the set of 1D knots used 22 | % to build the tensor grid 23 | % S.m: input vector m, m(i) = lenght(S.knots_per_dim{i}) 24 | 25 | 26 | %---------------------------------------------------- 27 | % Sparse Grid Matlab Kit 28 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 29 | % See LICENSE.txt for license 30 | %---------------------------------------------------- 31 | 32 | 33 | % if knots is a simple function, we replicate it in a cell 34 | if isa(knots,'function_handle') 35 | fknots=knots; 36 | knots=cell(1,N); 37 | for i=1:N 38 | knots{i}=fknots; 39 | end 40 | end 41 | 42 | sz=prod(m); 43 | 44 | S.knots=zeros(N,sz); 45 | S.weights=ones(1,sz); 46 | S.size = sz; 47 | S.knots_per_dim=cell(1,N); 48 | S.m = m; 49 | 50 | % generate the pattern that will be used for knots and weights matrices, e.g. 51 | % 52 | % pattern = [1 1 1 1 2 2 2 2; 53 | % 1 1 2 2 1 1 2 2; 54 | % 1 2 1 2 1 2 1 2] 55 | % 56 | % meaning "first node d-dim uses node 1 in direction 1, 2 and 3, second d-dim node uses node 1 in 57 | % direction 1 and 2 and node 2 in direction 3 ... 58 | 59 | pattern=generate_pattern(m); 60 | 61 | for n=1:N 62 | [xx,ww] = knots{n}(m(n)); 63 | S.knots_per_dim{n}=xx; 64 | S.knots(n,:) = xx(pattern(n,:)); 65 | S.weights = S.weights.*ww(pattern(n,:)); 66 | end 67 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/PPOnSphere.m: -------------------------------------------------------------------------------- 1 | function PPOnSphere(z,w,c,pres,tjmp) 2 | % phase plot of function on Riemann shphere 3 | % 4 | % Usage: PPOnSphere(z,w,c,pres,tjmp) 5 | % 6 | % z - values on domain 7 | % w - values of function at points z 8 | % c - color scheme (optional) 9 | % pres - resolution of phase (optional) 10 | % tjmp - jumps of phase (optional) 11 | 12 | % Part of the phase plot package 13 | % Version 2.3, January 15, 2014 14 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 15 | 16 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17 | 18 | 19 | % set lght = 1 for more realistic representation with light 20 | lght = 0; 21 | 22 | if nargin<2 23 | end 24 | 25 | if nargin==5 26 | RGB = colscheme(w,c,tjmp,pres); 27 | elseif nargin==4 28 | RGB = colscheme(w,c,[],pres); 29 | elseif nargin==3 30 | RGB = colscheme(w,c,[],30); 31 | elseif nargin==2 32 | RGB = colscheme(w,'m'); 33 | elseif nargin<=1 34 | disp(' ') 35 | disp('The best way to make a phase plot on the entire sphere is') 36 | disp('the usage of two different charts (no singularities)') 37 | disp(' ') 38 | disp('First phase plot on lower hemishpere from transformed unit square:'); 39 | disp(' ') 40 | disp('z = zdomain(-1-1i,1+1i,1000,1000);') 41 | disp('w = (z-1)./(z.^2+z+1);') 42 | disp('figure(1)') 43 | disp('hold on') 44 | disp('PPOnSphere(z,w);') 45 | z = zdomain(-1-1i,1+1i,1000,1000); 46 | w = (z-1)./(z.^2+z+1); 47 | figure(1) 48 | clf 49 | hold on 50 | PPOnSphere(z,w); 51 | disp('paused, press key to continue'); 52 | pause 53 | disp(' ') 54 | disp('Next phase plot on upper hemishpere from inverted unit square:'); 55 | disp(' ') 56 | disp('z = 1./z;') 57 | disp('w = (z-1)./(z.^2+z+1);') 58 | disp('PPOnSphere(z,w);') 59 | z = 1./z; 60 | w = (z-1)./(z.^2+z+1); 61 | PPOnSphere(z,w); 62 | disp('Phase Plot on upper hemishpere added'); 63 | disp(' ') 64 | return 65 | end 66 | 67 | [p,q,r] = StereoP2S(z); 68 | 69 | h=surf(p,q,r,RGB); 70 | 71 | set(h,'EdgeColor','none'); 72 | 73 | axis equal 74 | axis off 75 | axis(0.8*[-1,1,-1,1,-1,1]) 76 | 77 | view(30,20) 78 | 79 | if lght==1 80 | 81 | lightangle(140,60) 82 | 83 | set(gcf,'Renderer','zbuffer') 84 | set(findobj(gca,'type','surface'),... 85 | 'FaceLighting','phong',... 86 | 'AmbientStrength',.7,'DiffuseStrength',.3,... 87 | 'SpecularStrength',.5,'SpecularExponent',25,... 88 | 'BackFaceLighting','unlit') 89 | 90 | end 91 | 92 | end 93 | 94 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/docs-examples/test_sparse_interpolation.m: -------------------------------------------------------------------------------- 1 | %---------------------------------------------------- 2 | % Sparse Grid Matlab Kit 3 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 4 | % See LICENSE.txt for license 5 | %---------------------------------------------------- 6 | 7 | 8 | %% 9 | clear 10 | 11 | % dimension 12 | N=6; 13 | 14 | % vector-valued function to be interpolated. input column points, out 15 | % 2-row matrix, one per output component 16 | 17 | f1=@(x) 1./(1+0.5/N*sum(x)); 18 | f2=@(x) sum(abs(x).^3); 19 | 20 | f=@(x) [f1(x); f2(x)]; 21 | 22 | % define sparse grid 23 | [lev2knots,idxset]=define_functions_for_rule('TD',N); 24 | knots=@(n) knots_uniform(n,-1,1,'nonprob'); 25 | a=-1; b=1; 26 | 27 | 28 | 29 | % for loop 30 | 31 | w_max=6; 32 | interp_error=zeros(2,w_max+1); 33 | work=zeros(1,w_max+1); 34 | 35 | 36 | non_grid_points=rand(N,2000)*(b-a)+a; 37 | %non_grid_points=[0.5*ones(N,1), zeros(N,1)]; 38 | S_old = []; % we also recycle previous grids 39 | 40 | tic 41 | for w=0:w_max 42 | 43 | disp(w) 44 | 45 | % create grid 46 | [S,C]=smolyak_grid(N,w,knots,lev2knots,idxset,S_old); 47 | S_old = S; 48 | 49 | Sr=reduce_sparse_grid(S); 50 | 51 | 52 | % move points to actual interval here point are columns 53 | % Sr.knots=interval_map(Sr.knots); 54 | 55 | % compute work 56 | work(w+1)=Sr.size; 57 | 58 | % compute estimate of polynomial size 59 | pol_size(w+1)=size(C,1); 60 | 61 | % compute the nodal values to be used to interpolate. It has to be 62 | % row vector (more rows for vector-valued output functions) 63 | function_on_grid=f(Sr.knots); 64 | 65 | % compute interpolated values. Here f_values is row 66 | f_values = interpolate_on_sparse_grid(S,Sr,function_on_grid,non_grid_points); 67 | 68 | % compute error 69 | interp_error(:,w+1)=max( abs((f(non_grid_points) - f_values)), [],2 ) ; 70 | 71 | end 72 | toc 73 | 74 | %% 75 | figure 76 | semilogy(0:w,interp_error(1,:),'-or','DisplayName','Numerical Error component 1, w.r.t. grid level'); 77 | hold on 78 | semilogy(0:w,interp_error(2,:),'-ok','DisplayName','Numerical Error component 2, w.r.t. grid level'); 79 | semilogy(0:w_max,1./exp(0:w_max),'--o','DisplayName','exp(-level)') 80 | legend show 81 | 82 | %% 83 | figure 84 | loglog(work,interp_error(1,:),'-or','DisplayName','Numerical Error component 1, w.r.t. #points'); 85 | hold on 86 | loglog(work,interp_error(2,:),'-ok','DisplayName','Numerical Error component 2, w.r.t. #points'); 87 | legend show 88 | 89 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/generate_pattern.m: -------------------------------------------------------------------------------- 1 | function pattern = generate_pattern(m) 2 | 3 | % pattern = generate_pattern(m) 4 | % 5 | % given m=[m1 m2 m3 m4 ... mN] generares a matrix that can be used to generate the cartesian product 6 | % of {1,2,...,m1} x {1,2,...,m2} x {1,2,...m3} x .... 7 | % 8 | % e.g. 9 | % 10 | % generate_pattern([3 2 2]) 11 | % 12 | % pattern = 13 | % 14 | % 1 2 3 1 2 3 1 2 3 1 2 3 15 | % 1 1 1 2 2 2 1 1 1 2 2 2 16 | % 1 1 1 1 1 1 2 2 2 2 2 2 17 | 18 | 19 | %---------------------------------------------------- 20 | % Sparse Grid Matlab Kit 21 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 22 | % See LICENSE.txt for license 23 | %---------------------------------------------------- 24 | 25 | 26 | 27 | N=length(m); 28 | 29 | % it is convenient from a computational point of view to generate the pattern as unsigned int to create the pattern 30 | if max(m)<=intmax('uint8') 31 | pattern=zeros(N,prod(m),'uint8'); 32 | elseif max(m) <=intmax('uint16') 33 | warning('SparseGKit:uint16','more than 255 points are asked in one direction, using uint16 to handle this') 34 | pattern=zeros(N,prod(m),'uint16'); 35 | else 36 | warning('SparseGKit:double','more than 65535 points are asked in one direction, using double precision to handle this') 37 | pattern=zeros(N,prod(m)); 38 | end 39 | 40 | 41 | % the algorithm works one direction at a time. at the n-th iteration the n-th row of pattern is generated, 42 | % by repeating q times the vector BASE, which containes itselt a sequence, 43 | % obtained repeating p times each number from j=1 to j=m(n), e.g. 44 | % generate_pattern([3 2 2]) 45 | % 46 | % pattern = 47 | % 48 | % 1 2 3 1 2 3 1 2 3 1 2 3 49 | % 1 1 1 2 2 2 1 1 1 2 2 2 50 | % 1 1 1 1 1 1 2 2 2 2 2 2 51 | 52 | for k=1:N 53 | p = prod([1 m(1:k-1)]); 54 | q = prod([m(k+1:end) 1]); 55 | 56 | % length of base vector 57 | lb=p*m(k); 58 | base = zeros(1,lb); 59 | 60 | % generate base vector 61 | bb=1; 62 | for j=1:m(k) 63 | base(bb:bb+p-1)=j; 64 | bb=bb+p; 65 | end 66 | 67 | % repeat base vector 68 | pp=1; 69 | for j=1:q 70 | pattern(k,pp:pp+lb-1)=base; 71 | pp=pp+lb; 72 | end 73 | 74 | end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/rescaling_functions/get_interval_map.m: -------------------------------------------------------------------------------- 1 | function map = get_interval_map(a,b,type) 2 | 3 | % MAP defines functions to shift sparse grids. 4 | % 5 | % map = GET_INTERVAL_MAP(a,b,'uniform') where a,b are two vectors, 6 | % returns a function that takes column points from (-1,1)^N to the generic box 7 | % 8 | % ( a(1) b(1) ) x ( a(2) b(2) ) x ( a(3) b(3) ) ... 9 | % 10 | % map = GET_INTERVAL_MAP(a,b,'gaussian') where a,b are two vectors, 11 | % returns a function that takes points from R^N chosen according to standard gaussian measure 12 | % to points in R^N chosen according to a product of gaussians with means in a and stdev in b 13 | % 14 | % in both cases the output function must be used as 15 | % 16 | % X = interval_map(T) 17 | % 18 | % where T is a matrix of points in (-1,1)^N, one point per column (as in the output of 19 | % reduce_sparse_grid or tensor_grid). Similarly X is a matrix of points in 20 | % ( a(1) b(1) ) x ( a(2) b(2) ) x ( a(3) b(3) ), one point per column 21 | 22 | 23 | %---------------------------------------------------- 24 | % Sparse Grid Matlab Kit 25 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 26 | % See LICENSE.txt for license 27 | %---------------------------------------------------- 28 | 29 | 30 | switch type 31 | 32 | case 'uniform' 33 | 34 | % first we build D, resize matrix: it modifies a column vector "c" with components in 0,1 35 | % into a column vector "d" with components in ( 0 |b(1)-a(1)| ) x ( 0 |b(2)-a(2)| ) x ... 36 | D=diag(b-a); 37 | 38 | % next a translation vector: shifts a column vector "d" with components in ( 0 |b(1)-a(1)| ) x ( 0 |b(2)-a(2)| ) x ... 39 | % to "e" with components in ( a(1) b(1) ) x ( a(2) b(2) ) x ... 40 | 41 | [r,c]=size(a); 42 | if r>c 43 | % a is a column vector 44 | p=a; 45 | else 46 | % a is a row vector 47 | p=a'; 48 | end 49 | 50 | % finally, define the function 51 | map = @(T) D*(T+1)/2+p*ones(1,size(T,2)); 52 | 53 | case 'gaussian' 54 | 55 | % D is the stdev matrix 56 | D=diag(b); 57 | 58 | % shift vector, according to means 59 | [r,c]=size(a); 60 | if r>c 61 | % a is a column vector 62 | p=a; 63 | else 64 | % a is a row vector 65 | p=a'; 66 | end 67 | 68 | % finally, define the function 69 | map = @(T) D*T+p*ones(1,size(T,2)); 70 | 71 | end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/main/derive_sparse_grid.m: -------------------------------------------------------------------------------- 1 | function grads = derive_sparse_grid(S,Sr,values_on_grid,domain,eval_points,h) 2 | 3 | % DERIVE_SPARSE_GRID computes derivatives (gradients) of sparse grid by centered finite differences 4 | % 5 | % 6 | % GRADS = DERIVE_SPARSE_GRID(S,SR,VALUES_ON_GRID,DOMAIN,EVAL_POINTS) computes the derivative of the sparse grid. 7 | % by finite differences (see below for default value of increment size). 8 | % 9 | % S is a sparse grid struct, SR is the reduced version of S, VALUES_ON_GRID are the values of the interpolated 10 | % function on SR. 11 | % DOMAIN is a 2xN matrix = [a1, a2, a3, ...; b1, b2, b3, ...] defining the lower and upper bound of the 12 | % hyper-rectangle on which the sparse grid is defined. The finite differences increment size is chosen according to 13 | % to the length of each interval [an bn] as h_n = (b_n - a_n)/1E5 14 | % 15 | % EVAL_POINTS are the points where the derivative must be evaluated. It is a matrix with points stored as 16 | % columns, following the convention of the package 17 | % 18 | % The output GRADS contains the compute values of the derivatives (gradients). The gradients in each point are stored 19 | % as columns of GRADS, i.e., size(GRADS) = N x size(EVAL_POINTS,2) 20 | % 21 | % 22 | % GRADS = DERIVE_SPARSE_GRID(S,SR,VALUES_ON_GRID,DOMAIN,EVAL_POINTS,H) uses the input H as finite differences 23 | % increment. H can be a scalar or a vector, in which case the n-th entry will be used as increment to approximate 24 | % the n-th component of the gradient 25 | 26 | 27 | %---------------------------------------------------- 28 | % Sparse Grid Matlab Kit 29 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 30 | % See LICENSE.txt for license 31 | %---------------------------------------------------- 32 | 33 | 34 | 35 | % get dimensions 36 | N=size(domain,2); % the sparse grid is defined over an N-variate hypercube 37 | M=size(eval_points,2); % number of points where we need to evaluate the derivatives 38 | 39 | grads = zeros(N,M); 40 | 41 | switch nargin 42 | case 5 43 | h = zeros(1,N); 44 | a = domain(1,:); 45 | b = domain(2,:); 46 | 47 | for n=1:N 48 | h(n) = ( b(n)-a(n) ) / 1E5; 49 | end 50 | case 6 51 | if length(h) ==1 52 | h = h*ones(1,N); 53 | end 54 | end 55 | 56 | for k=1:N 57 | epsi = zeros(N,M); 58 | epsi(k,:) = h(k)*ones(1,M); 59 | grads(k,:) = ( interpolate_on_sparse_grid(S,Sr,values_on_grid,eval_points+epsi) - interpolate_on_sparse_grid(S,Sr,values_on_grid,eval_points-epsi) ) / (2*h(k)); 60 | end 61 | 62 | 63 | -------------------------------------------------------------------------------- /Duffing_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | % Simple example for the unforced duffing oscillator 4 | 5 | rng(1) 6 | %% Set parameters 7 | M1=10^3; % number of data points 8 | M2=50; 9 | delta_t=0.25; % time step 10 | ODEFUN=@(t,y) [y(2);y(1)-y(1).^3]; 11 | options = odeset('RelTol',1e-12,'AbsTol',1e-12); 12 | N=100; 13 | PHI = @(r) exp(-r); % radial basis function 14 | 15 | x_pts = -1.2:0.04:1.2; y_pts = -0.05:0.04:1.2; 16 | v=(10.^(-2:0.1:1)); 17 | 18 | %% Produce the data 19 | X=[]; 20 | Y=[]; 21 | for jj=1:M1 22 | Y0=(rand(2,1)-0.5)*4; 23 | [~,Y1]=ode45(ODEFUN,[0 0.000001 (1:(3+M2))*delta_t],Y0,options); 24 | Y1=Y1'; 25 | X = [X,Y1(:,[1,3:M2+1])]; 26 | Y = [Y,Y1(:,3:M2+2)]; 27 | end 28 | M = M1*M2; 29 | 30 | d=mean(vecnorm(X-mean(X')')); % scaling for radial function 31 | 32 | [~,C] = kmeans([X';Y'],N); % find centers 33 | 34 | PX = zeros(M,N); PY = zeros(M,N); 35 | 36 | for j = 1:N 37 | R = sqrt((X(1,:)-C(j,1)).^2+(X(2,:)-C(j,2)).^2); 38 | PX(:,j) = PHI(R(:)/d); 39 | R = sqrt((Y(1,:)-C(j,1)).^2+(Y(2,:)-C(j,2)).^2); 40 | PY(:,j) = PHI(R(:)/d); 41 | end 42 | 43 | %% Apply ResDMD algorithm 1 (residuals computed after EDMD) 44 | K = PX\PY; 45 | [V,LAM] = eig(K,'vector'); 46 | res = (vecnorm(PY*V-PX*V*diag(LAM))./vecnorm(PX*V))'; % residuals 47 | 48 | %% 49 | figure 50 | scatter(real(LAM),imag(LAM),250,res,'.'); 51 | colormap turbo; colorbar; 52 | ax=gca; ax.FontSize=14; axis equal tight; 53 | xlim([-1,1]); 54 | ylim([-1,1]); 55 | 56 | %% ResDMD for pseudospectrum 57 | z_pts=kron(x_pts,ones(length(y_pts),1))+1i*kron(ones(1,length(x_pts)),y_pts(:)); z_pts=z_pts(:); 58 | 59 | RES = KoopPseudoSpecQR(PX,PY,1/M,z_pts,'Parallel','off'); 60 | RES = reshape(RES,length(y_pts),length(x_pts)); 61 | 62 | %% 63 | figure 64 | contourf(reshape(real(z_pts),length(y_pts),length(x_pts)),reshape(imag(z_pts),length(y_pts),length(x_pts)),log10(max(min(v),real(RES))),log10(v)); 65 | hold on 66 | contourf(reshape(real(z_pts),length(y_pts),length(x_pts)),-reshape(imag(z_pts),length(y_pts),length(x_pts)),log10(max(min(v),real(RES))),log10(v)); 67 | cbh=colorbar; 68 | cbh.Ticks=log10([0.005,0.01,0.1,1]); 69 | cbh.TickLabels=[0,0.01,0.1,1]; 70 | clim([log10(min(v)),0]); 71 | reset(gcf) 72 | set(gca,'YDir','normal') 73 | colormap gray 74 | ax=gca; ax.FontSize=18; axis equal tight; axis([x_pts(1),x_pts(end),-y_pts(end),y_pts(end)]) 75 | xlabel('$\mathrm{Re}(\lambda)$','interpreter','latex','fontsize',18) 76 | ylabel('$\mathrm{Im}(\lambda)$','interpreter','latex','fontsize',18) 77 | title(sprintf('$\\mathrm{Sp}_\\epsilon(\\mathcal{K})$, $N=%d$',N),'interpreter','latex','fontsize',18) 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Examples_gallery_4/Cascade_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | 4 | 5 | %% Load and process the data 6 | load('pressure_data.mat') 7 | DATA = DATA-mean(DATA,1); 8 | %% Run new DMD with residuals 9 | M = 700; r = M; 10 | 11 | X = DATA(1:M,:)'/sqrt(M); 12 | Y = DATA(2:(M+1),:)'/sqrt(M); 13 | 14 | [U,S,V] = svd(X,'econ'); 15 | r = min(rank(S),r); 16 | U = U(:,1:r); V = V(:,1:r); S = S(1:r,1:r); Sinv = diag(1./diag(S)); 17 | K = (U')*Y*V*Sinv; % DMD matrix 18 | 19 | PX2 = X*V*diag(1./diag(S)); 20 | PY2 = Y*V*diag(1./diag(S)); 21 | [W,LAM,W2] = eig(K,'vector'); 22 | Phi = Y*V*Sinv*W; % DMD modes 23 | 24 | R = vecnorm(PY2*W-PX2*W*diag(LAM))./vecnorm(PX2*W); % residuals 25 | %% 26 | [~,I]=sort(abs(1-LAM),'ascend'); % reorder modes 27 | R = R(I); LAM = LAM(I); W = W(:,I); W2 = W2(:,I); Phi = Phi(:,I); 28 | 29 | %% 30 | 31 | figure 32 | scatter(real(LAM),imag(LAM),300,R,'.','LineWidth',1); 33 | hold on 34 | plot(cos(-1:0.01:2*pi),sin(-1:0.01:2*pi),'-k') 35 | xlim([0.95,1.01]) 36 | clim([0,max(R(real(LAM)>0.95))]) 37 | load('cmap.mat') 38 | colormap(cmap2); colorbar 39 | xlabel('$\mathrm{Re}(\lambda)$','interpreter','latex','fontsize',18) 40 | ylabel('$\mathrm{Im}(\lambda)$','interpreter','latex','fontsize',18) 41 | title('Residuals','interpreter','latex','fontsize',18) 42 | ax=gca; ax.FontSize=18; 43 | 44 | % exportgraphics(gcf,'cascade_res1.pdf','ContentType','vector','BackgroundColor','none') 45 | 46 | figure 47 | loglog([0.01,1],[0.01,1],'k','linewidth',2) 48 | hold on 49 | loglog(sqrt(abs(abs(LAM).^2-1)),R,'b.','markersize',20) 50 | xlabel('$\sqrt{|1-|\lambda|^2|}$','interpreter','latex','fontsize',18) 51 | ylabel('residual','interpreter','latex','fontsize',18) 52 | title('Residuals','interpreter','latex','fontsize',18) 53 | ax=gca; ax.FontSize=18; 54 | 55 | % exportgraphics(gcf,'cascade_res2.pdf','ContentType','vector','BackgroundColor','none') 56 | return 57 | 58 | %% Plot DMD modes 59 | 60 | close all 61 | sz2=abs(X_data-0.1); 62 | sz2=max(0,sz2-0.04); 63 | sz2=3-2.1*exp(-(sz2*5)); 64 | 65 | for ind = 1:11 66 | u = real(Phi(:,ind)); 67 | res = R(ind); 68 | L = LAM(ind); 69 | if imag(L)<0 70 | else 71 | figure; 72 | scatter(X_data,Z_data,sz2,u,'o','filled'); 73 | hold on 74 | scatter(X_data,Z_data+max(Z_data(:)),sz2,u,'o','filled'); 75 | title(sprintf('$\\lambda=%0.4f+%0.4fi,r=%0.4f$',real(L),imag(L),res),'interpreter','latex','fontsize',18) 76 | load('cmap.mat') 77 | colormap(cmap) 78 | clim([-3*std(u)+mean(u),3*std(u)+mean(u)]) 79 | % xlim([-0.1,0.3]) 80 | axis equal tight 81 | axis off 82 | % exportgraphics(gcf,sprintf('cascade_mode%d.png',ind),'ContentType','image','BackgroundColor','none') 83 | % close all 84 | end 85 | pause(1) 86 | % close all 87 | end 88 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/polynomials_functions/lagr_eval_multidim.m: -------------------------------------------------------------------------------- 1 | function L= lagr_eval_multidim(current_knot,knots_per_dim,non_grid_points) 2 | 3 | % L= LAGR_EVAL_MULTIDIM(current_knot,knots_per_dim,non_grid_points) 4 | % 5 | % evaluates the multidim Lagrange function L centered in current_knot in non_grid_points. 6 | % 7 | % -> non_grid_points is a matrix; each row is a point to be evaluated 8 | % 9 | % -> knots_per_dim is a cell_array, that contains one array per cell. In the arrays are stored all the 10 | % knots in each direction. E.g. 11 | % knots_per_dim={[0 0.5 1], 12 | % [0 0.2 0.4 0.6 0.8 1] } 13 | % it has to contain current_knot 14 | 15 | 16 | %---------------------------------------------------- 17 | % Sparse Grid Matlab Kit 18 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 19 | % See LICENSE.txt for license 20 | %---------------------------------------------------- 21 | 22 | 23 | 24 | % we are working on P points in N dimensions, 25 | [P,N]=size(non_grid_points); 26 | 27 | % the lagrangian functions in N dim are products of lagrangian functions in 1 D , so I work dimension-wise: 28 | % we evaluate the multidimensional lagrange function on the corresponding column of points non_grid_points 29 | % one dimension at a time and then we multiply 30 | lagrange_monodim_eval=zeros(P,N); 31 | 32 | for dim=1:N 33 | % these are the knots where the lagrange function is zero. 34 | % I compute it discarding the knot where I'm centering the multidim. lagr. function 35 | % this is an expensive way, with setdiff: 36 | % monodim_knots=setdiff(knots_per_dim{dim},current_knot(dim)); 37 | % this is much cheaper, with logical indexing 38 | monodim_knots_temp=knots_per_dim{dim}; 39 | monodim_knots=monodim_knots_temp(monodim_knots_temp~=current_knot(dim)); 40 | 41 | % now i compute the lagrange function in the dim-th dimension and evaluate it in the points 42 | lagrange_monodim_eval(:,dim)=lagr_eval(current_knot(dim),monodim_knots,non_grid_points(:,dim)); 43 | end 44 | 45 | L=prod(lagrange_monodim_eval,2); 46 | 47 | 48 | 49 | % switch type 50 | % case 'lagr' 51 | % monodim_knots_temp=knots_per_dim{dim}; 52 | % monodim_knots=monodim_knots_temp(monodim_knots_temp~=current_knot(dim)); 53 | % % now i compute the lagrange function in the dim-th dimension and evaluate it in the points 54 | % lagrange_monodim_eval(:,dim)=lagr_eval(current_knot(dim),monodim_knots,non_grid_points(:,dim)); 55 | % case 'newton' 56 | % versor=(knots_per_dim{dim}==current_knot(dim)); 57 | % lagrange_monodim_eval(:,dim)=lagr_eval_newton(knots_per_dim{dim},versor,non_grid_points(:,dim)');%lagr_eval(current_knot(dim),monodim_knots,non_grid_points(:,dim)); 58 | % end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/tools/idxset_functions/fast_TD_set.m: -------------------------------------------------------------------------------- 1 | function I = fast_TD_set(N,w) 2 | 3 | % I = fast_TD_set(N,w) returns the multiindex set TD(w) in N dimensions 4 | % (one row per multiindex) i.e. {ii in N_+ : sum(ii-1) <= w} 5 | 6 | 7 | %---------------------------------------------------- 8 | % Sparse Grid Matlab Kit 9 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 10 | % See LICENSE.txt for license 11 | %---------------------------------------------------- 12 | 13 | 14 | 15 | % initialize I 16 | TDsize=nchoosek(N+w,N); 17 | 18 | I=NaN(TDsize,N); 19 | 20 | r1=1; 21 | 22 | % compute one level at a time 23 | 24 | for i=0:w 25 | 26 | % compute number of rows 27 | r = setsize(N,i); 28 | r2= r1 + r-1; 29 | 30 | % now we do the recursive call 31 | I(r1:r2,:)=fast_TD_rec(N,i,r); 32 | r1=r2+1; 33 | 34 | end 35 | 36 | % sort rows to get lexicographic order. Note that this is not much time consuming 37 | I = sortrows(I); 38 | 39 | % if nargin==3 40 | % I=I+base; 41 | % end 42 | 43 | I=I+1; 44 | 45 | 46 | 47 | function I = fast_TD_rec(N,w,rows) 48 | 49 | % I = fast_TD_rec(N,w,rows) 50 | % 51 | % actually returns the sub matrix of the multindices in N dimensions st sum(i)=w. 52 | % rows is the number of rows and is needed for the recursive base step 53 | 54 | 55 | if N==1 56 | 57 | I=w*ones(rows,1); 58 | 59 | else 60 | 61 | 62 | switch w 63 | 64 | case 0 65 | 66 | I=zeros(rows,N); 67 | 68 | case 1 69 | 70 | I = eye(N); 71 | 72 | otherwise 73 | 74 | % initialize with NaN is faster than 0 75 | I = NaN(rows,N); 76 | 77 | % loop on levels and fill the submatrices 78 | 79 | r1=1; % first row of the submatrix 80 | 81 | for k=0:w 82 | 83 | % size of the submatrix 84 | inner_rows = setsize(N-1,w-k); 85 | 86 | % second row of the submatrix 87 | r2=r1+inner_rows-1; 88 | 89 | % rows of the submatrix 90 | rows_idx=r1:r2; 91 | 92 | % the first column 93 | I(rows_idx,1)=k*ones(inner_rows,1); 94 | 95 | % the submatrix 96 | I(rows_idx,2:end)= fast_TD_rec(N-1,w-k,inner_rows); 97 | 98 | % update row indices 99 | r1=r2+1; 100 | end 101 | end 102 | end 103 | 104 | 105 | 106 | 107 | 108 | 109 | function r = setsize(N,w) 110 | 111 | % r = setsize(N,w) 112 | % 113 | % returns the number of multiindices i in N dimensions s.t. sum(i)=w 114 | 115 | r=nchoosek(N+w-1,N-1); -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/find_lexicographic.m: -------------------------------------------------------------------------------- 1 | function [found,pos,iter] = find_lexicographic(lookfor,I,nocheck) 2 | 3 | % FIND_LEXICOGRAPHIC finds specific rows of a matrix that is sorted lexicographically 4 | % 5 | % [FOUND,POS] = FIND_LEXICOGRAPHIC(LOOKFOR,I) looks for the row vector LOOKFOR among 6 | % the rows of I. If found, FOUND=TRUE and POS is the rownumber of LOOKFOR, 7 | % i.e. LOOKFOR == I(POS,:). If not found, FOUND=FALSE and POS=[]. The function 8 | % performs a preliminar check whether I is actually lexicographically sorted. 9 | % 10 | % [FOUND,POS] = FIND_LEXICOGRAPHIC(LOOKFOR,I,'nocheck') is the same but does *not* 11 | % check whether I is actually lexicographically sorted. This could be useful for speed purposes 12 | % 13 | %---------------------------------------------------- 14 | % Sparse Grid Matlab Kit 15 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 16 | % See LICENSE.txt for license 17 | %---------------------------------------------------- 18 | 19 | 20 | % first a check on I being sorted. Observe that the function sortrows used is very efficient 21 | % so the cost of this preliminary analysis is negligible 22 | 23 | if nargin == 2 && ~issorted(I,'rows'), 24 | error('SparseGKit:SetNotSorted','I is not lexicographically sorted') 25 | end 26 | 27 | if nargin == 3 && ~strcmp(nocheck,'nocheck') 28 | error('SparseGKit:WrongInput','unknown 3rd input') 29 | end 30 | 31 | nb_idx = size(I,1); 32 | 33 | % we exploit the fact that I is sorted lexicographically and we proceed by binary search 34 | % which guarantees cost ~ log(nb_idx) 35 | % 36 | % Basically, we start from the middle row, compare it with the index to be found, and 37 | % if our index is larger we make a step in the increasing direction (i.e. we look in the upper half 38 | % of the sorting), and viceversa. Of course, the step halves at each iteration: 39 | % therefore we necessarily terminate in ceil(log2(nb_idx)) steps at most 40 | 41 | % the position to compare against -- if found, this is the position to be returned 42 | idx = ceil(nb_idx/2); 43 | % the associated vector 44 | jj = I(idx,:); 45 | 46 | found = isequal(jj,lookfor); 47 | 48 | iter=1; 49 | itermax = ceil(log2(nb_idx)); 50 | 51 | while ~found && iter <= itermax 52 | if islexico(jj,lookfor) % look in the upper half, unless we are already at the end 53 | if idx < nb_idx 54 | idx = min(idx+ceil(nb_idx/2^iter),nb_idx); 55 | jj = I(idx,:); % row entry of C2 56 | found = isequal(lookfor,jj); 57 | iter=iter+1; 58 | else 59 | break 60 | end 61 | else % look in the bottom half, unless we are already at the beginning 62 | if idx > 1 63 | idx = max(idx-ceil(nb_idx/2^iter),1); 64 | jj = I(idx,:); % row entry of C2 65 | found = isequal(lookfor,jj); 66 | iter=iter+1; 67 | else 68 | break 69 | end 70 | end 71 | end 72 | 73 | pos = []; 74 | if found, 75 | pos = idx; 76 | end -------------------------------------------------------------------------------- /Examples_gallery_1/CMV_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | %% 4 | sigma=0.001; % standard deviation for noisy experiment. NB: results will be slightly different each time due to randomness 5 | m=1; % order of kernel 6 | Nvec=[1:200,1000]; % vector of truncation sizes for convergence plot 7 | MU1=zeros(length(Nvec),1); % vector for measure with epsilon=0.5 8 | MU2=zeros(length(Nvec),1); % vector for measure with epsilon=0.1 9 | MU3=zeros(length(Nvec),1); % vector for measure with epsilon=0.01 10 | %% Compute approximations at theta=0.2 for different truncation sizes 11 | for j=1:length(Nvec) 12 | MU1(j)=CMV_meas(Nvec(j),m,0.5,0.2,sigma); 13 | MU2(j)=CMV_meas(Nvec(j),m,0.1,0.2,sigma); 14 | MU3(j)=CMV_meas(Nvec(j),m,0.01,0.2,sigma); 15 | end 16 | %% Plot the convergence (as relative errors) 17 | figure 18 | semilogy(Nvec,abs(MU1-MU1(end))/abs(MU1(end)),'linewidth',2) 19 | hold on 20 | semilogy(Nvec,abs(MU2-MU2(end))/abs(MU2(end)),'linewidth',2) 21 | semilogy(Nvec,abs(MU3-MU3(end))/abs(MU3(end)),'linewidth',2) 22 | ax = gca; ax.FontSize = 14; ylim([10^(-4),1]); xlim([0,200]); 23 | legend({'$\epsilon=0.5$','$\epsilon=0.1$','$\epsilon=0.01$'},'interpreter','latex','fontsize',14,'location','northeast') 24 | %% Compute approximations of measures over the interval [-pi,pi] 25 | theta=-pi:0.005:pi; 26 | mu = CMV_meas(10000,6,0.01,theta,0); % reference accurate solution 27 | mu1 = CMV_meas(200,1,0.1,theta,sigma); % smoothed measure with epsilon=0.1 28 | mu2 = CMV_meas(500,1,0.01,-pi:0.001:pi,sigma); % smoothed measure with epsilon=0.01 29 | %% Plot the results 30 | figure 31 | h2=plot(theta,mu1,'linewidth',2); 32 | xlim([-1,1]); ylim([0,2.5]); 33 | hold on 34 | plot(theta,mu1,'linewidth',2) 35 | plot(-pi:0.001:pi,mu2,'linewidth',2) 36 | plot(theta,mu,'k','linewidth',1) 37 | ax = gca; ax.FontSize = 14; 38 | legend({'$\epsilon=0.1$','$\epsilon=0.1$','$\epsilon=0.01$','$\rho_f$'},'interpreter','latex','fontsize',14,'location','northwest') 39 | delete(h2) 40 | 41 | function mu = CMV_meas(n,m,epsilon,theta,sigma) 42 | % For truncation size n, order of kernel m, smoothing parameter epsilon, 43 | % angles theta and noise level sigma, this approximates the spectral measure of the CMV example. 44 | 45 | % Set up the matrix. 46 | q=0.95; 47 | a_c = @(k) (-1).^k.*q.^((k+1)/2); 48 | rho_c = @(k) sqrt(1-abs(a_c(k)).^2); 49 | A=sparse(n+2,n+2); 50 | A(1:2,1:3)=[conj(a_c(0)) conj(a_c(1))*rho_c(0) rho_c(1)*rho_c(0); 51 | rho_c(0) -conj(a_c(1))*a_c(0) -rho_c(1)*a_c(0)]; 52 | for j=1:round((n+2)/2) 53 | A([2*j+1,2*j+2],[2*j:2*j+3])=[conj(a_c(2*j))*rho_c(2*j-1) -conj(a_c(2*j))*a_c(2*j-1) conj(a_c(2*j+1))*rho_c(2*j) rho_c(2*j)*rho_c(2*j+1); 54 | rho_c(2*j)*rho_c(2*j-1) -rho_c(2*j)*a_c(2*j-1) -conj(a_c(2*j+1))*a_c(2*j) -rho_c(2*j+1)*a_c(2*j)]; 55 | end 56 | A=A(1:n,1:n); 57 | if n<1000 58 | A=A+sigma*randn(n,n); 59 | end 60 | f=zeros(n,1); 61 | f(1)=1; 62 | % Call the routine for computing spectral measures. 63 | mu = IsomMeas(speye(n),A,speye(n),f,theta,epsilon,'order',m); 64 | end 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /main_routines/kernel_ResDMD.m: -------------------------------------------------------------------------------- 1 | function [G,K,L,PX,PY,PSI_x,PSI_y,PSI_y2] = kernel_ResDMD(Xa,Ya,varargin) 2 | % This code applies kernelized ResDMD. 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | % INPUTS 5 | % Xa and Ya: data matrices used in kernel_EDMD to form dictionary (columns 6 | % correspond to instances of the state variable) 7 | 8 | % OPTIONAL LABELLED INPUTS 9 | % N: size of computed dictionary, default is number of data points for kernel EDMD 10 | % type: kernel used, default is normalised Gaussian, "Laplacian" is for 11 | % nomralised Laplacian, and numeric value (e.g., 20) is for polynomial 12 | % kernel 13 | % cut_off: stability parameter for SVD, default is 0 14 | % Xb, Yb: additional data matrices used in ResDMD for test data 15 | % Y2: additional data matrix for stochastic version 16 | 17 | % OUTPUTS 18 | % G K L matrices for kernelResDMD 19 | % PSI matrices for ResDMD 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | 22 | % Collect the optional inputs 23 | p = inputParser; 24 | 25 | addParameter(p,'N',size(Xa,2),@(x) x==floor(x)) 26 | addParameter(p,'type',"Gaussian"); 27 | addParameter(p,'cut_off',0,@(x) x>=0) 28 | addParameter(p,'Xb',[],@isnumeric) 29 | addParameter(p,'Yb',[],@isnumeric) 30 | addParameter(p,'Y2',[],@isnumeric) 31 | 32 | p.CaseSensitive = false; 33 | parse(p,varargin{:}) 34 | 35 | % Apply kernel EDMD 36 | if isnumeric(p.Results.type) 37 | d = mean(vecnorm(Xa)); 38 | kernel_f = @(x,y) (y'*x/d^2+1).^(p.Results.type); 39 | elseif p.Results.type=="Linear" 40 | kernel_f = @(x,y) y'*x; 41 | elseif p.Results.type=="Laplacian" 42 | d = mean(vecnorm(Xa-mean(Xa,2))); 43 | if isa(Xa,'single') % safeguard against square root (but a little bit slower) 44 | kernel_f = @(x,y) exp(-pdist2(y',x')/d); 45 | else 46 | kernel_f = @(x,y) exp(-sqrt(-2*real(y'*x)+dot(x,x)+dot(y,y)')/d); 47 | end 48 | elseif p.Results.type=="Gaussian" 49 | d = mean(vecnorm(Xa-mean(Xa,2))); 50 | kernel_f = @(x,y) exp(-(-2*real(y'*x)+dot(x,x)+dot(y,y)')/d^2); 51 | elseif p.Results.type=="Lorentzian" 52 | d = mean(vecnorm(Xa-mean(Xa,2))); 53 | kernel_f = @(x,y) (1+(-2*real(y'*x)+dot(x,x)+dot(y,y)')/d^2).^(-1); 54 | end 55 | 56 | G1 = kernel_f(Xa,Xa); G1 = (G1+G1')/2; 57 | A1 = kernel_f(Ya,Xa)'; 58 | L1 = kernel_f(Ya,Ya); L1 = (L1+L1')/2; 59 | 60 | % Post processing 61 | 62 | [U,D0] = eig(G1+norm(G1)*p.Results.cut_off*eye(size(G1))); 63 | [~,I] = sort(diag(D0),'descend'); 64 | U = U(:,I); D0 = D0(I,I); 65 | N = min(p.Results.N,length(find(diag(D0)>0))); 66 | U = U(:,1:N); D0 = D0(1:N,1:N); 67 | UU = U*sqrt(diag(1./diag(D0))); 68 | 69 | % G = UU'*G1*UU; 70 | G = eye(N); 71 | K = UU'*A1*UU; 72 | L = UU'*L1*UU; 73 | 74 | PX = G1'*UU; 75 | PY = A1*UU; 76 | 77 | if ~isempty(p.Results.Xb) % test data case 78 | PSI_x = kernel_f(p.Results.Xb,Xa)'*UU; 79 | else 80 | PSI_x =[]; 81 | end 82 | 83 | if ~isempty(p.Results.Yb) % test data case 84 | PSI_y = kernel_f(p.Results.Yb,Xa)'*UU; 85 | else 86 | PSI_y =[]; 87 | end 88 | 89 | if ~isempty(p.Results.Y2) % stochastic case 90 | PSI_y2 = kernel_f(p.Results.Y2,Xa)'*UU; 91 | else 92 | PSI_y2 =[]; 93 | end 94 | 95 | 96 | end 97 | -------------------------------------------------------------------------------- /main_routines/KoopPseudoSpecQR.m: -------------------------------------------------------------------------------- 1 | function [RES,RES2,V2] = KoopPseudoSpecQR(PX,PY,W,z_pts,varargin) 2 | % This code computes pseudospectrum of K (currently written for dense matrices). 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | % INPUTS 5 | % PX: dictionary evaluated at snapshots 6 | % PY: dictionary evaluated at snapshots one time step later 7 | % W: vector of weights for the quadrature 8 | % z_pts: vector of complex points where we want to compute pseudospectra 9 | 10 | % OPTIONAL LABELLED INPUTS 11 | % parallel: parfor (on) or normal for (off) loop, default is "off" 12 | % z_pts2: vector of complex points where we want to compute 13 | % pseudoeigenfunctions 14 | % reg_param: regularisation parameter for G 15 | 16 | % OUTPUTS 17 | % RES: residual for shifts z_pts. 18 | % RES2: residual for pseudoeigenfunctions corresponding to shifts z_pts2. 19 | % RES2: pseudoeigenfunctions corresponding to shifts z_pts2. 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | 22 | % Collect the optional inputs 23 | p = inputParser; 24 | validPar = {'on','off'}; 25 | checkPar = @(x) any(validatestring(x,validPar)); 26 | 27 | addParameter(p,'Parallel','off',checkPar) 28 | addParameter(p,'z_pts2',[],@isnumeric) 29 | addParameter(p,'reg_param',10^(-14),@isnumeric) 30 | 31 | p.CaseSensitive = false; 32 | parse(p,varargin{:}) 33 | 34 | %% compute the pseudospectrum 35 | W = W(:); 36 | [Q,R] = qr(sqrt(W).*PX,"econ"); 37 | 38 | C1 = (sqrt(W).*PY)/R; 39 | L = C1'*C1; 40 | G = eye(size(PX,2)); 41 | A = Q'*C1; 42 | 43 | z_pts=z_pts(:); 44 | LL=length(z_pts); 45 | RES=zeros(LL,1); 46 | 47 | if LL>0 48 | warning('off','all') 49 | pf = parfor_progress(LL); 50 | pfcleanup = onCleanup(@() delete(pf)); 51 | if p.Results.Parallel=="on" 52 | parfor jj=1:LL 53 | warning('off','all') 54 | RES(jj)=sqrt(real(eigs(L-z_pts(jj)*A'-conj(z_pts(jj))*A+abs(z_pts(jj))^2*G,1,'smallestabs'))); 55 | parfor_progress(pf); 56 | end 57 | else 58 | for jj=1:LL 59 | RES(jj)=sqrt(real(eigs(L-z_pts(jj)*A'-conj(z_pts(jj))*A+abs(z_pts(jj))^2*G,1,'smallestabs'))); 60 | parfor_progress(pf); 61 | end 62 | end 63 | end 64 | 65 | RES2=[]; 66 | V2=[]; 67 | 68 | if ~isempty(p.Results.z_pts2) 69 | RES2=zeros(length(p.Results.z_pts2),1); 70 | V2=zeros(size(G,1),length(p.Results.z_pts2)); 71 | pf = parfor_progress(length(p.Results.z_pts2)); 72 | pfcleanup = onCleanup(@() delete(pf)); 73 | if p.Results.Parallel=="on" 74 | parfor jj=1:length(p.Results.z_pts2) 75 | warning('off','all') 76 | [V,D]=eigs( L-p.Results.z_pts2(jj)*A'-conj(p.Results.z_pts2(jj))*A+abs(p.Results.z_pts2(jj))^2*G,1,'smallestabs'); 77 | V2(:,jj)=V; RES2(jj)=sqrt(real(D(1,1))); 78 | parfor_progress(pf); 79 | end 80 | else 81 | for jj=1:length(p.Results.z_pts2) 82 | [V,D]=eigs( L-p.Results.z_pts2(jj)*A'-conj(p.Results.z_pts2(jj))*A+abs(p.Results.z_pts2(jj))^2*G,1,'smallestabs'); 83 | V2(:,jj)=V; RES2(jj)=sqrt(real(D(1,1))); 84 | parfor_progress(pf); 85 | end 86 | end 87 | V2=R\V2; 88 | end 89 | 90 | warning('on','all') 91 | 92 | 93 | 94 | end -------------------------------------------------------------------------------- /main_routines/KoopPseudoSpec.m: -------------------------------------------------------------------------------- 1 | function [RES,RES2,V2] = KoopPseudoSpec(G,A,L,z_pts,varargin) 2 | % This code computes pseudospectrum of K (currently written for dense matrices). 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | % INPUTS 5 | % G: Gram matrix 6 | % A: 1st Galerkin matrix i.e. 7 | % L: 2nd Galerkin matrix i.e. 8 | % z_pts: vector of complex points where we want to compute pseudospectra 9 | 10 | % OPTIONAL LABELLED INPUTS 11 | % parallel: parfor (on) or normal for (off) loop, default is "off" 12 | % z_pts2: vector of complex points where we want to compute 13 | % pseudoeigenfunctions 14 | % reg_param: regularisation parameter for G 15 | 16 | % OUTPUTS 17 | % RES: residual for shifts z_pts. 18 | % RES2: residual for pseudoeigenfunctions corresponding to shifts z_pts2. 19 | % RES2: pseudoeigenfunctions corresponding to shifts z_pts2. 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | 22 | % Collect the optional inputs 23 | p = inputParser; 24 | % addRequired(p,'G',@isnumeric); 25 | % addRequired(p,'A',@isnumeric); 26 | % addRequired(p,'L',@isnumeric); 27 | % addRequired(p,'z_pts',@isnumeric); 28 | 29 | validPar = {'on','off'}; 30 | checkPar = @(x) any(validatestring(x,validPar)); 31 | 32 | addParameter(p,'Parallel','off',checkPar) 33 | addParameter(p,'z_pts2',[],@isnumeric) 34 | addParameter(p,'reg_param',10^(-14),@isnumeric) 35 | 36 | p.CaseSensitive = false; 37 | parse(p,varargin{:}) 38 | 39 | %% compute the pseudospectrum 40 | G=(G+G')/2; L=(L+L')/2; % safeguards 41 | [VG,DG]=eig(G+norm(G)*(p.Results.reg_param)*eye(size(G))); 42 | DG(abs(DG)>0)=sqrt(1./abs(DG(abs(DG)>0))); 43 | SQ=VG*DG*(VG'); % needed to compute pseudospectra according to Gram matrix G 44 | 45 | z_pts=z_pts(:); 46 | LL=length(z_pts); 47 | RES=zeros(LL,1); 48 | 49 | if LL>0 50 | warning('off','all') 51 | pf = parfor_progress(LL); 52 | pfcleanup = onCleanup(@() delete(pf)); 53 | if p.Results.Parallel=="on" 54 | parfor jj=1:LL 55 | warning('off','all') 56 | RES(jj)=sqrt(real(eigs( SQ*((L)-z_pts(jj)*A'-conj(z_pts(jj))*A+(abs(z_pts(jj))^2)*G)*SQ,1,'smallestabs'))); 57 | parfor_progress(pf); 58 | end 59 | else 60 | for jj=1:LL 61 | RES(jj)=sqrt(real(eigs( SQ*((L)-z_pts(jj)*A'-conj(z_pts(jj))*A+(abs(z_pts(jj))^2)*G)*SQ,1,'smallestabs'))); 62 | parfor_progress(pf); 63 | end 64 | end 65 | end 66 | 67 | RES2=[]; 68 | V2=[]; 69 | 70 | if ~isempty(p.Results.z_pts2) 71 | RES2=zeros(length(p.Results.z_pts2),1); 72 | V2=zeros(size(G,1),length(p.Results.z_pts2)); 73 | pf = parfor_progress(length(p.Results.z_pts2)); 74 | pfcleanup = onCleanup(@() delete(pf)); 75 | if p.Results.Parallel=="on" 76 | parfor jj=1:length(p.Results.z_pts2) 77 | warning('off','all') 78 | [V,D]=eigs( SQ*((L)-p.Results.z_pts2(jj)*A'-conj(p.Results.z_pts2(jj))*A+(abs(p.Results.z_pts2(jj))^2)*G)*SQ,1,'smallestabs'); 79 | V2(:,jj)=V; RES2(jj)=sqrt(real(D(1,1))); 80 | parfor_progress(pf); 81 | end 82 | else 83 | for jj=1:length(p.Results.z_pts2) 84 | [V,D]=eigs( SQ*((L)-p.Results.z_pts2(jj)*A'-conj(p.Results.z_pts2(jj))*A+(abs(p.Results.z_pts2(jj))^2)*G)*SQ,1,'smallestabs'); 85 | V2(:,jj)=V; RES2(jj)=sqrt(real(D(1,1))); 86 | parfor_progress(pf); 87 | end 88 | end 89 | V2=SQ*V2; 90 | end 91 | 92 | warning('on','all') 93 | 94 | 95 | 96 | end 97 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/README.m: -------------------------------------------------------------------------------- 1 | %---------------------------------------------------------------------------------- 2 | % Sparse Grids Matlab Kit 3 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 4 | % See LICENSE.txt for license 5 | %---------------------------------------------------------------------------------- 6 | 7 | 8 | 9 | %--------------------------- 10 | % Contributors 11 | %--------------------------- 12 | % 13 | % 1) Lorenzo Tamellini 14 | % 2) Diane Guignard 15 | % 3) Fabio Nobile 16 | % 4) Giovanni Porta 17 | % 5) Bjorn Sprungk 18 | % 6) Francesco Tesei 19 | 20 | 21 | %--------------------------- 22 | % 1) QUICK START 23 | % 24 | % Take a look at: 25 | % 26 | % -- RELEASE_NOTE.m for a detailed list of diffrences with the previous version 27 | % 28 | % -- SPARSE_GRIDS_TUTORIAL.m in the folder docs-examples for a gradual introduction to the code 29 | % 30 | % -- the slides SPARSE_GRIDS_MATLAB_KIT_TALK.pdf in the folder docs-examples also discuss basic and some advanced features of the code 31 | 32 | 33 | 34 | %--------------------------- 35 | % 2) HOW TO INSTALL THE TOOLKIT 36 | % 37 | % add to path this folder (with subfolders). Alternatively, run 38 | % 39 | % addpath(genpath(pwd)) 40 | % 41 | % at the beginning of the Matlab session. Consider launching Matlab as 42 | % 43 | % matlab -r addpath(genpath(pwd)) 44 | % 45 | % under Unix, it will run add_to_path during the start-up 46 | 47 | 48 | 49 | 50 | %--------------------------- 51 | % 3) HOW TO USE THE TOOLKIT 52 | % 53 | % To create a sparse grids, use any of these two functions: 54 | % 55 | % -> smolyak_grid 56 | % -> smolyak_grid_multiidx_set 57 | % 58 | % A number of functionalities to operate on sparse grids are provided: 59 | % 60 | % -> adapt_sparse_grid 61 | % -> convert_to_modal 62 | % -> compute_sobol_indices_from_sparse_grid 63 | % -> derive_sparse_grid 64 | % -> export_sparse_grid_to_file 65 | % -> evaluate_on_sparse_grid 66 | % -> interpolate_on_sparse_grid 67 | % -> plot_sparse_grid 68 | % -> plot_sparse_grid_interpolant 69 | % -> quadrature_on_sparse_grid 70 | % -> reduce_sparse_grid 71 | % 72 | % type HELP FUNCTIONAME to access help for each function. 73 | % Documentation and examples can be found in docs-examples folder. 74 | 75 | 76 | 77 | 78 | %--------------------------- 79 | % 4) REPORT BUGS to tamellini@imati.cnr.it 80 | % 81 | % also, let us know your email address if you want us to warn you whenever we release a new version of the toolbox 82 | 83 | 84 | 85 | 86 | %--------------------------- 87 | % 5) PLEASE CITE US 88 | 89 | % Please cite our toolbox by mentioning the webpage containing the package (http://csqi.epfl.ch) 90 | % and adding the following reference to your work: 91 | % 92 | % @InCollection{back.nobile.eal:comparison, 93 | % author = {B\"ack, J. and Nobile, F. and Tamellini, L. and Tempone, R.}, 94 | % title = {Stochastic spectral {G}alerkin and collocation methods for {PDE}s with random coefficients: a numerical comparison}, 95 | % booktitle = {Spectral and High Order Methods for Partial Differential Equations}, 96 | % pages = {43--62}, 97 | % publisher = {Springer}, 98 | % year = 2011, 99 | % volume = 76, 100 | % series = {Lecture Notes in Computational Science and Engineering}, 101 | % editor = {Hesthaven, J.S. and Ronquist, E.M.}, 102 | % note = {Selected papers from the ICOSAHOM '09 conference, June 22-26, Trondheim, Norway} 103 | %} 104 | 105 | -------------------------------------------------------------------------------- /main_routines/parfor_progress.m: -------------------------------------------------------------------------------- 1 | function [percent, elapsed] = parfor_progress(N, varargin) 2 | 3 | narginchk(1, 2); 4 | 5 | if isnumeric(N) && N > 0 6 | if nargin > 1 7 | file = varargin{1}; 8 | else 9 | file = [tempname '_parfor.txt']; 10 | end 11 | fid = fopen(file, 'w'); 12 | if fid < 0, error('Could not open file for writing (perms?): %s', file); end 13 | % write N, start time (0.1s resolution), and iteration (0 for now) 14 | progress = [N floor(now*864000) 0]; 15 | fprintf(fid, '%d\n%d\n0\n', progress); 16 | fclose(fid); 17 | computeprogress(progress, false, true); 18 | percent = file; 19 | elapsed = 0; 20 | else 21 | file = N; 22 | if ~ischar(file) || ~exist(file, 'file') 23 | error('Not initialized. See HELP PARFOR_PROGRESS.'); 24 | end 25 | % update (read and write) in one go 26 | fid = fopen(file, 'r+'); 27 | progress = fscanf(fid, '%f'); % read the 3 values 28 | progress(3) = progress(3) + 1; % update iteration number 29 | fseek(fid, 0, 'bof'); 30 | fprintf(fid, '%d\n%d\n%d\n', round(progress)); % write back to file 31 | fclose(fid); 32 | [percent, elapsed] = computeprogress(progress, true, nargout == 0); 33 | end 34 | 35 | end 36 | 37 | %---------------- PRIVATE FUNCTIONS ----------------% 38 | 39 | function [percent, elapsed] = computeprogress (progress, update, show) 40 | elapsed = (now - progress(2)/864000) * 86400; % compute elapsed seconds 41 | percent = progress(3) / progress(1); 42 | if percent == 0 43 | duration = 0; 44 | remaining = 0; 45 | else 46 | duration = elapsed / percent; % TODO: improve this crude estimate, exp smoothing filter? 47 | remaining = duration - elapsed; 48 | end 49 | if show 50 | r = humantime(remaining); 51 | e = humantime(elapsed); 52 | t = humantime(duration); 53 | s = sprintf('%8.2f%%, %s (el), %s (rem), %s (tot)\n', ... 54 | percent * 100, e, r, t); 55 | if update, back = repmat(char(8),1,length(s)); else back = ''; end 56 | fprintf('%s%s', back, s); 57 | % % if not GUI mode then show one line per tick (useful for log files) 58 | % %screenSize = get(0,'ScreenSize'); 59 | % %if isequal(screenSize(3:4),[1 1]) 60 | % if ~usejava('jvm') || ~feature('ShowFigureWindows') 61 | % fprintf('%6.2f%%, %s (el), %s (rem), %s (tot)\n', ... 62 | % percent * 100, e, r, t); 63 | % else 64 | % width = 50; % width of progress bar 65 | % ticks = round(percent*width); 66 | % if update, back = repmat(char(8), 1, (width+8+length(r)+length(e)+4)); else back = ''; end 67 | % disp([back, sprintf('%3d%%',round(percent*100)), ' [', ... 68 | % repmat('=', 1, ticks), repmat(' ', 1, width - ticks), '] ' e ' / ' r]); 69 | % end 70 | end 71 | end 72 | 73 | function t = humantime (s) 74 | if s < 60, t = sprintf('%4.1fs', s); 75 | elseif s < 3600, t = sprintf('%4.1fm', s/60); 76 | elseif s < 86400, t = sprintf('%4.1fh', s/3600); 77 | elseif s < 604800, t = sprintf('%4.1fd', s/86400); % 86400 = 1 day = 24 * 3600 78 | elseif s < 2629800, t = sprintf('%4.1fw', s/604800); % 604800 = 1 week = 7 * 86400 79 | elseif s < 31557600, t = sprintf('%4.1fM', s/2629800); % 2629800 = 1 average month = 365.25/12 * 86400 80 | else t = sprintf('%4.1fy', s/31557600); % 31557600 = 1 average year = 365.25 * 86400 81 | end 82 | %t = sprintf('%3dh%02dm%02ds', floor(s/3600), mod(floor(s/60),60), mod(floor(s),60)); 83 | end 84 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/main/compute_sobol_indices_from_sparse_grid.m: -------------------------------------------------------------------------------- 1 | function [Sob_i,Tot_Sob_i,Mean,Var] = compute_sobol_indices_from_sparse_grid(S,Sr,nodal_values,domain,flags) 2 | 3 | 4 | % COMPUTE_SOBOL_INDICES_FROM_SPARSE_GRID computes the Sobol indices of a function in two steps: 5 | % 1) converts the sparse grid approximation of that function into its equivalent Polynomial Chaos Expansion (PCE); 6 | % this operation is performed by calling CONVERT_TO_MODAL 7 | % 2) performs algebraic manipulations of the PCE coefficients. 8 | % 9 | % [SOB_I,TOT_SOB_I,MEAN,VAR] = COMPUTE_SOBOL_INDICES_FROM_SPARSE_GRID(S,SR,NODAL_VALUES,DOMAIN,FLAGS) takes the 10 | % same inputs of CONVERT_TO_MODAL (see step 1 above) and returns the Sobol indices of the function F. 11 | % 12 | % In details: 13 | % 1) SOB_I is the principal Sobol index of the i-th variable, y_i; i.e., the fraction of variability of F that 14 | % can be ascribed to y_i only 15 | % 2) TOT_SOB_I is the total Sobol index of y_i; i.e., the fraction of variability of F that can be ascribed 16 | % to y_i either alone or combined with any other variable. 17 | % 18 | % As by-products, the function returns also: 19 | % 3) MEAN, the expected value of F, computed as the coefficient of the constant polynomial in the PCE 20 | % 4) VAR, the variance of F, computed as sum of squares of PCE coefficients minus MEAN^2 21 | % 22 | 23 | %---------------------------------------------------- 24 | % Sparse Grid Matlab Kit 25 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile, G. Porta 26 | % See LICENSE.txt for license 27 | %---------------------------------------------------- 28 | 29 | 30 | % first, call convert_to_modal 31 | [gpce_coeffs,idx_set] = convert_to_modal(S,Sr,nodal_values,domain,flags); 32 | 33 | N = size(Sr.knots,1); 34 | Nb_coeff = length(gpce_coeffs); 35 | 36 | % I create two matrices that I use to mark the coefficients that I need to sum to get the Sobol indices. 37 | % Both have one column for each variable and one row for each gPCE coefficient. 38 | % 39 | % In the first one, I mark with 1 the entry (i,j) if the i-th coefficient must be used to compute 40 | % the principal Sobol index of the j-th variable. 41 | % 42 | % In the second one, I do the same but for the Total Sobol index 43 | Fact_STi = zeros(Nb_coeff,N); 44 | Fact_Si = zeros(Nb_coeff,N); 45 | 46 | % loop on coefficients, for each one decide if I should mark it or not. Note that the first PCE coeff 47 | % gives the mean of the function and does not enter the Sobol index computation, so I can start from 48 | % the 2nd coefficient 49 | 50 | for r=2:Nb_coeff 51 | 52 | % check the multi-idx of this coefficient and find which entries are non-zero 53 | Ind=find(idx_set(r,:)>0); 54 | 55 | % the current coefficients is then to be used to compute the total sobol index 56 | % of all those variables 57 | Fact_STi(r,Ind) = 1; 58 | 59 | % moreover, if there is only one non-zero entry in the multi-idx, than this coefficient 60 | % must be marked for use in the computation of the principal sobol index 61 | if length(Ind)==1 62 | Fact_Si(r,Ind) = 1; 63 | end 64 | 65 | end 66 | 67 | % compute mean and variance from the PCE coefficients 68 | Mean = gpce_coeffs(1); 69 | gpce_squared = (gpce_coeffs.^2); 70 | Var=sum(gpce_squared)-Mean.^2; 71 | 72 | % now for each variable, sum all coefficients that have been marked as contributing to the Total Sobol index, 73 | % then normalize by variance 74 | VTi=(Fact_STi')*gpce_squared; 75 | Tot_Sob_i=VTi/Var; 76 | 77 | % repeat for the principal Sobol index 78 | Vi=(Fact_Si')*gpce_squared; 79 | Sob_i=Vi/Var; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Residual-Dynamic-Mode-Decomposition 2 | 3 | Computation of spectral properties of Koopman operators associated with discrete-time autonomous dynamical systems. Highlights include: verified computation of spectra with error control (and avoidance of spurious modes) and computation of spectral measures with explicit high-order convergence. 4 | 5 | This repository will grow as further papers are written and if you are interested in collaborating, please get in touch at: m.colbrook@damtp.cam.ac.uk 6 | 7 | The code includes **"main_routines"** that are used across the papers (see that subfolder for the additional README file). Each paper has a gallery of examples. 8 | 9 | To get started on a simple example, try the file **"Duffing_example.m"** 10 | 11 | For a pedagogical review of DMD methods, including code, see the repository: https://github.com/MColbrook/DMD-Multiverse 12 | 13 | For measure-preserving EDMD, see the repository: https://github.com/MColbrook/Measure-preserving-Extended-Dynamic-Mode-Decomposition 14 | 15 | Code for the papers: 16 | 17 | 1. M.J. Colbrook, A. Townsend, *"Rigorous data-driven computation of spectral properties of Koopman operators for dynamical systems"* in **"Examples_gallery_1"**. Paper can be found here: http://www.damtp.cam.ac.uk/user/mjc249/pdfs/RigorousKoopman.pdf
18 | Please cite using the following bibtex: @article{colbrook2024rigorous, 19 | title={Rigorous data-driven computation of spectral properties of Koopman operators for dynamical systems}, 20 | author={Colbrook, Matthew J and Townsend, Alex}, 21 | journal={Communications on Pure and Applied Mathematics}, 22 | volume={77}, 23 | number={1}, 24 | pages={221--283}, 25 | year={2024}, 26 | publisher={Wiley Online Library} 27 | } 28 | 29 | 2. M.J. Colbrook, L. Ayton, M. Szőke, *"Residual Dynamic Mode Decomposition: Robust and verified Koopmanism"* in **"Examples_gallery_2"**. Paper can be found here: https://www.cambridge.org/core/journals/journal-of-fluid-mechanics/article/residual-dynamic-mode-decomposition-robust-and-verified-koopmanism
30 | Please cite using the following bibtex: @article{colbrook2023residual, 31 | title={Residual dynamic mode decomposition: robust and verified {K}oopmanism}, 32 | author={Colbrook, Matthew J and Ayton, Lorna J and Sz{\H{o}}ke, M{\'a}t{\'e}}, 33 | journal={Journal of Fluid Mechanics}, 34 | volume={955}, 35 | pages={A21}, 36 | year={2023}, 37 | publisher={Cambridge University Press} 38 | } 39 | 40 | 3. M.J. Colbrook, Q. Li, R.V. Raut, A. Townsend, *"Beyond expectations: Residual Dynamic Mode Decomposition and 41 | Variance for Stochastic Dynamical Systems"* in **"Examples_gallery_3"**. Paper can be found here: [https://www.cambridge.org/core/journals/journal-of-fluid-mechanics/article/residual-dynamic-mode-decomposition-robust-and-verified-koopmanism](https://link.springer.com/article/10.1007/s11071-023-09135-w)
42 | Please cite using the following bibtex: @article{colbrook2024beyond, 43 | title={Beyond expectations: residual dynamic mode decomposition and variance for stochastic dynamical systems}, 44 | author={Colbrook, Matthew J and Li, Qin and Raut, Ryan V and Townsend, Alex}, 45 | journal={Nonlinear Dynamics}, 46 | volume={112}, 47 | number={3}, 48 | pages={2037--2061}, 49 | year={2024}, 50 | publisher={Springer} 51 | } 52 | 53 | 4. M.J. Colbrook, *"Another look at Residual Dynamic Mode Decomposition in the regime of fewer Snapshots than Dictionary Size"* in **"Examples_gallery_4"**. 54 | 55 | **Datasets** (needed for some of the examples) can be found here: https://www.dropbox.com/sh/xj59e5in7dfsobi/AAAfkxqa1x9WFSTgrvqoqqRqa?dl=0 56 | 57 | Some of the code for setting up the examples makes use of Chebfun, which can be found at https://www.chebfun.org/. 58 | -------------------------------------------------------------------------------- /Examples_gallery_1/Gauss_map_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | %% Compute quadrature errors 4 | test=quad_error(200,1); 5 | 6 | Mvec=unique(round(10.^(0.2:0.05:4))); % vector of sample sizes to track convergence 7 | Mvec(Mvec==200)=201; 8 | E=zeros(length(Mvec),4); 9 | ct=1; % counter for forloop 10 | for j=Mvec 11 | for k=0:3 12 | A=quad_error(j,k); 13 | E(ct,k+1)=max(abs(test(:)-A(:))); 14 | end 15 | ct=ct+1; 16 | end 17 | %% Plot quadrature errors 18 | close all 19 | figure 20 | loglog(Mvec,E(:,2),'linewidth',2) 21 | hold on 22 | loglog(Mvec,E(:,3),'linewidth',2) 23 | loglog(Mvec,E(:,4),'linewidth',2) 24 | loglog(Mvec,E(:,1),'linewidth',2) 25 | loglog(Mvec(50:end),20./Mvec(50:end),'k:','linewidth',2) 26 | loglog(Mvec(50:end),5000./Mvec(50:end).^2,'k:','linewidth',2) 27 | loglog(Mvec(50:end),10./Mvec(50:end).^0.5,'k:','linewidth',2) 28 | legend({'Gauss--Legendre','Trapezoidal','Riemann sum','Monte Carlo'},'interpreter','latex','fontsize',14,'location','southeast') 29 | ax = gca; ax.FontSize = 14; 30 | xlim([10,10000]) 31 | ylim([10^(-15),10]) 32 | 33 | %% Construct the three ResDMD matrices 34 | alpha=2; beta=-1-exp(-alpha); 35 | N=40; M=100; 36 | [X, W] = legpts(M,[-1,0]); 37 | DATA=exp(-alpha*X(:).^2)+beta; 38 | 39 | chebpoly(0); 40 | XH=zeros(M,N); YH=XH; 41 | for j=1:N 42 | f=legpoly(j-1,[-1,0]); 43 | XH(:,j)=f(X)/sqrt(2/(2*j-1))*sqrt(2); 44 | YH(:,j)=f(DATA)/sqrt(2/(2*j-1))*sqrt(2); 45 | end 46 | G=zeros(N); A=zeros(N); L=zeros(N); 47 | 48 | pf = parfor_progress(M); 49 | pfcleanup = onCleanup(@() delete(pf)); 50 | for j=1:M % 51 | G=G+(XH(j,:).*W(j))'*XH(j,:); 52 | A=A+(XH(j,:).*W(j))'*YH(j,:); 53 | L=L+(YH(j,:).*W(j))'*YH(j,:); 54 | parfor_progress(pf); 55 | end 56 | 57 | %% Pseudospectra plot 58 | x_pts=-1.5:0.05:1.5; y_pts=x_pts; 59 | z_pts=kron(x_pts,ones(length(y_pts),1))+1i*kron(ones(1,length(x_pts)),y_pts(:)); z_pts=z_pts(:); % spectral parameter where we compute spectra 60 | 61 | RES=KoopPseudoSpec(G,A,L,z_pts); % compute pseudospectra 62 | RES=reshape(RES,length(y_pts),length(x_pts)); 63 | 64 | E=eig(A); % EDMD eigenvalues 65 | 66 | %% 67 | figure 68 | v=([0.001,0.01,0.1,0.3]); 69 | contour(reshape(real(z_pts),length(y_pts),length(x_pts)),reshape(imag(z_pts),length(y_pts),length(x_pts)),real(RES*0.99),v,'k',... 70 | 'linewidth',1.5,'ShowText','on') 71 | set(gca,'YDir','normal') 72 | colormap bone 73 | ax=gca; ax.FontSize=14; 74 | axis equal tight; axis([x_pts(1),x_pts(end),y_pts(1),y_pts(end)]) 75 | 76 | hold on 77 | II1=find((abs(imag(E))<10^(-6))&(real(E)>-0.01)); 78 | C = setdiff( 1:length(E),II1 ); 79 | plot(real(E(C)),imag(E(C)),'.m') 80 | plot(real(E(II1)),imag(E(II1)),'xb','MarkerSize',7) 81 | 82 | function A = quad_error(M,type) 83 | % This function constructs the Koopman matrix for various quadrature 84 | % rules. type 1 is Legendre-quad, 2 is trapezoidal, 0 is random, other 85 | % is Riemann sum 86 | alpha=2; 87 | beta=-1-exp(-alpha); 88 | N=40; 89 | 90 | if type==1 91 | [X, W] = legpts(M,[-1,0]); 92 | elseif type==2 93 | X=linspace(-1,0,M); 94 | X=X(:); W=0*X+X(2)-X(1); 95 | W(1)=W(1)/2; 96 | W(end)=W(end)/2; 97 | else 98 | X=linspace(-1,0,M); 99 | X=X(:); W=0*X+X(2)-X(1); 100 | end 101 | if type==0 102 | X=-rand(M,1); 103 | X=X(:); W=0*X+1/M; 104 | end 105 | DATA=exp(-alpha*X(:).^2)+beta; 106 | 107 | XH=zeros(M,N); YH=XH; 108 | for j=1:N 109 | f=legpoly(j-1,[-1,0]); 110 | XH(:,j)=f(X)/sqrt(2/(2*j-1))*sqrt(2); 111 | YH(:,j)=f(DATA)/sqrt(2/(2*j-1))*sqrt(2); 112 | end 113 | A=zeros(N); 114 | for j=1:M 115 | A=A+(XH(j,:).*W(j))'*YH(j,:); 116 | end 117 | end -------------------------------------------------------------------------------- /Examples_gallery_1/filter_plots_and_shift_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | figure(10) 4 | h = plot(1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11); 5 | c = get(h,'Color'); close(10); clc 6 | 7 | %% Plot the filters 8 | phi_fejer = @(x) 1-abs(x); 9 | phi_cosine = @(x) (1+cos(pi*x))/2; 10 | phi_opt4 = @(x) 1- x.^4.*(-20*abs(x).^3 + 70*x.^2 - 84*abs(x) + 35); 11 | phi_sharp_cosine = @(x) phi_cosine(x).^4.*(35-84*phi_cosine(x)+70*phi_cosine(x).^2-20*phi_cosine(x).^3); 12 | phi_us = @(x) exp(-2./(1-abs(x)).*exp(-0.109550455106347./abs(x).^4)); 13 | 14 | xp=-1:0.01:1; 15 | 16 | figure 17 | plot(xp,phi_fejer(xp),'linewidth',2,'color',c{1}) 18 | hold on 19 | plot(xp,phi_cosine(xp),'linewidth',2,'color',c{2}) 20 | plot(xp,phi_opt4(xp),'linewidth',2,'color',c{3}) 21 | plot(xp,phi_sharp_cosine(xp),'linewidth',2,'color',c{4}) 22 | plot(xp,phi_us(xp),'linewidth',2,'color',c{5}) 23 | legend({'Fej\''er','Cosine (RC)','Vandeven 4th','Sharp. RC','Bump'},'interpreter','latex','fontsize',14,'location','south') 24 | ax = gca; ax.FontSize = 14; 25 | ylim([0,1]) 26 | 27 | %% real space plots 28 | N=10; 29 | thetap=-pi:0.001:pi; 30 | X=zeros(2*N+1,length(thetap)); 31 | for j=1:2*N+1 32 | X(j,:)=exp(1i*(j-N-1)*thetap)/(2*pi); 33 | end 34 | 35 | figure 36 | plot(thetap,phi_fejer((-N:N)/N)*X,'linewidth',2,'color',c{1}) 37 | hold on 38 | plot(thetap,phi_cosine((-N:N)/N)*X,'linewidth',2,'color',c{2}) 39 | plot(thetap,phi_opt4((-N:N)/N)*X,'linewidth',2,'color',c{3}) 40 | plot(thetap,(phi_sharp_cosine((-N:N)/N)*X),'linewidth',2,'color',c{4}) 41 | plot(thetap,(phi_us((-N:N)/N)*X),'linewidth',2,'color',c{5}) 42 | ax = gca; ax.FontSize = 14; 43 | xlim([-pi,pi]) 44 | legend({'Fej\''er','Cosine (RC)','Vandeven 4th','Sharp. RC','Bump'},'interpreter','latex','fontsize',14,'location','northeast') 45 | 46 | 47 | %% Shift example 48 | Nvec=10:1:1000; 49 | f = chebfun(@(t) (abs(t)<1),[-pi pi],'splitting','on'); 50 | rho = f*conj(f)/(2*pi); % analytic form of density of spectral measure 51 | 52 | phi = chebfun(@(t) cos(5*t)/(2+cos(t)),[-pi pi],'trig'); % test function for weak convergence 53 | 54 | MU_an = chebfun(@(t) abs(f(t)).^2/(2*pi),[-pi pi],'trig','splitting','on'); 55 | I=-0.023176565271898; 56 | 57 | Ew=zeros(length(Nvec),5); 58 | X=0; 59 | E=zeros(length(Nvec),5); 60 | 61 | for j=1:length(Nvec) 62 | MU=(sin(-Nvec(j):Nvec(j))/(2*pi^2))./(-Nvec(j):Nvec(j)); 63 | MU(Nvec(j)+1)=1/(2*pi^2); 64 | 65 | MU_trunc = MomentMeas(MU,'filt','fejer'); 66 | Ew(j,1)=abs(sum(MU_trunc*phi)-I)/abs(I); % error of integration against test function 67 | E(j,1)=abs(MU_trunc(X)-rho(X))/rho(X); % pointwise error of density 68 | 69 | MU_trunc = MomentMeas(MU,'filt','cosine'); 70 | Ew(j,2)=abs(sum(MU_trunc*phi)-I)/abs(I); 71 | E(j,2)=abs(MU_trunc(X)-rho(X))/rho(X); 72 | 73 | MU_trunc = MomentMeas(MU,'filt','vand'); 74 | Ew(j,3)=abs(sum(MU_trunc*phi)-I)/abs(I); 75 | E(j,3)=abs(MU_trunc(X)-rho(X))/rho(X); 76 | 77 | MU_trunc = MomentMeas(MU); 78 | Ew(j,5)=abs(sum(MU_trunc*phi)-I)/abs(I); 79 | E(j,5)=abs(MU_trunc(X)-rho(X))/rho(X); 80 | end 81 | 82 | 83 | %% Pointwise error 84 | figure 85 | loglog(Nvec,E(:,1),'linewidth',2,'color',c{1}) 86 | hold on 87 | loglog(Nvec,E(:,2),'linewidth',2,'color',c{2}) 88 | ct=3; 89 | for j=[3,5] 90 | loglog(Nvec,E(:,j),'linewidth',2,'color',c{ct}); 91 | ct=ct+1; 92 | end 93 | ax = gca; ax.FontSize = 14; 94 | ylim([10^(-15),1]) 95 | 96 | %% Weak convergence error 97 | figure 98 | loglog(Nvec,Ew(:,1),'linewidth',2,'color',c{1}) 99 | hold on 100 | loglog(Nvec,Ew(:,2),'linewidth',2,'color',c{2}) 101 | ct=3; 102 | for j=[3,5] 103 | loglog(Nvec,Ew(:,j),'linewidth',2,'color',c{ct}); 104 | ct=ct+1; 105 | end 106 | ax = gca; ax.FontSize = 14; 107 | ylim([10^(-15),1]) 108 | 109 | -------------------------------------------------------------------------------- /Examples_gallery_4/Cylinder_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | 4 | load('Vorticity_data.mat') 5 | %% 6 | r = 50; 7 | M = r; 8 | ind = (1:M); 9 | X = VORT(:,ind); 10 | Y = VORT(:,ind+1); 11 | 12 | % Kernel ResDMD 13 | [G,K,L,PX,PY] = kernel_ResDMD(X,Y,'N',r,'type',"Laplacian"); 14 | 15 | [W,LAM,W2] = eig(K,'vector'); 16 | R = abs(sqrt(real(diag(W2'*L*W2)./diag(W2'*W2)-abs(LAM).^2))); 17 | 18 | figure 19 | scatter(real(LAM),imag(LAM),300,R,'.','LineWidth',1); 20 | hold on 21 | % scatter(real(LAM),imag(LAM),250,R,'.'); 22 | plot(cos(0:0.01:2*pi),sin(0:0.01:2*pi),'-k') 23 | axis equal 24 | axis([-1.15,1.15,-1.15,1.15]) 25 | clim([0,1]) 26 | load('cmap.mat') 27 | colormap(cmap2); colorbar 28 | xlabel('$\mathrm{Re}(\lambda)$','interpreter','latex','fontsize',18) 29 | ylabel('$\mathrm{Im}(\lambda)$','interpreter','latex','fontsize',18) 30 | title(sprintf('Residuals ($M=%d$)',M),'interpreter','latex','fontsize',18) 31 | ax=gca; ax.FontSize=18; 32 | 33 | exportgraphics(gcf,sprintf('cylinder_res_M%d.pdf',M),'ContentType','vector','BackgroundColor','none') 34 | 35 | figure 36 | loglog([0.001,1],[0.001,1],'k','linewidth',2) 37 | hold on 38 | loglog(sqrt(abs(abs(LAM).^2-1)),R,'b.','markersize',20) 39 | xlabel('$\sqrt{|1-|\lambda|^2|}$','interpreter','latex','fontsize',18) 40 | ylabel('residual','interpreter','latex','fontsize',18) 41 | title(sprintf('Residuals ($M=%d$)',M),'interpreter','latex','fontsize',18) 42 | ax=gca; ax.FontSize=18; 43 | 44 | exportgraphics(gcf,sprintf('cylinder_res2_M%d.pdf',M),'ContentType','vector','BackgroundColor','none') 45 | 46 | %% 47 | 48 | 49 | x_pts=-1.2:0.02:1.2; y_pts=-0.02:0.02:1.2; 50 | z_pts=kron(x_pts,ones(length(y_pts),1))+1i*kron(ones(1,length(x_pts)),y_pts(:)); z_pts=z_pts(:); % complex points where we compute pseudospectra 51 | RES0 = KoopPseudoSpecQR(PX,PY,1/M,z_pts); 52 | RES0=reshape(RES0,length(y_pts),length(x_pts)); 53 | 54 | RES = KoopPseudoSpec(double(G),double(K),double(L),z_pts,'Parallel','off'); % compute pseudospectra 55 | RES=reshape(RES,length(y_pts),length(x_pts)); 56 | 57 | %% Plot pseudospectra 58 | 59 | figure 60 | hold on 61 | v=(10.^(-10:0.2:0)); 62 | contourf(reshape(real(z_pts),length(y_pts),length(x_pts)),reshape(imag(z_pts),length(y_pts),length(x_pts)),log10(real(RES0)),log10(v)); 63 | hold on 64 | contourf(reshape(real(z_pts),length(y_pts),length(x_pts)),-reshape(imag(z_pts),length(y_pts),length(x_pts)),log10(real(RES0)),log10(v)); 65 | cbh=colorbar; 66 | cbh.Ticks=log10(10.^(-4:1:0)); 67 | cbh.TickLabels=10.^(-4:1:0); 68 | clim([-4,0]); 69 | reset(gcf) 70 | set(gca,'YDir','normal') 71 | colormap gray 72 | axis equal; 73 | 74 | title(sprintf('Naive Residual ($M=%d$)',M),'interpreter','latex','fontsize',18) 75 | xlabel('$\mathrm{Re}(z)$','interpreter','latex','fontsize',18) 76 | ylabel('$\mathrm{Im}(z)$','interpreter','latex','fontsize',18) 77 | 78 | ax=gca; ax.FontSize=18; axis equal tight; axis([x_pts(1),x_pts(end),-y_pts(end),y_pts(end)]) 79 | hold on 80 | plot(real(LAM),imag(LAM),'.r','markersize',12); 81 | box on 82 | exportgraphics(gcf,sprintf('cylinder_pseudoW_M%d.pdf',M),'ContentType','vector','BackgroundColor','none') 83 | 84 | 85 | 86 | 87 | figure 88 | hold on 89 | v=(10.^(-10:0.2:0)); 90 | contourf(reshape(real(z_pts),length(y_pts),length(x_pts)),reshape(imag(z_pts),length(y_pts),length(x_pts)),log10(real(RES)),log10(v)); 91 | hold on 92 | contourf(reshape(real(z_pts),length(y_pts),length(x_pts)),-reshape(imag(z_pts),length(y_pts),length(x_pts)),log10(real(RES)),log10(v)); 93 | cbh=colorbar; 94 | cbh.Ticks=log10(10.^(-4:1:0)); 95 | cbh.TickLabels=10.^(-4:1:0); 96 | clim([-4,0]); 97 | reset(gcf) 98 | set(gca,'YDir','normal') 99 | colormap gray 100 | axis equal; 101 | 102 | title(sprintf('Pseudospectrum ($M=%d$)',M),'interpreter','latex','fontsize',18) 103 | xlabel('$\mathrm{Re}(z)$','interpreter','latex','fontsize',18) 104 | ylabel('$\mathrm{Im}(z)$','interpreter','latex','fontsize',18) 105 | 106 | ax=gca; ax.FontSize=18; axis equal tight; axis([x_pts(1),x_pts(end),-y_pts(end),y_pts(end)]) 107 | hold on 108 | plot(real(LAM),imag(LAM),'.r','markersize',12); 109 | box on 110 | exportgraphics(gcf,sprintf('cylinder_pseudo_M%d.pdf',M),'ContentType','vector','BackgroundColor','none') 111 | 112 | 113 | -------------------------------------------------------------------------------- /main_routines/IsomMeas.m: -------------------------------------------------------------------------------- 1 | function [nu] = IsomMeas(G,A,L,f,THETA,epsilon,varargin) 2 | % This code computes smoothed spectral measures of an isometry using the 3 | % ResDMD matrices. 4 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 | % INPUTS 6 | % G: Gram matrix, i.e., 7 | % A: 1st Galerkin matrix, i.e., 8 | % L: 2nd Galerkin matrix, i.e., 9 | % f: vector in \mathbb{C}^N (discretization of the observable) 10 | % THETA: vector of points in periodic interval [-pi,pi] where we compute smoothed measures 11 | % epsilon: the smoothing parameter 12 | 13 | % OPTIONAL LABELLED INPUTS 14 | % parallel: parfor (on) or normal for (off) loop, default is "off" 15 | % order: order of kernel used, default is 2 16 | 17 | % OUTPUTS 18 | % nu: smoothed measure at points THETA 19 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20 | 21 | % Collect the optional inputs 22 | p = inputParser; 23 | addRequired(p,'G',@isnumeric); 24 | addRequired(p,'A',@isnumeric); 25 | addRequired(p,'L',@isnumeric); 26 | addRequired(p,'f',@isnumeric); 27 | addRequired(p,'THETA',@isnumeric); 28 | addRequired(p,'epsilon',@isnumeric); 29 | 30 | validLQ = {'on','off'}; 31 | checkLQ = @(x) any(validatestring(x,validLQ)); 32 | validPar = {'on','off'}; 33 | checkPar = @(x) any(validatestring(x,validPar)); 34 | 35 | addParameter(p,'least_squares','off',checkLQ) 36 | addParameter(p,'Parallel','off',checkPar) 37 | addParameter(p,'Order',2,@(x) x==floor(x)) 38 | 39 | p.CaseSensitive = false; 40 | parse(p,G,A,L,f,THETA,epsilon,varargin{:}) 41 | 42 | G=(G+G')/2; 43 | 44 | %% compute the poles and residues 45 | delta=(2*(1:p.Results.Order)/(p.Results.Order+1)-1)*1i+1; 46 | [c,d] = unitary_kern(delta,epsilon); 47 | 48 | %% perform computation 49 | if issparse(A)&&issparse(G) 50 | v1=G*f; 51 | v2=v1; 52 | v3=(A')*f; 53 | % perform computation 54 | nu=0*THETA; 55 | pf = parfor_progress(length(THETA)); 56 | pfcleanup = onCleanup(@() delete(pf)); 57 | if p.Results.Parallel=="off" 58 | for k=1:length(THETA) 59 | for j=1:p.Results.Order 60 | lambda=exp(1i*THETA(k))*(1+epsilon*delta(j)); 61 | Ij=(A-lambda*G)\v1; 62 | nu(k)=nu(k)-real(1/(2*pi)*(c(j)*conj(lambda)*(Ij'*v2)+d(j)*(v3'*Ij))); 63 | end 64 | parfor_progress(pf); 65 | end 66 | else 67 | parfor k=1:length(THETA) 68 | for j=1:p.Results.Order 69 | lambda=exp(1i*THETA(k))*(1+epsilon*delta(j)); 70 | Ij=(A-lambda*G)\v1; 71 | nu(k)=nu(k)-real(1/(2*pi)*(c(j)*conj(lambda)*(Ij'*v2)+d(j)*(v3'*Ij))); 72 | end 73 | parfor_progress(pf); 74 | end 75 | end 76 | else 77 | if norm(full(G)-eye(size(G)),'fro')<10^(-14)*norm(full(G),'fro') 78 | [Q,S]=schur(A); 79 | Z=Q; 80 | T=speye(size(A)); 81 | else 82 | [S,T,Q,Z]=qz(A,G); 83 | Q=Q'; 84 | end 85 | v1=T*(Z')*f; 86 | v2=(T')*(Q')*f; 87 | v3=(S')*(Q')*f; 88 | % perform computation 89 | nu=0*THETA; 90 | pf = parfor_progress(length(THETA)); 91 | pfcleanup = onCleanup(@() delete(pf)); 92 | if p.Results.Parallel=="off" 93 | for k=1:length(THETA) 94 | for j=1:p.Results.Order 95 | lambda=exp(1i*THETA(k))*(1+epsilon*delta(j)); 96 | Ij=(S-lambda*T)\v1; 97 | nu(k)=nu(k)-real(1/(2*pi)*(c(j)*conj(lambda)*(Ij'*v2)+d(j)*(v3'*Ij))); 98 | end 99 | parfor_progress(pf); 100 | end 101 | else 102 | parfor k=1:length(THETA) 103 | for j=1:p.Results.Order 104 | lambda=exp(1i*THETA(k))*(1+epsilon*delta(j)); 105 | Ij=(S-lambda*T)\v1; 106 | nu(k)=nu(k)-real(1/(2*pi)*(c(j)*conj(lambda)*(Ij'*v2)+d(j)*(v3'*Ij))); 107 | end 108 | parfor_progress(pf); 109 | end 110 | end 111 | end 112 | 113 | end 114 | 115 | function [c,d] = unitary_kern(Z,epsilon) 116 | m=length(Z); 117 | sigma=-conj(Z(:))./(1+epsilon*conj(Z(:))); 118 | V1=zeros(m); V2=V1; 119 | for i=1:m 120 | V1(:,i)=(sigma(:)).^(i-1); 121 | V2(:,i)=(Z(:)).^(i-1); 122 | end 123 | 124 | rhs=eye(m,1); 125 | c=transpose(V1)\rhs; 126 | d=transpose(V2)\rhs; 127 | end 128 | -------------------------------------------------------------------------------- /Examples_gallery_1/pendulum_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | 4 | %%%%% UNCOMMENT THE FOLLOWING TO PERFORM COMPUTATIONS TO SIMULATE DATA %%%%% 5 | % %% 6 | % delta_t=0.5; 7 | % ODEFUN=@(t,y) [y(2);-sin(y(1))]; 8 | % options = odeset('RelTol',1e-16,'AbsTol',1e-16); 9 | % 10 | % %% set up the computational grid for integration 11 | % M1=300; 12 | % M2=M1; 13 | % N1=50; N2=100; 14 | % %% 15 | % 16 | % 17 | % L=15; % cut off 18 | % x1=linspace(-pi,pi,M1+1); 19 | % x1=x1+(x1(2)-x1(1))/2; 20 | % x1=x1(1:end-1); 21 | % x2=linspace(-L,L,M2); 22 | % [X1,X2] = meshgrid(x1(1:end-1),x2); 23 | % X1=X1(:); X2=X2(:); 24 | % M=length(X1); % number of data points 25 | % 26 | % DATA=zeros(M,2); 27 | % 28 | % pf = parfor_progress(M); 29 | % pfcleanup = onCleanup(@() delete(pf)); 30 | % parfor j=1:M 31 | % Y0=[X1(j);X2(j)]; 32 | % [~,Y]=ode45(ODEFUN,[0.000001 delta_t 2*delta_t],Y0,options); 33 | % DATA(j,:)=[Y(2,1),Y(2,2)]; 34 | % parfor_progress(pf); 35 | % end 36 | % W=zeros(M,1)+(x1(2)-x1(1))*(x2(2)-x2(1)); 37 | % 38 | % %% construct the relevant matrices using the bases 39 | % A=zeros((2*N1+1)*N2); 40 | % 41 | % %compute Hermite function values 42 | % XH=zeros(M,N2); 43 | % XH(:,1)=exp(-0.5*X2(:).^2)/(pi^(1/4)); 44 | % XH(:,2)=exp(-0.5*X2(:).^2)/(pi^(1/4))*sqrt(2).*X2(:); 45 | % for j=3:N2 46 | % XH(:,j)=sqrt(2)/sqrt(j-1)*XH(:,j-1).*X2(:)-sqrt(j-2)/sqrt(j-1)*XH(:,j-2); 47 | % end 48 | % 49 | % YH=zeros(M,N2); 50 | % YH(:,1)=exp(-0.5*DATA(:,2).^2)/(pi^(1/4)); 51 | % YH(:,2)=exp(-0.5*DATA(:,2).^2)/(pi^(1/4))*sqrt(2).*DATA(:,2); 52 | % for j=3:N2 53 | % YH(:,j)=sqrt(2)/sqrt(j-1)*YH(:,j-1).*DATA(:,2)-sqrt(j-2)/sqrt(j-1)*YH(:,j-2); 54 | % end 55 | % %% 56 | % 57 | % whos A 58 | % pf = parfor_progress(M); 59 | % pfcleanup = onCleanup(@() delete(pf)); 60 | % parfor (j=1:M,15) 61 | % X=kron(exp(1i*(-N1:N1)*X1(j))/sqrt(2*pi),XH(j,:)); 62 | % Y=kron(exp(1i*(-N1:N1)*DATA(j,1))/sqrt(2*pi),YH(j,:)); 63 | % A=A+(X')*Y;% kron(X',Y) - slightly slower; 64 | % parfor_progress(pf); 65 | % end 66 | % A=A*W(1); 67 | 68 | %% Load data from above computation - file available from the dropbox link 69 | clear 70 | load('pendulum_data.mat','A','N1','N2') 71 | 72 | Id1=max(kron(abs(-N1:N1),ones(1,N2)),1); Id2=kron(ones(1,2*N1+1),1:N2); 73 | N_trun=N2; 74 | Id=find((abs(Id1).*abs(Id2) 63 | 64 | 65 | % add missing to missing set 66 | if isempty(missing_set) 67 | missing_set=missing; 68 | else 69 | missing_set=[missing_set; setdiff(missing,missing_set,'rows')]; %#ok 70 | end 71 | 72 | % add missing to the queue 73 | the_queue=[the_queue; setdiff(missing,the_queue,'rows')]; %#ok 74 | 75 | 76 | % version with unique, does not work on R2011b 77 | %---------------------------------- 78 | 79 | % add missing to completed_set 80 | % completed_set=unique([completed_set; missing],'rows','stable'); 81 | 82 | % add missing to missing set 83 | % missing_set=unique([missing_set; missing],'rows','stable'); 84 | 85 | % add missing to the queue 86 | % the_queue=unique([the_queue; missing],'rows','stable'); 87 | 88 | end 89 | 90 | % delete current i from the queue 91 | the_queue(1,:)=[]; 92 | end 93 | 94 | 95 | % if requested, sort in ascending lexicographic order 96 | if nargin==3 97 | 98 | if strcmp(sort_option,'sorting') 99 | missing_set=sortrows(missing_set); 100 | completed_set=sortrows(completed_set); 101 | else 102 | error('SparseGKit:WrongInput','unknown sorting option') 103 | end 104 | end 105 | 106 | 107 | 108 | 109 | function S = needed_set(idx) 110 | 111 | % S = needed_set(idx) 112 | % 113 | % computes the indices of the form idx-e_j where e_j is the j-th N-dimensional unit vector, 114 | % and store them as rows of S 115 | 116 | N=length(idx); 117 | 118 | % I can build the set quickly with matrices operation: [idx; idx; ... ; idx] - eye(N) 119 | 120 | S=ones(N,1)*idx - eye(N); 121 | 122 | % if idx has 1 inside, like [2 1 1], [3 1 2] etc, care has to be taken: the minimum value for indices is 123 | % 1, so I don't have to check for [2 0 1], [2 1 0] etc to be in the set. I handle this deleting all rows 124 | % that contain 0. Note that 0 can be only in the main diagonal of needed_set 125 | 126 | D=diag(S); 127 | S(D==0,:)=[]; -------------------------------------------------------------------------------- /Examples_gallery_1/double_pendulum_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | 4 | %%%%% UNCOMMENT THE FOLLOWING TO PERFORM COMPUTATIONS TO SIMULATE DATA %%%%% 5 | % %% y is [theta1,theta2,p1,p2] , ml^2=6, g/l=1/3 6 | % delta_t=1; 7 | % ODEFUN=@(t,y) [(2*y(3)-3*y(4)*cos(y(1)-y(2)))/(16-9*cos(y(1)-y(2))^2); 8 | % (8*y(4)-3*y(3)*cos(y(1)-y(2)))/(16-9*cos(y(1)-y(2))^2); 9 | % -3*((2*y(3)-3*y(4)*cos(y(1)-y(2)))/(16-9*cos(y(1)-y(2))^2)*(8*y(4)-3*y(3)*cos(y(1)-y(2)))/(16-9*cos(y(1)-y(2))^2)*sin(y(1)-y(2))+sin(y(1))); 10 | % -3*(-(2*y(3)-3*y(4)*cos(y(1)-y(2)))/(16-9*cos(y(1)-y(2))^2)*(8*y(4)-3*y(3)*cos(y(1)-y(2)))/(16-9*cos(y(1)-y(2))^2)*sin(y(1)-y(2))+sin(y(2))/3)]; 11 | % options = odeset('RelTol',1e-13,'AbsTol',1e-14); 12 | % 13 | % %% Set up the computational grid for integration 14 | % M1=50; M2=25; 15 | % L=5; % cut off 16 | % x1=linspace(-pi,pi,M1+1); 17 | % x1=x1+(x1(2)-x1(1))/2; 18 | % 19 | % theta_grid=x1(1:end-1); 20 | % p_grid=linspace(-L,L,M2); 21 | % 22 | % X1=kron(theta_grid(:),kron(ones(M1,1),kron(ones(M2,1),ones(M2,1)))); 23 | % X2=kron(ones(M1,1),kron(theta_grid(:),kron(ones(M2,1),ones(M2,1)))); 24 | % X3=kron(ones(M1,1),kron(ones(M1,1),kron(p_grid(:),ones(M2,1)))); 25 | % X4=kron(ones(M1,1),kron(ones(M1,1),kron(ones(M2,1),p_grid(:)))); 26 | % 27 | % M=length(X1); % number of data points 28 | % 29 | % DATA=zeros(M,4); 30 | % 31 | % pf = parfor_progress(M); 32 | % pfcleanup = onCleanup(@() delete(pf)); 33 | % parfor j=1:M 34 | % Y0=[X1(j);X2(j);X3(j);X4(j)]; 35 | % [~,Y]=ode45(ODEFUN,[0.000001 delta_t 2*delta_t],Y0,options); 36 | % DATA(j,:)=Y(2,:); 37 | % parfor_progress(pf); 38 | % end 39 | % W=zeros(M,1)+(theta_grid(2)-theta_grid(1))^2*(p_grid(2)-p_grid(1))^2; 40 | % 41 | % %% Construct the relevant matrices using the bases 42 | % N1=30; N2=30; 43 | % 44 | % % Compute Hermite function values 45 | % XH1=zeros(M,N2); 46 | % XH1(:,1)=exp(-0.5*X3(:).^2)/(pi^(1/4)); 47 | % XH1(:,2)=exp(-0.5*X3(:).^2)/(pi^(1/4))*sqrt(2).*X3(:); 48 | % for j=3:N2 49 | % XH1(:,j)=sqrt(2)/sqrt(j-1)*XH1(:,j-1).*X3(:)-sqrt(j-2)/sqrt(j-1)*XH1(:,j-2); 50 | % end 51 | % XH2=zeros(M,N2); 52 | % XH2(:,1)=exp(-0.5*X4(:).^2)/(pi^(1/4)); 53 | % XH2(:,2)=exp(-0.5*X4(:).^2)/(pi^(1/4))*sqrt(2).*X4(:); 54 | % for j=3:N2 55 | % XH2(:,j)=sqrt(2)/sqrt(j-1)*XH2(:,j-1).*X4(:)-sqrt(j-2)/sqrt(j-1)*XH2(:,j-2); 56 | % end 57 | % 58 | % YH1=zeros(M,N2); 59 | % YH1(:,1)=exp(-0.5*DATA(:,3).^2)/(pi^(1/4)); 60 | % YH1(:,2)=exp(-0.5*DATA(:,3).^2)/(pi^(1/4))*sqrt(2).*DATA(:,3); 61 | % for j=3:N2 62 | % YH1(:,j)=sqrt(2)/sqrt(j-1)*YH1(:,j-1).*DATA(:,3)-sqrt(j-2)/sqrt(j-1)*YH1(:,j-2); 63 | % end 64 | % YH2=zeros(M,N2); 65 | % YH2(:,1)=exp(-0.5*DATA(:,4).^2)/(pi^(1/4)); 66 | % YH2(:,2)=exp(-0.5*DATA(:,4).^2)/(pi^(1/4))*sqrt(2).*DATA(:,4); 67 | % for j=3:N2 68 | % YH2(:,j)=sqrt(2)/sqrt(j-1)*YH2(:,j-1).*DATA(:,4)-sqrt(j-2)/sqrt(j-1)*YH2(:,j-2); 69 | % end 70 | % 71 | % %% 72 | % I1=max(abs(-N1:N1),1); 73 | % I2=(1:N2); 74 | % IDX=kron(I1,kron(I1,kron(I2,I2))); 75 | % I=find(IDX<25); 76 | % A=zeros(length(I)); 77 | % whos A 78 | % 79 | % pf = parfor_progress(M); 80 | % pfcleanup = onCleanup(@() delete(pf)); 81 | % parfor (j=1:M,40) 82 | % X=kron(exp(1i*(-N1:N1)*X1(j))/sqrt(2*pi),kron(exp(1i*(-N1:N1)*X2(j))/sqrt(2*pi),kron(XH1(j,:),XH2(j,:)))); 83 | % Y=kron(exp(1i*(-N1:N1)*DATA(j,1))/sqrt(2*pi),kron(exp(1i*(-N1:N1)*DATA(j,2))/sqrt(2*pi),kron(YH1(j,:),YH2(j,:)))); 84 | % X=X(I); Y=Y(I); 85 | % A=A+(X')*Y; 86 | % parfor_progress(pf); 87 | % end 88 | % A=A*W(1); 89 | 90 | %% Load data from above computation - file available from the dropbox link 91 | load('double_pendulum_data.mat') 92 | I1=max(abs(-N1:N1),1); I2=(1:N2); IDX=kron(I1,kron(I1,kron(I2,I2))); I=find(IDX<25); IDX=IDX(I); I2=find(IDX0.002),0]; theta=sort(theta); 98 | epsilon=0.1; % smoothing parameter 99 | 100 | c1=zeros(1,2*N1+1); c2=c1; c3=zeros(1,N2); c4=c3; 101 | CASE=1; % the observables in the paper 102 | if CASE==1 103 | c1(N1+2)=1; c2(N1+1)=1; c3(1)=1; c4(1)=1; 104 | elseif CASE ==2 105 | c1(N1+1)=1; c2(N1+2)=1; c3(1)=1; c4(1)=1; 106 | elseif CASE==3 107 | c1(N1+1)=1; c2(N1+1)=1; c3(2)=1; c4(1)=1; 108 | else 109 | c1(N1+1)=1; c2(N1+1)=1; c3(1)=1; c4(2)=1; 110 | end 111 | f=transpose(kron(c1,kron(c2,kron(c3,c4)))); f=f(I); f=f(I2); f=f/norm(f); % coefficient vector for the test functions 112 | 113 | nu1 = IsomMeas(eye(size(A)),A,eye(size(A)),f,theta,epsilon,'parallel','on','order',1); 114 | nu6 = IsomMeas(eye(size(A)),A,eye(size(A)),f,theta,epsilon,'parallel','on','order',6); 115 | %% Plot the results 116 | figure 117 | plot(theta,nu1,'linewidth',2) 118 | hold on 119 | plot(theta,nu6,'linewidth',2) 120 | xlim([-pi,pi]); ax = gca; ax.FontSize=14; 121 | legend({'$m=1$','$m=6$'},'interpreter','latex','fontsize',20,'location','northeast') 122 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/compute_modal_tensor.m: -------------------------------------------------------------------------------- 1 | function U = compute_modal_tensor(S,S_values,domain,flags) 2 | 3 | % COMPUTE_MODAL_TENSOR given a tensor grid and the values on it, re-express the interpolant 4 | % as a modal expansion. 5 | % 6 | % U=COMPUTE_MODAL_TENSOR(S,S_VALUES,DOMAIN,'legendre') considers the tensor grid S on the 7 | % hyper-rectangle DOMAIN with associated point evaluations S_VALUES and converts the 8 | % resulting lagrangian multivariate interpolant to a sum of Legendre polynomials. 9 | % DOMAIN is a 2xN matrix = [a1, a2, a3, ...; b1, b2, b3, ...] 10 | % defining the hyper-rectangluar domain of the sparse grid: (a1,b1) x (a2,b2) x ... 11 | % U is a struct with fields U.size (the number of Legendre polynomials needed), 12 | % U.multi_indices (one multi-index per Legendre polynomial), U.coeffs 13 | % 14 | % U=COMPUTE_MODAL_TENSOR(S,S_values,domain,'chebyshev') works as the previous call, using 15 | % Chebyshev polynomials 16 | % 17 | % U=COMPUTE_MODAL_TENSOR(S,S_values,domain,'hermite') works as the previous call, using 18 | % Hermite polynomials. Here DOMAIN is a 2XN matrix = [mu1, mu2, mu3, ...; sigma1, sigma2, sigma3,...] 19 | % such that the first variable has normal distribution with mean mu1 and std sigma1 20 | % and so on. 21 | % 22 | % U=COMPUTE_MODAL_TENSOR(S,S_values,domain,{,,,...}) works as the previous call, using 23 | % polynomials of type in direction n. Here DOMAIN is a 2XN matrix where each column gives 24 | % the parameters of the n-th family of polynomials (a,b for legendre, mu,sig for hermite...) 25 | 26 | 27 | %---------------------------------------------------- 28 | % Sparse Grid Matlab Kit 29 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 30 | % See LICENSE.txt for license 31 | %---------------------------------------------------- 32 | 33 | 34 | 35 | if any(~ismember(flags,{'legendre','chebyshev','hermite'})); 36 | error('SparseGKit:WrongInput',['Input argument FLAG unrecognized. '... 37 | ' Please note that COMPUTE_MODAL_TENSOR does not accept INTERVAL_MAP '... 38 | 'input argument any longer. '... 39 | 'Type help convert_to_modal for help. '... 40 | 'This error message will not be shown in future releases of SPARSE-GRID-MATLAB-KIT']); 41 | end 42 | 43 | 44 | % I will need the knots in each dimension separately. 45 | % As the number of knots is different in each direction, I use a cell array 46 | 47 | nb_dim=size(S.knots,1); 48 | 49 | % knots_per_dim=cell(1,nb_dim); 50 | % for dim=1:nb_dim 51 | % knots_per_dim{dim}=unique(S.knots(dim,:)); 52 | % end 53 | 54 | knots_per_dim=S.knots_per_dim; 55 | 56 | 57 | % The modal expansion in i-th direction uses up to degree k, with k as follows 58 | 59 | degrees=zeros(1,nb_dim); 60 | for dim=1:nb_dim 61 | degrees(dim) = length(knots_per_dim{dim})-1; 62 | end 63 | 64 | % the modal polynomials to be used are s.t. the corresponding multi-indices have 65 | % all components less than or equal to the maximum degree 66 | 67 | I = multiidx_box_set(degrees,0); 68 | 69 | % return multiindex_set as 70 | U.multi_indices=I; 71 | 72 | nb_multiindices=size(I,1); 73 | U.size=nb_multiindices; 74 | 75 | % safety check. I have solve a system, so I need the vandermonde matrix to be squared! 76 | rows = S.size; % one equation per point 77 | cols = nb_multiindices; % one unknown per polynomial 78 | 79 | if rows~=cols, error('SparseGKit:FailedSanityChk','vandermonde matrix will not be square!'), end 80 | 81 | 82 | % now create the vandermonde matrix with evaluation of each multi-index in every point 83 | % of the grid 84 | 85 | V = zeros(rows,cols); 86 | 87 | if length(flags)==1 || ischar(flags) % the second condition for when the function is called on one sigle family of polynomials 88 | for c=1:cols 89 | k = I(c,:); 90 | %vc = lege_eval_multidim(interval_map(S.knots),k,domain(1,:),domain(2,:)); 91 | switch flags 92 | case 'legendre' 93 | vc = lege_eval_multidim(S.knots,k,domain(1,:),domain(2,:)); 94 | case 'hermite' 95 | vc = herm_eval_multidim(S.knots,k,domain(1,:),domain(2,:)); 96 | case 'chebyshev' 97 | vc = cheb_eval_multidim(S.knots,k,domain(1,:),domain(2,:)); 98 | otherwise 99 | error('SparseGKit:WrongInput','unknown family of polynomials') 100 | end 101 | V(:,c)=vc'; 102 | end 103 | else 104 | for c=1:cols 105 | k = I(c,:); 106 | vc=ones(1,size(S.knots,2)); 107 | for n=1:nb_dim 108 | switch flags{n} 109 | case 'legendre' 110 | vc = vc.*lege_eval(S.knots(n,:),k(n),domain(1,n),domain(2,n)); 111 | case 'hermite' 112 | vc = vc.*herm_eval(S.knots(n,:),k(n),domain(1,n),domain(2,n)); 113 | case 'chebyshev' 114 | vc = vc.*cheb_eval(S.knots(n,:),k(n),domain(1,n),domain(2,n)); 115 | otherwise 116 | error('SparseGKit:WrongInput','unknown family of polynomials') 117 | end 118 | end 119 | V(:,c)=vc'; 120 | 121 | end 122 | end 123 | 124 | % now solve the system 125 | 126 | U.modal_coeffs = V \ S_values; 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/main/quadrature_on_sparse_grid.m: -------------------------------------------------------------------------------- 1 | function [res,evals] = quadrature_on_sparse_grid(f,S,Sr,evals_old,S_old,Sr_old,paral,tol) 2 | 3 | % QUADRATURE_ON_SPARSE_GRID uses a sparse grid to compute the integral of a function. 4 | % It provides evaluation recycling and parallel toolbox support. This function behaves as 5 | % EVALUATE_ON_SPARSE_GRID, except that it return the value of the approximated integral 6 | % of the function. See EVALUATE_ON_SPARSE_GRID for more information on inputs. Possible calls: 7 | % 8 | % res = QUADRATURE_ON_SPARSE_GRID(F,SR) 9 | % 10 | % 11 | % res = QUADRATURE_ON_SPARSE_GRID(F,S,SR,EVALS_OLD,S_OLD,SR_OLD) 12 | % 13 | % res = QUADRATURE_ON_SPARSE_GRID(F,S,SR,[],[],[]) 14 | % 15 | % res = QUADRATURE_ON_SPARSE_GRID(F,S,SR,EVALS_OLD,[],SR_OLD) 16 | % 17 | % 18 | % res = QUADRATURE_ON_SPARSE_GRID(F,S,SR,EVALS_OLD,S_OLD,SR_OLD,PARAL) 19 | % 20 | % 21 | % res = QUADRATURE_ON_SPARSE_GRID(F,S,SR,EVALS_OLD,S_OLD,SR_OLD,PARAL,TOL) 22 | % 23 | % 24 | % [res,evals] = QUADRATURE_ON_SPARSE_GRID(...) returns the evaluations of the function F 25 | % over the points of the sparse grid S 26 | 27 | 28 | %---------------------------------------------------- 29 | % Sparse Grid Matlab Kit 30 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 31 | % See LICENSE.txt for license 32 | %---------------------------------------------------- 33 | 34 | % declare a global variable controlling verbosity 35 | global MATLAB_SPARSE_KIT_VERBOSE 36 | if isempty(MATLAB_SPARSE_KIT_VERBOSE) 37 | MATLAB_SPARSE_KIT_VERBOSE=1; 38 | end 39 | 40 | 41 | switch nargin 42 | 43 | case 1 44 | error('SparseGKit:WrongInput','not enough input arguments') 45 | 46 | case 2 47 | % res = QUADRATURE_ON_SPARSE_GRID(f,S), S being a reduced sparse grid. 48 | if ~isreduced(S) 49 | error('SparseGKit:WrongInput','when quadrature_on_sparse_grid is called with two inputs, the second one must be a reduced sparse grid') 50 | end 51 | evals = evaluate_on_sparse_grid(f,S); 52 | res = evals*S.weights'; 53 | return 54 | 55 | case {3,4} 56 | errmsg = ['QUADRATURE_ON_SPARSE_GRID does not accept ',num2str(nargin),' inputs. ' ... 57 | 'Observe that QUADRATURE_ON_SPARSE_GRID has been changed after release 15.8 and ' ... 58 | 'now takes as input also the non-reduced versions of the sparse grids on which ' ... 59 | 'one wants to evaluate the function. This allows for significant savings in computational '... 60 | 'time, especially for N large. See QUADRATURE_ON_SPARSE_GRID for more information and '... 61 | 'QUADRATURE_ON_SPARSE_GRID_LEGACY if you are still using a version of the Sparse Grids Matlab kit older than 14.4']; 62 | error('SparseGKit:WrongInput',errmsg) 63 | 64 | case 5 65 | errmsg = ['QUADRATURE_ON_SPARSE_GRID does not accept ',num2str(nargin),' inputs. ' ... 66 | 'Observe that QUADRATURE_ON_SPARSE_GRID has been changed after release 15.8 and ' ... 67 | 'now takes as input also the non-reduced versions of the sparse grids on which ' ... 68 | 'one wants to evaluate the function. This allows for significant savings in computational '... 69 | 'time, especially for N large. See QUADRATURE_ON_SPARSE_GRID for more information. '... 70 | 'As a quick fix, you can use QUADRATURE_ON_SPARSE_GRID_LEGACY '... 71 | 'which is the old version of QUADRATURE_ON_SPARSE_GRID, see help QUADRATURE_ON_SPARSE_GRID_LEGACY. '... 72 | 'This function is however deprecated and will disappear from future relesases of the Sparse Grid Matlab Kit. ']; 73 | error('SparseGKit:WrongInput',errmsg) 74 | 75 | case 6 76 | % in the previous versions, this was evals = quadrature_on_sparse_grid(f,Sr,evals_old,Sr_old,paral,tol); 77 | % 78 | % while now it is: 79 | % 80 | % quadrature_on_sparse_grid(f,S,Sr,evals_old,S_old,Sr_old) 81 | % or 82 | % quadrature_on_sparse_grid(f,S,Sr,[],[],[]) 83 | % or 84 | % quadrature_on_sparse_grid(f,S,Sr,evals_old,[],Sr_old) 85 | 86 | if ~issmolyak(S) 87 | errmsg = ['The second input of QUADRATURE_ON_SPARSE_GRID must be a non-reduced sparse grid if the function is called with 6 inputs. ' ... 88 | 'Observe that QUADRATURE_ON_SPARSE_GRID has been changed after release 15.8 and ' ... 89 | 'now takes as input also the non-reduced versions of the sparse grids on which ' ... 90 | 'one wants to evaluate the function. This allows for significant savings in computational '... 91 | 'time, especially for N large. See QUADRATURE_ON_SPARSE_GRID for more information. '... 92 | 'As a quick fix, you can use QUADRATURE_ON_SPARSE_GRID_LEGACY '... 93 | 'which is the old version of QUADRATURE_ON_SPARSE_GRID, see help QUADRATURE_ON_SPARSE_GRID_LEGACY. '... 94 | 'This function is however deprecated and will disappear from future relesases of the Sparse Grid Matlab Kit.']; 95 | error('SparseGKit:WrongInput',errmsg) 96 | end 97 | evals = evaluate_on_sparse_grid(f,S,Sr,evals_old,S_old,Sr_old); 98 | case 7 99 | evals = evaluate_on_sparse_grid(f,S,Sr,evals_old,S_old,Sr_old,paral); 100 | case 8 101 | evals = evaluate_on_sparse_grid(f,S,Sr,evals_old,S_old,Sr_old,paral,tol); 102 | end 103 | 104 | res = evals*Sr.weights'; -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/sparse-grids/src/mysortrows.m: -------------------------------------------------------------------------------- 1 | function [A,i_ord]=mysortrows(A,Tol,i,i_ord,n) 2 | 3 | % Similar to Matlab builtin function sortrows. Given a matrix A 4 | % of real numbers, sorts the rows in lexicographic order; entries 5 | % that differ less than Tol are treated as equal (default Tol is 1e-14). 6 | % 7 | % usage: 8 | % [B,i]=mysortrows(A,Tol) 9 | % input 10 | % A: input matrix 11 | % Tol: (optional) tolerance used to identify coincident entries 12 | % (default 1e-14) 13 | % output 14 | % B: sorted matrix 15 | % i: index vector such that A(i,:)=B 16 | % 17 | % mysortrows has a recursive implementation. 18 | % recursive call: [A,i_ord]=mysortrows(A,Tol,i,i_ord,n) (with i index) 19 | % sorts the submatrix A(i,n:end); modifies the matrix itself and 20 | % stores the rows permutation in the global vector i_ord. 21 | 22 | 23 | 24 | %---------------------------------------------------- 25 | % Sparse Grid Matlab Kit 26 | % Copyright (c) 2009-2018 L. Tamellini, F. Nobile 27 | % See LICENSE.txt for license 28 | %---------------------------------------------------- 29 | 30 | 31 | % main ides: what points are to be considered equal even though numerically different? Let us take consecutive 32 | % differences between the n-th column of A sorted increasingly: any time such difference is >Tol, then we have a match. Observe that this is NOT stable: 33 | % if all the points are separated by less then Tol (say e.g. a:Tol/10:b) they are considered the same 34 | % even if a-b >> Tol. In other words, points are supposed to cluster in groups whose size is ``a few deltas'', 35 | % separated by ``many deltas''. 36 | 37 | % more specifically, we need a recursive call like 38 | % 39 | % [A,i_ord]=mysortrows(A,Tol,i,i_ord,n) 40 | % 41 | % and we will need three auxiliary vectors. 42 | % 43 | % -> i_ord is the GLOBAL final output, that returns the overall sorting. It keeps been partially rewritten at each 44 | % recursive call (i.e. any time a sort a submatrix I need to keep track of the swaps I am doing) 45 | % 46 | % -> i is the GLOBAL partial order: it is as 1: and says the global position of the submatrix 47 | % before the ordering. 48 | % 49 | % -> ii is the LOCAL final order of each submatrix I am considering 50 | % 51 | % E.g: suppose that after sorting the entries A([3 4 5 10 15],:) are ``Tol-similar'' and need to be sorted as A([3 5 10 15 4],:); 52 | % then 53 | % 54 | % i = [3 4 5 10 15], 55 | % ii = [1 3 4 5 2], 56 | % the entries of i_ord in position [3 4 5 10 15] must be swapped to positions [3 5 10 15 4], 57 | % AND we look for submatrices that need further ordering 58 | 59 | 60 | % this if happens only at user calls, not at recursive calls 61 | if nargin==1 62 | Tol=1e-14; 63 | n=1; 64 | i=1:size(A,1); 65 | i_ord=i; 66 | elseif nargin==2 67 | n=1; 68 | i=1:size(A,1); 69 | i_ord=i; 70 | end 71 | 72 | %disp(['mysortrows level ',num2str(n)]) 73 | 74 | % Note that although the sorting is according to the rightward part of A, we always sort the WHOLE line 75 | [~,ii]=sort(A(i,n)); 76 | A(i,:)=A(i(ii),:); 77 | i_ord(i)=i_ord(i(ii)); 78 | 79 | 80 | 81 | if nTol, then we have a match. Observe that this is NOT stable: 85 | % if all the points are separated by less then Tol (say e.g. a:Tol/10:b) they are considered the same 86 | % even if a-b >> Tol. In other words, points are supposed to cluster in groups whose size is ``a few deltas'', 87 | % separated by ``many deltas''. 88 | 89 | % to begin with, we therefore take differences between to points: whenever the difference is smaller than Tol, 90 | % we will ignore such point. The first and last points of the list have a special treatment. Indeed, say 91 | % the 1st and 2nd points are equal: then we would get a 0 in their difference and lose track of the 1st point! 92 | % to fix this, we put a "1" in front of the diff vector. For reasons that will be clearer in a second, we also 93 | % append "1" at the end. 94 | j=[1;diff(A(i,n))>Tol;1]; 95 | 96 | % now j contains a sequence of "1" and "0", e.g. [1 1 0 0 0 1 1 0 0 0 1 0 0 0 1 1]. Every time we run into 97 | % a "1 0" fragment, it means that a sequence of points to be considered as equal starts, and ends where we find the 98 | % opposite fragement "0 1". We can find the positions of these fragments by taking diff of j and looking for 99 | % +1 and -1, and we bookkeep the positions in two additional vectors, jm (beginning of a fragment) and jp (end 100 | % of a fragment). Now it's clear why we appended "1" at the end of j. Indeed, if the point list ends like [b a a] 101 | % (one points and two occurrences of the same), then diff would be [1 0], meaning that a fragment begins but 102 | % does not end; hence we need to append 1. Observe that a point list ending in [.. c c b a] implies diff ends in [.. 0 1 1] 103 | % and appending 1 does not matter (we do NOT focus on consecutive "1" fragments) 104 | 105 | jm=find(diff(j)==-1); 106 | jp=find(diff(j)==1); 107 | 108 | % now we need to consider each repeated entry and sort the rightward part of the matrix according to the same 109 | % criterion --> recursive call. 110 | 111 | for k=1:length(jm) 112 | % let us identify the rows of A (in the current ordering that need to be sorted) 113 | v=i(jm(k):jp(k))'; 114 | % we need to sort the submatrix and track all swaps in i_ord, whose lenght is always that of the full matrix 115 | [A,i_ord]=mysortrows(A,Tol,v,i_ord,n+1); 116 | end 117 | end -------------------------------------------------------------------------------- /Examples_gallery_1/supplementary_files/PP_Ver_2_3/PPDemo.m: -------------------------------------------------------------------------------- 1 | function PPDemo(cs) 2 | % demonstration of phase plots with various color schemes 3 | % 4 | % Usage: PPDemo, PPDemo(cs) 5 | % 6 | % cs - color scheme (for example 'p' or 'pn') 7 | % 8 | % call PPDemo without argument to see a demonstration of available color schemes 9 | % call 'help colscheme' to get a list of available color schemes 10 | 11 | % Part of the phase plot package 12 | % Version 2.3, January 15, 2014 13 | % Copyright (c) 2012-2014 by Elias Wegert (elias@wegert.com, www.wegert.com) 14 | 15 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 | 17 | %% if there are memory problems reduce the resolution 18 | 19 | xres = 800; 20 | yres = 800; 21 | 22 | %% 23 | 24 | z = zdomain(-2-2i,2+2i,xres,yres); 25 | 26 | clf 27 | 28 | w = (z-1)./(z.*z+z+1); 29 | 30 | if nargin == 1; 31 | %if strcmp(cs,'f') || strcmp(cs,'fn'), w=z+1./z; end 32 | PhasePlot(z,w,cs); 33 | else 34 | 35 | %% proper phase plot 36 | 37 | PhasePlot(z,w,'p'); 38 | title('p - proper phase plot, hsv coloring') 39 | 40 | disp(' ') 41 | disp('DEMO: PHASE PLOTS OF COMPLEX FUNCTIONS') 42 | disp(' ') 43 | disp('To create a phase plot of w=f(z), call PhasePlot(z,w,cs), where') 44 | disp('z is a 2D field of complex numbers covering the domain of f') 45 | disp('w is a 2D field of corresponding values f(z)') 46 | disp('cs is a colorscheme (optional), for example cs=''p''') 47 | disp(' ') 48 | disp('The function f(z)=(z-1)/(z^2+z+1) is depicted in |Re(z)|<2, |Im(z)|<2') 49 | pause 50 | 51 | PhasePlot(z,w,'pn'); 52 | title('pn - proper phase plot, hsv coloring modified according to NIST standard') 53 | disp(' ') 54 | disp('Note that all color schemes can be modified to the NIST standard') 55 | disp('by appending ''n'' to cs, for example cs=''pn'''); 56 | disp('For details see http://dlmf.nist.gov/help/vrml/aboutcolor'); 57 | pause 58 | 59 | %% colored modifications 60 | 61 | 62 | PhasePlot(z,w,'m'); 63 | title('m - enhanced phase plot with modulus jumps') 64 | disp(' ') 65 | disp('There are various modifications of the standard color scheme.') 66 | disp('Here we use shading to generate contour lines of |f(z)|.') 67 | pause 68 | 69 | PhasePlot(z,w,'c'); 70 | title('c - phase plot with conformal polar grid') 71 | disp(' ') 72 | disp('Here we further added contour lines of arg f(z)') 73 | disp('which generates tiles of almost square shape.') 74 | pause 75 | 76 | PhasePlot(z,w,'j'); 77 | title('j - phase plot with some enhanced isochromatic lines') 78 | disp(' ') 79 | disp('The contour lines of arg f(z) are isochromatic.') 80 | pause 81 | 82 | %PhasePlot(z,w,'q'); 83 | %title('q - phase plot colored in steps ') 84 | %pause 85 | 86 | PhasePlot(z,w,'d'); 87 | title('d - standard domain coloring') 88 | disp(' ') 89 | disp('This is standard domain coloring, where color corresponds to phase') 90 | disp('and the gray values represent the modulus of f(z).') 91 | 92 | pause 93 | 94 | PhasePlot(z,w,'e'); 95 | title('e - enhanced domain coloring') 96 | disp(' ') 97 | disp('Here we see enhanced domain coloring with contour lines of |f(z)|.') 98 | pause 99 | 100 | %% black and white modifications 101 | 102 | PhasePlot(z,w,'u'); 103 | title('u - polar chessboard') 104 | disp(' ') 105 | disp('The color scheme ''u'' is good to visualize conformal mappings.') 106 | pause 107 | 108 | PhasePlot(z,w,'a'); 109 | title('a - alternating black and white phase') 110 | disp(' ') 111 | disp('The color scheme ''a'' is appropriate to depict electric field lines.') 112 | pause 113 | hold on 114 | plot3(cos(2*pi/3),sin(2*pi/3),20,'r.','Markersize',20); 115 | plot3(cos(4*pi/3),sin(4*pi/3),20,'r.','Markersize',20); 116 | plot3(1,0,1,'b.','Markersize',20); 117 | disp('Here we have two positive and one negative point charges.') 118 | pause 119 | 120 | PhasePlot(z,w,'b'); 121 | title('b - alternating black and white modulus') 122 | disp(' ') 123 | disp('Using the scheme ''b'' highlights the corresponding potential lines.') 124 | pause 125 | hold off 126 | 127 | 128 | %% color schemes based on cartesian coordinates 129 | 130 | PhasePlot(z,w,'v'); 131 | title('v - Cartesian chessboard') 132 | 133 | %% color scheme for depicting stream lines of potential flows 134 | 135 | disp(' ') 136 | disp('The scheme ''f'' is designed for depicting stream lines of potential flows.') 137 | disp('Here f(z)=(z+1/z)/2 is the Joukovski function.') 138 | PhasePlot(z,z+1./z,'f'); 139 | pause 140 | disp('The function in the interior of the unit circle is irrelevant.') 141 | t = exp(1i*linspace(0,2*pi,1000)); 142 | patch(real(t),imag(t),20*ones(size(t)),'k'); 143 | title('Plane potential flow around a circular cylinder') 144 | pause 145 | 146 | disp(' ') 147 | disp('Call PPDemo(cs) to see the standard example represented by color scheme cs.'); 148 | pause 149 | 150 | clf 151 | disp(' ') 152 | disp('Phase plots can also be depicted on the Riemann sphere using the routine PPOnSphere.'); 153 | disp('This code uses one chart to (almost) cover the sphere:') 154 | disp(' ') 155 | disp('z = zplanePP; w = (z-1)./(z.^2+z+1); PPOnSphere(z,w);') 156 | 157 | z = zplanePP; 158 | w = (z-1)./(z.^2+z+1); 159 | PPOnSphere(z,w); 160 | pause 161 | 162 | disp(' ') 163 | disp('Using two charts to cover the sphere yields a more uniform distribution of points:'); 164 | disp(' ') 165 | disp('z1= zdomain(-1-1i,1+1i); w1=(z1-1)./(z1.^2+z1+1); PPOnSphere(z1,w1);') 166 | disp('z2=1./z1; w2=(z2-1)./(z2.^2+z2+1); PPOnSphere(z2,w2);') 167 | 168 | clf, hold on 169 | z = 2*zdomain(-1-1i,1+1i,1000,1000); 170 | w=(z-1)./(z.^2+z+1); 171 | PPOnSphere(z,w); 172 | zz=1./z; 173 | ww=(zz-1)./(zz.^2+zz+1); 174 | PPOnSphere(zz,ww); 175 | hold off 176 | pause 177 | 178 | disp(' ') 179 | disp('Visit a gallery of phase plots at www.visual.wegert.com') 180 | disp(' ') 181 | disp('For detailed information read') 182 | disp('E. Wegert: Visual Complex Functions, Springer/Birkhaeuser 2012') 183 | pause 184 | 185 | disp(' ') 186 | disp('Now invoking the phase plot user interface PPGUI ...') 187 | PPGUI 188 | 189 | end 190 | 191 | -------------------------------------------------------------------------------- /Examples_gallery_3/circle_map.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | addpath(genpath('./data_from_runs')) 4 | 5 | load('circle_data.mat') 6 | 7 | %%%% UNCOMMENT TO RUN 8 | % %% Parameters 9 | % c=1/5; 10 | % f = @(theta) (1/2)*sin(2*pi*theta)/(2*pi); 11 | % F = @(theta) theta + c +(rand(size(theta,1),1)-0.5)/(5*pi)+f(theta); 12 | % 13 | % %% Dictionary 14 | % n = 20; 15 | % Phi = [chebfun(@(t) exp(2*pi*1i*((-n:n))*t),[0 1],'periodic')]; 16 | % 17 | % %% Form ResDMD matrices 18 | % % M=10^7; 19 | % M1=4*n; 20 | % M2=2*10^4; 21 | % M=M1*M2; 22 | % xM = linspace(0,1,M1+1).'; xM(end) = []; 23 | % xM = repmat(xM,M2,1); 24 | % yM = mod(F(xM),1); 25 | % yMb = mod(F(xM),1); 26 | % 27 | % PX = Phi(xM,:); 28 | % PY1 = Phi(yM,:); 29 | % PY2 = Phi(yMb,:); 30 | % 31 | % G=eye(2*n+1); 32 | % A = (1/M)*PX'*(PY1+PY2)/2; 33 | % L = (1/M)*(PY1'*PY1+PY2'*PY2)/2; 34 | % H = (1/M)*(PY1'*PY2+PY2'*PY1)/2; 35 | % 36 | % 37 | % %% Convergence of ResDMD matrices in Frobenius norm 38 | % 39 | % Mvec=round(10.^(2:0.1:4)); 40 | % E1=0*Mvec; 41 | % E2=0*Mvec; 42 | % E3=0*Mvec; 43 | % E4=0*Mvec; 44 | % 45 | % for jj=1:length(Mvec) 46 | % jj 47 | % M2=Mvec(jj); 48 | % M=M1*M2; 49 | % xM = linspace(0,1,M1+1).'; xM(end) = []; 50 | % xM = repmat(xM,M2,1); 51 | % yM = mod(F(xM),1); 52 | % yMb = mod(F(xM),1); 53 | % 54 | % PXb = PX(1:M,:);%Phi(xM,:); 55 | % PY1b = PY1(1:M,:);%Phi(yM,:); 56 | % PY2b = PY2(1:M,:);%Phi(yMb,:); 57 | % 58 | % G2=(1/M)*(PXb'*PXb); 59 | % A2 = (1/M)*PXb'*(PY1b+PY2b)/2; 60 | % L2 = (1/M)*(PY1b'*PY1b+PY2b'*PY2b)/2; 61 | % H2 = (1/M)*(PY1b'*PY2b+PY2b'*PY1b)/2; 62 | % 63 | % E1(jj) = norm(G-G2,'fro'); E2(jj) = norm(A-A2,'fro'); E3(jj) = norm(L-L2,'fro'); E4(jj) = norm(H-H2,'fro'); 64 | % end 65 | % 66 | % %% Compute eigenvalues and residuals 67 | % 68 | % [V,lam] = eig(A,'vector'); 69 | % lam_var = 0*lam; 70 | % lam_res = 0*lam; 71 | % for j=1:length(lam) 72 | % lam_var(j)=sqrt(max(real(V(:,j)'*(L-lam(j)*A'-conj(lam(j))*A+abs(lam(j))^2*G)*V(:,j))/norm(V(:,j))^2,0)); 73 | % lam_res(j)=sqrt(max(real(V(:,j)'*(H-lam(j)*A'-conj(lam(j))*A+abs(lam(j))^2*G)*V(:,j))/norm(V(:,j))^2,0)); 74 | % end 75 | 76 | 77 | % %% Compute pseudospectra 78 | % x_pts=-1.5:0.01:1.5; 79 | % y_pts=x_pts; 80 | % z_pts=kron(x_pts,ones(length(y_pts),1))+1i*kron(ones(1,length(x_pts)),y_pts(:)); 81 | % z_pts=z_pts(:); 82 | % RES = KoopPseudoSpec(G,A,L,z_pts,'Parallel','on'); 83 | % RES = reshape(RES,length(y_pts),length(x_pts)); 84 | % % 85 | % RESb = KoopPseudoSpec(G,A,H,z_pts,'Parallel','on'); 86 | % RESb = reshape(RESb,length(y_pts),length(x_pts)); 87 | 88 | 89 | %% Plot results 90 | 91 | v=(10.^(-3:0.1:0)); 92 | 93 | figure 94 | contourf(reshape(real(z_pts),length(y_pts),length(x_pts)),reshape(imag(z_pts),length(y_pts),length(x_pts)),log10(real(RES)),log10(v)); 95 | cbh=colorbar; 96 | cbh.Ticks=log10([0.005,0.01,0.1,1]); 97 | cbh.TickLabels=[0,0.01,0.1,1]; 98 | clim([log10(0.01),0]); 99 | reset(gcf) 100 | set(gca,'YDir','normal') 101 | colormap gray 102 | ax=gca; ax.FontSize=16; axis equal tight; axis([x_pts(1),x_pts(end),y_pts(1),y_pts(end)]) 103 | hold on 104 | plot(real(lam),imag(lam),'.r','markersize',15); 105 | xlabel('$\mathrm{Re}(\lambda)$','interpreter','latex','fontsize',16) 106 | ylabel('$\mathrm{Im}(\lambda)$','interpreter','latex','fontsize',16) 107 | title('$\mathrm{Sp}_\epsilon^{\mathrm{var}}(\mathcal{K}_{(1)})$','interpreter','latex','fontsize',16) 108 | exportgraphics(gcf,'circle_var_pseudospec.pdf','Resolution',1000); 109 | % 110 | figure 111 | contourf(reshape(real(z_pts),length(y_pts),length(x_pts)),reshape(imag(z_pts),length(y_pts),length(x_pts)),log10(max(real(RESb),0.01)),log10(v)); 112 | cbh=colorbar; 113 | cbh.Ticks=log10([0.005,0.01,0.1,1]); 114 | cbh.TickLabels=[0,0.01,0.1,1]; 115 | clim([log10(0.01),0]); 116 | reset(gcf) 117 | set(gca,'YDir','normal') 118 | colormap gray 119 | ax=gca; ax.FontSize=16; axis equal tight; axis([x_pts(1),x_pts(end),y_pts(1),y_pts(end)]) 120 | hold on 121 | plot(real(lam),imag(lam),'.r','markersize',15); 122 | xlabel('$\mathrm{Re}(\lambda)$','interpreter','latex','fontsize',16) 123 | ylabel('$\mathrm{Im}(\lambda)$','interpreter','latex','fontsize',16) 124 | title('$\mathrm{Sp}_\epsilon(\mathcal{K}_{(1)})$','interpreter','latex','fontsize',16) 125 | exportgraphics(gcf,'circle_pseudospec.pdf','Resolution',1000); 126 | %% 127 | 128 | % Covariance plot 129 | COV = L -H; 130 | COV(1,1)=1; 131 | 132 | figure 133 | imagesc([-n,n],[-n,n],min(max(log10(abs(COV)),-10),0)) 134 | title('$|\tilde{L}-\tilde{H}|$','interpreter','latex','fontsize',16) 135 | cbh=colorbar; 136 | cbh.Ticks=-10:2:0; 137 | cbh.TickLabels={'1e-10','1e-8','1e-6','1e-4','1e-2','1'}; 138 | ax=gca; ax.FontSize=16; axis equal tight; 139 | colormap hot 140 | exportgraphics(gcf,'circle_covariance.pdf','Resolution',1000); 141 | 142 | 143 | figure 144 | plot(abs(lam),lam_var,'.','markersize',20) 145 | hold on 146 | plot(abs(lam),abs(lam_res),'.','markersize',20) 147 | xlabel('$|\lambda|$','interpreter','latex','fontsize',16) 148 | legend({'$\mathrm{res}^{\mathrm{var}}(\lambda,g)$','$\mathrm{res}(\lambda,g)$'},'interpreter','latex','fontsize',16) 149 | ax = gca; ax.FontSize = 16; 150 | xlim([0,1]) 151 | exportgraphics(gcf,'circle_residual.pdf','Resolution',1000); 152 | %% 153 | figure 154 | loglog(Mvec,E2,'.','markersize',20) 155 | hold on 156 | loglog(Mvec,E3,'.','markersize',20) 157 | loglog(Mvec,E4,'.','markersize',20) 158 | loglog(Mvec(6:end-5),2./sqrt(Mvec(6:end-5)),'k','linewidth',2) 159 | text(500,0.04,'$\mathcal{O}(M_2^{-1/2})$','interpreter','latex','fontsize',16) 160 | xlabel('$M_2$','interpreter','latex','fontsize',16) 161 | legend({'$\|\tilde{A}-A\|_{\mathrm{Fr}}$','$\|\tilde{L}-L\|_{\mathrm{Fr}}$','$\|\tilde{H}-H\|_{\mathrm{Fr}}$'},'interpreter','latex','fontsize',16) 162 | ax = gca; ax.FontSize = 16; 163 | ylim([0.01,1]) 164 | exportgraphics(gcf,'circle_convergence.pdf','Resolution',1000); 165 | -------------------------------------------------------------------------------- /Examples_gallery_2/Cylinder_wake.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | 4 | %% The following data files are available from the dropbox link 5 | 6 | use_DMD=1; % choice of basis: set to 1 to use DMD, set to 0 to use kEDMD 7 | if use_DMD==1 % linear dictionary 8 | load('Cylinder_DMD.mat') % precomputed matrices 9 | elseif use_DMD==2 % combined 10 | load('Cylinder_DMD.mat') 11 | PSI_x0=PSI_x; PSI_y0=PSI_y; 12 | load('Cylinder_EDMD.mat') 13 | N=2*N; % non-linear dictionary 14 | PSI_x=[PSI_x,PSI_x0]; 15 | PSI_y=[PSI_y,PSI_y0]; 16 | else 17 | load('Cylinder_EDMD.mat') % precomputed matrices 18 | end 19 | 20 | %%%%% UNCOMMENT THE FOLLOWING TO PERFORM COMPUTATIONS FROM DATA FILE 'Cylinder_data.mat' %%%%% 21 | % load('Cylinder_data.mat'); 22 | % %% Algorithmic parameters 23 | % N=200; % number of basis functions used 24 | % M1=500; % number of snapshots to compute the basis 25 | % M2=1000; % number of snapshots used for ResDMD matrices 26 | % 27 | % ind1=(1:M1)+6000; % 5000 is roughly where we reach post transient regime 28 | % ind2=(1:M2)+ind1(end)+500; 29 | % 30 | % %% Apply ResDMD 31 | % if use_DMD~=1 32 | % [~,~,~,~,~,PSI_x,PSI_y] = kernel_ResDMD(DATA(:,ind1),DATA(:,ind1+1),'Xb',DATA(:,ind2),'Yb',DATA(:,ind2+1),'N',N,'type','Laplacian'); 33 | % else 34 | % [~,S,V]=svd(transpose(DATA(:,ind1))/sqrt(M1),'econ'); 35 | % PSI_x=transpose(DATA(:,ind2))*V(:,1:N)*diag(1./(diag(S(1:N,1:N)))); 36 | % PSI_y=transpose(DATA(:,ind2+1))*V(:,1:N)*diag(1./(diag(S(1:N,1:N)))); 37 | % clear S V 38 | % end 39 | % 40 | % %% 41 | G_matrix=(PSI_x'*PSI_x)/M2; 42 | A_matrix=(PSI_x'*PSI_y)/M2; 43 | L_matrix=(PSI_y'*PSI_y)/M2; 44 | 45 | %% Compute pseudospectra 46 | x_pts=-1.5:0.05:1.5; y_pts=x_pts; 47 | z_pts=kron(x_pts,ones(length(y_pts),1))+1i*kron(ones(1,length(x_pts)),y_pts(:)); z_pts=z_pts(:); % complex points where we compute pseudospectra 48 | RES = KoopPseudoSpec(G_matrix,A_matrix,L_matrix,z_pts,'Parallel','on'); % compute pseudospectra 49 | RES=reshape(RES,length(y_pts),length(x_pts)); 50 | [V,D]=eig((G_matrix)\(A_matrix)); E=diag(D); % EDMD eigenvalues 51 | 52 | %% Plot pseudospectra 53 | figure 54 | hold on 55 | v=(10.^(-2:0.2:0)); 56 | contourf(reshape(real(z_pts),length(y_pts),length(x_pts)),reshape(imag(z_pts),length(y_pts),length(x_pts)),log10(real(RES)),log10(v)); 57 | cbh=colorbar; 58 | cbh.Ticks=log10([0.005,0.01,0.1,1]); 59 | cbh.TickLabels=[0,0.01,0.1,1]; 60 | caxis([log10(0.01),log10(1)]); 61 | reset(gcf) 62 | set(gca,'YDir','normal') 63 | colormap bone 64 | ax=gca; ax.FontSize=14; axis equal tight; axis([x_pts(1),x_pts(end),y_pts(1),y_pts(end)]) 65 | hold on 66 | plot(real(E),imag(E),'.r'); 67 | 68 | %% 69 | RES2 = zeros(N,1); 70 | for j=1:N 71 | RES2(j)=abs(sqrt(V(:,j)'*(L_matrix-E(j)*A_matrix'-conj(E(j))*A_matrix+abs(E(j))^2*G_matrix)*V(:,j))/sqrt(V(:,j)'*G_matrix*V(:,j))); 72 | end 73 | %% Plot EDMD eigenvalues against residual 74 | [RES_p,I]=sort(RES2,'ascend'); 75 | figure 76 | semilogy(angle(E(I)),RES_p,'.r','markersize',10) 77 | set(gca,'yscale','log') 78 | ax=gca; ax.FontSize=14; 79 | ylim([10^(-8),1]) 80 | 81 | %% Check the lattice structure 82 | evec_x=PSI_x*V(:,I); 83 | lam=E(I); 84 | t1=0.967585567481353 + 0.252543401421919i; 85 | t1=lam(abs(lam-t1)==min(abs(lam-t1))); 86 | lam1=zeros(100,1); ang1=zeros(100,1); res1=zeros(100,1); 87 | for j=1:100 88 | I2=find(abs(lam-t1^j)0 90 | break 91 | end 92 | b1=evec_x(:,abs(lam-t1)1 46 | PSI_x_DMD=transpose(X2)*V2*diag(1./diag(S2)); 47 | PSI_y_DMD=transpose(Y2)*V2*diag(1./diag(S2)); 48 | else 49 | PSI_x_DMD=transpose(X2); 50 | PSI_y_DMD=transpose(Y2); 51 | end 52 | if delay>1 53 | PSI_x=[PSI_x,PSI_x_DMD]; 54 | PSI_y=[PSI_y,PSI_y_DMD]; 55 | end 56 | 57 | %% 58 | M2=size(X2,2); 59 | G_matrix=(PSI_x'*PSI_x)/M2; A_matrix=(PSI_x'*PSI_y)/M2; L_matrix=(PSI_y'*PSI_y)/M2; 60 | G_matrix_DMD=(PSI_x_DMD'*PSI_x_DMD)/M2; A_matrix_DMD=(PSI_x_DMD'*PSI_y_DMD)/M2; L_matrix_DMD=(PSI_y_DMD'*PSI_y_DMD)/M2; 61 | 62 | %% Compute pseudospectra 63 | x_pts=-1.5:0.02:1.5; y_pts=x_pts; 64 | z_pts=kron(x_pts,ones(length(y_pts),1))+1i*kron(ones(1,length(x_pts)),y_pts(:)); z_pts=z_pts(:); 65 | RES = KoopPseudoSpec(G_matrix,A_matrix,L_matrix,z_pts,'Parallel','on'); RES=reshape(RES,length(y_pts),length(x_pts)); 66 | 67 | [V,D]=eig((A_matrix),(G_matrix)); E=diag(D); % EDMD eigenvalues 68 | [V_DMD,D_DMD]=eig((A_matrix_DMD),(G_matrix_DMD)); E_DMD=diag(D_DMD); % DMD eigenvalues 69 | 70 | %% Plot results 71 | figure 72 | hold on 73 | v=(10.^(-5:0.25:0)); 74 | contourf(reshape(real(z_pts),length(y_pts),length(x_pts)),reshape(imag(z_pts),length(y_pts),length(x_pts)),log10(real(RES)),log10(v)); 75 | cbh=colorbar; 76 | cbh.Ticks=log10([0.0005,0.001,0.01,0.1,1]); 77 | cbh.TickLabels=[0,0.001,0.01,0.1,1]; 78 | caxis([log10(0.001),log10(1)]); 79 | reset(gcf) 80 | set(gca,'YDir','normal') 81 | c = turbo; 82 | c = flipud(c); 83 | colormap(c); 84 | colormap bone 85 | 86 | ax=gca; ax.FontSize=14; axis equal tight; axis([x_pts(1),x_pts(end),y_pts(1),y_pts(end)]) 87 | hold on 88 | plot(real(E),imag(E),'.r'); 89 | 90 | 91 | %% Test ResDMD compression 92 | RES2 = KoopPseudoSpec(G_matrix,A_matrix,L_matrix,E,'Parallel','on'); 93 | 94 | % linear vs non-linear 95 | [~,~,~,~,~,PSI_x2,PSI_y2] = kernel_ResDMD(X1,Y1,'Xb',X3{1},'Yb',Y3{1},'N',N,'type','Laplacian'); 96 | 97 | if delay==1 98 | PSI_x2_DMD=transpose(X3{1}); 99 | PSI_y2_DMD=transpose(Y3{1}); 100 | else 101 | PSI_x2_DMD=transpose(X3{1})*V2*diag(1./diag(S2)); 102 | PSI_y2_DMD=transpose(Y3{1})*V2*diag(1./diag(S2)); 103 | PSI_x2=[PSI_x2,PSI_x2_DMD]; 104 | PSI_y2=[PSI_y2,PSI_y2_DMD]; 105 | end 106 | 107 | xQ2=transpose(X2(1,:)); 108 | coeff_mat=G_matrix\(PSI_x'*xQ2/M2); 109 | MAT1=V\coeff_mat; 110 | coeff_mat_DMD=G_matrix_DMD\(PSI_x_DMD'*xQ2/M2); 111 | MAT1_DMD=V_DMD\coeff_mat_DMD; 112 | 113 | Dt=diag(D); Dt_DMD=diag(D_DMD); 114 | 115 | y_test=zeros(1,(length(X3{1}(1,:))-1)+1); y_testb=zeros(1,(length(X3{1}(1,:))-1)+1); 116 | for dd=1:delay 117 | MAT2=PSI_x2(dd,:)*V; 118 | MAT2_DMD=PSI_x2_DMD(dd,:)*V_DMD; 119 | for n=delay:(length(X3{1}(1,:))-1) 120 | y_test(n+1)=y_test(n+1)+real((MAT2.*transpose(Dt.^(n+1-dd)))*MAT1); 121 | y_testb(n+1)=y_testb(n+1)+real((MAT2_DMD.*transpose(Dt_DMD.^(n+1-dd)))*MAT1_DMD); 122 | end 123 | end 124 | y_real=real(X3{1}(1,1:(length(X3{1}(1,:))-1)+1)); 125 | y_test=y_test/delay; 126 | y_testb=y_testb/delay; 127 | 128 | load('LIP_times.mat') 129 | t=t-t(1); 130 | figure 131 | plot(t(1:end-delay),y_real,'b','linewidth',2) 132 | hold on 133 | y_test(delay)=y_real(delay); 134 | y_testb(delay)=y_real(delay); 135 | plot(t(delay:length(y_real)),y_testb(delay:end),'or','linewidth',1) 136 | plot(t(delay:length(y_real)),y_test(delay:end),'og','linewidth',1) 137 | 138 | plot(0*[delay,delay]+t(delay),[-100,100],'--m') 139 | legend({'true','linear dictionary','non-linear dictionary'},'interpreter','latex','fontsize',14,'location','best') 140 | ax=gca; ax.FontSize=14; 141 | xlim([0,t(end-delay)]) 142 | 143 | % modulus vs residual ordering 144 | [~,IP]=sort(RES2,'ascend'); 145 | 146 | PSI_x_res=PSI_x*V(:,IP(1:40)); 147 | PSI_x2_res=PSI_x2*V(:,IP(1:40)); 148 | xQ2=transpose(X2(1,:)); 149 | MAT1_res=pinv(PSI_x_res)*xQ2; 150 | Dt_res=Dt(IP(1:40)); 151 | 152 | y_residual=zeros(1,(length(X3{1}(1,:))-1)+1); 153 | for dd=1:delay 154 | MAT2_res=PSI_x2_res(dd,:); 155 | for n=delay:(length(X3{1}(1,:))-1) 156 | y_residual(n+1)=y_residual(n+1)+real((MAT2_res.*transpose(Dt_res.^(n+1-dd)))*MAT1_res); 157 | end 158 | end 159 | y_residual=y_residual/delay; 160 | 161 | [~,IP]=sort(abs(E),'descend'); 162 | 163 | PSI_x_res=PSI_x*V(:,IP(1:40)); 164 | PSI_x2_res=PSI_x2*V(:,IP(1:40)); 165 | xQ2=transpose(X2(1,:)); 166 | MAT1_res=pinv(PSI_x_res)*xQ2; 167 | Dt_res=Dt(IP(1:40)); 168 | 169 | y_energy=zeros(1,(length(X3{1}(1,:))-1)+1); 170 | for dd=1:delay 171 | MAT2_res=PSI_x2_res(dd,:); 172 | for n=delay:(length(X3{1}(1,:))-1) 173 | y_energy(n+1)=y_energy(n+1)+real((MAT2_res.*transpose(Dt_res.^(n+1-dd)))*MAT1_res); 174 | end 175 | end 176 | y_energy=y_energy/delay; 177 | 178 | figure 179 | plot(t(1:end-delay),y_real,'b','linewidth',2) 180 | % 181 | hold on 182 | y_energy(delay)=y_real(delay); 183 | y_residual(delay)=y_real(delay); 184 | plot(t(delay:length(y_real)),y_energy(delay:end),'or','linewidth',1) 185 | plot(t(delay:length(y_real)),y_residual(delay:end),'ok','linewidth',1) 186 | 187 | plot(0*[delay,delay]+t(delay),[-100,100],'--m') 188 | legend({'true','modulus ordering','residual ordering'},'interpreter','latex','fontsize',14,'location','best') 189 | ax=gca; ax.FontSize=14; 190 | xlim([0,t(end-delay)]) 191 | 192 | -------------------------------------------------------------------------------- /Examples_gallery_1/tent_map_example.m: -------------------------------------------------------------------------------- 1 | clear 2 | close all 3 | %% 4 | figure(10) 5 | h = plot(1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11,1:10,1:10,1:10,2:11); 6 | c = get(h,'Color'); 7 | close(10) 8 | 9 | %% Choose observable 10 | g = @(x) abs(x-1/3)+(x>0.78)+sin(20*x); gg = chebfun(@(x) g(x),[0,1],'splitting','on'); 11 | f = @(x) g(x)/sqrt(sum(gg*conj(gg))); ff = chebfun(@(x) f(x),[0,1],'splitting','on'); % function we compute measure wrt 12 | n=15; % trunction size to compute the inner products 13 | %% Setup the koopman matrix wrt Haar system 14 | K=sparse(2^n,2^n); 15 | % set up the indexing 16 | nId=0; kId=0; 17 | for j=1:n 18 | nId=[nId(:); zeros(2^(j-1),1)+j]; kId=[kId(:); transpose(0:(2^(j-1)-1))]; 19 | end 20 | K(1,1)=1; 21 | for j=2:2^(n-1) 22 | I1 = find((nId==(nId(j)+1)).*(kId==kId(j))); 23 | if ~isempty(I1) 24 | K(I1,j)=1/sqrt(2); 25 | end 26 | I1 = find((nId==(nId(j)+1)).*(kId==(2^(nId(j))-(kId(j)+1)))); 27 | if ~isempty(I1) 28 | K(I1,j)=-1/sqrt(2); 29 | end 30 | end 31 | 32 | %% Compute wavelet coefficients 33 | xpts=1/(2^(n+1)):2^(-n):1; 34 | [coeffs,L]=wavedec(f(xpts),round(log2(length(xpts))),'db1'); 35 | coeffs=coeffs/sqrt(length(xpts)); 36 | at=coeffs(1); 37 | coeffs(1)=0; % subtract off the atomic part, will add on later 38 | coeffs=coeffs(:); 39 | 40 | %% Compute the fourier coefficients 41 | MU=zeros(2*(2^n)+1,1); N=1000; 42 | MU(N+1)=(coeffs'*coeffs)/(2*pi); 43 | 44 | Fc=coeffs; 45 | for j=1:N 46 | Fc=K*Fc; 47 | MU(N-j+1)=(coeffs'*Fc)/(2*pi); 48 | MU(N+1+j)=(MU(N-j+1))'; 49 | end 50 | 51 | MU=MU+abs(at)^2/(2*pi); % add atomic part back on 52 | 53 | %% Spectral measures plot 54 | N1=100; N2=1000; 55 | 56 | MU01=chebfun(full(MU((N+1-N1):(N+1+N1))),[-pi pi],'trig','coeffs'); % approximation with no filter 57 | MU1=MomentMeas(MU((N+1-N1):(N+1+N1))); % approximation with filter 58 | MU02=chebfun(full(MU((N+1-N2):(N+1+N2))),[-pi pi],'trig','coeffs'); % approximation with no filter 59 | MU2=MomentMeas(MU((N+1-N2):(N+1+N2))); % approximation with filter 60 | 61 | %% N=100 plot 62 | figure 63 | semilogy(max(real(MU01),0),'color',c{2},'linewidth',1) 64 | hold on 65 | semilogy(max(real(MU1),10^(-16)),'color',c{1},'linewidth',1); hold on 66 | ylim([10^(-2),50]); ax = gca; ax.FontSize = 14; 67 | legend({'no filter','with filter'},'interpreter','latex','fontsize',14,'location','northwest') 68 | %% N=1000 plot 69 | figure 70 | semilogy(max(real(MU02),0),'color',c{2},'linewidth',1) 71 | hold on 72 | semilogy(max(real(MU2),10^(-16)),'color',c{1},'linewidth',1); hold on 73 | ylim([10^(-2),50]); ax = gca; ax.FontSize = 14; 74 | legend({'no filter','with filter'},'interpreter','latex','fontsize',14,'location','northeast') 75 | 76 | a2 = axes(); a2.Position = [0.18 0.70 0.3 0.2]; % xlocation, ylocation, xsize, ysize 77 | semilogy(max(real(MU02),0),'color',c{2},'linewidth',1) 78 | hold on 79 | semilogy(max(real(MU2),10^(-16)),'color',c{1},'linewidth',1); hold on 80 | axis([-1,-0.8,10^(-5),1]) 81 | 82 | %% Convergence in number of data points 83 | % g = chebfun(@(x) abs(x-1/3)+(x>0.78)+sin(20*x),[0,1],'splitting','on'); 84 | % g = chebfun(@(x) cos(pi*x-0.1),[0,1],'splitting','on'); 85 | g = chebfun(@(x) cos(100*pi*x),[0,1],'splitting','on'); 86 | f = @(x) g(x)/sqrt(sum(g*conj(g))); 87 | 88 | Nvec=1:12; 89 | LL=zeros(length(Nvec),10); 90 | ct=1; 91 | 92 | for n=Nvec 93 | 94 | K=sparse(2^n,2^n); 95 | % set up the indexing 96 | nId=0; kId=0; 97 | for j=1:n 98 | nId=[nId(:); zeros(2^(j-1),1)+j]; kId=[kId(:); transpose(0:(2^(j-1)-1))]; 99 | end 100 | 101 | K(1,1)=1; 102 | 103 | for j=2:2^(n-1) 104 | I1 = find((nId==(nId(j)+1)).*(kId==kId(j))); 105 | if ~isempty(I1) 106 | K(I1,j)=1/sqrt(2); 107 | end 108 | I1 = find((nId==(nId(j)+1)).*(kId==(2^(nId(j))-(kId(j)+1)))); 109 | if ~isempty(I1) 110 | K(I1,j)=-1/sqrt(2); 111 | end 112 | end 113 | 114 | xpts=1/(2^(n+1)):2^(-n):1; 115 | [coeffs,L]=wavedec(f(xpts),round(log2(length(xpts))),'db1'); 116 | coeffs=coeffs/sqrt(length(xpts)); 117 | at=coeffs(1); 118 | coeffs(1)=0; % subtract off the atomic part 119 | coeffs=coeffs(:); 120 | 121 | MU=zeros(2*(2^n)+1,1); N=2^n; 122 | MU(N+1)=(coeffs'*coeffs)/(2*pi); 123 | LL(ct,1)=(coeffs'*coeffs)/(2*pi)+abs(at)^2/(2*pi); 124 | Fc=coeffs; 125 | for j=1:N 126 | Fc=K*Fc; 127 | MU(N-j+1)=(coeffs'*Fc)/(2*pi); 128 | MU(N+1+j)=(MU(N-j+1))'; 129 | if j<11 130 | LL(ct,j+1)=MU(N-j+1)+abs(at)^2/(2*pi); 131 | end 132 | end 133 | MU=MU+abs(at)^2/(2*pi); % add atomic part back on 134 | 135 | ct=ct+1; 136 | end 137 | 138 | %% Compute the fourier modes via ergodic sampling 139 | N=10; 140 | SVEC=2.^Nvec(1:end-2)*10; 141 | MU_an=LL(end,1:N+1); 142 | 143 | ct=1; 144 | for M=SVEC 145 | MU2=zeros(1,N+1); 146 | x1=rand(1); 147 | FT = @(x) max((min(2*(2*x<1).*x+(2*x>=1)*2.*(1-x),1)),0); 148 | Ya=zeros(M,1); 149 | Ya(1)=f(x1); 150 | Yb=Ya; 151 | xa=x1; 152 | xb=x1; 153 | 154 | for j=1:M-1 155 | xa=FT(xa); 156 | xb=FT(xb)+rand(1,1)*0.0001; % this kick is to stop underflow 157 | Ya(j+1)=f(xa); 158 | Yb(j+1)=f(xb); 159 | end 160 | for j=0:N 161 | MU2(j+1)=(Ya(1:(M-j))'*Ya((j+1):M)/(M-j))/(2*pi); 162 | end 163 | E(ct,1)=max(abs(MU2-MU_an)); 164 | for j=0:N 165 | MU2(j+1)=(Yb(1:(M-j))'*Yb((j+1):M)/(M-j))/(2*pi); 166 | end 167 | E(ct,2)=max(abs(MU2-MU_an)); 168 | 169 | ct=ct+1; 170 | end 171 | 172 | %% 173 | figure 174 | loglog(2.^Nvec(1:4)*10,max((abs(LL(1:4,:)-repmat(LL(end,:),[4,1])))'),'o-','color',c{1},'linewidth',2) 175 | hold on 176 | loglog(SVEC,E(1:length(SVEC),2),'o-','color',c{2},'linewidth',2) 177 | ax = gca; ax.FontSize = 14; 178 | loglog(SVEC,SVEC.^(-0.5),'k:','linewidth',2) 179 | ylim([10^(-16),1]) 180 | xlim([10,10^4*2]);%[max(min(2.^Nvec)/2,1.0001),max(2.^Nvec)]) 181 | 182 | --------------------------------------------------------------------------------