├── LICENSE ├── lib ├── Box.c ├── Iter.c ├── Tree.c ├── Vec.c ├── defs.c ├── Matrix.c ├── Stack.c ├── Rectangle.c ├── gaio │ ├── Box.h │ ├── Iter.h │ ├── Tree.h │ ├── Vec.h │ ├── defs.h │ ├── Matrix.h │ ├── Stack.h │ ├── Rectangle.h │ ├── SparseVector.h │ ├── mxHandling.h │ ├── Set.h │ ├── Node.h │ ├── IndSubshift.h │ └── SparseMatrix.h ├── SparseVector.c ├── Node.c ├── Set.c ├── SparseMatrix.c └── IndSubshift.c ├── demos ├── gaio.m ├── lorenz.m ├── attractor.m ├── html │ ├── chua2.jpg │ ├── ftle.jpg │ ├── lorenz.jpg │ ├── lorenz.png │ ├── attractor.png │ ├── lorenz_01.png │ ├── lorenz_02.png │ ├── umanifold.pdf │ ├── attractor_01.png │ ├── attractor_02.png │ ├── lorenz_eq17800.png │ ├── lorenz_eq33184.png │ ├── lorenz_eq33920.png │ ├── lorenz_eq64243.png │ ├── lorenz_eq69357.png │ ├── lorenz_eq77330.png │ ├── lorenz_eq95576.png │ ├── lorenz_measure.png │ ├── attractor_eq40306.png │ ├── attractor_eq42561.png │ ├── implicit_manifold.png │ ├── invariant_density.png │ ├── lorenz_measure_01.png │ ├── implicit_manifold_01.png │ ├── invariant_density_01.png │ ├── style.css │ ├── invariant_density.html │ ├── matlab-style.css │ ├── gaio.html │ ├── ftle.html │ ├── implicit_manifold.html │ ├── attractor.html │ ├── lorenz_measure.html │ ├── lorenz.html │ └── mxdom2mathjax.xsl ├── attractor_fast.m ├── lorenz_cmap.mat ├── lyapunov_henon.m ├── Conlex index │ ├── henon_script.m │ ├── henon_script.m~ │ ├── main │ │ ├── flags.m │ │ ├── conn_comp.m │ │ ├── get_nbhd.m │ │ ├── box2cub.m │ │ ├── cycle.m │ │ ├── grow_isolated.m │ │ ├── build_ip.m │ │ ├── nbhd_graph.m │ │ ├── in_int.m │ │ ├── henon_bias.c │ │ ├── conn_comp_map.m │ │ └── tm2map.m │ ├── henon-A.dat │ ├── henon-X.dat │ ├── henon-B.dat │ ├── henon-Y.dat │ └── henon.map ├── invariant_density.m ├── double_gyre_map.m ├── lyapunov_logistic.m ├── chain_recurrent.m ├── almost_invariant_sets.m ├── tpgraph_out.m ├── topological_entropy.m ├── ftle.m ├── cyclic.m ├── value_function.m ├── implicit_manifold.m ├── chua.m ├── pickover.m ├── lorenz_measure.m ├── stable_manifold.m └── lorenz_fast.m ├── matlab ├── tree_.c ├── scc.mexa64 ├── scc.mexw32 ├── scc.mexw64 ├── scc.mexmaci64 ├── tree_.mexa64 ├── tree_.mexw32 ├── tree_.mexw64 ├── dijkstra.mexa64 ├── dijkstra.mexw32 ├── dijkstra.mexw64 ├── subshift.mexa64 ├── subshift.mexw32 ├── subshift.mexw64 ├── tree_.mexmaci64 ├── dijkstra.mexmaci64 ├── fwd_inv_set.mexw32 ├── subshift.mexmaci64 ├── fwd_inv_set.mexmaci64 ├── shortest_path.m ├── dispr.m ├── max_inv_set.m ├── dijkstra.m ├── rk4.m ├── rk4u.m ├── crs.m ├── fwd_inv_set.c ├── mis.m ├── tpmatrix_slow.m ├── dpgraph.m ├── rga.m ├── tpmatrix.m ├── subshift.c ├── gum.m ├── boxplot2.m ├── scc.c ├── boxplot3.m ├── plotshadows.m └── dijkstra.c ├── @Tree ├── subsasgn.c ├── delete.mexa64 ├── delete.mexw32 ├── delete.mexw64 ├── subsref.mexa64 ├── subsref.mexw32 ├── subsref.mexw64 ├── delete.mexmaci64 ├── subsasgn.mexa64 ├── subsasgn.mexw32 ├── subsasgn.mexw64 ├── subsref.mexmaci64 ├── subsasgn.mexmaci64 ├── delete.c ├── Tree.m └── subsref.c ├── .gitignore ├── Contents.m ├── compile.m └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright by djs2 GbR, Paderborn, Germany 2 | -------------------------------------------------------------------------------- /lib/Box.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/Box.c -------------------------------------------------------------------------------- /lib/Iter.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/Iter.c -------------------------------------------------------------------------------- /lib/Tree.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/Tree.c -------------------------------------------------------------------------------- /lib/Vec.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/Vec.c -------------------------------------------------------------------------------- /lib/defs.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/defs.c -------------------------------------------------------------------------------- /demos/gaio.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/gaio.m -------------------------------------------------------------------------------- /lib/Matrix.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/Matrix.c -------------------------------------------------------------------------------- /lib/Stack.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/Stack.c -------------------------------------------------------------------------------- /demos/lorenz.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/lorenz.m -------------------------------------------------------------------------------- /lib/Rectangle.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/Rectangle.c -------------------------------------------------------------------------------- /lib/gaio/Box.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/gaio/Box.h -------------------------------------------------------------------------------- /lib/gaio/Iter.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/gaio/Iter.h -------------------------------------------------------------------------------- /lib/gaio/Tree.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/gaio/Tree.h -------------------------------------------------------------------------------- /lib/gaio/Vec.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/gaio/Vec.h -------------------------------------------------------------------------------- /lib/gaio/defs.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/gaio/defs.h -------------------------------------------------------------------------------- /matlab/tree_.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/tree_.c -------------------------------------------------------------------------------- /@Tree/subsasgn.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/subsasgn.c -------------------------------------------------------------------------------- /demos/attractor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/attractor.m -------------------------------------------------------------------------------- /lib/SparseVector.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/SparseVector.c -------------------------------------------------------------------------------- /lib/gaio/Matrix.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/gaio/Matrix.h -------------------------------------------------------------------------------- /lib/gaio/Stack.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/gaio/Stack.h -------------------------------------------------------------------------------- /matlab/scc.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/scc.mexa64 -------------------------------------------------------------------------------- /matlab/scc.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/scc.mexw32 -------------------------------------------------------------------------------- /matlab/scc.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/scc.mexw64 -------------------------------------------------------------------------------- /@Tree/delete.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/delete.mexa64 -------------------------------------------------------------------------------- /@Tree/delete.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/delete.mexw32 -------------------------------------------------------------------------------- /@Tree/delete.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/delete.mexw64 -------------------------------------------------------------------------------- /@Tree/subsref.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/subsref.mexa64 -------------------------------------------------------------------------------- /@Tree/subsref.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/subsref.mexw32 -------------------------------------------------------------------------------- /@Tree/subsref.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/subsref.mexw64 -------------------------------------------------------------------------------- /demos/html/chua2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/chua2.jpg -------------------------------------------------------------------------------- /demos/html/ftle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/ftle.jpg -------------------------------------------------------------------------------- /lib/gaio/Rectangle.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/gaio/Rectangle.h -------------------------------------------------------------------------------- /matlab/scc.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/scc.mexmaci64 -------------------------------------------------------------------------------- /matlab/tree_.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/tree_.mexa64 -------------------------------------------------------------------------------- /matlab/tree_.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/tree_.mexw32 -------------------------------------------------------------------------------- /matlab/tree_.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/tree_.mexw64 -------------------------------------------------------------------------------- /@Tree/delete.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/delete.mexmaci64 -------------------------------------------------------------------------------- /@Tree/subsasgn.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/subsasgn.mexa64 -------------------------------------------------------------------------------- /@Tree/subsasgn.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/subsasgn.mexw32 -------------------------------------------------------------------------------- /@Tree/subsasgn.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/subsasgn.mexw64 -------------------------------------------------------------------------------- /@Tree/subsref.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/subsref.mexmaci64 -------------------------------------------------------------------------------- /demos/attractor_fast.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/attractor_fast.m -------------------------------------------------------------------------------- /demos/html/lorenz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz.jpg -------------------------------------------------------------------------------- /demos/html/lorenz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz.png -------------------------------------------------------------------------------- /demos/lorenz_cmap.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/lorenz_cmap.mat -------------------------------------------------------------------------------- /demos/lyapunov_henon.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/lyapunov_henon.m -------------------------------------------------------------------------------- /lib/gaio/SparseVector.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/gaio/SparseVector.h -------------------------------------------------------------------------------- /lib/gaio/mxHandling.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/lib/gaio/mxHandling.h -------------------------------------------------------------------------------- /matlab/dijkstra.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/dijkstra.mexa64 -------------------------------------------------------------------------------- /matlab/dijkstra.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/dijkstra.mexw32 -------------------------------------------------------------------------------- /matlab/dijkstra.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/dijkstra.mexw64 -------------------------------------------------------------------------------- /matlab/subshift.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/subshift.mexa64 -------------------------------------------------------------------------------- /matlab/subshift.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/subshift.mexw32 -------------------------------------------------------------------------------- /matlab/subshift.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/subshift.mexw64 -------------------------------------------------------------------------------- /matlab/tree_.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/tree_.mexmaci64 -------------------------------------------------------------------------------- /@Tree/subsasgn.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/@Tree/subsasgn.mexmaci64 -------------------------------------------------------------------------------- /demos/html/attractor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/attractor.png -------------------------------------------------------------------------------- /demos/html/lorenz_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_01.png -------------------------------------------------------------------------------- /demos/html/lorenz_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_02.png -------------------------------------------------------------------------------- /demos/html/umanifold.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/umanifold.pdf -------------------------------------------------------------------------------- /matlab/dijkstra.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/dijkstra.mexmaci64 -------------------------------------------------------------------------------- /matlab/fwd_inv_set.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/fwd_inv_set.mexw32 -------------------------------------------------------------------------------- /matlab/subshift.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/subshift.mexmaci64 -------------------------------------------------------------------------------- /demos/html/attractor_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/attractor_01.png -------------------------------------------------------------------------------- /demos/html/attractor_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/attractor_02.png -------------------------------------------------------------------------------- /matlab/fwd_inv_set.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/matlab/fwd_inv_set.mexmaci64 -------------------------------------------------------------------------------- /demos/html/lorenz_eq17800.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_eq17800.png -------------------------------------------------------------------------------- /demos/html/lorenz_eq33184.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_eq33184.png -------------------------------------------------------------------------------- /demos/html/lorenz_eq33920.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_eq33920.png -------------------------------------------------------------------------------- /demos/html/lorenz_eq64243.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_eq64243.png -------------------------------------------------------------------------------- /demos/html/lorenz_eq69357.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_eq69357.png -------------------------------------------------------------------------------- /demos/html/lorenz_eq77330.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_eq77330.png -------------------------------------------------------------------------------- /demos/html/lorenz_eq95576.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_eq95576.png -------------------------------------------------------------------------------- /demos/html/lorenz_measure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_measure.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .PowerFolder/Last_sync 3 | 4 | .PowerFolder/.PowerFolder.db 5 | 6 | .PowerFolder/FolderStatistic 7 | -------------------------------------------------------------------------------- /demos/Conlex index/henon_script.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/Conlex index/henon_script.m -------------------------------------------------------------------------------- /demos/html/attractor_eq40306.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/attractor_eq40306.png -------------------------------------------------------------------------------- /demos/html/attractor_eq42561.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/attractor_eq42561.png -------------------------------------------------------------------------------- /demos/html/implicit_manifold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/implicit_manifold.png -------------------------------------------------------------------------------- /demos/html/invariant_density.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/invariant_density.png -------------------------------------------------------------------------------- /demos/html/lorenz_measure_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/lorenz_measure_01.png -------------------------------------------------------------------------------- /demos/Conlex index/henon_script.m~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/Conlex index/henon_script.m~ -------------------------------------------------------------------------------- /demos/html/implicit_manifold_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/implicit_manifold_01.png -------------------------------------------------------------------------------- /demos/html/invariant_density_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dpsanders/GAIO/master/demos/html/invariant_density_01.png -------------------------------------------------------------------------------- /matlab/shortest_path.m: -------------------------------------------------------------------------------- 1 | function o = shortest_path(P, s, d) 2 | 3 | [V,N] = dijkstra(P',d); 4 | 5 | o = s; 6 | for k = 1:V(s), 7 | o = [o; N(o(end))]; 8 | end 9 | -------------------------------------------------------------------------------- /matlab/dispr.m: -------------------------------------------------------------------------------- 1 | function dispr(s,n) 2 | 3 | persistent l; 4 | if n == 0, l = 0; end 5 | if l > 0 6 | for j=1:l+1, fprintf('\b'); end; 7 | end 8 | l = fprintf(s); 9 | -------------------------------------------------------------------------------- /demos/Conlex index/main/flags.m: -------------------------------------------------------------------------------- 1 | function f = flags(I, n) 2 | 3 | % F = flags(I, N) returns an N-vector F, for which F(I)=1 and 4 | % F=0 elsewhere 5 | 6 | f = zeros(n, 1); 7 | f(I) = 1; 8 | 9 | -------------------------------------------------------------------------------- /demos/Conlex index/henon-A.dat: -------------------------------------------------------------------------------- 1 | dimension 2 2 | (-49,117) 3 | (-49,118) 4 | (-40,113) 5 | (-40,114) 6 | (-41,115) 7 | (-40,115) 8 | (113,-49) 9 | (113,-48) 10 | (113,-47) 11 | (119,-43) 12 | (119,-42) 13 | (119,-41) 14 | -------------------------------------------------------------------------------- /matlab/max_inv_set.m: -------------------------------------------------------------------------------- 1 | function M = max_inv_set(P) 2 | 3 | % MAX_INV_SET maximal invariant set. 4 | % MAX_INV_SET(P) computes the maximal invariant set of the transition 5 | % matrix P. 6 | % 7 | 8 | M = fwd_inv_set(P) & fwd_inv_set(P'); 9 | -------------------------------------------------------------------------------- /matlab/dijkstra.m: -------------------------------------------------------------------------------- 1 | function [V,N] = dijkstra(A, D) 2 | 3 | %DIJKSTRA shortest paths 4 | % [V,~] = DIJKSTRA(A, D) computes the lengths of the shortest paths 5 | % between all nodes and the destination D, regarding the sparse matrix 6 | % A as a directed weighted graph, where the entry (i,j) in A defines 7 | % the weight of the edge j->i. 8 | -------------------------------------------------------------------------------- /matlab/rk4.m: -------------------------------------------------------------------------------- 1 | function X = rk4(v,X,h,n) 2 | 3 | % RK4 Runge-Kutta scheme of order 4 4 | % performs n steps of the scheme for the vector field v 5 | % using stepsize h on each row of the matrix X 6 | % v maps an (m x d)-matrix to an (m x d)-matrix 7 | 8 | for i = 1:n 9 | k1 = v(X); 10 | k2 = v(X + h/2*k1); 11 | k3 = v(X + h/2*k2); 12 | k4 = v(X + h*k3); 13 | X = X + h*(k1 + 2*k2 + 2*k3 + k4)/6; 14 | end -------------------------------------------------------------------------------- /matlab/rk4u.m: -------------------------------------------------------------------------------- 1 | function X = rk4u(v,X,U,h,n) 2 | 3 | % RK4U Runge-Kutta scheme of order 4 for control system 4 | % rk4u(v,X,U,h,n) performs n steps of the scheme for the vector field v 5 | % using stepsize h on each row of the matrix X 6 | % 7 | % v(X,U) maps an (m x d)-matrix X and an (m x p)-matrix U 8 | % to an (m x d)-matrix 9 | 10 | for i = 1:n 11 | k1 = v(X,U); 12 | k2 = v(X + h/2*k1,U); 13 | k3 = v(X + h/2*k2,U); 14 | k4 = v(X + h*k3,U); 15 | X = X + h*(k1 + 2*k2 + 2*k3 + k4)/6; 16 | end -------------------------------------------------------------------------------- /@Tree/delete.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2013 djs2 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | void mexFunction( 10 | int nlhs, mxArray *plhs[], 11 | int nrhs, const mxArray *prhs[] 12 | ) 13 | { 14 | mxArray *null; 15 | Iter *iter = (Iter *)ptrFromMxArray(mxGetField(prhs[0], 0, "handle")); 16 | IterFree(&iter); 17 | null = mxCreateDoubleMatrix(1,1,mxREAL); 18 | *mxGetPr(null) = 0; 19 | mxSetField((mxArray *)prhs[0], 0, "handle", null); 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /demos/Conlex index/main/conn_comp.m: -------------------------------------------------------------------------------- 1 | function C = conn_comp(N, S, b) 2 | 3 | % C = conn_comp(N, S, B) 4 | % computes the connected component of the subset S containing the box B; 5 | % N is a neighborhood graph; S a vector of box numbers and B a box 6 | % number (1<=B<=size(N)) 7 | 8 | Cf = zeros(1,size(N,1)); 9 | A = N(S, S); 10 | A = sparse(A); 11 | G = Graph(A); 12 | scc = G.strong_components; 13 | c = zeros(1,size(N,1)); 14 | for i=1:max(scc), 15 | c(S(find(scc==i))) = i; 16 | end 17 | Cf(find(c==c(b))) = 1; 18 | C = find(Cf); 19 | 20 | delete(G); 21 | 22 | 23 | -------------------------------------------------------------------------------- /demos/Conlex index/main/get_nbhd.m: -------------------------------------------------------------------------------- 1 | function N = get_nbhd(tree, S, depth) 2 | 3 | % N = get_nbhd(tree, S, depth) 4 | % computes the smallest 'representable' neighbourhood of the given subset 5 | % S of the boxes on depth D of the tree T; S is a vector of box numbers 6 | 7 | % see o.m also 8 | 9 | d = tree.dim; 10 | b = tree.boxes(depth); 11 | S = S(:); 12 | n = zeros(1, size(b,2)); 13 | 14 | for bi = 1:size(S,1), 15 | c = b(1:d, S(bi)); 16 | r = b(d+1:2*d, S(bi)) + 0.1*b(d+1:2*d, S(bi)); 17 | I = tree.search_box(c, r); 18 | n(I) = 1; 19 | end 20 | 21 | N = find(n); 22 | -------------------------------------------------------------------------------- /demos/Conlex index/main/box2cub.m: -------------------------------------------------------------------------------- 1 | function box2cub(b, filename) 2 | 3 | %% Converts a box collection, b, in GAIO to a list of cubes written in 'filename' for 'homcubes'. 4 | 5 | fid = fopen(filename,'w'); 6 | 7 | d = (size(b,1)-2)/2; 8 | 9 | fprintf(fid, 'dimension %d\n', d); 10 | 11 | r = b(d+1:2*d,1); 12 | for i=1:d 13 | b(i,:) = b(i,:)/r(i)/2; 14 | end 15 | 16 | q = round(b(1:d,:)-0.5)'; 17 | for i=1:size(q,1) 18 | fprintf(fid, '('); 19 | for j=1:d-1, 20 | fprintf(fid, '%d,', q(i,j)); 21 | end 22 | fprintf(fid, '%d)\n', q(i,d)); 23 | end 24 | 25 | fclose(fid); 26 | 27 | -------------------------------------------------------------------------------- /demos/Conlex index/main/cycle.m: -------------------------------------------------------------------------------- 1 | function orbit = cycle(tree, s, P, period) 2 | 3 | % Finds a periodic orbit of length "period" containing initial guess s. 4 | 5 | n = size(P,1); 6 | Im = find(P*flags(s,n)); 7 | i = 1; 8 | orbit_length = 0; 9 | 10 | if (period == 1), 11 | if ismember(s,Im), 12 | orbit = s; 13 | else 14 | orbit = []; 15 | end 16 | orbit_length = 1; 17 | end 18 | 19 | while orbit_length~=period 20 | if i > length(Im), 21 | orbit = []; 22 | break; 23 | end 24 | 25 | orbit = shortest_path(P, Im(i), s); 26 | orbit_length = size(orbit); 27 | i = i+1; 28 | end 29 | 30 | -------------------------------------------------------------------------------- /demos/Conlex index/main/grow_isolated.m: -------------------------------------------------------------------------------- 1 | function I = grow_isolated(S, P, tree, depth) 2 | 3 | % Grows an isolating neighborhood containing S. 4 | % P = transition matrix 5 | 6 | % initializing I (vector of box numbers) 7 | I = S; 8 | oI = get_nbhd(tree, I, depth); 9 | 10 | % computing maximal invariant set (vector of box numbers) in a 11 | % neighborhood of I 12 | Inv_oI = oI(find(max_inv_set(P(oI,oI)))); 13 | 14 | % if maximal invariant set in oI is not in interior of oI, expand 15 | % neighborhood by a one box layer 16 | 17 | while ~in_int(tree, Inv_oI, oI, depth) 18 | oI = get_nbhd(tree, Inv_oI, depth); 19 | Inv_oI = oI(find(max_inv_set(P(oI,oI)))); 20 | end 21 | 22 | I = Inv_oI; 23 | -------------------------------------------------------------------------------- /demos/invariant_density.m: -------------------------------------------------------------------------------- 1 | %% GAIO demo: Natural invariant measure of the logistic map 2 | % 3 | 4 | mu = 4; f = @(x) mu*x.*(1-x); % the logistic map 5 | n = 300; X = linspace(-1,1,n)'; % uniform grid of sample points 6 | c = [0.5]; r = [0.5]; t = Tree(c, r); % the tree 7 | 8 | %% Construct full subdivison 9 | sd = 8; depth = 14; 10 | for i=1:depth, 11 | t.set_flags('all', sd); 12 | t.subdivide; 13 | end 14 | 15 | %% Compute invariant vector 16 | P = tpmatrix(t, f, X, depth, 0); 17 | [v,lambda] = eigs(P,1); 18 | 19 | %% Plot invariant density 20 | n = t.count(depth); x = linspace(0,1,n); 21 | h = abs(v)*n./norm(v,1); 22 | bar(x,h,1); axis([0 1 0 10]); 23 | xlabel('x'); ylabel('density'); 24 | -------------------------------------------------------------------------------- /demos/Conlex index/henon-X.dat: -------------------------------------------------------------------------------- 1 | dimension 2 2 | (-47,116) 3 | (-46,116) 4 | (-45,115) 5 | (-45,116) 6 | (-44,115) 7 | (-44,116) 8 | (-49,117) 9 | (-49,118) 10 | (-48,117) 11 | (-48,118) 12 | (-47,117) 13 | (-47,118) 14 | (-46,117) 15 | (-45,117) 16 | (-44,117) 17 | (-42,114) 18 | (-43,115) 19 | (-43,116) 20 | (-42,115) 21 | (-42,116) 22 | (-41,114) 23 | (-40,113) 24 | (-40,114) 25 | (-41,115) 26 | (-40,115) 27 | (113,-49) 28 | (113,-48) 29 | (114,-48) 30 | (113,-47) 31 | (114,-47) 32 | (114,-46) 33 | (115,-47) 34 | (115,-46) 35 | (116,-47) 36 | (116,-46) 37 | (115,-45) 38 | (116,-45) 39 | (116,-44) 40 | (117,-45) 41 | (117,-44) 42 | (118,-44) 43 | (117,-43) 44 | (118,-43) 45 | (118,-42) 46 | (119,-43) 47 | (119,-42) 48 | (119,-41) 49 | -------------------------------------------------------------------------------- /demos/Conlex index/main/build_ip.m: -------------------------------------------------------------------------------- 1 | function [X, A] = build_ip(tree, depth, I, P) 2 | 3 | % Building modified combinatorial index pairs for the combinatorial isolating neighborhood I. 4 | 5 | n = tree.count(depth); 6 | oI = get_nbhd(tree, I, depth); 7 | 8 | % initial X 9 | FI = find(P*flags(I,n)); 10 | X = union(I, FI); 11 | 12 | % initial A (restricted to neighborhood of I) 13 | A = setdiff(X, I); 14 | A = intersect(A, oI); 15 | 16 | new = [1]; 17 | 18 | while (~isempty(new)) 19 | % image of A (restricted to neighborhood of I) 20 | FA = find(P*flags(A,n)); 21 | FA = intersect(FA, oI); 22 | 23 | % new boxes in oI to be added to A 24 | new = setdiff(FA, A); 25 | % new A 26 | A = union(A, new); 27 | end 28 | 29 | % new X 30 | X = union(I, A); 31 | 32 | -------------------------------------------------------------------------------- /demos/Conlex index/henon-B.dat: -------------------------------------------------------------------------------- 1 | dimension 2 2 | (-54,119) 3 | (-54,120) 4 | (-52,118) 5 | (-53,119) 6 | (-53,120) 7 | (-52,119) 8 | (-52,120) 9 | (-51,118) 10 | (-50,117) 11 | (-50,118) 12 | (-51,119) 13 | (-50,119) 14 | (-49,117) 15 | (-49,118) 16 | (-40,113) 17 | (-40,114) 18 | (-41,115) 19 | (-40,115) 20 | (-38,112) 21 | (-37,112) 22 | (-36,112) 23 | (-39,113) 24 | (-39,114) 25 | (-38,113) 26 | (-38,114) 27 | (-37,113) 28 | (-37,114) 29 | (-36,113) 30 | (-35,112) 31 | (111,-50) 32 | (112,-50) 33 | (111,-49) 34 | (112,-49) 35 | (112,-48) 36 | (113,-49) 37 | (113,-48) 38 | (113,-47) 39 | (119,-43) 40 | (119,-42) 41 | (120,-42) 42 | (119,-41) 43 | (119,-40) 44 | (120,-41) 45 | (120,-40) 46 | (120,-39) 47 | (121,-41) 48 | (121,-40) 49 | (122,-40) 50 | (121,-39) 51 | -------------------------------------------------------------------------------- /demos/double_gyre_map.m: -------------------------------------------------------------------------------- 1 | function y = double_gyre_map(x) 2 | 3 | global tau; 4 | 5 | A = 0.25; eps = 0.25; om = 2*pi; 6 | n = 40; h = tau/n; t = 0; 7 | 8 | function y = v(x) 9 | 10 | function y = f(x,t) 11 | y = eps*sin(om*t).*x.^2 + (1-2*eps*sin(om*t)).*x; 12 | end 13 | 14 | function y = df(x,t) 15 | y = 2*eps*sin(om*t).*x + (1-2*eps*sin(om*t)); 16 | end 17 | 18 | y = [-pi*A*sin(pi*f(x(:,1),x(:,3))).*cos(pi*x(:,2)) ... 19 | pi*A*cos(pi*f(x(:,1),x(:,3))).*sin(pi*x(:,2)).*df(x(:,1),x(:,3)) ... 20 | ones(size(x,1),1)]; 21 | end 22 | 23 | X = [x ones(size(x,1),1)*t]; 24 | z = rk4(@v,X,h,n); 25 | y = z(:,1:2); 26 | 27 | end 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Contents.m: -------------------------------------------------------------------------------- 1 | % GAIO 2 | % 3 | % GAIO is a toolbox for the set oriented numerical analysis of 4 | % dynamical systems. It provides data structures and algorithms 5 | % for the computation of 6 | % - invariant sets (maximal invariant set, chain recurrent set, 7 | % periodic points, global attractor); 8 | % - invariant manifolds (stable/unstable manifold of an arbitrary 9 | % invariant set); 10 | % - invariant measures, almost invariant sets 11 | % - value functions for optimal control problems 12 | % 13 | % data structure 14 | % Tree - basic data structure for storing the set collections 15 | % 16 | % functions 17 | % tpgraph - transition probability graph 18 | % dpgraph - dynamic programming graph 19 | % dijkstra - shortest paths in a directed graph 20 | % boxplot2/3 - box plot in 2D and 3D 21 | -------------------------------------------------------------------------------- /matlab/crs.m: -------------------------------------------------------------------------------- 1 | function crs(t, f, X, depth) 2 | 3 | dim = t.dim; hit = 1; sd = 8; tic 4 | for d = 1:depth 5 | t.set_flags('all', sd); % flag all boxes for subdivision 6 | t.subdivide(sd); % subdivide flagged boxes 7 | G = tpmatrix(t, f, X, t.depth, 0); % compute transition matrix/graph 8 | sc = scc(G,G'); % strongly connected components of G 9 | sc(find(sc > -1)) = 1; % sc == -1 means that the box is not contained in any scc 10 | sc(find(sc == -1)) = 0; 11 | flags = sprintf('%1d', sc); 12 | t.set_flags(flags, hit); % flag boxes which are contained in some scc 13 | t.remove(hit); % remove flagged boxes 14 | fprintf('depth %d, %d boxes, %.1f sec\n',t.depth,t.count(-1),toc); 15 | end 16 | -------------------------------------------------------------------------------- /demos/Conlex index/main/nbhd_graph.m: -------------------------------------------------------------------------------- 1 | function N = nbhd_graph(tree, depth) 2 | 3 | % N = nbhd_graph(T, D) 4 | % computes a sparse matrix N of dimension b, where b is the number of 5 | % boxes on depth D of the tree T such that if two boxes B_i, B_j 6 | % intersect (at the boundary) then the (i,j)-th entry of N is nonzero 7 | 8 | d = tree.dim; 9 | no_of_points = 3^d; 10 | n = tree.count(depth); 11 | N = sparse([],[],[],n,n,n*(no_of_points-1)); 12 | grid = Points('Grid', d, no_of_points); 13 | 14 | i = 1; 15 | b = tree.first_box(depth); 16 | while (~isempty(b)) 17 | c = b(1:d); 18 | % this is kind of ad hoc 19 | r = b(d+1:2*d) + 1e-8*b(d+1:2*d); 20 | p = grid.get(c, r); 21 | v = tree.search(p, depth); 22 | I = find(v > 0); 23 | N(i,v(I)) = 1; 24 | i = i + 1; 25 | b = tree.next_box(depth); 26 | end 27 | 28 | delete(grid); -------------------------------------------------------------------------------- /demos/Conlex index/main/in_int.m: -------------------------------------------------------------------------------- 1 | function in = in_int(tree, S, N, depth) 2 | 3 | % in_int(tree, S, N, depth) 4 | % checks, whether the set S is contained in the interior of the set N 5 | % (S, N vectors of box numbers) 6 | 7 | d = tree.dim; 8 | if d~=2, error('current implementation restricted to 2d.'); end 9 | no_of_points = 3^d; 10 | n = 3; x = linspace(-1,1,n)'; 11 | [XX,YY] = meshgrid(x,x); 12 | X = [ XX(:) YY(:) ]; 13 | 14 | b = tree.boxes(depth); 15 | Nf = zeros(size(b,2),1); 16 | Nf(N) = 1; 17 | S = S(:); 18 | 19 | in = 1; 20 | for i = 1:size(S,1), 21 | c = b(1:d,S(i)); 22 | r = b(d+1:2*d, S(i)) + 0.1*b(d+1:2*d, S(i)); 23 | p = X*diag(r) + ones(size(X))*diag(c); % sample points in current box 24 | s = tree.search(p', depth); 25 | if sum(Nf(s(find(s>0))))<(length(s)-length(s(find(s<0)))), 26 | in = 0; 27 | break; 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /compile.m: -------------------------------------------------------------------------------- 1 | %% script for compiling the C-core of GAIO 2 | % You only need to call this script if you work on a (currently) 3 | % unsupported platform, i.e. there is no need to call this script 4 | % on Mac/Intel, Linux/Intel and Windows/Intel platforms. 5 | % 6 | % Note: Your Matlab mex compiler needs to be be setup first ('mex -setup') 7 | 8 | cd matlab 9 | mex -largeArrayDims -D_MEASURE_ -I../lib tree_.c "../lib/*.c" 10 | mex -largeArrayDims -D_MEASURE_ -I../lib dijkstra.c "../lib/*.c" 11 | mex -largeArrayDims -D_MEASURE_ -I../lib scc.c "../lib/*.c" 12 | mex -largeArrayDims -D_MEASURE_ -I../lib subshift.c "../lib/*.c" 13 | mex -largeArrayDims -D_MEASURE_ -I../lib fwd_inv_set.c "../lib/*.c" 14 | cd ..; cd @Tree 15 | mex -D_MEASURE_ -I../lib subsref.c "../lib/*.c" 16 | mex -D_MEASURE_ -I../lib subsasgn.c "../lib/*.c" 17 | mex -D_MEASURE_ -I../lib delete.c "../lib/*.c" 18 | cd .. 19 | 20 | -------------------------------------------------------------------------------- /demos/lyapunov_logistic.m: -------------------------------------------------------------------------------- 1 | %% GAIO demo: largest Lyapunov exponents 2 | % 3 | mu = 4; f = @(x) mu*x.*(1-x); % the logistic map 4 | df = @(x) mu*(1-2*x); 5 | 6 | %% compute Lyapunov exponent 7 | x = 0.95; 8 | N = 1e5; clear lam 9 | lam(1) = log(abs(df(x))); 10 | for n = 1:N 11 | x = f(x); 12 | lam(n+1) = 1/(n+1)*(n*lam(n) + log(abs(df(x)))); 13 | end 14 | %loglog(abs(lam)) 15 | lam(end) 16 | 17 | %% Lyapunov exponent via spatial integration 18 | n = 10; X = linspace(-1,1,n)'; % uniform grid of sample points 19 | c = [0.5]; r = [0.5]; t = Tree(c, r); % the tree 20 | sd = 8; depth = 18; dx = 1/2^depth; 21 | for i = 1:depth, 22 | t.set_flags('all', sd); 23 | t.subdivide; 24 | end 25 | b = t.boxes(depth); c = b(1,:); 26 | P = tpmatrix(t, f, X, depth, 0); 27 | [v,e] = eigs(P,1); e 28 | %% 29 | h = v/sum(v)*1/dx; 30 | lambda = sum(log(abs(df(c))).*h'*dx) 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /demos/chain_recurrent.m: -------------------------------------------------------------------------------- 1 | % GAIO demo 2 | % chain recurrent set for the Henon map 3 | 4 | % Henon map 5 | a = 1.3; b = 0.2; 6 | f = @(x) [1-a*x(:,1).^2+x(:,2)./5 b*x(:,1)*5]; 7 | % sample points on the edges of the unit square 8 | n = 40; X1 = linspace(-1,1,n)'; 9 | X = [ X1 -ones(size(X1)); X1 ones(size(X1)); -ones(size(X1)) X1; ones(size(X1)) X1]; 10 | % the tree 11 | c = [0 0]; r = [1.5 1.5]; t = Tree(c, r); 12 | 13 | %% subdivision algorithm 14 | dim = t.dim; hit = 1; sd = 8; depth = 14; tic 15 | for d = 1:depth 16 | t.set_flags('all', sd); 17 | t.subdivide; 18 | G = tpmatrix(t, f, X, d, 1); 19 | sc = scc(G,G'); 20 | sc(find(sc > -1)) = 1; sc(find(sc == -1)) = 0; 21 | flags = sprintf('%1d', sc); 22 | t.set_flags(flags, hit); 23 | t.remove(hit); 24 | fprintf('step %d: %d boxes\r', d, t.count(-1)); 25 | end 26 | 27 | %% plot 28 | boxplot2(t); xlabel('x'); ylabel('y'); 29 | 30 | %% clean up 31 | delete(t); -------------------------------------------------------------------------------- /demos/almost_invariant_sets.m: -------------------------------------------------------------------------------- 1 | % GAIO demo 2 | % almost invariant sets in the standard map 3 | 4 | %% standard map 5 | a = 0.971635; 6 | f = @(x) mod([ x(:,1) + x(:,2) + a*sin(x(:,1)), x(:,2) + a*sin(x(:,1)) ],2*pi); 7 | 8 | %% tree 9 | n = 10; x = linspace(-1,1,n)'; [XX,YY] = meshgrid(x,x); 10 | X = [ XX(:) YY(:) ]; % sample points (uniform grid) 11 | c = [pi pi]; r = [pi pi]; 12 | tree = Tree(c, r); % the box collection 13 | sd = 8; depth = 14; 14 | for i = 1:depth, 15 | tree.set_flags('all', sd); % flag all leaves 16 | tree.subdivide; % subdivide all flagged leaves 17 | end 18 | 19 | %% Ulam matrix 20 | P = tpmatrix(tree, f, X, depth, 1); 21 | [xh,lambda] = eigs(P,4,'LR'); 22 | l = diag(lambda) 23 | 24 | %% plot of second eigenvector 25 | clf; ev = xh(:,3)/norm(xh(:,3),inf); 26 | boxplot2(tree,'depth',depth,'density',ev); 27 | axis tight; axis square; shading flat;colorbar; %caxis([-1,1]); 28 | 29 | -------------------------------------------------------------------------------- /matlab/fwd_inv_set.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | double *D, *I; 5 | 6 | struct GRAPH { 7 | int n; 8 | mwIndex *ep; 9 | mwIndex *edge; 10 | double *ew; 11 | } graph; 12 | 13 | int fis_rec(int n) { 14 | int j; 15 | 16 | if (I[n] > 0) return 1; 17 | if (D[n] > 0) return 0; 18 | 19 | I[n] = 1; 20 | for (j=(graph.ep)[n]; j<(graph.ep)[n+1]; j++) 21 | if (fis_rec((graph.edge)[j])) return 1; 22 | 23 | I[n] = 0; 24 | D[n] = 1; 25 | 26 | return 0; 27 | } 28 | 29 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 30 | 31 | int n; 32 | 33 | if (!mxIsSparse(prhs[0])) 34 | mexErrMsgTxt("first parameter must be sparse."); 35 | 36 | graph.n = mxGetM(prhs[0]); 37 | graph.ep = mxGetJc(prhs[0]); 38 | graph.edge = mxGetIr(prhs[0]); 39 | 40 | plhs[0] = mxCreateDoubleMatrix(1, graph.n, mxREAL); 41 | I = mxGetPr(plhs[0]); 42 | D = (double *)mxCalloc((unsigned)(graph.n),sizeof(double)); 43 | 44 | for (n=0; n0)); 21 | if (length(I) > 0) 22 | [I,J,S] = find(sparse(I, no, 1, N, N)); 23 | if k+length(I) > length(ijs) 24 | ijs = [ijs; zeros(size(ijs,1),3)]; 25 | end 26 | ijs(k:k+length(I)-1,:) = [I J S]; 27 | end 28 | k = k + length(I); 29 | b = t.next_box(d); 30 | no = no + 1; 31 | end 32 | T = sparse(ijs(1:k-1,1), ijs(1:k-1,2), ijs(1:k-1,3), N, N); 33 | cs = sum(T); 34 | T = T*spdiags(1./cs', 0, N, N); 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /demos/Conlex index/main/henon_bias.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Bias2.h" 4 | #include "types.h" 5 | #include 6 | 7 | double a = 1.4, b = 0.3; 8 | 9 | void rhs(int dim, INTERVAL_VECTOR& x, INTERVAL_VECTOR& y) { 10 | y(1) = a - x(1)*x(1) + b*x(2); 11 | y(2) = x(1); 12 | } 13 | 14 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 15 | { 16 | BIASINTERVAL *pR; 17 | BIASINTERVAL *pA; 18 | double *pa; 19 | double *pr; 20 | unsigned int Arows, Acols; 21 | int i, j, Aclass; 22 | 23 | BiasInit(); 24 | 25 | Arows = mxGetM(prhs[0])/2; 26 | if (Arows!=2) mexErrMsgTxt("input interval matrix must be 2 x n."); 27 | Acols = mxGetN(prhs[0]); 28 | 29 | pA = (BIASINTERVAL *) mxGetPr(prhs[0]); 30 | 31 | //for (i=0; i0)); 21 | if (length(I) > 0) 22 | [I,J,S] = find(sparse(I, no, 1, N, N)); 23 | if k+length(I) > length(ijs) 24 | ijs = [ijs; zeros(size(ijs,1),3)]; 25 | end 26 | ijs(k:k+length(I)-1,:) = [I J S]; 27 | end 28 | k = k + length(I); 29 | b = t.next_box(d); 30 | no = no + 1; 31 | if ~rem(no,floor(N/100)), 32 | fprintf('\b\b\b\b%3d%%',ceil(no*100/N)); 33 | end 34 | end 35 | T = sparse(ijs(1:k-1,1), ijs(1:k-1,2), ijs(1:k-1,3), N, N); 36 | cs = sum(T); 37 | T = T*spdiags(1./cs', 0, N, N); 38 | fprintf('\n'); 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /demos/Conlex index/main/conn_comp_map.m: -------------------------------------------------------------------------------- 1 | function [G, C, Length_comp] = conn_comp_map(I, tree, depth, P) 2 | 3 | %% Computes graph G (from P) on connected components of I, 4 | %% on component C(:,i), with length Length_comp(i) 5 | 6 | b = tree.boxes(depth); 7 | n = tree.count(depth); 8 | 9 | % Partitioning into connected components; 10 | no_comp = 1; 11 | N = nbhd_graph(tree, depth); 12 | Comp = conn_comp(N, I, I(1)); 13 | add = length(I) - length(Comp); 14 | Comp_full = [Comp'; zeros(add,1)]; 15 | C = Comp_full; 16 | Length_comp = zeros(length(I)); 17 | Length_comp(no_comp) = length(Comp); 18 | remaining = setdiff(I, Comp); 19 | 20 | 21 | 22 | while (~isempty(remaining)) 23 | Comp = conn_comp(N, I, remaining(1)); 24 | add = length(I) - length(Comp); 25 | Comp_full = [Comp'; zeros(add,1)]; 26 | C = [C Comp_full]; 27 | remaining = setdiff(remaining, Comp); 28 | no_comp = no_comp+1; 29 | Length_comp(no_comp) = length(Comp); 30 | end 31 | 32 | G = zeros(no_comp, no_comp); 33 | 34 | for j = 1:no_comp 35 | Comp = C(1:Length_comp(j),j); 36 | FC = find(P*flags(Comp,n)); 37 | for i = 1:no_comp 38 | if (~isempty(intersect(C(:,i), FC))), G(i,j)=1; 39 | end 40 | end 41 | end 42 | 43 | -------------------------------------------------------------------------------- /lib/gaio/Set.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Oliver Junge, for details see COPYING 3 | * 4 | * Set.h 5 | * 6 | */ 7 | 8 | #ifndef _Set_h 9 | #define _Set_h 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | static int __Set_no = 0; 16 | 17 | typedef struct _SetElement SetElement; 18 | 19 | struct _SetElement { 20 | int no; 21 | void *ptr; 22 | void (*Free)(void**); 23 | void (*Info)(FILE *out, int, void *); 24 | SetElement *parent, *child[2]; 25 | }; 26 | 27 | typedef struct { 28 | int no_of_elements; 29 | SetElement *root; 30 | } Set; 31 | 32 | SetElement *SetElementNew(int no, void *ptr, void (*Free)(void**), 33 | void (*Info)(FILE*, int, void*)); 34 | void SetElementFree(SetElement **s); 35 | int SetElementInsert(SetElement *s, SetElement *node); 36 | void SetElementPushToStack(SetElement *se, Stack *st); 37 | SetElement *SetElementContains(SetElement *s, int no); 38 | void SetElementInfo(FILE *out, int n, SetElement *sn); 39 | 40 | Set *SetNew(); 41 | void SetFree(Set **set); 42 | Stack *SetToStack(Set *s); 43 | int SetInsert(Set *s, SetElement *node); 44 | SetElement *SetContains(Set *s, int no); 45 | void SetInfo(FILE *out, int n, Set *s); 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /demos/topological_entropy.m: -------------------------------------------------------------------------------- 1 | % GAIO 3.0 demo 2 | % topological entropy of the Henon map 3 | 4 | % Henon map 5 | a = 1.4; b = 0.3; 6 | f = @(x) [1 - a*x(:,1).^2 + b*x(:,2) x(:,1)]; 7 | % sample points on agrid 8 | n = 40; X1 = linspace(-1,1,n)'; 9 | [XX,YY] = meshgrid(X1,X1); X = [ XX(:) YY(:) ]; 10 | % the tree 11 | c = [0 0]; r = [1.5 1.5]; t = Tree(c, r); 12 | 13 | %% subdivision algorithm for the chain recurrent sets 14 | dim = t.dim; hit = 1; sd = 8; depth = 16; tic 15 | for d = 1:depth 16 | t.set_flags('all', sd); 17 | t.subdivide; 18 | G = tpgraph_out(t, f, X, d); % not rigorous yet !! 19 | sc = scc(G,G'); 20 | sc(find(sc > -1)) = 1; sc(find(sc == -1)) = 0; 21 | flags = sprintf('%1d', sc); 22 | t.set_flags(flags, hit); 23 | t.remove(hit); 24 | fprintf('step %d: %d boxes\r', d, t.count(-1)); 25 | end 26 | 27 | %% computing the entropy 28 | tic; depth = 16; 29 | b = t.boxes(depth); 30 | letters = zeros(size(b,2),1); 31 | I = find(b(2,:) > 0); letters(I) = 1; 32 | % note: tow letters suffice here (since entropy <= log(2)) 33 | G = tpgraph_out(t, f, X, depth); 34 | start = 2; 35 | [i,j,e] = subshift(G, uint8(letters), start); S = sparse(i,j,e); 36 | l = eigs(S); log(max(l)) 37 | toc 38 | 39 | %% clean up 40 | delete(t); 41 | -------------------------------------------------------------------------------- /lib/gaio/Node.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Oliver Junge, for details see COPYING 3 | * 4 | * Node.h 5 | * 6 | */ 7 | 8 | #ifndef _Node_h 9 | #define _Node_h 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | static int __Node_no = 0; 16 | 17 | typedef struct _Node Node; 18 | 19 | struct _Node { 20 | int sof; /* number of node of sofic graph */ 21 | int sub; /* number within the induced subshift */ 22 | unsigned long flags; /* indicating, which letters have been parsed */ 23 | Set *childs; 24 | }; 25 | 26 | /* creates and returns new node */ 27 | Node *NodeNew(int sof); 28 | 29 | /* deletes node *node and all children, sets *node=0 */ 30 | void NodeFree(Node **node); 31 | 32 | /* inserts (or finds) a (new) node with number sof in the childs of 33 | parent, returns the inserted (or found) node */ 34 | Node *NodeInsert(Node *parent, int sof); 35 | 36 | /* prints some information about the node on the stream out */ 37 | void NodeInfo(FILE *out, int n, Node *node); 38 | 39 | /* saves the node to the stream out */ 40 | void NodeSave(FILE *out, Node *node); 41 | 42 | /* loads a node from the stream in */ 43 | Node *NodeLoad(FILE *in); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /demos/Conlex index/henon-Y.dat: -------------------------------------------------------------------------------- 1 | dimension 2 2 | (-47,116) 3 | (-46,116) 4 | (-45,115) 5 | (-45,116) 6 | (-44,115) 7 | (-44,116) 8 | (-54,119) 9 | (-54,120) 10 | (-52,118) 11 | (-53,119) 12 | (-53,120) 13 | (-52,119) 14 | (-52,120) 15 | (-51,118) 16 | (-50,117) 17 | (-50,118) 18 | (-51,119) 19 | (-50,119) 20 | (-49,117) 21 | (-49,118) 22 | (-48,117) 23 | (-48,118) 24 | (-47,117) 25 | (-47,118) 26 | (-46,117) 27 | (-45,117) 28 | (-44,117) 29 | (-42,114) 30 | (-43,115) 31 | (-43,116) 32 | (-42,115) 33 | (-42,116) 34 | (-41,114) 35 | (-40,113) 36 | (-40,114) 37 | (-41,115) 38 | (-40,115) 39 | (-38,112) 40 | (-37,112) 41 | (-36,112) 42 | (-39,113) 43 | (-39,114) 44 | (-38,113) 45 | (-38,114) 46 | (-37,113) 47 | (-37,114) 48 | (-36,113) 49 | (-35,112) 50 | (111,-50) 51 | (112,-50) 52 | (111,-49) 53 | (112,-49) 54 | (112,-48) 55 | (113,-49) 56 | (113,-48) 57 | (114,-48) 58 | (113,-47) 59 | (114,-47) 60 | (114,-46) 61 | (115,-47) 62 | (115,-46) 63 | (116,-47) 64 | (116,-46) 65 | (115,-45) 66 | (116,-45) 67 | (116,-44) 68 | (117,-45) 69 | (117,-44) 70 | (118,-44) 71 | (117,-43) 72 | (118,-43) 73 | (118,-42) 74 | (119,-43) 75 | (119,-42) 76 | (120,-42) 77 | (119,-41) 78 | (119,-40) 79 | (120,-41) 80 | (120,-40) 81 | (120,-39) 82 | (121,-41) 83 | (121,-40) 84 | (122,-40) 85 | (121,-39) 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GAIO 2 | 3 | A Matlab toolbox for the global analysis of invariant objects in dynamical systems. GAIO provides data structures and algorithms for the set-oriented computation of 4 | * invariant sets (maximal invariant set, chain recurrent set, periodic points, global attractor) of arbitrary dimension or topology 5 | * invariant manifolds (stable/unstable manifold of an arbitrary invariant set) 6 | * invariant measures, almost invariant sets, coherent sets 7 | * value functions for optimal control problems 8 | 9 | ## Installation 10 | 11 | After unpacking the archive add the resulting folder to your Matlab path, e.g. 12 | 13 | >> addpath(genpath('/Users/gaioguy/GAIO')) 14 | 15 | ## References 16 | 17 | * Dellnitz, M.; Froyland, G.; Junge, O.: The algorithms behind GAIO - Set oriented numerical methods for dynamical systems, 18 | _in: B. Fiedler (ed.): Ergodic theory, analysis, and efficient simulation of dynamical systems_, Springer, 2001. 19 | * Dellnitz, M.; Junge, O.: On the approximation of complicated dynamical behavior, _SIAM Journal on Numerical Analysis_, 36 (2), 1999. 20 | * Dellnitz, M.; Hohmann, A.: A subdivision algorithm for the computation of unstable manifolds and global attractors. 21 | _Numerische Mathematik_ 75, pp. 293-317, 1997. 22 | 23 | 24 | -------------------------------------------------------------------------------- /demos/ftle.m: -------------------------------------------------------------------------------- 1 | global tau ; 2 | tau = 10; 3 | f = @(x) double_gyre_map(x); 4 | 5 | %% constructing the box partition 6 | c = [1 0.5]; r = [1 0.5]; 7 | t = Tree(c, r); 8 | dim = t.dim; sd = 8; depth = 12; % depth 12 means 2^12 boxes, i.e. 2^6=64 in each direction 9 | for i=1:depth, 10 | t.set_flags('all', sd); % flag all leaves for subdivision 11 | t.subdivide; % subdivide flagged leaves 12 | end 13 | 14 | %% computing the FTLE field 15 | n = 20; X = 2*rand(n,2)-1; % sample points 16 | h = 1e-6; ftle = zeros(t.count(-1),1); 17 | b = t.first_box(-1); k = 1; 18 | while (~isempty(b)) 19 | c = b(1:dim); r = b(dim+1:2*dim); % center and radius of current box 20 | p = X*diag(r) + ones(size(X))*diag(c); % sample points in the current box 21 | q = X*diag(r) + ones(size(X))*diag(c)+h*(2*rand(size(X,1),2)-1); % slightly shifted sample points 22 | d = sum(((f(p)-f(q)).^2)')./sum(((p-q).^2)'); % relative distances of their images 23 | ftle(k) = max(log(d)/(2*tau)); % the FTLE in that box 24 | if rem(k,100)==0 disp(sprintf('box no %d',k)); end 25 | b = t.next_box(-1); k = k+1; 26 | end 27 | toc 28 | 29 | %% plot 30 | clf; boxplot2(t,'density', ftle); colormap hot; shading flat 31 | 32 | -------------------------------------------------------------------------------- /demos/cyclic.m: -------------------------------------------------------------------------------- 1 | %% GAIO demo 2 | % extraction of cyclic behaviour 3 | 4 | alpha = -1.7; % map from "On the approximation of complicated behaviour" 5 | ft = @(z) exp(-(2*pi*i)/3)*((abs(z).^2+alpha).*z+0.5*conj(z).^2); 6 | f = @(x) [real(ft(x(:,1)+i*x(:,2))) imag(ft(x(:,1)+i*x(:,2)))]; 7 | n = 10; x = linspace(-1,1,n)'; [XX,YY] = meshgrid(x,x); 8 | X = [ XX(:) YY(:) ]; % sample points (uniform grid) 9 | c = [0 0]; r = [1 1]; B = Tree(c, r); % the box collection B 10 | depth = 14; 11 | rga(B, f, X, depth); % compute attractor 12 | P = tpmatrix(B, f, X, depth,'1'); % transition matrix 13 | [rho,lambda] = eigs(P,6); % eigenvectors 14 | l = diag(lambda) 15 | 16 | %% extracting cyclic behaviour 17 | r = 6; 18 | [m2,I] = max(min(abs(rho)')'); % index where none of the rhos vanishes 19 | v = rho*diag(1./rho(I,:)); % scale by that component 20 | u = v*[l l.^2 l.^3 l.^4 l.^5 l.^6]; % transform into desired basis 21 | 22 | %% plot of the invariant density 23 | w = abs(rho(:,1))/norm(rho(:,1),1); 24 | boxplot2(B,'density',log10(w)); shading flat; c = colorbar; 25 | axis([-1 1 -1 1]); xlabel('Re'); ylabel('Im'); 26 | 27 | %% plot of the cyclic components 28 | clf; 29 | for k = 1:r 30 | cols = ['r', 'b', 'g', 'c', 'k', 'm']; 31 | I = find(abs(u(:,k))>1e-8); b = B.boxes(depth); 32 | boxplot2(b(1:4,I)','color',cols(k),'edgecolor',cols(k)); 33 | xlabel('Re'); ylabel('Im'); 34 | end 35 | 36 | -------------------------------------------------------------------------------- /matlab/dpgraph.m: -------------------------------------------------------------------------------- 1 | function A = dpgraph(t, f, X, U, depth) 2 | 3 | % DPGRAPH dynamic programming graph 4 | % dpgraph(t, f, X, U, depth) computes a graph of transition 5 | % costs between the boxes at level depth of the tree t using 6 | % the map f with sample points X and inputs U 7 | % 8 | % inputs: 9 | % t GAIO tree 10 | % f map, f(X,U) maps mxd-matrix X and mxp-matrix U to 11 | % a mx(d+1)-matrix, the additional column contains 12 | % the transition costs 13 | % X m x d-matrix of sample points 14 | % U m x p-matrix of control inputs (one for each sample points) 15 | 16 | dim = t.dim; n = t.count(depth); 17 | ijs = zeros(n,3); 18 | E = ones(size(U,1),1); D = ones(size(X,1),1); 19 | no = 1; k = 1; 20 | b = t.first_box(depth); dispr('computing cost graph\n',0); 21 | while (~isempty(b)) 22 | c = b(1:dim); r = b(dim+1:2*dim); 23 | P = X*diag(r) + ones(size(X))*diag(c); 24 | fP = f(kron(E,P), kron(U,D))'; 25 | bn = t.search(fP(1:dim,:), depth); 26 | Ibn = find(bn > -1); 27 | [B,I,J] = unique(bn(Ibn)); 28 | if k+length(B) > size(ijs,1), 29 | ijs = [ijs; zeros(n,3)]; 30 | end 31 | for l=0:length(B)-1, 32 | ijs(k+l,3) = min(fP(dim+1,Ibn(find(J==(l+1))))); 33 | end 34 | ijs(k:k+length(B)-1,1:2) = [B ones(length(B),1)*no]; 35 | k = k+length(B); 36 | dispr(sprintf('box no %d', no),1); 37 | no = no + 1; 38 | b = t.next_box(depth); 39 | end 40 | A = sparse(ijs(1:k-1,1), ijs(1:k-1,2), ijs(1:k-1,3), n, n); 41 | -------------------------------------------------------------------------------- /demos/value_function.m: -------------------------------------------------------------------------------- 1 | %% value function for an inverted pendulum on a cart 2 | 3 | m = 2; M = 8; l = 0.5; g = 9.8; q1 = 0.1; q2 = 0.05; r0 = 0.01; m_r = m/(m+M); 4 | v = @(x,u) [ x(:,2), ... % vector field of the pedulum 5 | (g/l*sin(x(:,1)) - 0.5*m_r*x(:,2).^2.*sin(2*x(:,1)) - ... 6 | m_r/(m*l)*u.*cos(x(:,1)))./(4.0/3.0 - m_r*cos(x(:,1)).^2), ... 7 | 0.5*( q1*(x(:,1).^2) + q2*(x(:,2).^2) + r0*u.^2 )]; 8 | h = 0.02; steps = 5; % step size and # of steps 9 | f = @(x,u) rk4u(v,[x zeros(size(x,1),1)],u,h,steps); % control system 10 | n = 2; x = linspace(-1,1,n)'; [XX,YY] = meshgrid(x,x); 11 | X = [ XX(:) YY(:) ]; % sample points 12 | U = linspace(-128,128,33)'; % control samples 13 | 14 | depth = 16; c = [1e-5 1e-5]; r = [8 10]; 15 | tree = Tree(c, r); % construct full tree 16 | for i = 1:depth, 17 | tree.set_flags('all', 8); tree.subdivide; 18 | end 19 | A = dpgraph(tree, f, X, U, depth); % compute graph 20 | dest = tree.search([0;0], depth); % find destination box 21 | [V,~] = dijkstra(A', dest); % compute value function 22 | 23 | %% 24 | V(find(V < 0)) = Inf; 25 | clf; boxplot2(tree, 'density', max(min(V,7),0)); % plot value function 26 | colorbar; colormap jet; shading flat; axis('tight') 27 | 28 | -------------------------------------------------------------------------------- /demos/implicit_manifold.m: -------------------------------------------------------------------------------- 1 | %% GAIO demo: Computing implicitely defined manifolds 2 | % 3 | 4 | %% Definition of the manifold 5 | % Here is the Devils's curve: 6 | a = 0.9; b = 1; 7 | H = @(x) x(:,1).^2.*(x(:,1).^2-b^2) - x(:,2).^2.*(x(:,2).^2-a^2); 8 | 9 | %% Preparations 10 | n = 20; x = linspace(-1,1,n)'; 11 | [XX,YY] = meshgrid(x,x); X = [ XX(:) YY(:) ]; % sample points in the unit square 12 | c = [0 0]; r = [2 2]; t = Tree(c, r); % the box collection 13 | 14 | %% Computing the manifold by a subdivison algorithm 15 | dim = t.dim; depth = 18; 16 | hit = 1; sd = 8; % define some flags 17 | for d = 1:depth, 18 | t.set_flags('all', sd); % flags all boxes for subdivision 19 | t.subdivide; % subdivide all flaged boxes 20 | b = t.first_box(-1); % loop over all leaves of the tree 21 | while (~isempty(b)) 22 | c = b(1:dim); r = b(dim+1:2*dim); % center and radius of the current box 23 | p = X*diag(r) + ones(size(X))*diag(c); % sample points in the current box 24 | if min(sign(H(p)))*max(sign(H(p))) < 0 % check whether box intersects the manifold 25 | t.set_flags(c, hit); % if so, flag box 26 | end 27 | b = t.next_box(-1); 28 | end 29 | t.remove(hit); % remove all *non* flaged boxes 30 | end 31 | 32 | %% Plot 33 | boxplot2(t); xlabel('$x$'); ylabel('$y$'); 34 | 35 | %% Cleanup 36 | delete(t); 37 | -------------------------------------------------------------------------------- /demos/chua.m: -------------------------------------------------------------------------------- 1 | %% GAIO demo 2 | % almost invariant sets in Chua's circuit 3 | 4 | %% the map 5 | a = 16; b = 33; m0 = -0.2; m1 = 0.01; % Chua's circuit 6 | v = @(x) [a*(x(:,2) - m0*x(:,1) - m1/3*x(:,1).^3), ... 7 | x(:,1)-x(:,2)+x(:,3),... 8 | -b*x(:,2)]; 9 | h = 0.05; n = 5; f = @(x) rk4(v,x,h,n); % f is the flow map 10 | 11 | %% preparations 12 | n = 5; x = linspace(-1,1,n)'; [XX,YY,ZZ] = meshgrid(x,x,x); 13 | X = [ XX(:) YY(:) ZZ(:) ]; % sample points 14 | c = [0 0 0]; r = [12, 2.5, 20]; t = Tree(c,r); % the box collection 15 | 16 | %% computing the covering (here, by continuation) 17 | x0 = [sqrt(3*m0/m1) 0 -sqrt(3*m0/m1)]; % equilibrium 18 | depth = 24; t.insert([x0; -x0]', depth); % initialization 19 | gum(t, f, X, depth); % global unstable manifold 20 | 21 | %% computing the measure 22 | X = 2*rand(100,3)-1; % points for MC quadrature 23 | P = tpmatrix(t, f, X, depth, 1); % transition matrix 24 | [w,lambda] = eigs(P,2,'lr',opts); % eigenvectors 25 | 26 | %% plot 27 | % wp = log10(abs(w(:,1))); % uncomment for inv. measure 28 | wp = log10(max(w(:,2),1e-16))-log10(max(-w(:,2),1e-16)); % 2nd eigenvector 29 | clf; boxplot3(t,'depth',depth,'density', wp,'alpha',0.1); 30 | load lorenz_cmap; colormap(cmap); colorbar % special colormap 31 | view(20,20); axis square; axis tight; 32 | xlabel('x'); ylabel('y'); zlabel('z'); 33 | -------------------------------------------------------------------------------- /lib/Node.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Oliver Junge, for details see COPYING 3 | * 4 | * Node.c 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | /* creates a NEW Node */ 12 | Node *NodeNew(int sof) { 13 | Node *node; 14 | NEW1(node, Node*, 1); 15 | 16 | node->sof = sof; 17 | node->sub = 0; 18 | node->flags = 0; 19 | node->childs = SetNew(); 20 | __Node_no++; 21 | 22 | return node; 23 | } 24 | 25 | /* deletes Node *node and recursively all children of it, sets *node=0 */ 26 | void NodeFree(Node **node) { 27 | int i; 28 | if (*node) { 29 | SetFree(&((*node)->childs)); 30 | FREE(*node); 31 | *node = 0; 32 | __Node_no--; 33 | } 34 | } 35 | 36 | Node *NodeInsert(Node *parent, int sof) { 37 | Node *n; 38 | SetElement *s; 39 | 40 | s = SetContains(parent->childs, sof); 41 | if (!s) { 42 | n = NodeNew(sof); 43 | s = SetElementNew(sof, (void *)n, (void (*)(void**))NodeFree, 44 | (void (*)(FILE*, int, void*))NodeInfo); 45 | SetInsert(parent->childs, s); 46 | } else 47 | n = (Node *)s->ptr; 48 | 49 | return n; 50 | } 51 | 52 | void NodeInfo(FILE *out, int n, Node *node) { 53 | if (node) { 54 | fputns(' ', n, out); 55 | fprintf(out, "(%d,%d,%lu)\n", node->sof, node->sub, node->flags); 56 | SetInfo(out, n+7, node->childs); 57 | } 58 | } 59 | 60 | void NodeSave(FILE *out, Node *node) { 61 | if (node) { 62 | } 63 | } 64 | 65 | Node *NodeLoad(FILE *in) { 66 | Node *node; 67 | 68 | return node; 69 | } 70 | 71 | -------------------------------------------------------------------------------- /demos/pickover.m: -------------------------------------------------------------------------------- 1 | % GAIO demo 2 | % attractor of the pickover system 3 | 4 | a = 1.76; b = .4; c = -.6; d = -2.4; % pickover system 5 | f = @(x) [sin(a*x(:,2)) - x(:,3).*cos(b*x(:,1)), ... 6 | x(:,3).*sin(c*x(:,1)) - cos(d*x(:,2)), ... 7 | sin(x(:,1))]; 8 | n = 7; x = linspace(-1,1,n)'; [XX,YY,ZZ] = meshgrid(x,x,x); 9 | X = [ XX(:) YY(:) ZZ(:) ]; % sample points (uniform grid) 10 | c = [0 0 0]; r = [2 2 1]; tree = Tree(c,r); % the box collection 11 | 12 | N = 1e5; x = zeros(N,3); % simulation 13 | for k = 1:N-1, x(k+1,:) = f(x(k,:)); end 14 | plot3(x(:,1),x(:,2),x(:,3),'.'); 15 | 16 | %% Computation of the global unstable manifold 17 | x0 = x(end,:); % some point on the attractor 18 | depth = 21; tree.insert(x0', depth); % construct [x0] 19 | gum(tree, f, X, depth); % compute global unstable manifold 20 | 21 | %% Computation of the invariant measure 22 | X = 2*rand(100,3)-1; % points for Monte Carlo quadrature 23 | P = tpmatrix(tree, f, X, depth, 1); % transition matrix 24 | [w,lambda] = eigs(P,1,'lm'); % compute eigenvector at eigenvalue 1 25 | wp = log10(max(abs(w(:,1)),1e-16)); % plot measure logarithmically 26 | 27 | %% Visualization 28 | boxplot3(tree,'depth',depth,'density', wp ,'alpha',0.1); 29 | load lorenz_cmap; colormap(cmap); % special colormap 30 | view(20,30); axis square; axis tight; 31 | xlabel('x'); ylabel('y'); zlabel('z'); 32 | 33 | %% Cleanup 34 | delete(tree); 35 | -------------------------------------------------------------------------------- /demos/lorenz_measure.m: -------------------------------------------------------------------------------- 1 | 2 | %% GAIO demo: Invariant measure in the Lorenz system 3 | % 4 | 5 | s = 10; rh = 28; b = 0.4; % the Lorenz system 6 | v = @(x) [s*(x(:,2)-x(:,1)) ... 7 | rh*x(:,1)-x(:,2)-x(:,1).*x(:,3) ... 8 | x(:,1).*x(:,2)-b*x(:,3)]; 9 | h = 0.01; n = 10; f = @(x) rk4(v,x,h,n); % f is the flow 10 | 11 | %% Preparations 12 | % choose sample points, construct box tree 13 | n = 7; x = linspace(-1,1,n)'; [XX,YY,ZZ] = meshgrid(x,x,x); 14 | X = [ XX(:) YY(:) ZZ(:) ]; % $7^3$ sample points 15 | c = [0.1 0.1 27]; r = [30 30 40]; 16 | t = Tree(c,r); % the box collection 17 | 18 | %% Computation of the global unstable manifold 19 | a = sqrt(b*(rh-1)); x0 = [a a rh-1;-a -a rh-1]; % equilibria 20 | depth = 21; t.insert(x0', depth); % construct [x0] 21 | gum(t, f, X, depth); % compute global unstable manifold 22 | 23 | %% Computation of the invariant measure 24 | X = 2*rand(100,3)-1; % points for Monte Carlo quadrature 25 | P = tpmatrix(t, f, X, depth, 1); % transition matrix 26 | [w,lambda] = eigs(P,1,'lm'); % compute eigenvector at eigenvalue 1 27 | wp = log10(max(abs(w(:,1)),1e-16)); % plot measure logarithmically 28 | 29 | %% Visualization 30 | boxplot3(t,'depth',depth,'density', wp ,'alpha',0.1); 31 | load lorenz_cmap; colormap(cmap); % special colormap 32 | view(20,30); axis square; axis tight; 33 | xlabel('x'); ylabel('y'); zlabel('z'); 34 | 35 | %% Cleanup 36 | delete(t); 37 | -------------------------------------------------------------------------------- /lib/gaio/IndSubshift.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Oliver Junge, for details see COPYING 3 | * 4 | * IndSubshift.h 5 | * 6 | */ 7 | 8 | #ifndef _IndSubshift_h 9 | #define _IndSubshift_h 10 | 11 | #include 12 | #include 13 | 14 | typedef struct { 15 | int dim_sof; /* dimension of the sofic shift */ 16 | int dim_sub; /* dimension of the induced subshift */ 17 | int max_nodesize; /* maximal size of a hypernode */ 18 | SparseMatrix *A; /* transition matrix of the sofic shift */ 19 | unsigned char *letters; /* letters of nodes in the sofic shift */ 20 | int no_of_letters; /* power of alphabet */ 21 | Node *root; /* of the graph */ 22 | Node *current; 23 | 24 | } IndSubshift; 25 | 26 | IndSubshift *IndSubshiftNew(SparseMatrix *A, unsigned char *letters); 27 | void IndSubshiftFree(IndSubshift **s); 28 | 29 | /* inserts (or finds) a new hypernode in the induced subshift and 30 | returns it */ 31 | Node *IndSubshiftInsert(IndSubshift *s, char *node); 32 | 33 | /* computes a new ("hyper")node of the induced subshift */ 34 | int IndSubshiftNewnode(IndSubshift *s, char letter, char *node, 35 | char *newnode); 36 | 37 | /* computes the induced graph starting from node */ 38 | void IndSubshiftPath(IndSubshift *s, SparseMatrix *A, int letter, 39 | char *_node); 40 | 41 | void IndSubshiftExtend(IndSubshift *s, SparseMatrix *A, char *node, Node *n); 42 | 43 | SparseMatrix *IndSubshiftGraph(IndSubshift *s, int start); 44 | 45 | void IndSubshiftInfo(FILE *out, IndSubshift *s); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /matlab/rga.m: -------------------------------------------------------------------------------- 1 | function rga(t, f, X, steps) 2 | 3 | % RGA relative global attractor. 4 | % 5 | % RGA(t, f, X, steps) performs the subdivision algorithm for computing 6 | % the relative global attractor of the map f, cf. [1]. 7 | % 8 | % t tree containing the box covering 9 | % f map 10 | % X m x d-matrix of sample points 11 | % steps number of steps 12 | 13 | % [1] M. Dellnitz, A. Hohmann: A subdivision algorithm for the computation 14 | % of unstable manifolds and global attractors, Num. Math., 75, 15 | % pp. 293-317, 1997. 16 | % 17 | % (C) 2013, djs GbR 18 | 19 | dim = t.dim; hit = 1; sd = 8; tic; 20 | for s = 1:steps, 21 | t.set_flags('all', sd); % flag all boxes for subdivision 22 | t.subdivide(sd); % subdivide flagged boxes 23 | b = t.boxes(-1); N = size(b,2); % get boxes from the leaves 24 | S = whos('X'); l = floor(5e7/S.bytes); 25 | for k = 0:floor(N/l), % split in chunks of size l 26 | K = k*l+1:min((k+1)*l,N); 27 | c = b(1:dim,K); % center ... 28 | r = b(dim+1:2*dim,1); % ... and radii of the boxes 29 | n = size(c,2); E = ones(n,1); 30 | P = kron(E,X)*diag(r) + ... % sample points in all boxes 31 | kron(c',ones(size(X,1),1)); 32 | t.set_flags(f(P)', hit); % map points and flag hit boxes 33 | end 34 | t.remove(hit); % remove non-flagged boxes 35 | fprintf('depth %d, %d boxes, %.1f sec\n',t.depth,t.count(-1),toc); 36 | end 37 | -------------------------------------------------------------------------------- /matlab/tpmatrix.m: -------------------------------------------------------------------------------- 1 | function T = tpmatrix(t, f, X, depth, verbose) 2 | 3 | % TPMATRIX transition probability matrix. 4 | % 5 | % TPMATRIX(t, f, X, d, v) computes the matrix T of transition 6 | % probabilities between the boxes in the tree t 7 | % 8 | % t tree containing the box covering 9 | % f map 10 | % X m x d-matrix of sample points 11 | % d depth of the tree on which the matrix is computed 12 | % v verbose flag: '0' or '1' ('1' prints progress) 13 | 14 | % (C) 2013, djs2 GbR 15 | 16 | d = t.dim; 17 | b = t.boxes(depth); % get the geometry of the boxes 18 | N = size(b,2); S = whos('X'); l = floor(5e7/S.bytes); 19 | I = []; IJS = []; tic; 20 | for k = 0:floor(N/l), % split in chunks of size l 21 | K = k*l+1:min((k+1)*l,N); 22 | c = b(1:d,K); r = b(d+1:2*d,1); % center and radii of the boxes 23 | n = size(c,2); E = ones(n,1); % sample points in all boxes 24 | P = kron(E,X)*diag(r) + kron(c',ones(size(X,1),1)); 25 | I = t.search(f(P)', depth); % get box numbers of image points 26 | pI = find(I>0); % I <= 0 iff f(P) is outside of covering 27 | J = kron(K',ones(size(X,1),1)); % column numbers 28 | [I,J,S] = find(sparse(I(pI), J(pI), 1, N, N)); % transition matrix 29 | IJS = [IJS; I,J,S]; 30 | if verbose, fprintf('%d of %d boxes, %.1f sec\n',min((k+1)*l,N),N,toc); end 31 | end 32 | T = sparse(IJS(:,1), IJS(:,2), IJS(:,3), N, N); % transition matrix 33 | cs = sum(T); 34 | T = T*spdiags(1./cs', 0, N, N); % normalize 35 | if verbose, fprintf('\n'); end 36 | 37 | 38 | -------------------------------------------------------------------------------- /demos/Conlex index/main/tm2map.m: -------------------------------------------------------------------------------- 1 | function tm2map(tree, depth, X, Y, P, filename) 2 | 3 | % tm2map writes map given by the transition matrix P with domain X and range Y 4 | % to file to be read by 'homcubes' 5 | 6 | fid = fopen(filename,'w'); 7 | b = tree.boxes(depth); 8 | 9 | % space dimension 10 | d = (size(b,1)-2)/2; 11 | 12 | % box radius 13 | r = b(d+1:2*d,1)'; 14 | 15 | % rescaling to integer lattice 16 | for i=1:d 17 | b(i,:) = b(i,:)/r(i)/2; 18 | b(i+d,:) = b(i+d,:)/r(i)/2; 19 | end 20 | 21 | % for domain boxes in X, image is restricted to Y 22 | for i=1:size(b(:,X),2), 23 | % for domain box i: center, lower left corner 24 | c = b(1:d,X(i))'; 25 | ll = round(c-0.5); 26 | 27 | % print domain box 28 | fprintf(fid, '('); 29 | for j=1:d-1, fprintf(fid, '%d,', ll(j)); end 30 | fprintf(fid, '%d) ' , ll(d)); 31 | 32 | % compute image (restricted to Y) 33 | Im = find(P(:,X(i))); 34 | Im = intersect(Im,Y); 35 | fprintf(fid, ' -> {'); 36 | if (~isempty(Im)) 37 | % print image of box i 38 | for k=1:length(Im)-1, 39 | % kth box in image 40 | c = b(1:d,Im(k))'; 41 | ll = round(c-0.5); 42 | 43 | % print kth box in image 44 | fprintf(fid, '('); 45 | for j=1:d-1, fprintf(fid, '%d,', ll(j)); end 46 | fprintf(fid, '%d) ', ll(d)); 47 | end 48 | % last box 49 | % last box in image 50 | c = b(1:d,Im(length(Im)))'; 51 | ll = round(c-0.5); 52 | 53 | % print kth box in image 54 | fprintf(fid, '('); 55 | for j=1:d-1, fprintf(fid, '%d,', ll(j)); end 56 | fprintf(fid, '%d)', ll(d)); 57 | else 58 | fprintf('WARNING: box no %d has empty image. \n', X(i)); 59 | end 60 | fprintf(fid, '}\n'); 61 | end 62 | 63 | 64 | 65 | fclose(fid); 66 | -------------------------------------------------------------------------------- /demos/stable_manifold.m: -------------------------------------------------------------------------------- 1 | % GAIO demo 2 | % global stable manifold of the origin in the Lorenz system 3 | % -- fast version -- 4 | 5 | s = 10; rh = 28; b = 8/3; % Lorenz system 6 | v = @(x) [s*(x(:,2)-x(:,1)) ... 7 | rh*x(:,1)-x(:,2)-x(:,1).*x(:,3) ... 8 | x(:,1).*x(:,2)-b*x(:,3)]; 9 | h = -0.01; n = 10; f = @(x) rk4(v,x,h,n); % flow map (backward) 10 | n = 20; X1 = linspace(-1,1,n)'; E = ones(size(X1)); 11 | X = [ X1 -E -E; X1 -E E; X1 E -E; X1 E E; ... 12 | -E X1 -E; -E X1 E; E X1 -E; E X1 E; ... 13 | -E -E X1; -E E X1; E -E X1; E E X1]; % sample points 14 | c = [0 0 0]; r = [120 120 160]; 15 | tree = Tree(c,r); % the box collection 16 | 17 | %% continuation algorithm 18 | x = [0 0 0]; % equilibrium 19 | depth = 21; 20 | tree.insert(x', depth); 21 | d = 3; 22 | 23 | none = 0; hit = 1; ins = 2; expd = 4; 24 | n0 = 0; n1 = tree.count(depth); 25 | while n1 > n0 % while boxes are being added 26 | tree.change_flags('all', ins, expd); % flag inserted boxes for expansion 27 | b = tree.boxes(depth); 28 | flags = b(2*d+1,:); 29 | I = find(bitand(flags,expd)); % find boxes to be expanded 30 | c = b(1:d,I); r = b(d+1:2*d,1); % get center and radii 31 | n = length(I); E = ones(n,1); 32 | P = kron(E,X)*diag(r) + kron(c',ones(size(X,1),1)); % sample points 33 | tree.insert(f(P)', depth, ins, none); % insert boxes which are hit by f(P) 34 | tree.unset_flags('all', expd); % unflag recently expanded boxes 35 | n0 = n1; n1 = tree.count(depth); 36 | disp(sprintf('%d boxes', n1)); 37 | clf; boxplot3(tree,'alpha',0.9); axis tight; 38 | light('position',[-1,2,2]); view(20,30); drawnow; 39 | end 40 | 41 | 42 | %% cleanup 43 | delete(tree); -------------------------------------------------------------------------------- /demos/lorenz_fast.m: -------------------------------------------------------------------------------- 1 | % GAIO demo 2 | % global unstable manifold of an equilibrium in the Lorenz system 3 | % -- fast version -- 4 | 5 | s = 10; rh = 28; b = 0.4; % Lorenz system 6 | v = @(x) [s*(x(:,2)-x(:,1)) ... 7 | rh*x(:,1)-x(:,2)-x(:,1).*x(:,3) ... 8 | x(:,1).*x(:,2)-b*x(:,3)]; 9 | h = 0.01; n = 20; f = @(x) rk4(v,x,h,n); % flow map 10 | n = 7; x = linspace(-1,1,n)'; [XX,YY,ZZ] = meshgrid(x,x,x); 11 | X = [ XX(:) YY(:) ZZ(:) ]; % sample points (uniform grid) 12 | c = [0 0 27]; r = [30 30 40]; tree = Tree(c,r); % the box collection 13 | 14 | %% continuation algorithm 15 | d = 3; depth = 21; 16 | x0 = [sqrt(b*(rh-1)) sqrt(b*(rh-1)) rh-1]; % equilibrium 17 | tree.insert(x0', depth); 18 | 19 | none = 0; hit = 1; ins = 2; expd = 4; 20 | n0 = 0; n1 = tree.count(depth); tic 21 | while n1 > n0 % while boxes are being added 22 | tree.change_flags('all', ins, expd); % flag inserted boxes for expansion 23 | b = tree.boxes(depth); 24 | flags = b(2*d+1,:); 25 | I = find(bitand(flags,expd)); % find boxes to be expanded 26 | c = b(1:d,I); r = b(d+1:2*d,1); % get center and radii 27 | n = length(I); E = ones(n,1); 28 | P = kron(E,X)*diag(r) + kron(c',ones(size(X,1),1)); % sample points 29 | tree.insert(f(P)', depth, ins, none); % insert boxes which are hit by f(P) 30 | tree.unset_flags('all', expd); % unflag recently expanded boxes 31 | n0 = n1; n1 = tree.count(depth); 32 | disp(sprintf('%d boxes', n1)); 33 | boxplot3(tree); view(20,30); axis square; axis tight; drawnow; pause 34 | end 35 | toc 36 | 37 | %% plot 38 | boxplot3(tree); view(20,30); axis square; axis tight; 39 | xlabel('x'); ylabel('y'); zlabel('z'); 40 | 41 | %% cleanup 42 | delete(tree); -------------------------------------------------------------------------------- /lib/gaio/SparseMatrix.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998 Oliver Junge, for details see COPYING 3 | * 4 | * SparseMatrix.h 5 | * 6 | */ 7 | 8 | #ifndef _SparseMatrix_h 9 | #define _SparseMatrix_h 10 | 11 | #include 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | typedef struct { 19 | 20 | int dim; /* dimension of the matrix */ 21 | int nz; /* number of nonzeros of the matrix */ 22 | int *rows; 23 | int *cols; 24 | double *entries; 25 | int size; /* length of the vectors rows, cols and entries */ 26 | 27 | } SparseMatrix; 28 | 29 | SparseMatrix *SparseMatrixNew(int dim); 30 | void SparseMatrixFree(SparseMatrix **A); 31 | void SparseMatrixAddEntry(SparseMatrix *A, int row, int col, double entry); 32 | 33 | /* adds a to the diagonal of A */ 34 | void SparseMatrixAddDiag(SparseMatrix *A, double a); 35 | 36 | /* returns a char vector c such that c[i]=(A[i,i]!=0) */ 37 | char *SparseMatrixEquilibria(SparseMatrix *A); 38 | 39 | /* returns a char vector c s.t. 40 | which = 1: c[i]=1, if A[i,j]>0 and v[i]*v[j]<0, 41 | which = -1: c[j]=1, if A[i,j]>0 and v[i]*v[j]<0 */ 42 | char *SparseMatrixFindSignChange(SparseMatrix *A, Matrix *v, int which); 43 | 44 | /* y=Ax */ 45 | void SparseMatrixMult(SparseMatrix *A, double *x, double *y); 46 | 47 | /* y=transpose(A)x */ 48 | void SparseMatrixTMult(SparseMatrix *A, double *x, double *y); 49 | 50 | /* Norm(A,which), which==-1: inf-Norm, which==1: 1-Norm */ 51 | double SparseMatrixNorm(SparseMatrix *A, int which); 52 | 53 | void SparseMatrixInfo(FILE *out, SparseMatrix *A); 54 | void SparseMatrixPrint(FILE *out, SparseMatrix *A); 55 | SparseMatrix *SparseMatrixLoad(FILE *in); 56 | 57 | /* the vector scc assinging the number of the strongly connected 58 | component to each column of A this function returns a vector of flags, 59 | indictating which column corresponds to a sink cell */ 60 | char *SparseMatrixSinks(SparseMatrix *A, Matrix *scc); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /matlab/subshift.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static SparseMatrix *mxSparse_to_SparseMatrix(const mxArray *A) { 8 | 9 | SparseMatrix *SA; 10 | double *pr; 11 | mwIndex *ir, *jc, row_start, row_stop, row; 12 | mwSize col, total=0, n; 13 | 14 | n = mxGetN(A); 15 | SA = SparseMatrixNew(n); 16 | 17 | pr = mxGetPr(A); ir = mxGetIr(A); jc = mxGetJc(A); 18 | 19 | for (col=0; coldim = %d\n",A->dim); */ 47 | s = IndSubshiftNew(A, letters); 48 | HA = IndSubshiftGraph(s, start); 49 | /* SparseMatrixInfo(stdout,HA); */ 50 | plhs[0] = mxCreateDoubleMatrix(HA->nz,1,mxREAL); 51 | pr = mxGetPr(plhs[0]); 52 | for (i=0; inz; i++) pr[i] = HA->rows[i]+1; 53 | plhs[1] = mxCreateDoubleMatrix(HA->nz,1,mxREAL); 54 | pr = mxGetPr(plhs[1]); 55 | for (i=0; inz; i++) pr[i] = HA->cols[i]+1; 56 | plhs[2] = mxCreateDoubleMatrix(HA->nz,1,mxREAL); 57 | pr = mxGetPr(plhs[2]); 58 | for (i=0; inz; i++) pr[i] = HA->entries[i]; 59 | 60 | IndSubshiftFree(&s); 61 | SparseMatrixFree(&HA); 62 | 63 | return; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /matlab/gum.m: -------------------------------------------------------------------------------- 1 | function gum(t, f, X, depth) 2 | 3 | % GUM global unstable manifold. 4 | % 5 | % GUM(t, f, X, steps) performs the continuation algorithm for computing 6 | % (part of) some global unstable manifold of the map f, cf. [1]. 7 | % 8 | % t tree containing the box covering (and initially a covering 9 | % of the object for which the unstable manifold is to be computed) 10 | % f map 11 | % X m x d-matrix of sample points 12 | % depth depth of the tree on which the continuation is performed 13 | 14 | % [1] M. Dellnitz, A. Hohmann: The computation of unstable manifolds 15 | % using subdivision and continuation, in: H.W. Broer and S.A. van Gils 16 | % and I. Hoveijn and F. Takens (eds.), Nonlinear Dynamical Systems and 17 | % Chaos, Birkh\"auser, PNLDE 19, pp. 449-459, 1996. 18 | % 19 | % (C) 2013, djs GbR 20 | 21 | dim = t.dim; 22 | none = 0; ins = 2; expd = 4; % defining flags 23 | nb0 = 0; nb1 = t.count(depth); % bookkeeping of the number of boxes 24 | tic; j = 1; 25 | t.set_flags('all', ins, depth); 26 | while nb1 > nb0 % while new boxes are being inserted 27 | t.change_flags('all', ins, expd); % mark inserted boxes as to be expanded 28 | b = t.boxes(depth); M = size(b,2); % get the geometry of the boxes 29 | flags = b(2*dim+1, :); 30 | I = find(bitand(flags,expd)); % find boxes to expand 31 | b = b(:,I); N = size(b,2); 32 | S = whos('X'); l = floor(5e7/S.bytes); 33 | for k = 0:floor(N/l), % split in chunks of size l 34 | K = k*l+1:min((k+1)*l,N); 35 | c = b(1:dim,K); % center ... 36 | r = b(dim+1:2*dim,1); % ... and radii of the boxes 37 | n = size(c,2); E = ones(n,1); 38 | P = kron(E,X)*diag(r) + ... % sample points in all boxes 39 | kron(c',ones(size(X,1),1)); 40 | t.insert(f(P)', depth, ins, none); % map sample points and insert boxes 41 | end 42 | fprintf('step %d: %d of %d boxes, %.1f sec\n',j,N,M,toc); 43 | t.unset_flags('all', expd); % unflag recently expanded boxes 44 | nb0 = nb1; nb1 = t.count(depth); 45 | j = j+1; 46 | end 47 | -------------------------------------------------------------------------------- /matlab/boxplot2.m: -------------------------------------------------------------------------------- 1 | function h = boxplot2(B, varargin) 2 | 3 | %BOXPLOT2 2d box plot. 4 | % 5 | % BOXPLOT2(B) plots the boxes given by B. B can be matrix, then each row 6 | % defines one box (columns 1:size(B,2)/2 define the centers, the 7 | % remaining columns the radii of the boxes) or a Tree, then the leaves of the tree are 8 | % plotted. 9 | % 10 | % BOXPLOT2(B,'depth',d) plots the boxes given by the nodes at depth d 11 | % 12 | % BOXPLOT2(B,'color',c) uses color c (with the standard Matlab colors) 13 | % 14 | % BOXPLOT2(B,'coords',[i j]) uses the coordinates i and j (default is i=1 15 | % and j=2) for higher dimensional boxes 16 | % 17 | % BOXPLOT2(B,'density',v) colors the boxes according to the colors 18 | % specified in the vector v 19 | % 20 | % BOXPLOT2(B,'alpha',a) sets the opacity of the boxes to a 21 | % 22 | % These options can be combined arbitrarily. 23 | 24 | p = inputParser; 25 | defaultColor = 'r'; 26 | defaultCoords = [1 2]; 27 | defaultDepth = -1; 28 | defaultAlpha = 1; alpha_edge = 1; 29 | defaultEdgeColor = 'k'; 30 | 31 | addRequired(p,'B'); 32 | addParamValue(p,'color',defaultColor,@ischar); 33 | addParamValue(p,'coords',defaultCoords,@isvector); 34 | addParamValue(p,'depth',defaultDepth,@isnumeric); 35 | addParamValue(p,'density',[],@isvector); 36 | addParamValue(p,'alpha',defaultAlpha,@isnumeric); 37 | addParamValue(p,'edgecolor',defaultEdgeColor,@ischar); 38 | 39 | parse(p, B, varargin{:}); 40 | ix = p.Results.coords(1); 41 | iy = p.Results.coords(2); 42 | depth = p.Results.depth; 43 | alpha = p.Results.alpha; 44 | edgecolor = p.Results.edgecolor; 45 | if alpha < 1, 46 | alpha_edge = 0; 47 | end 48 | if isempty(p.Results.density) 49 | col = p.Results.color; 50 | else 51 | col = p.Results.density(:)'; 52 | end 53 | 54 | if isa(B,'Tree') 55 | b = B.boxes(depth)'; 56 | dim = B.dim; 57 | else 58 | b = B; 59 | dim = size(b,2)/2; 60 | end 61 | 62 | x = [b(:,ix)-b(:,ix+dim) b(:,ix)+b(:,ix+dim) b(:,ix)+b(:,ix+dim) b(:,ix)-b(:,ix+dim)]; 63 | y = [b(:,iy)-b(:,iy+dim) b(:,iy)-b(:,iy+dim) b(:,iy)+b(:,iy+dim) b(:,iy)+b(:,iy+dim)]; 64 | h = patch(x',y',col); set(h,'edgeColor',edgecolor,'FaceAlpha',alpha,'EdgeAlpha',alpha_edge); 65 | 66 | -------------------------------------------------------------------------------- /demos/html/style.css: -------------------------------------------------------------------------------- 1 | /** BASIC */ 2 | 3 | html { 4 | overflow-y: scroll 5 | } 6 | 7 | body { 8 | margin: 20px; 9 | padding: 0px; 10 | font-size: 14px; 11 | color: #000; 12 | background-color: #FFF; 13 | font-family: "Lucida Sans", Arial, Helvetica, sans-serif; 14 | } 15 | 16 | a:link { 17 | color: #004784; 18 | background: inherit; 19 | text-decoration: none; 20 | } 21 | 22 | a:visited { 23 | color: #004784; 24 | background: inherit; 25 | text-decoration: none; 26 | } 27 | 28 | a:hover { 29 | color:#627684; 30 | background-color: inherit; 31 | text-decoration: none; 32 | } 33 | 34 | h1 { 35 | font-family: Arial, Helvetica, sans-serif; 36 | font-weight: bold; 37 | color:#d55000; 38 | font-size: 14pt; 39 | text-transform: uppercase; 40 | margin-top: 20px; 41 | } 42 | 43 | h2 { 44 | font-family: Arial, Helvetica, sans-serif; 45 | font-size: 14px; 46 | color: #d55000; 47 | font-size: 12pt; 48 | margin-top: 1px; 49 | } 50 | 51 | h3 { 52 | margin: 0px; 53 | padding: 0px; 54 | font-size: 11px; 55 | text-transform: uppercase; 56 | } 57 | 58 | p, ol, ul { 59 | margin-top: 0px; 60 | } 61 | 62 | .hr1 { 63 | clear: both; 64 | margin: 2px 0px 2px 0px; 65 | border: 1px dashed #4d506d; 66 | } 67 | 68 | .hr1 hr { 69 | display: none; 70 | } 71 | 72 | table { 73 | margin-left: auto; 74 | margin-right: auto; 75 | } 76 | 77 | td { 78 | padding:0; 79 | } 80 | 81 | span.comment { 82 | color:green; 83 | } 84 | 85 | pre,p,h1,h2,div.content div { 86 | max-width: 800px; 87 | width: auto !important; width: 800px; 88 | } 89 | 90 | pre.codeinput { 91 | background: #EEEEEE; 92 | padding: 10px; 93 | } 94 | 95 | @media print { 96 | pre.codeinput {word-wrap:break-word; width:100%;} 97 | } 98 | 99 | span.keyword {color: #0000FF} 100 | span.comment {color: #228B22} 101 | span.string {color: #A020F0} 102 | span.untermstring {color: #B20000} 103 | span.syscmd {color: #B28C00} 104 | 105 | pre.codeoutput { 106 | color: #666666; 107 | padding: 10px; 108 | word-wrap:break-word; 109 | } 110 | 111 | pre.error { 112 | color: red; 113 | } 114 | pre, tt, code { font-size:14px; } 115 | pre { margin:0px 0px 20px; } 116 | 117 | pre.error { color:red; } 118 | pre.codeinput { padding:10px; border:1px solid #d3d3d3; background:#f7f7f7; } 119 | pre.codeoutput { padding:10px 11px; margin:0px 0px 10px; color:#4c4c4c; } 120 | 121 | pre.codeoutput { 122 | color: #444; 123 | font-family: Courier, "Courier New", "Lucida Console", "Lucida Sans Typewriter", Lucidatypewriter, "Andale Mono", fixed, monospace; 124 | } 125 | 126 | pre.codeinput { 127 | font-family: Courier, "Courier New", "Lucida Console", "Lucida Sans Typewriter", Lucidatypewriter, "Andale Mono", fixed, monospace; 128 | } 129 | 130 | img { 131 | margin-left: auto; 132 | margin-right: auto; 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /demos/html/invariant_density.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | invariant_density

GAIO demo: Natural invariant measure of the logistic map

mu = 4; f = @(x) mu*x.*(1-x);          % the logistic map
14 | n = 300; X = linspace(-1,1,n)';        % uniform grid of sample points
15 | c = [0.5]; r = [0.5]; t = Tree(c, r);  % the tree
16 | 

Construct full subdivison

sd = 8; depth = 8;
17 | for i=1:depth,
18 |     t.set_flags('all', sd);
19 |     t.subdivide;
20 | end
21 | 

Compute invariant vector

P = tpmatrix(t, f, X, depth);
22 | [v,lambda] = eigs(P,1);
23 | 
256 of 256 boxes, 0.0 sec
24 | 

Plot invariant density

n = t.count(depth); x = linspace(0,1,n);
25 | h = abs(v)*n./norm(v,1);
26 | bar(x,h,1); axis([0 1 0 10]);
27 | xlabel('x'); ylabel('density');
28 | 
-------------------------------------------------------------------------------- /lib/Set.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Oliver Junge, for details see COPYING 3 | * 4 | * Set.c 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | SetElement *SetElementNew(int no, void *ptr, void (*Free)(void**), 12 | void (*Info)(FILE*, int, void*)) { 13 | SetElement *s; 14 | 15 | NEW1(s, SetElement*, 1); 16 | s->no = no; 17 | s->ptr = ptr; 18 | s->Free = Free; 19 | s->Info = Info; 20 | s->parent = 0; 21 | s->child[0] = 0; 22 | s->child[1] = 0; 23 | 24 | return s; 25 | } 26 | 27 | void SetElementFree(SetElement **s) { 28 | if (*s) { 29 | if ((*s)->Free) (*s)->Free(&((*s)->ptr)); 30 | SetElementFree(&((*s)->child[0])); 31 | SetElementFree(&((*s)->child[1])); 32 | FREE(*s); 33 | *s = 0; 34 | } 35 | } 36 | 37 | int SetElementInsert(SetElement *s, SetElement *node) { 38 | if (node->no < s->no) { 39 | if (!s->child[0]) { 40 | s->child[0] = node; 41 | node->parent = s; 42 | return 1; 43 | } else 44 | return SetElementInsert(s->child[0], node); 45 | } else if (node->no > s->no) { 46 | if (!s->child[1]) { 47 | s->child[1] = node; 48 | node->parent = s; 49 | return 1; 50 | } else 51 | return SetElementInsert(s->child[1], node); 52 | } 53 | return 0; 54 | } 55 | 56 | void SetElementPushToStack(SetElement *se, Stack *st) { 57 | if (se) { 58 | StackPush(st, (void *)se); 59 | SetElementPushToStack(se->child[0], st); 60 | SetElementPushToStack(se->child[1], st); 61 | } 62 | } 63 | 64 | SetElement *SetElementContains(SetElement *s, int no) { 65 | if (!s) 66 | return 0; 67 | if (s->no==no) 68 | return s; 69 | else { 70 | if (no < s->no) 71 | return SetElementContains(s->child[0], no); 72 | else 73 | return SetElementContains(s->child[1], no); 74 | } 75 | } 76 | 77 | void SetElementInfo(FILE *out, int n, SetElement *sn) { 78 | if (sn) { 79 | if (sn->Info) sn->Info(out, n, sn->ptr); 80 | if (!sn->child[0] && !sn->child[1]) 81 | fprintf(out, "\n"); 82 | else { 83 | SetElementInfo(out, n, sn->child[0]); 84 | SetElementInfo(out, n, sn->child[1]); 85 | } 86 | } 87 | } 88 | 89 | Set *SetNew() { 90 | Set *set; 91 | 92 | NEW1(set, Set*, 1); 93 | set->no_of_elements = 0; 94 | set->root = 0; 95 | __Set_no++; 96 | 97 | return set; 98 | } 99 | 100 | void SetFree(Set **s) { 101 | if (*s) { 102 | SetElementFree(&((*s)->root)); 103 | FREE(*s); 104 | *s = 0; 105 | __Set_no--; 106 | } 107 | } 108 | 109 | Stack *SetToStack(Set *s) { 110 | Stack *st; 111 | 112 | st = StackNew(); 113 | SetElementPushToStack(s->root, st); 114 | 115 | return st; 116 | } 117 | 118 | int SetInsert(Set *s, SetElement *node) { 119 | int r; 120 | 121 | if (!s->root) { 122 | s->root = node; 123 | r = 1; 124 | } else 125 | r = SetElementInsert(s->root, node); 126 | 127 | s->no_of_elements += r; 128 | 129 | return r; 130 | } 131 | 132 | SetElement *SetContains(Set *s, int no) { 133 | return SetElementContains(s->root, no); 134 | } 135 | 136 | void SetInfo(FILE *out, int n, Set *s) { 137 | if (s) { 138 | SetElementInfo(out, n, s->root); 139 | } 140 | } 141 | 142 | -------------------------------------------------------------------------------- /demos/html/matlab-style.css: -------------------------------------------------------------------------------- 1 | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th, 2 | td {margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent} 3 | 4 | body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outine:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0} 5 | 6 | html { min-height:100%; margin-bottom:1px; } 7 | html body { height:100%; margin:0px; font-family:Arial, Helvetica, sans-serif; font-size:10px; color:#000; line-height:140%; background:#fff none; overflow-y:scroll; } 8 | html body td { vertical-align:top; text-align:left; } 9 | 10 | h1 { padding:0px; margin:0px 0px 25px; font-family:Arial, Helvetica, sans-serif; font-size:1.5em; color:#d55000; line-height:100%; font-weight:normal; } 11 | h2 { padding:0px; margin:0px 0px 8px; font-family:Arial, Helvetica, sans-serif; font-size:1.2em; color:#000; font-weight:bold; line-height:140%; border-bottom:1px solid #d6d4d4; display:block; } 12 | h3 { padding:0px; margin:0px 0px 5px; font-family:Arial, Helvetica, sans-serif; font-size:1.1em; color:#000; font-weight:bold; line-height:140%; } 13 | 14 | a { color:#005fce; text-decoration:none; } 15 | a:hover { color:#005fce; text-decoration:underline; } 16 | a:visited { color:#004aa0; text-decoration:none; } 17 | 18 | p { padding:0px; margin:0px 0px 20px; } 19 | img { padding:0px; margin:0px 0px 20px; border:none; } 20 | p img, pre img, tt img, li img { margin-bottom:0px; } 21 | 22 | ul { padding:0px; margin:0px 0px 20px 23px; list-style:square; } 23 | ul li { padding:0px; margin:0px 0px 7px 0px; } 24 | ul li ul { padding:5px 0px 0px; margin:0px 0px 7px 23px; } 25 | ul li ol li { list-style:decimal; } 26 | ol { padding:0px; margin:0px 0px 20px 0px; list-style:decimal; } 27 | ol li { padding:0px; margin:0px 0px 7px 23px; list-style-type:decimal; } 28 | ol li ol { padding:5px 0px 0px; margin:0px 0px 7px 0px; } 29 | ol li ol li { list-style-type:lower-alpha; } 30 | ol li ul { padding-top:7px; } 31 | ol li ul li { list-style:square; } 32 | 33 | .content { font-size:1.2em; line-height:140%; padding: 20px; } 34 | 35 | pre, tt, code { font-size:12px; } 36 | pre { margin:0px 0px 20px; } 37 | pre.error { color:red; } 38 | pre.codeinput { padding:10px; border:1px solid #d3d3d3; background:#f7f7f7; } 39 | pre.codeoutput { padding:10px 11px; margin:0px 0px 20px; color:#4c4c4c; } 40 | 41 | @media print { pre.codeinput, pre.codeoutput { word-wrap:break-word; width:100%; } } 42 | 43 | span.keyword { color:#0000FF } 44 | span.comment { color:#228B22 } 45 | span.string { color:#A020F0 } 46 | span.untermstring { color:#B20000 } 47 | span.syscmd { color:#B28C00 } 48 | 49 | .footer { width:auto; padding:10px 0px; margin:25px 0px 0px; border-top:1px dotted #878787; font-size:0.8em; line-height:140%; font-style:italic; color:#878787; text-align:left; float:none; } 50 | .footer p { margin:0px; } 51 | .footer a { color:#878787; } 52 | .footer a:hover { color:#878787; text-decoration:underline; } 53 | .footer a:visited { color:#878787; } 54 | 55 | table th { padding:7px 5px; text-align:left; vertical-align:middle; border: 1px solid #d6d4d4; font-weight:bold; } 56 | table td { padding:7px 5px; text-align:left; vertical-align:top; border:1px solid #d6d4d4; } 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /matlab/scc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct GRAPH { 6 | int n; 7 | mwIndex *ep; 8 | mwIndex *edge; 9 | double *ew; 10 | }; 11 | 12 | 13 | static void visit (struct GRAPH graph, int vertex, int *taken, int *finished, int *n_finished) 14 | { int j; 15 | 16 | taken[vertex] = 1; 17 | 18 | for (j=graph.ep[vertex]; j=0; i--) 61 | if (taken[finished[i]] == 1) 62 | { int new_scc=0; 63 | for (j=graphT.ep[finished[i]]; j 90) | (az < -90), 16 | p = patch(xQ',yQ',zQ',[0.8 0.8 0.8],'edgealpha',0); 17 | patch(xB',yB',zB','k','edgealpha',0,'facealpha',0.2); 18 | end 19 | % front 20 | xQ = [Q(:,1)-Q(:,1+d) Q(:,1)+Q(:,1+d) Q(:,1)+Q(:,1+d) Q(:,1)-Q(:,1+d)]; 21 | yQ = [Q(:,2)+Q(:,2+d) Q(:,2)+Q(:,2+d) Q(:,2)+Q(:,2+d) Q(:,2)+Q(:,2+d)]; 22 | zQ = [Q(:,3)-Q(:,3+d) Q(:,3)-Q(:,3+d) Q(:,3)+Q(:,3+d) Q(:,3)+Q(:,3+d)]; 23 | xB = [B(:,1)-B(:,1+d) B(:,1)+B(:,1+d) B(:,1)+B(:,1+d) B(:,1)-B(:,1+d)]; 24 | yB = kron([Q(:,2)+Q(:,2+d) Q(:,2)+Q(:,2+d) Q(:,2)+Q(:,2+d) Q(:,2)+Q(:,2+d)]*0.95, ones(size(xB,1),1)); 25 | zB = [B(:,3)-B(:,3+d) B(:,3)-B(:,3+d) B(:,3)+B(:,3+d) B(:,3)+B(:,3+d)]; 26 | if az > -90 & az < 90, 27 | patch(xQ',yQ',zQ',[0.8 0.8 0.8],'edgealpha',0); 28 | patch(xB',yB',zB','k','edgealpha',0,'facealpha',0.2); 29 | end 30 | % right 31 | xQ = [Q(:,1)+Q(:,1+d) Q(:,1)+Q(:,1+d) Q(:,1)+Q(:,1+d) Q(:,1)+Q(:,1+d)]; 32 | yQ = [Q(:,2)-Q(:,2+d) Q(:,2)+Q(:,2+d) Q(:,2)+Q(:,2+d) Q(:,2)-Q(:,2+d)]; 33 | zQ = [Q(:,3)-Q(:,3+d) Q(:,3)-Q(:,3+d) Q(:,3)+Q(:,3+d) Q(:,3)+Q(:,3+d)]; 34 | yB = [B(:,2)-B(:,2+d) B(:,2)+B(:,2+d) B(:,2)+B(:,2+d) B(:,2)-B(:,2+d)]; 35 | zB = [B(:,3)-B(:,3+d) B(:,3)-B(:,3+d) B(:,3)+B(:,3+d) B(:,3)+B(:,3+d)]; 36 | xB = kron([Q(:,1)+Q(:,1+d) Q(:,1)+Q(:,1+d) Q(:,1)+Q(:,1+d) Q(:,1)+Q(:,1+d)]*0.95, ones(size(xB,1),1)); 37 | if az < 0, 38 | patch(xQ',yQ',zQ',[0.8 0.8 0.8],'edgealpha',0); 39 | patch(xB',yB',zB','k','edgealpha',0,'facealpha',0.2); 40 | end 41 | % left 42 | xQ = [Q(:,1)-Q(:,1+d) Q(:,1)-Q(:,1+d) Q(:,1)-Q(:,1+d) Q(:,1)-Q(:,1+d)]; 43 | yQ = [Q(:,2)-Q(:,2+d) Q(:,2)+Q(:,2+d) Q(:,2)+Q(:,2+d) Q(:,2)-Q(:,2+d)]; 44 | zQ = [Q(:,3)-Q(:,3+d) Q(:,3)-Q(:,3+d) Q(:,3)+Q(:,3+d) Q(:,3)+Q(:,3+d)]; 45 | yB = [B(:,2)-B(:,2+d) B(:,2)+B(:,2+d) B(:,2)+B(:,2+d) B(:,2)-B(:,2+d)]; 46 | zB = [B(:,3)-B(:,3+d) B(:,3)-B(:,3+d) B(:,3)+B(:,3+d) B(:,3)+B(:,3+d)]; 47 | xB = kron([Q(:,1)-Q(:,1+d) Q(:,1)-Q(:,1+d) Q(:,1)-Q(:,1+d) Q(:,1)-Q(:,1+d)]*0.95, ones(size(xB,1),1)); 48 | if az > 0, 49 | patch(xQ',yQ',zQ',[0.8 0.8 0.8],'edgealpha',0); 50 | patch(xB',yB',zB','k','edgealpha',0,'facealpha',0.2); 51 | end 52 | % top 53 | xQ = [Q(:,1)-Q(:,1+d) Q(:,1)+Q(:,1+d) Q(:,1)+Q(:,1+d) Q(:,1)-Q(:,1+d)]; 54 | yQ = [Q(:,2)-Q(:,2+d) Q(:,2)-Q(:,2+d) Q(:,2)+Q(:,2+d) Q(:,2)+Q(:,2+d)]; 55 | zQ = [Q(:,3)+Q(:,3+d) Q(:,3)+Q(:,3+d) Q(:,3)+Q(:,3+d) Q(:,3)+Q(:,3+d)]; 56 | xB = [B(:,1)-B(:,1+d) B(:,1)+B(:,1+d) B(:,1)+B(:,1+d) B(:,1)-B(:,1+d)]; 57 | yB = [B(:,2)-B(:,2+d) B(:,2)-B(:,2+d) B(:,2)+B(:,2+d) B(:,2)+B(:,2+d)]; 58 | zB = kron([Q(:,3)+Q(:,3+d) Q(:,3)+Q(:,3+d) Q(:,3)+Q(:,3+d) Q(:,3)+Q(:,3+d)]*0.95, ones(size(xB,1),1)); 59 | if el < 0, 60 | patch(xQ',yQ',zQ',[0.8 0.8 0.8],'edgealpha',0); 61 | patch(xB',yB',zB','k','edgealpha',0,'facealpha',0.2); 62 | end 63 | % bottom 64 | xQ = [Q(:,1)-Q(:,1+d) Q(:,1)+Q(:,1+d) Q(:,1)+Q(:,1+d) Q(:,1)-Q(:,1+d)]; 65 | yQ = [Q(:,2)-Q(:,2+d) Q(:,2)-Q(:,2+d) Q(:,2)+Q(:,2+d) Q(:,2)+Q(:,2+d)]; 66 | zQ = [Q(:,3)-Q(:,3+d) Q(:,3)-Q(:,3+d) Q(:,3)-Q(:,3+d) Q(:,3)-Q(:,3+d)]; 67 | xB = [B(:,1)-B(:,1+d) B(:,1)+B(:,1+d) B(:,1)+B(:,1+d) B(:,1)-B(:,1+d)]; 68 | yB = [B(:,2)-B(:,2+d) B(:,2)-B(:,2+d) B(:,2)+B(:,2+d) B(:,2)+B(:,2+d)]; 69 | zB = kron([Q(:,3)-Q(:,3+d) Q(:,3)-Q(:,3+d) Q(:,3)-Q(:,3+d) Q(:,3)-Q(:,3+d)]*0.95, ones(size(xB,1),1)); 70 | if el > 0, 71 | patch(xQ',yQ',zQ',[0.8 0.8 0.8],'edgealpha',0); 72 | patch(xB',yB',zB','k','edgealpha',0,'facealpha',0.2); 73 | end 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /demos/html/gaio.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | gaio

GAIO
Global Analysis 16 | of Invariant Objects

GAIO is a Matlab toolbox for set oriented numerics.

17 | 18 | 19 |

Download (v3.0)

Demos

References

  • M. Dellnitz, O. Junge. Set Oriented Numerical Methods for Dynamical Systems. In: B. Fiedler (ed.): Handbook of Dynamical Systems 2, Elsevier, pp. 221-264, 2002.
  • M. Dellnitz, G. Froyland, O. Junge. The algorithms behind GAIO -- Set oriented numerical methods for dynamical systems. In: B. Fiedler (ed.): Ergodic Theory, Analysis, and Efficient Simulation of Dynamical Systems, pp. 145-174, Springer, 2001.

Copyright

(C) 2003-2014 by djs$^2$ GbR, Paderborn

-------------------------------------------------------------------------------- /demos/html/ftle.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | ftle
global tau ;
14 | tau = 10;
15 | f = @(x) double_gyre_map(x);
16 | 

constructing the box partition

c = [1 0.5]; r = [1 0.5];
17 | t = Tree(c, r);
18 | dim = t.dim; sd = 8; depth = 12;   % depth 12 means 2^12 boxes, i.e. 2^6=64 in each direction
19 | for i=1:depth,
20 |     t.set_flags('all', sd);        % flag all leaves for subdivision
21 |     t.subdivide;                   % subdivide flagged leaves
22 | end
23 | 

computing the FTLE field

n = 10; X = 2*rand(n,2)-1;         % sample points
24 | h = 1e-6; ftle = zeros(t.count(-1),1);
25 | b = t.first_box(-1); k = 1; dispr("",0);
26 | while (~isempty(b))
27 |     c = b(1:dim); r = b(dim+1:2*dim);         % center and radius of current box
28 |     p = X*diag(r) + ones(size(X))*diag(c);    % sample points in the current box
29 |     q = X*diag(r) + ones(size(X))*diag(c)+h*(2*rand(size(X,1),2)-1);  % slightly shifted sample points
30 |     d = sum(((f(p)-f(q)).^2)')./sum(((p-q).^2)'); % relative distances of their images
31 |     ftle(k) = max(log(d)/(2*tau));            % the FTLE in that box
32 |     b = t.next_box(-1); k = k+1;
33 |     dispr(sprintf('box no %d',k),1);
34 | end
35 | toc
36 | 

plot

clf; boxplot2(t,'depth',depth,'density', ftle);
37 | 
-------------------------------------------------------------------------------- /demos/Conlex index/henon.map: -------------------------------------------------------------------------------- 1 | (-47,116) -> {(113,-48) (114,-48) (113,-47) (114,-47) (114,-46) (115,-47) (115,-46)} 2 | (-46,116) -> {(114,-47) (114,-46) (115,-47) (115,-46) (116,-46) (115,-45) (116,-45)} 3 | (-45,115) -> {(115,-46) (116,-46) (115,-45) (116,-45) (116,-44) (117,-45)} 4 | (-45,116) -> {(115,-46) (116,-46) (115,-45) (116,-45) (116,-44) (117,-45) (117,-44)} 5 | (-44,115) -> {(116,-45) (116,-44) (117,-45) (117,-44) (118,-44) (117,-43)} 6 | (-44,116) -> {(116,-45) (116,-44) (117,-45) (117,-44) (118,-44) (117,-43) (118,-43)} 7 | (-49,117) -> {(111,-50) (112,-50) (111,-49) (112,-49) (112,-48) (113,-49) (113,-48)} 8 | (-49,118) -> {(111,-50) (112,-50) (111,-49) (112,-49) (112,-48) (113,-49) (113,-48)} 9 | (-48,117) -> {(112,-49) (112,-48) (113,-49) (113,-48) (114,-48) (113,-47) (114,-47)} 10 | (-48,118) -> {(112,-49) (112,-48) (113,-49) (113,-48) (114,-48) (113,-47) (114,-47)} 11 | (-47,117) -> {(113,-48) (114,-48) (113,-47) (114,-47) (114,-46) (115,-47) (115,-46)} 12 | (-47,118) -> {(113,-48) (114,-48) (113,-47) (114,-47) (114,-46) (115,-47) (115,-46) (116,-47)} 13 | (-46,117) -> {(114,-47) (114,-46) (115,-47) (115,-46) (116,-46) (115,-45) (116,-45)} 14 | (-45,117) -> {(115,-46) (116,-46) (115,-45) (116,-45) (116,-44) (117,-45) (117,-44)} 15 | (-44,117) -> {(116,-45) (116,-44) (117,-45) (117,-44) (118,-44) (117,-43) (118,-43)} 16 | (-42,114) -> {(118,-43) (118,-42) (119,-43) (119,-42) (120,-42) (119,-41)} 17 | (-43,115) -> {(117,-44) (118,-44) (117,-43) (118,-43) (118,-42) (119,-43)} 18 | (-43,116) -> {(117,-44) (118,-44) (117,-43) (118,-43) (118,-42) (119,-43) (119,-42)} 19 | (-42,115) -> {(118,-43) (118,-42) (119,-43) (119,-42) (120,-42) (119,-41)} 20 | (-42,116) -> {(118,-43) (118,-42) (119,-43) (119,-42) (120,-42) (119,-41) (120,-41)} 21 | (-41,114) -> {(118,-42) (119,-42) (120,-42) (119,-41) (120,-41) (120,-40) (121,-41)} 22 | (-40,113) -> {(119,-41) (119,-40) (120,-41) (120,-40) (120,-39) (121,-40) (121,-39)} 23 | (-40,114) -> {(119,-41) (120,-41) (120,-40) (120,-39) (121,-41) (121,-40) (122,-40) (121,-39)} 24 | (-41,115) -> {(119,-42) (120,-42) (119,-41) (120,-41) (120,-40) (121,-41)} 25 | (-40,115) -> {(120,-41) (120,-40) (121,-41) (121,-40) (122,-40) (121,-39)} 26 | (113,-49) -> {(-40,113) (-38,112) (-37,112) (-36,112) (-39,113) (-39,114) (-38,113) (-38,114) (-37,113) (-36,113)} 27 | (113,-48) -> {(-37,112) (-36,112) (-39,113) (-39,114) (-38,113) (-38,114) (-37,113) (-36,113)} 28 | (114,-48) -> {(-42,114) (-41,114) (-40,113) (-40,114) (-41,115) (-40,115) (-39,113) (-39,114) (-38,113) (-38,114)} 29 | (113,-47) -> {(-37,112) (-36,112) (-39,113) (-39,114) (-38,113) (-38,114) (-37,113) (-37,114) (-36,113) (-35,112)} 30 | (114,-47) -> {(-42,114) (-41,114) (-40,113) (-40,114) (-41,115) (-40,115) (-39,113) (-39,114) (-38,113) (-38,114)} 31 | (114,-46) -> {(-42,114) (-41,114) (-40,113) (-40,114) (-41,115) (-40,115) (-39,113) (-39,114) (-38,113) (-38,114)} 32 | (115,-47) -> {(-44,115) (-44,116) (-42,114) (-43,115) (-43,116) (-42,115) (-42,116) (-41,114) (-41,115)} 33 | (115,-46) -> {(-44,115) (-44,116) (-42,114) (-43,115) (-43,116) (-42,115) (-42,116) (-41,114) (-40,114) (-41,115)} 34 | (116,-47) -> {(-47,116) (-46,116) (-45,115) (-45,116) (-44,115) (-44,116) (-46,117) (-45,117) (-43,115) (-43,116)} 35 | (116,-46) -> {(-47,116) (-46,116) (-45,115) (-45,116) (-44,115) (-44,116) (-46,117) (-45,117) (-43,115) (-43,116)} 36 | (115,-45) -> {(-44,115) (-42,114) (-43,115) (-43,116) (-42,115) (-42,116) (-41,114) (-40,114) (-41,115) (-40,115)} 37 | (116,-45) -> {(-47,116) (-46,116) (-45,115) (-45,116) (-44,115) (-44,116) (-46,117) (-45,117) (-43,115) (-43,116)} 38 | (116,-44) -> {(-46,116) (-45,116) (-44,115) (-44,116) (-46,117) (-45,117) (-44,117) (-43,115) (-43,116)} 39 | (117,-45) -> {(-47,116) (-46,116) (-45,116) (-49,117) (-49,118) (-48,117) (-48,118) (-47,117) (-47,118) (-46,117)} 40 | (117,-44) -> {(-47,116) (-46,116) (-45,116) (-49,117) (-48,117) (-48,118) (-47,117) (-47,118) (-46,117) (-45,117)} 41 | (118,-44) -> {(-52,118) (-51,118) (-50,117) (-50,118) (-51,119) (-50,119) (-49,117) (-49,118) (-48,117) (-48,118)} 42 | (117,-43) -> {(-47,116) (-46,116) (-45,116) (-49,117) (-48,117) (-48,118) (-47,117) (-47,118) (-46,117) (-45,117)} 43 | (118,-43) -> {(-51,118) (-50,118) (-51,119) (-50,119) (-49,117) (-49,118) (-48,117) (-48,118)} 44 | (118,-42) -> {(-51,118) (-50,118) (-51,119) (-50,119) (-49,117) (-49,118) (-48,117) (-48,118) (-47,117)} 45 | (119,-43) -> {(-54,119) (-54,120) (-52,118) (-53,119) (-53,120) (-52,119) (-52,120) (-51,118) (-50,118) (-51,119) (-50,119)} 46 | (119,-42) -> {(-54,119) (-52,118) (-53,119) (-53,120) (-52,119) (-52,120) (-51,118) (-50,118) (-51,119) (-50,119)} 47 | (119,-41) -> {(-54,119) (-52,118) (-53,119) (-53,120) (-52,119) (-52,120) (-51,118) (-50,118) (-51,119) (-50,119)} 48 | -------------------------------------------------------------------------------- /demos/html/implicit_manifold.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | GAIO demo: Computing implicitely defined manifolds

GAIO demo: Computing implicitely defined manifolds

Definition of the manifold

Here is the Devils's curve:

a = 0.9; b = 1;
14 | H = @(x) x(:,1).^2.*(x(:,1).^2-b^2) - x(:,2).^2.*(x(:,2).^2-a^2);
15 | 

Preparations

n = 20; x = linspace(-1,1,n)';
16 | [XX,YY] = meshgrid(x,x); X = [ XX(:) YY(:) ];  % sample points in the unit square
17 | c = [0 0]; r = [2 2]; t = Tree(c, r);          % the box collection
18 | 

Computing the manifold by a subdivison algorithm

dim = t.dim; depth = 18;
19 | hit = 1; sd = 8;                               % define some flags
20 | for d = 1:depth,
21 |     t.set_flags('all', sd);                    % flags all boxes for subdivision
22 |     t.subdivide;                               % subdivide all flaged boxes
23 |     b = t.first_box(-1);                       % loop over all leaves of the tree
24 |     while (~isempty(b))
25 |         c = b(1:dim); r = b(dim+1:2*dim);      % center and radius of the current box
26 |         p = X*diag(r) + ones(size(X))*diag(c); % sample points in the current box
27 |         if min(sign(H(p)))*max(sign(H(p))) < 0 % check whether box intersects the manifold
28 |            t.set_flags(c, hit);                % if so, flag box
29 |         end
30 |         b = t.next_box(-1);
31 |     end
32 |     t.remove(hit);                             % remove all *non* flaged boxes
33 | end
34 | 

Plot

boxplot2(t); xlabel('$x$'); ylabel('$y$');
35 | 

Cleanup

delete(t);
36 | 
-------------------------------------------------------------------------------- /@Tree/Tree.m: -------------------------------------------------------------------------------- 1 | function t = Tree(arg0, arg1, arg2) 2 | 3 | % Tree - create a tree object 4 | % t = Tree(C, R) creates an empty tree with an outer box 5 | % of center C and radius R. 6 | % t = Tree('foo') loads a tree from file 'foo' 7 | % 8 | % NOTE: call delete(t); clear t; to delete the tree from memory. 9 | % 10 | % Attributes 11 | % t.dim - dimension of state space 12 | % t.depth - current depth 13 | % t.center - center of the outer box Q 14 | % t.center = c - sets center of outer box Q to c 15 | % t.radius - radius of the outer box Q 16 | % t.radius = r - sets the radius of outer box Q to r 17 | % t.sd - vector which defines in which coordinate direction 18 | % boxes on a certain depth will be subdivided (i.e. 19 | % boxes on depth i will be subdivided in coordinate 20 | % direction t.sd[i]) 21 | % t.sd = sd - sets the vector t.sd to sd 22 | % 23 | % Methods 24 | % t.boxes(d) - the box collection on depth d (use d=-1 for 25 | % the leaves). Each column of the returned 26 | % ((2*dim+2) x m)-matrix (where m is number 27 | % of boxes on depth d) describes one box B(C,R) in 28 | % the format [C; R; flags; color]; 29 | % t.change_flags(w,f,g,d) - see set_flags, changes the flags from f to g; 30 | % t.count(d) - enumerates the boxes and returns the 31 | % number of boxes on depth d; 32 | % t.delete(d) - deletes all boxes on depth d, i.e. afterwards 33 | % the tree has at most depth d-1; 34 | % box = t.first_box(d) - positions onto the first box on 35 | % depth d and returns its geometry in 36 | % the format [center radius flags color] 37 | % t.insert(x,d[,f0,f1,c]) - inserts the boxes on depth d which contain the 38 | % points x; each newly created box gets 39 | % the flag f0 (default=2), others the 40 | % flag f1 (default=0); you may specify 41 | % a vector c (length(x)=length(c)) 42 | % determining the color of the inserted boxes; 43 | % the values of c must lie between 1 and 255 44 | % box = t.next_box(d) - positions onto the next box on 45 | % depth d and returns its geometry in 46 | % the format [center radius flags color] 47 | % t.remove(f) - Removes all leaves b (and corresponding parents) 48 | % for which b->flags!=f; 49 | % t.save('tree') - saves tree t on hard-disk in file 'tree' 50 | % tt = Tree('tree') - loads tree which was saved into file 'tree' into tt 51 | % t.search(x [, d]) - searches for the points given by the columns 52 | % of x on depth d (default = -1); returns a 53 | % vector of length size(x,2), each entry 54 | % of this vector either denotes the number 55 | % of the box the corresponding point is contained 56 | % in or is -1; !! You have to call t.count(d) once 57 | % before using t.search in order to enumerate 58 | % the boxes on depth d; 59 | % t.search_box(C,R[,d]) - finds all boxes on depth d (default = -1) of the 60 | % tree which have a nonempty intersection with the 61 | % rectangle B(C,R) with center C and radius R; 62 | % returns a vector containing the numbers of the boxes 63 | % found or a vector of length 0 if no boxes were found; 64 | % !! You have to call t.count(d) once before using 65 | % t.search in order to enumerate the boxes on depth d; 66 | % t.set_flags(w, f, d) - sets flags f in the i-th box on depth d 67 | % if the i-th character of string w is a '1' 68 | % if w=='all', all boxes are considered; 69 | % t.set_flags(x, f, d) - sets flags f in the boxes on depth d which 70 | % contain the points x; returns 1, if the flag 71 | % of some box was set, otherwise 0; 72 | % t.subdivide(f) - subdivides all leaves which have the flags f 73 | % set; returns the number of subdivided boxes; 74 | % t.unset_flags(w, f, d) - see set_flags, but unsets the flags; 75 | % t.unsubdivide(f) - Unsubdivides all leaves which have the flag f 76 | % set; returns the number of unsubdivided boxes; 77 | 78 | % (c) 2013 djs2 GbR 79 | 80 | if nargin==0 81 | error('Too few input arguments: filename or center/radius expected.') 82 | elseif nargin==1 83 | if ~ischar(arg0) 84 | error('filename expected.'); 85 | end 86 | t.handle = load_tree(arg0); 87 | t = class(t, 'Tree'); 88 | elseif nargin==2 89 | if (length(arg1)~=length(arg0)) 90 | error('center and radius must have the same dimension.'); 91 | end 92 | t.handle = tree_(length(arg0), arg0, arg1); 93 | t = class(t, 'Tree'); 94 | end 95 | 96 | -------------------------------------------------------------------------------- /matlab/dijkstra.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define VERY_LARGE 100000 5 | 6 | struct GRAPH { 7 | int n; 8 | mwIndex *ep; 9 | mwIndex *edge; 10 | double *ew; 11 | }; 12 | 13 | struct BHEAP { 14 | int n; 15 | int space; 16 | int *ele; 17 | int *pos; 18 | }; 19 | 20 | int bheapNew (struct BHEAP *bheap, int n) 21 | { int i; 22 | 23 | bheap->n = bheap->space = n; 24 | 25 | if(!(bheap->ele = (int*)mxCalloc((unsigned)n,sizeof(int))) || 26 | !(bheap->pos = (int*)mxCalloc((unsigned)n,sizeof(int))) ) 27 | { printf("ERROR...calloc!\n"); return 1; } 28 | for (i=0; iele[i] = bheap->pos[i] = i; 30 | return 0; 31 | } 32 | 33 | void bheapFree (struct BHEAP bheap) 34 | { mxFree(bheap.ele); 35 | mxFree(bheap.pos); 36 | } 37 | 38 | int bheap_size (struct BHEAP *bheap) 39 | { 40 | return bheap->n; 41 | } 42 | 43 | int bheap_min (struct BHEAP *bheap) 44 | { 45 | return bheap->ele[0]; 46 | } 47 | 48 | 49 | void bheap_check (struct BHEAP bheap, double *d) 50 | { int i,left,right; 51 | 52 | for (i=0; i0 && d[element]ele[0]; 93 | bheap->ele[0] = bheap->ele[--(bheap->n)]; 94 | bheap->pos[bheap->ele[0]] = 0; 95 | heapify(*bheap,0,d); 96 | return min; 97 | } 98 | 99 | int dijkstra(struct GRAPH graph, int sour, double *d, int *pre) 100 | { int i, j; 101 | struct BHEAP bheap; 102 | 103 | for (i=0; i d[sour] + (graph.ew[j])) 114 | { d[graph.edge[j]] = d[sour] + (graph.ew[j]); 115 | pre[graph.edge[j]] = sour; 116 | bheap_decrease_key(bheap,graph.edge[j],d); 117 | } 118 | } 119 | 120 | do { 121 | i = bheap_extract_min(&bheap,d); 122 | for (j=graph.ep[i]; j d[i] + (graph.ew[j])) { 124 | d[graph.edge[j]] = d[i] + (graph.ew[j]); 125 | pre[graph.edge[j]] = i; 126 | bheap_decrease_key(bheap,graph.edge[j],d); 127 | } 128 | } 129 | } while (bheap_size(&bheap)>0 && d[bheap_min(&bheap)] < VERY_LARGE); 130 | 131 | bheapFree (bheap); 132 | return 0; 133 | } 134 | 135 | 136 | /* Das Array 'd' zeigt die Distanz von dem jeweilgen Knoten zum 137 | 'dest'-Knoten an. 138 | Das Array 'next' zeigt fuer jeden Knoten an, zu welchem naechsten Knoten 139 | es weiter gehen muss um zu dem 'dest'-Knoten zu kommen. 140 | */ 141 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 142 | 143 | int i, e, dest, *next; 144 | struct GRAPH graph,fgraph; 145 | double *pr, *d; 146 | 147 | if (nrhs < 2) 148 | mexErrMsgTxt("usage: dijkstra_all(matrix, destination)."); 149 | if (!mxIsSparse(prhs[0])) 150 | mexErrMsgTxt("first parameter must be sparse."); 151 | 152 | graph.n = mxGetM(prhs[0]); 153 | graph.ep = mxGetJc(prhs[0]); 154 | graph.edge = mxGetIr(prhs[0]); 155 | graph.ew = mxGetPr(prhs[0]); 156 | 157 | dest = (int)*mxGetPr(prhs[1]) - 1; 158 | if (dest < 0 || dest >= graph.n) 159 | mexErrMsgTxt("destination node out of range."); 160 | /* printf("dest = %d\n", dest); fflush(stdout); */ 161 | 162 | if (!(d = (double*)mxCalloc((unsigned)graph.n,sizeof(double))) || 163 | !(next= (int*) mxCalloc((unsigned)graph.n,sizeof(int))) ) 164 | { printf("ERROR...calloc!\n"); return; } 165 | 166 | if (dijkstra(graph, dest, d, next)) 167 | mexErrMsgTxt("allocation error in New."); 168 | 169 | plhs[0] = mxCreateDoubleMatrix(1, graph.n, mxREAL); 170 | pr = mxGetPr(plhs[0]); 171 | for (i=0; i 1) { 173 | plhs[1] = mxCreateDoubleMatrix(1, graph.n, mxREAL); 174 | pr = mxGetPr(plhs[1]); 175 | for (i=0; i 11 | #include 12 | 13 | SparseMatrix *SparseMatrixNew(int dim) { 14 | SparseMatrix *A; 15 | 16 | NEW1(A, SparseMatrix*, 1); 17 | A->dim = dim; 18 | A->nz = 0; 19 | A->size=dim*NZperCOL; 20 | NEW1(A->rows, int*, A->size); 21 | NEW1(A->cols, int*, A->size); 22 | NEW1(A->entries, double*, A->size); 23 | 24 | return A; 25 | } 26 | 27 | void SparseMatrixFree(SparseMatrix **A) { 28 | if (*A) { 29 | FREE((*A)->entries); 30 | FREE((*A)->cols); 31 | FREE((*A)->rows); 32 | FREE(*A); 33 | A = 0; 34 | } 35 | } 36 | 37 | void SparseMatrixAddEntry(SparseMatrix *A, int row, int col, double entry) { 38 | if (A->nz >= A->size) { 39 | A->size *= 2; 40 | A->rows = (int*)realloc(A->rows, A->size*sizeof(int)); 41 | A->cols = (int*)realloc(A->cols, A->size*sizeof(int)); 42 | A->entries = (double*)realloc(A->entries, A->size*sizeof(double)); 43 | } 44 | A->dim = max(max(A->dim, row+1), col+1); 45 | A->rows[A->nz] = row; 46 | A->cols[A->nz] = col; 47 | A->entries[A->nz] = entry; 48 | A->nz++; 49 | } 50 | 51 | void SparseMatrixAddDiag(SparseMatrix *A, double a) { 52 | if (A) { 53 | int k; 54 | int *flag; 55 | NEW1(flag, int*, A->dim); 56 | 57 | /* looking for diagonal elemenst in existing entries */ 58 | for (k=0; k < A->nz; k++) { 59 | if (A->rows[k]==A->cols[k]) { 60 | A->entries[k] += a; 61 | flag[A->rows[k]-1] = 1; 62 | } 63 | } 64 | 65 | /* inserting the remaining elements */ 66 | for (k=1; k <= A->dim; k++) 67 | if (!flag[k-1]) 68 | SparseMatrixAddEntry(A, k, k, a); 69 | } 70 | } 71 | 72 | char *SparseMatrixEquilibria(SparseMatrix *A) { 73 | int i, n = A->dim; 74 | char *flags; 75 | NEW1(flags, char*, n+1); 76 | flags[n] = 0; 77 | 78 | for (i=0; inz; i++) 80 | if ((A->rows[i]==A->cols[i]) && A->entries[i]!=0.0) 81 | flags[A->rows[i]] = '1'; 82 | 83 | return flags; 84 | } 85 | 86 | char *SparseMatrixFindSignChange(SparseMatrix *A, Matrix *v, int which) { 87 | int i, n = A->dim; 88 | char *flags; 89 | NEW1(flags, char*, n+1); 90 | flags[n] = 0; 91 | 92 | for (i=0; inz; i++) 94 | if (A->entries[i]!=0.0) { 95 | double from = MatrixGetElement(v, A->cols[i], 0); 96 | double to = MatrixGetElement(v, A->rows[i], 0); 97 | if (sign(from)!=sign(to)) 98 | switch (which) { 99 | case 1: flags[A->cols[i]] = '1'; 100 | break; 101 | case -1:flags[A->rows[i]] = '1'; 102 | break; 103 | } 104 | } 105 | return flags; 106 | } 107 | 108 | void SparseMatrixMult(SparseMatrix *A, double *x, double *y) { 109 | int i, j, k; 110 | for (i=0; i < A->dim; i++) y[i] = 0; 111 | for (k=0; k < A->nz; k++) { 112 | i = A->rows[k]; 113 | j = A->cols[k]; 114 | y[i] += A->entries[k]*x[j]; 115 | } 116 | } 117 | 118 | void SparseMatrixTMult(SparseMatrix *A, double *x, double *y) { 119 | int i, j, k; 120 | for (i=0; i < A->dim; i++) y[i] = 0; 121 | for (k=0; k < A->nz; k++) { 122 | j = A->rows[k]; 123 | i = A->cols[k]; 124 | y[i] += A->entries[k]*x[j]; 125 | } 126 | } 127 | 128 | double SparseMatrixNorm(SparseMatrix *A, int which) { 129 | int i; 130 | double *sums; 131 | double norm = 0.0; 132 | 133 | NEW1(sums, double*, A->dim); 134 | for (i=0;idim;i++) sums[i] = 0.0; 135 | 136 | switch(which) { 137 | case -1: /* Norm(A,inf) */ 138 | for (i=0;inz;i++) { 139 | sums[A->rows[i]] += fabs(A->entries[i]); 140 | norm = max(norm, sums[A->rows[i]]); 141 | } 142 | case 1: /* Norm(A,1) */ 143 | for (i=0;inz;i++) { 144 | sums[A->cols[i]] += fabs(A->entries[i]); 145 | norm = max(norm, sums[A->cols[i]]); 146 | } 147 | } 148 | 149 | FREE(sums); 150 | 151 | return norm; 152 | } 153 | 154 | void SparseMatrixInfo(FILE *out, SparseMatrix *A) { 155 | mexPrintf("sparse matrix at %p:\n", A); 156 | if (A) { 157 | int i; 158 | mexPrintf(" dim = %d\n", A->dim); 159 | mexPrintf(" nonzeros = %d\n", A->nz); 160 | for (i=0; i < A->nz; i++) 161 | mexPrintf(" (%d, %d) = %g\n", A->rows[i]+1, A->cols[i]+1, A->entries[i]); 162 | } 163 | } 164 | 165 | void SparseMatrixPrint(FILE *out, SparseMatrix *A) { 166 | if (A) { 167 | int i; 168 | for (i=0; i < A->nz; i++) 169 | fprintf(out, "%d %d %g\n", A->rows[i]+1, A->cols[i]+1, A->entries[i]); 170 | } 171 | } 172 | 173 | SparseMatrix *SparseMatrixLoad(FILE *in) { 174 | int row,col; 175 | double entry; 176 | SparseMatrix *A; 177 | 178 | NEW1(A, SparseMatrix*, 1); 179 | A->dim = 0; 180 | A->nz = 0; 181 | A->size = 100*NZperCOL; 182 | NEW1(A->rows, int*, A->size); 183 | NEW1(A->cols, int*, A->size); 184 | NEW1(A->entries, double*, A->size); 185 | 186 | while (fscanf(in,"%d %d %lf",&row,&col,&entry)==3) { 187 | A->dim=max(A->dim,max(row,col)); 188 | if (A->nz >= A->size) { 189 | A->size *= 2; 190 | A->rows = (int*)realloc(A->rows, A->size*sizeof(int)); 191 | A->cols = (int*)realloc(A->cols, A->size*sizeof(int)); 192 | A->entries = (double*)realloc(A->entries, A->size*sizeof(double)); 193 | } 194 | A->rows[A->nz] = row-1; 195 | A->cols[A->nz] = col-1; 196 | A->entries[A->nz] = entry; 197 | A->nz++; 198 | } 199 | return A; 200 | } 201 | 202 | char *SparseMatrixSinks(SparseMatrix *A, Matrix *scc) { 203 | 204 | int i, dim; 205 | char *flags; 206 | 207 | dim = A->dim; 208 | NEW1(flags, char*, dim+1); 209 | flags[dim] = 0; 210 | for (i=0; inz; i++) 213 | if (A->entries[i]!=0.0) { 214 | double from = MatrixGetElement(scc, A->cols[i], 0); 215 | double to = MatrixGetElement(scc, A->rows[i], 0); 216 | if (from!=to) flags[A->cols[i]] = '0'; 217 | } 218 | 219 | return flags; 220 | } 221 | -------------------------------------------------------------------------------- /lib/IndSubshift.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Oliver Junge, for details see COPYING 3 | * 4 | * IndSubshift.c 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | static int _no_of_newnodes = 0; 13 | 14 | IndSubshift *IndSubshiftNew(SparseMatrix *A, unsigned char *letters) { 15 | int i; 16 | IndSubshift *s; 17 | 18 | NEW(s, 1); 19 | s->dim_sof = A->dim; 20 | s->dim_sub = 0; 21 | s->max_nodesize = 0; 22 | s->A = A; 23 | NEW(s->letters, A->dim); 24 | s->no_of_letters = letters[0]+1; 25 | for (i=1; idim; i++) { 26 | /* mexPrintf("letters[%d] = %d\n", i, letters[i]); */ 27 | if (letters[i]+1 > s->no_of_letters) 28 | s->no_of_letters = letters[i]+1; 29 | } 30 | memcpy(s->letters, letters, (A->dim)); 31 | /* mexPrintf("IndSubshiftNew: no_of_letters = %d\n", s->no_of_letters); */ 32 | s->root = NodeNew(0); 33 | s->root->sub = -1; 34 | 35 | return s; 36 | } 37 | 38 | void IndSubshiftFree(IndSubshift **s) { 39 | if (*s) { 40 | FREE((*s)->letters); 41 | NodeFree(&((*s)->root)); 42 | FREE(*s); 43 | *s = 0; 44 | } 45 | } 46 | 47 | Node *IndSubshiftInsert(IndSubshift *s, char *node) { 48 | unsigned int i, flag; 49 | Node *current; 50 | 51 | current = s->root; 52 | for (i=0; idim_sof; i++) 53 | if (node[i]) 54 | current = NodeInsert(current, i+1); 55 | 56 | if (current->sub==0) 57 | current->sub = ++s->dim_sub; 58 | 59 | return current; 60 | } 61 | 62 | int IndSubshiftNewnode(IndSubshift *s, char letter, char *node, 63 | char *newnode) { 64 | int k, hits = 0; 65 | 66 | memset(newnode, 0, s->dim_sof); 67 | 68 | for (k=0; kA->nz; k++) { 69 | int i = s->A->rows[k]; 70 | int j = s->A->cols[k]; 71 | /* printf("i=%d, j=%d, ent=%lf, node[j]=%d, let[j]=%d\n", i, j, 72 | s->A->entries[k], node[j], s->letters[j]); */ 73 | if (s->A->entries[k]!=0.0 && node[j] && s->letters[j]==letter) { 74 | hits = 1; 75 | newnode[i] = 1; 76 | } 77 | } 78 | return hits; 79 | } 80 | 81 | void NodePrint(char *n, int dim) { 82 | int i; 83 | 84 | for (i=0; idim_sof); */ 95 | /* memcpy(node, _node, s->dim_sof); */ 96 | /* NEW(newnode, s->dim_sof); */ 97 | /* n = IndSubshiftInsert(s, node); */ 98 | /* hits = 1; */ 99 | 100 | /* while (!(n->flags & (1 << letter)) && hits) { */ 101 | /* hits = IndSubshiftNewnode(s, letter, node, newnode); */ 102 | /* n->flags |= (1 << letter); */ 103 | /* printf("letter = %d\n", letter); */ 104 | /* NodePrint(stdout, node, s->dim_sof); */ 105 | /* NodePrint(stdout, newnode, s->dim_sof); */ 106 | /* if (hits) { */ 107 | /* newn = IndSubshiftInsert(s, newnode); */ 108 | /* SparseMatrixAddEntry(A, newn->sub-1, n->sub-1, 1.0); */ 109 | /* n = newn; */ 110 | /* tmpnode = node; node = newnode; newnode = tmpnode; */ 111 | /* } */ 112 | /* } */ 113 | 114 | /* FREE(newnode); */ 115 | /* FREE(node); */ 116 | /* } */ 117 | 118 | void IndSubshiftExtend(IndSubshift *s, SparseMatrix *A, char *node, Node *n) { 119 | 120 | long l, l1; /* letter */ 121 | int hits; /* number of nodes in sofic shift hit by _n */ 122 | char *newnode; 123 | Node *newn; 124 | 125 | s->max_nodesize = max(s->max_nodesize, sumchars(node, s->dim_sof)); 126 | 127 | NEW(newnode, s->dim_sof); 128 | 129 | for (l=0; l < s->no_of_letters; l++) { 130 | /* mexPrintf("letter = %d\n", l); */ 131 | if (!(n->flags & ((long)1 << l))) { 132 | hits = IndSubshiftNewnode(s, l, node, newnode); 133 | n->flags |= ((long)1 << l); 134 | /* NodePrint(node, s->dim_sof); 135 | NodePrint(newnode, s->dim_sof); */ 136 | if (hits) { 137 | newn = IndSubshiftInsert(s, newnode); 138 | SparseMatrixAddEntry(A, newn->sub-1, n->sub-1, 1.0); 139 | IndSubshiftExtend(s, A, newnode, newn); 140 | } 141 | } 142 | } 143 | 144 | FREE(newnode); 145 | 146 | return; 147 | } 148 | 149 | SparseMatrix *IndSubshiftGraph(IndSubshift *s, int start) { 150 | int i, max_nodesize; 151 | char *node; 152 | SparseMatrix *A; 153 | Node *n; 154 | 155 | A = SparseMatrixNew(1); 156 | 157 | NEW(node, s->dim_sof); 158 | 159 | /* i = 0; */ 160 | /* memset(node, 0, s->dim_sof); */ 161 | /* do { */ 162 | /* node[i] = 1; */ 163 | /* n = IndSubshiftInsert(s, node); */ 164 | /* IndSubshiftExtend(s, A, node, n); */ 165 | /* node[i] = 0; */ 166 | /* i++; */ 167 | /* } while (i < s->dim_sof); */ 168 | memset(node, 0, s->dim_sof); 169 | node[start] = 1; 170 | n = IndSubshiftInsert(s, node); 171 | IndSubshiftExtend(s, A, node, n); 172 | /* mexPrintf("max_nodesize = %d\n", s->max_nodesize); */ 173 | 174 | FREE(node); 175 | 176 | return A; 177 | } 178 | 179 | /* SparseMatrix *IndSubshiftGraph(IndSubshift *s) { */ 180 | /* char *node; */ 181 | /* SparseMatrix *A; */ 182 | /* int letter, i; */ 183 | 184 | /* NEW(node, s->dim_sof); */ 185 | /* A = SparseMatrixNew(1); */ 186 | 187 | /* for (letter=0; letterno_of_letters; letter++) { */ 188 | /* memset(node, 0, s->dim_sof); */ 189 | /* i=0; */ 190 | /* while (s->letters[i]!=letter) i++; */ 191 | /* node[i] = 1; */ 192 | /* IndSubshiftPath(s, A, letter, node); */ 193 | /* } */ 194 | 195 | /* i = 0; */ 196 | /* memset(node, 0, s->dim_sof); */ 197 | /* node[i] = 1; */ 198 | /* do { */ 199 | /* node[i] = 1; */ 200 | /* IndSubshiftPath(s, A, s->letters[i], node); */ 201 | /* node[i] = 0; */ 202 | /* i++; */ 203 | /* } while (i < s->dim_sof); */ 204 | 205 | /* FREE(node); */ 206 | 207 | /* return A; */ 208 | /* } */ 209 | 210 | 211 | void IndSubshiftInfo(FILE *out, IndSubshift *s) { 212 | fprintf(out, "IndSubshift at %p:\n", s); 213 | if (s) { 214 | fprintf(out, " dim_sof = %d\n", s->dim_sof); 215 | fprintf(out, " dim_sub = %d\n", s->dim_sub); 216 | NodeInfo(out, 0, s->root); 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /demos/html/attractor.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | GAIO demo: Relative global attractor of the Hénon map

GAIO demo: Relative global attractor of the Hénon map

The Hénon map

The Hénon map is a well known example of a map which exhibits complicated dynamics . Here is a plot of its attractor for \$a=1.4\$ and \$b=0.3\$.

a = 1.4; b = 0.3;                                       % parameters of the map
14 | f = @(x) [1-a*x(:,1).^2+x(:,2)  b*x(:,1)];              % Hénon map
15 | x = [0.1 0.1];                                          % initial point
16 | for i=1:10000, x = [x; f(x(end,:))]; end                % iteration
17 | plot(x(:,1),x(:,2),'.'); xlabel('x'); ylabel('y');      % plot of the attractor
18 | 

Preparations

In order to compute a covering of the attractor, we first choose sample points in the square \$[-1,1]^\$. Here, we chose these points on the edges of the square.

n = 40; X1 = linspace(-1,1,n)'; E = ones(size(X1));     % 1d points
19 | X = [ X1 -E; X1 E; -E X1; E X1];                        % sample points in \$[-1,1]^\$
20 | 

and initialize the tree using the square [-3,3]^2

c = [0 0]; r = [3 3];
21 | t = Tree(c, r);
22 | 

Subdivison algorithm

We can now run the subdivision algorithm for the (relative) global attractor.

dim = t.dim; depth = 20;
23 | hit = 1; sd = 8;                                 % define flags
24 | for i=1:depth,                                   % subdivide up to the given depth
25 |     t.set_flags('all', sd);                      % flag all boxes for subdivision
26 |     t.subdivide;                                 % subdivide all flaged boxes
27 |     b = t.first_box(-1);                         % loop over leaves of the tree
28 |     while (~isempty(b))
29 |         c = b(1:dim); r = b(dim+1:2*dim);        % center and radius of current box
30 |         p = X*diag(r) + ones(size(X))*diag(c);   % sample points in current box
31 |         t.set_flags(f(p)', hit);                 % map points and flag hit boxes
32 |         b = t.next_box(-1);
33 |     end
34 |     t.remove(hit);                               % remove all boxes which have *not* been hit
35 | end
36 | 

Plot of the box collection

boxplot2(t); xlabel('x'); ylabel('y');
37 | 

Cleanup

delete(t);
38 | 
-------------------------------------------------------------------------------- /demos/html/lorenz_measure.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | lorenz_measure

GAIO demo: Invariant measure in the Lorenz system

s = 10; rh = 28; b = 0.4;                % the Lorenz system
 14 | v = @(x) [s*(x(:,2)-x(:,1)) ...
 15 |           rh*x(:,1)-x(:,2)-x(:,1).*x(:,3) ...
 16 |           x(:,1).*x(:,2)-b*x(:,3)];
 17 | h = 0.01; n = 10; f = @(x) rk4(v,x,h,n); % f is the flow
 18 | 

Preparations

choose sample points, construct box tree

n = 7; x = linspace(-1,1,n)'; [XX,YY,ZZ] = meshgrid(x,x,x);
 19 | X = [ XX(:) YY(:) ZZ(:) ];               % $7^3$ sample points
 20 | c = [0.1 0.1 27]; r = [30 30 40];
 21 | t = Tree(c,r);                           % the box collection
 22 | 

Computation of the global unstable manifold

a = sqrt(b*(rh-1)); x0 = [a a rh-1;-a -a rh-1]; % equilibria
 23 | depth = 21; t.insert(x0', depth);        % construct [x0]
 24 | gum(t, f, X, depth);                     % compute global unstable manifold
 25 | 
step 1: 2 of 2 boxes, 0.0 sec
 26 | step 2: 12 of 12 boxes, 0.0 sec
 27 | step 3: 29 of 29 boxes, 0.0 sec
 28 | step 4: 51 of 51 boxes, 0.0 sec
 29 | step 5: 84 of 84 boxes, 0.1 sec
 30 | step 6: 107 of 107 boxes, 0.2 sec
 31 | step 7: 125 of 125 boxes, 0.2 sec
 32 | step 8: 166 of 166 boxes, 0.3 sec
 33 | step 9: 176 of 176 boxes, 0.4 sec
 34 | step 10: 216 of 216 boxes, 0.6 sec
 35 | step 11: 249 of 249 boxes, 0.7 sec
 36 | step 12: 287 of 287 boxes, 0.8 sec
 37 | step 13: 338 of 338 boxes, 1.0 sec
 38 | step 14: 385 of 385 boxes, 1.3 sec
 39 | step 15: 400 of 400 boxes, 1.5 sec
 40 | step 16: 456 of 456 boxes, 1.7 sec
 41 | step 17: 446 of 446 boxes, 1.9 sec
 42 | step 18: 491 of 491 boxes, 2.2 sec
 43 | step 19: 543 of 543 boxes, 2.5 sec
 44 | step 20: 661 of 661 boxes, 2.8 sec
 45 | step 21: 738 of 738 boxes, 3.2 sec
 46 | step 22: 831 of 831 boxes, 3.6 sec
 47 | step 23: 870 of 870 boxes, 4.0 sec
 48 | step 24: 852 of 852 boxes, 4.5 sec
 49 | step 25: 794 of 794 boxes, 4.9 sec
 50 | step 26: 797 of 797 boxes, 5.3 sec
 51 | step 27: 797 of 797 boxes, 5.7 sec
 52 | step 28: 801 of 801 boxes, 6.1 sec
 53 | step 29: 835 of 835 boxes, 6.5 sec
 54 | step 30: 866 of 866 boxes, 7.0 sec
 55 | step 31: 882 of 882 boxes, 7.4 sec
 56 | step 32: 942 of 942 boxes, 7.9 sec
 57 | step 33: 971 of 971 boxes, 8.5 sec
 58 | step 34: 981 of 981 boxes, 9.0 sec
 59 | step 35: 1002 of 1002 boxes, 9.6 sec
 60 | step 36: 1050 of 1050 boxes, 10.1 sec
 61 | step 37: 1065 of 1065 boxes, 10.7 sec
 62 | step 38: 1104 of 1104 boxes, 11.3 sec
 63 | step 39: 1128 of 1128 boxes, 11.9 sec
 64 | step 40: 1184 of 1184 boxes, 12.5 sec
 65 | step 41: 1211 of 1211 boxes, 13.1 sec
 66 | step 42: 1186 of 1186 boxes, 13.8 sec
 67 | step 43: 1204 of 1204 boxes, 14.4 sec
 68 | step 44: 1198 of 1198 boxes, 15.1 sec
 69 | step 45: 1208 of 1208 boxes, 15.8 sec
 70 | step 46: 1155 of 1155 boxes, 16.5 sec
 71 | step 47: 992 of 992 boxes, 17.0 sec
 72 | step 48: 681 of 681 boxes, 17.5 sec
 73 | step 49: 393 of 393 boxes, 17.8 sec
 74 | step 50: 217 of 217 boxes, 17.9 sec
 75 | step 51: 101 of 101 boxes, 18.0 sec
 76 | step 52: 43 of 43 boxes, 18.0 sec
 77 | step 53: 17 of 17 boxes, 18.0 sec
 78 | 

Computation of the invariant measure

X = 2*rand(100,3)-1;                     % points for Monte Carlo quadrature
 79 | P = tpmatrix(t, f, X, depth);            % transition matrix
 80 | [w,lambda] = eigs(P,1,'lm');             % compute eigenvector at eigenvalue 1
 81 | wp = log10(max(abs(w(:,1)),1e-16));      % plot measure logarithmically
 82 | 
33320 of 33320 boxes, 5.5 sec
 83 | 

Visualization

boxplot3(t,'depth',depth,'density', wp ,'alpha',0.1);
 84 | load lorenz_cmap; colormap(cmap);        % special colormap
 85 | view(20,30); axis square; axis tight;
 86 | xlabel('x'); ylabel('y'); zlabel('z');
 87 | 

Cleanup

delete(t);
 88 | 
-------------------------------------------------------------------------------- /demos/html/lorenz.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | GAIO demo: A global unstable manifold in the Lorenz system

GAIO demo: A global unstable manifold in the Lorenz system

The Lorenz attractor

The Lorenz system \[ \begin{align} \dot x & = \sigma(y-x)\\ \dot y & = \rho x-y-xz\\ \dot z & = xy-\beta z \end{align}\] (with standard parameters , and ) was derived by Edward Lorenz in 1963 as a simplified model for atmospheric convection. A simulation shows the famous Lorenz attractor :

sigma = 10; rho = 28; beta = 8/3;
 14 | v = @(x) [sigma*(x(:,2)-x(:,1)) ...             % the Lorenz system
 15 |           rho*x(:,1)-x(:,2)-x(:,1).*x(:,3) ...
 16 |           x(:,1).*x(:,2)-beta*x(:,3)];
 17 | f = @(x) rk4(v,x,0.01,1);                       % f is the time-0.01-map
 18 | y(1,:) = rand(1,3);                             % random initial point
 19 | for k = 1:2e4, y(k+1,:) = f(y(k,:)); end        % integrate
 20 | plot3(y(:,1),y(:,2),y(:,3),'.','markersize',1); % plot trajectory
 21 | view(20,30); axis tight; axis square;
 22 | xlabel('x'); ylabel('y'); zlabel('z');
 23 | 

Preparations

We first choose sample points on a uniform grid in the cube ,

n = 7; x = linspace(-1,1,n)';
 24 | [XX,YY,ZZ] = meshgrid(x,x,x);
 25 | X = [ XX(:) YY(:) ZZ(:) ];                           % $7^3$ sample points
 26 | 

initialize the tree using the box and initalize the covering by constructing a single box containing one of the two unstable equilibria of the Lorenz system

c = [0 0 27]; r = [30 30 40]; t = Tree(c,r);         % the box tree
 27 | dim = 3; depth = 18;                                 % the depth of the tree
 28 | x0 = [sqrt(beta*(rho-1)) sqrt(beta*(rho-1)) rho-1];  % an unstable equilibrium
 29 | t.insert(x0', depth);                                % construct box around x0
 30 | 

The continuation algorithm

The following algorithm from [M. Dellnitz, A. Hohmann. The computation of unstable manifolds using subdivision and continuation. In: H.W. Broer et. al. (eds.): Nonlinear Dynamical Systems and Chaos, PNLDE 19, Birkhäuser, pp. 449-459, 1996.] computes a covering of the global unstable manifold of .

f = @(x) rk4(v,x,0.01,20);                   % time-0.2-map
 31 | none = 0; hit = 1; ins = 2; expd = 4;        % define various flags
 32 | nb0 = 0; nb1 = t.count(depth); k = 0;
 33 | while nb1 > nb0
 34 |   t.change_flags('all', ins, expd);          % flag inserted boxes as to be expanded
 35 |   b = t.first_box(depth);                    % start loop over boxes
 36 |   while (~isempty(b))
 37 |     c = b(1:dim); r = b(dim+1:2*dim);        % center and radius of current box
 38 |     flags = b(2*dim+1);                      % flags of current box
 39 |     if (bitand(flags, expd))                 % if box is to be expanded
 40 |       P = X*diag(r) + ones(size(X))*diag(c); % sample points in current box
 41 |       t.insert(f(P)', depth, ins, none);     % map points and insert boxes
 42 |     end
 43 |     b = t.next_box(depth);                   % loop to next box
 44 |   end
 45 |   t.unset_flags('all', expd);                % unflag recently expanded boxes
 46 |   nb0 = nb1; nb1 = t.count(depth); k = k+1;
 47 |   disp(sprintf('step %d, %d boxes', k, nb1));
 48 | end
 49 | 
step 1, 7 boxes
 50 | step 2, 19 boxes
 51 | step 3, 42 boxes
 52 | step 4, 76 boxes
 53 | step 5, 120 boxes
 54 | step 6, 168 boxes
 55 | step 7, 259 boxes
 56 | step 8, 347 boxes
 57 | step 9, 437 boxes
 58 | step 10, 622 boxes
 59 | step 11, 955 boxes
 60 | step 12, 1601 boxes
 61 | step 13, 2584 boxes
 62 | step 14, 3681 boxes
 63 | step 15, 4492 boxes
 64 | step 16, 4864 boxes
 65 | step 17, 4926 boxes
 66 | step 18, 4931 boxes
 67 | step 19, 4931 boxes
 68 | 

Plot of the box collection

boxplot3(t); view(20,30); axis tight; axis square;
 69 | xlabel('x'); ylabel('y'); zlabel('z');
 70 | 

Cleanup

delete(t);
 71 | 
-------------------------------------------------------------------------------- /demos/html/mxdom2mathjax.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | ]> 11 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 39 | 44 | 45 | 46 | This HTML was auto-generated from MATLAB code. 47 | To make changes, update the MATLAB code and republish this document. 48 | 49 | 50 | <xsl:value-of select="$title"/> 51 | 52 | 53 | MATLAB 54 | 55 | 56 | 57 | 58 | 59 | 60 | .m 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
72 | 73 | 74 | 75 | 76 | 77 | 78 |

79 | introduction 80 | 81 | /introduction 82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | h1 93 | h2 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 |
118 | 119 | 120 | 121 | 122 | 123 |
124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 135 | 136 | 137 | 138 | 139 | 140 |

Contents

141 |
    142 | 143 | 144 |
  • #
  • 145 |
    146 |
    147 |
148 |
149 | 150 | 151 | 152 | 153 |

154 |
155 | 156 |
157 |
158 | 159 |
160 |
161 | 162 |
  • 163 |
    164 | 165 | 166 | 167 |
    168 |
    169 | 170 |
    171 |
    172 |
    173 |
    174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 |
    
    197 | 
    198 |
    199 | 200 | 201 | 202 | 203 |
    
    204 | 
    205 |
    206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 |
    214 |
    215 |
    216 |
    217 | 218 | 219 | 220 | 221 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | T 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | ##### SOURCE BEGIN ##### 262 | 263 | ##### SOURCE END ##### 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 309 | 310 | 312 | 313 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 |
    324 | -------------------------------------------------------------------------------- /@Tree/subsref.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2012 djs2 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | void mexFunction( 15 | int nlhs, mxArray *plhs[], 16 | int nrhs, const mxArray *prhs[] 17 | ) 18 | { 19 | char *type, *attr; 20 | mxArray *ptr; 21 | double *pr, *pl; 22 | int k, dim; 23 | Iter *iter; 24 | 25 | ptr = mxGetField(prhs[0], 0, "handle"); 26 | iter = (Iter *)ptrFromMxArray(ptr); 27 | if (iter==NULL) mexErrMsgTxt("Tree: tree is empty."); 28 | 29 | dim = iter->tree->Q->dim; 30 | 31 | ptr = mxGetField(prhs[1], 0, "type"); 32 | type = mxArrayToString(ptr); 33 | 34 | ptr = mxGetField(prhs[1], 0, "subs"); 35 | attr = mxArrayToString(ptr); 36 | 37 | /* attributes */ 38 | if (mxGetNumberOfElements(prhs[1])==1 && !strcmp(type,".")) { 39 | 40 | if (!strcmp(attr, "dim")) { 41 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 42 | pr = mxGetPr(plhs[0]); 43 | pr[0] = dim; 44 | } 45 | else if (!strcmp(attr, "radius")) { 46 | plhs[0] = mxCreateDoubleMatrix(1, dim, mxREAL); 47 | pr = mxGetPr(plhs[0]); 48 | for (k=0; k < dim; k++) pr[k] = iter->tree->Q->r[k]; 49 | } 50 | else if (!strcmp(attr, "center")) { 51 | plhs[0] = mxCreateDoubleMatrix(1, dim, mxREAL); 52 | pr = mxGetPr(plhs[0]); 53 | for (k=0; k tree->Q->c[k]; 54 | } 55 | else if (!strcmp(attr, "info")) { 56 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 57 | pr = mxGetPr(plhs[0]); 58 | IterInfo(stdout, iter); 59 | TreeInfo(stdout, iter->tree); 60 | } 61 | else if (!strcmp(attr, "verbose")) { 62 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 63 | pr = mxGetPr(plhs[0]); 64 | pr[0] = iter->verbose; 65 | } 66 | else if (!strcmp(attr, "depth")) { 67 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 68 | pr = mxGetPr(plhs[0]); 69 | pr[0] = TreeDepth(iter->tree->root); 70 | } 71 | else if (!strcmp(attr, "subdivide")) { 72 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 73 | pr = mxGetPr(plhs[0]); 74 | pr[0] = TreeSubdivide(iter->tree, SUBDIVIDE); 75 | } 76 | else if (!strcmp(attr, "unsubdivide")) { 77 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 78 | pr = mxGetPr(plhs[0]); 79 | pr[0] = TreeUnsubdivide(iter->tree, SUBDIVIDE); 80 | } 81 | else if (!strcmp(attr, "unsubdivide_current_box")) { 82 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 83 | pr = mxGetPr(plhs[0]); 84 | pr[0] = BoxUnsubdivide(iter->tree->box); 85 | } 86 | else if (!strcmp(attr, "sd")) { 87 | int i; 88 | plhs[0] = mxCreateDoubleMatrix(DEPTH_MAX(dim)+1, 1, mxREAL); 89 | pr = mxGetPr(plhs[0]); 90 | for (i=0; itree->sd[i]; 91 | } 92 | else if (!strcmp(attr, "collapse")) { /* collapse */ 93 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 94 | pr = mxGetPr(plhs[0]); 95 | pr[0] = TreeCollapse(iter->tree); 96 | } 97 | else { 98 | mexErrMsgTxt("Tree: unknown field."); 99 | } 100 | } 101 | 102 | /* methods */ 103 | if (mxGetNumberOfElements(prhs[1])==2 && !strcmp(type,".")) { 104 | int nargin, dim0, dim1 = 0; 105 | mxArray *cell0, *cell1 = 0; 106 | 107 | ptr = mxGetField(prhs[1], 1, "subs"); 108 | nargin = mxGetNumberOfElements(ptr); 109 | if (nargin == 0) { 110 | char errMsg[128]; 111 | sprintf(errMsg, "Tree.%.100s: missing arguments", attr); 112 | mexErrMsgTxt(errMsg); 113 | } 114 | 115 | cell0 = mxGetCell(ptr, 0); 116 | dim0 = mxGetNumberOfElements(cell0); 117 | if (nargin > 1) { 118 | cell1 = mxGetCell(ptr, 1); 119 | dim1 = mxGetNumberOfElements(cell1); 120 | } 121 | 122 | if (!strcmp(attr, "color")) { /* color */ 123 | char *colors; 124 | int depth = -1; 125 | colors = mxArrayToString(cell0); 126 | if (nargin > 1) depth = (int)*mxGetPr(mxGetCell(ptr, 1)); 127 | TreeColor(iter->searchTree, colors, depth); 128 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 129 | } 130 | else if (!strcmp(attr, "change_Q")) { /* change_Q */ 131 | int m_c, m_r; 132 | double *pr_c, *pr_r; 133 | Rectangle *Q; 134 | if (nargin < 2) 135 | mexErrMsgTxt("Tree.change_Q: radius is missing."); 136 | pr_c = mxGetPr(cell0); 137 | m_c = mxGetNumberOfElements(cell0); 138 | pr_r = mxGetPr(cell1); 139 | m_r = mxGetNumberOfElements(cell1); 140 | VecPrint(stdout, pr_c, m_c); 141 | VecPrint(stdout, pr_r, m_r); 142 | if (m_c != m_r) 143 | mexErrMsgTxt("Tree.change_Q: dim(center)!=dim(radius)."); 144 | Q = RectangleNew(pr_c, pr_r, m_c); 145 | TreeFree(&(iter->searchTree)); 146 | TreeChangeQ(iter->tree, Q); 147 | iter->searchTree = TreeCopy(iter->tree); 148 | plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); 149 | } 150 | else if (!strcmp(attr, "count")) { /* count */ 151 | if (dim0 > 1) mexErrMsgTxt("Tree.count: scalar expected."); 152 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 153 | pr = mxGetPr(plhs[0]); 154 | pr[0] = TreeCountDepth(iter->searchTree, (int)*mxGetPr(cell0)); 155 | } 156 | else if (!strcmp(attr, "delete")) { /* delete */ 157 | if (dim0 > 1) mexErrMsgTxt("Tree.delete: scalar expected."); 158 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 159 | pr = mxGetPr(plhs[0]); 160 | TreeDeleteDepth(iter->tree, (int)*mxGetPr(cell0)); 161 | } 162 | else if (!strcmp(attr, "first_box")) { /* first_box */ 163 | if (dim0 > 1) mexErrMsgTxt("Tree.first_box: scalar expected."); 164 | if (TreeFirstBox(iter->tree, (int)*mxGetPr(cell0))) { 165 | plhs[0] = mxCreateDoubleMatrix(2*dim+2, 1, mxREAL); 166 | VecCopy(iter->tree->c, mxGetPr(plhs[0]), dim); 167 | VecCopy(iter->tree->r, mxGetPr(plhs[0]) + dim, dim); 168 | *(mxGetPr(plhs[0]) + 2*dim) = (double)iter->tree->box->flags; 169 | #ifdef _MEASURE_ 170 | *(mxGetPr(plhs[0]) + 2*dim + 1) = (double)iter->tree->box->no + 1; 171 | #endif 172 | } 173 | else { 174 | plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL); 175 | } 176 | } 177 | else if (!strcmp(attr, "next_box")) { /* next_box */ 178 | if (dim0 > 1) mexErrMsgTxt("Tree.next_box: scalar expected."); 179 | if (TreeNextBox(iter->tree, (int)*mxGetPr(cell0))) { 180 | plhs[0] = mxCreateDoubleMatrix(2*dim+2, 1, mxREAL); 181 | VecCopy(iter->tree->c, mxGetPr(plhs[0]), dim); 182 | VecCopy(iter->tree->r, mxGetPr(plhs[0]) + dim, dim); 183 | *(mxGetPr(plhs[0]) + 2*dim) = (double)iter->tree->box->flags; 184 | #ifdef _MEASURE_ 185 | *(mxGetPr(plhs[0]) + 2*dim + 1) = (double)iter->tree->box->no + 1; 186 | #endif 187 | } 188 | else { 189 | plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL); 190 | } 191 | } 192 | else if (!strcmp(attr, "insert")) { /* insert */ 193 | 194 | double *color; 195 | int i, m, n, flag_inserted = INSERTED, flag_found = NONE; 196 | if (nargin < 2) 197 | mexErrMsgTxt("usage: Tree.insert(x, depth)."); 198 | m = mxGetM(cell0); 199 | if (m != dim) 200 | mexErrMsgTxt("Tree.insert: matrix has wrong dimension."); 201 | n = mxGetN(cell0); 202 | plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL); 203 | pr = mxGetPr(plhs[0]); 204 | if (nargin > 2) 205 | flag_inserted = (int)*mxGetPr(mxGetCell(ptr, 2)); 206 | if (nargin > 3) 207 | flag_found = (int)*mxGetPr(mxGetCell(ptr, 3)); 208 | if (nargin > 4) { 209 | color = mxGetPr(mxGetCell(ptr, 4)); 210 | for (i=0; isearchTree, 212 | mxGetPr(cell0) + i*dim, (int)*mxGetPr(cell1), 213 | flag_inserted, flag_found, (byte)*(color + i)); 214 | } 215 | else 216 | for (i=0; isearchTree, 218 | mxGetPr(cell0) + i*dim, (int)*mxGetPr(cell1), 219 | flag_inserted, flag_found, 1); 220 | } 221 | else if (!strcmp(attr, "insert_box")) { /* insert_box */ 222 | double *pr1; 223 | byte color = 1, flag_inserted = INSERTED, flag_found = NONE; 224 | int inserted, n0, m0, n1, m1, depth = -1; 225 | if (nargin < 2) { 226 | mexErrMsgTxt("usage: Tree.insert_box(center, radius)."); 227 | } 228 | m0 = mxGetM(cell0); 229 | n0 = mxGetN(cell0); 230 | if (m0!=dim || n0!=1) 231 | mexErrMsgTxt("Tree.insert_box: center has wrong dimension."); 232 | pr = mxGetPr(cell0); 233 | m1 = mxGetM(cell1); 234 | n1 = mxGetN(cell1); 235 | if (m1!=dim || n1!=1) 236 | mexErrMsgTxt("Tree.insert_box: radius has wrong dimension."); 237 | pr1 = mxGetPr(cell1); 238 | if (nargin > 2) depth = (int)*mxGetPr(mxGetCell(ptr, 2)); 239 | if (nargin > 3) flag_inserted = (byte)*mxGetPr(mxGetCell(ptr, 3)); 240 | if (nargin > 4) flag_found = (byte)*mxGetPr(mxGetCell(ptr, 4)); 241 | if (nargin > 5) color = (byte)*mxGetPr(mxGetCell(ptr, 5)); 242 | /* VecPrint(stdout, pr, dim); */ 243 | /* VecPrint(stdout, pr1, dim); */ 244 | /* printf("depth = %d\n", depth); */ 245 | 246 | inserted = TreeInsertBox(iter->searchTree, pr, pr1, depth, 247 | flag_inserted, flag_found, color); 248 | 249 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 250 | pl = mxGetPr(plhs[0]); 251 | pl[0] = inserted; 252 | } 253 | else if (!strcmp(attr, "boxes")) { /* boxes */ 254 | int dims[2]; 255 | if (dim0 > 1) mexErrMsgTxt("Tree.boxes: scalar expected."); 256 | dims[0] = TreeCountDepth(iter->searchTree, (int)*mxGetPr(cell0)); 257 | dims[1] = 2*iter->tree->Q->dim + 2; 258 | plhs[0] = mxCreateDoubleMatrix(dims[1],dims[0],mxREAL); 259 | pr = mxGetPr(plhs[0]); 260 | TreePrintToMatrix(iter->searchTree, (int)*mxGetPr(cell0), pr); 261 | } 262 | else if (!strcmp(attr, "get_flags")) { /* get_flags */ 263 | char *choice; 264 | int depth = -1; 265 | if (nargin < 2) 266 | mexErrMsgTxt("Tree.get_flags: two arguments required."); 267 | depth = (int)*mxGetPr(cell1); 268 | if (mxIsChar(cell0)) { 269 | int no = TreeCountDepth(iter->tree, depth); 270 | mwSize dims[2]; 271 | dims[0] = no; 272 | dims[1] = 1; 273 | plhs[0] = mxCreateNumericArray(2, dims, mxUINT8_CLASS, mxREAL); 274 | choice = mxArrayToString(cell0); 275 | if (strcmp(choice,"all")) 276 | mexErrMsgTxt("Tree.get_flags: either 'all' or a point expected."); 277 | TreeGetFlags(iter->tree, depth, (byte*)mxGetData(plhs[0])); 278 | mxFree(choice); 279 | } 280 | else { 281 | byte *ptr; 282 | mwSize dims[1]; 283 | dims[0] = 1; 284 | if (dim0 != dim) 285 | mexErrMsgTxt("Tree.get_flags: point has wrong dimension."); 286 | plhs[0] = mxCreateNumericArray(1, dims, mxUINT8_CLASS, mxREAL); 287 | ptr = (byte*)mxGetData(plhs[0]); 288 | if (TreeSearch(iter->tree, mxGetPr(cell0), depth) > 0) { 289 | ptr[0] = BoxGetFlags(iter->tree->box); 290 | } 291 | } 292 | } 293 | else if (!strcmp(attr, "set_flags")) { /* set_flags */ 294 | 295 | char *choice; 296 | byte flag; 297 | int depth = -1; 298 | if (nargin < 2) 299 | mexErrMsgTxt("Tree.set_flags: at least two arguments expected."); 300 | flag = (byte)*mxGetPr(cell1); 301 | if (nargin > 2) depth = (int)*mxGetPr(mxGetCell(ptr, 2)); 302 | if (mxIsChar(cell0)) { 303 | choice = mxArrayToString(cell0); 304 | TreeSetFlags(iter->tree, depth, choice, flag); 305 | mxFree(choice); 306 | plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL); 307 | } 308 | else { 309 | double *ptr; 310 | int i, m, n, found = 0; 311 | m = mxGetM(cell0); 312 | if (m!=dim) 313 | mexErrMsgTxt("Tree.set_flags: input matrix has wrong dimension."); 314 | n = mxGetN(cell0); 315 | pr = mxGetPr(cell0); 316 | for (i=0; isearchTree, pr + i*dim, depth) > 0) { 318 | BoxSetFlag(iter->searchTree->box, flag); 319 | found = 1; 320 | } 321 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 322 | ptr = mxGetPr(plhs[0]); 323 | ptr[0] = found; 324 | } 325 | } 326 | else if (!strcmp(attr, "unset_flags")) { /* unset_flags */ 327 | char *choice; 328 | byte flag; 329 | int depth = -1; 330 | if (nargin < 2) 331 | mexErrMsgTxt("Tree.unset_flags: at least two arguments expected."); 332 | flag = (byte)*mxGetPr(cell1); 333 | if (nargin > 2) depth = (int)*mxGetPr(mxGetCell(ptr, 2)); 334 | if (mxIsChar(cell0)) { 335 | choice = mxArrayToString(cell0); 336 | TreeUnsetFlags(iter->tree, depth, choice, flag); 337 | mxFree(choice); 338 | } 339 | else { 340 | int i, m, n; 341 | m = mxGetM(cell0); 342 | if (m!=dim) 343 | mexErrMsgTxt("Tree.unset_flags: input matrix has wrong dimension."); 344 | n = mxGetN(cell0); 345 | pr = mxGetPr(cell0); 346 | for (i=0; isearchTree, pr + i*dim, depth) > 0) 348 | BoxUnsetFlag(iter->searchTree->box, flag); 349 | } 350 | plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL); 351 | } 352 | else if (!strcmp(attr, "change_flags")) { /* change_flags */ 353 | char *choice; 354 | byte from, to; 355 | int depth = -1; 356 | if (nargin < 3) 357 | mexErrMsgTxt("Tree.change_flags: at least three arguments expected."); 358 | from = (byte)*mxGetPr(cell1); 359 | to = (byte)*mxGetPr(mxGetCell(ptr, 2)); 360 | if (nargin > 3) depth = (int)*mxGetPr(mxGetCell(ptr, 3)); 361 | if (mxIsChar(cell0)) { 362 | choice = mxArrayToString(cell0); 363 | TreeChangeFlags(iter->tree, depth, choice, from, to); 364 | mxFree(choice); 365 | } 366 | else { 367 | int i, m, n; 368 | m = mxGetM(cell0); 369 | if (m!=dim) 370 | mexErrMsgTxt("Tree.change_flags: input matrix has wrong dimension."); 371 | n = mxGetN(cell0); 372 | pr = mxGetPr(cell0); 373 | for (i=0; isearchTree, pr + i*dim, depth) > 0) 375 | BoxChangeFlag(iter->searchTree->box, from, to); 376 | } 377 | plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL); 378 | } 379 | #ifdef _NORMALS_ 380 | else if (!strcmp(attr, "normals")) { /* normals */ 381 | if (nargin<2) 382 | mexErrMsgTxt("Tree.normals: two input arguments expected."); 383 | if (dim0 != dim) 384 | mexErrMsgTxt("Tree.normals: radius has wrong dimension."); 385 | if (dim1 > 1) 386 | mexErrMsgTxt("Tree.normals: scalar as second arg expected."); 387 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 388 | IterNormals(iter, (int)*mxGetPr(cell1), mxGetPr(cell0)); 389 | } 390 | #endif 391 | else if (!strcmp(attr, "remove")) { /* remove */ 392 | if (dim0 > 1) mexErrMsgTxt("Tree.remove: scalar expected."); 393 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 394 | pr = mxGetPr(plhs[0]); 395 | pr[0] = TreeRemove(iter->tree->root, (byte)*mxGetPr(cell0)); 396 | } 397 | else if (!strcmp(attr, "search")) { /* search */ 398 | int i, n, m, depth = -1, found; 399 | double *pl1 = NULL; 400 | m = mxGetM(cell0); 401 | if (m!=dim) 402 | mexErrMsgTxt("Tree.search: input matrix has wrong dimension."); 403 | n = mxGetN(cell0); 404 | pr = mxGetPr(cell0); 405 | plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL); 406 | pl = mxGetPr(plhs[0]); 407 | if (nlhs > 1) { 408 | #ifdef __x86_64 409 | mexWarnMsgTxt("Tree.search: second output argument ignored on this architecture."); 410 | pl1 = NULL; 411 | #else 412 | mwSize dims[2]; 413 | dims[0] = n; 414 | dims[1] = 1; 415 | plhs[1] = mxCreateNumericArray(2, dims, mxUINT32_CLASS, mxREAL); 416 | pl1 = mxGetPr(plhs[1]); 417 | #endif 418 | } 419 | if (nargin > 1) depth = (int)*mxGetPr(mxGetCell(ptr, 1)); 420 | for (i=0; i < n; i++) { 421 | found = TreeSearch(iter->searchTree, pr + i*dim, depth); 422 | #ifdef _MEASURE_ 423 | pl[i] = (found > 0 ? iter->searchTree->box->no + 1: -1); 424 | #else 425 | pl[i] = found; 426 | #endif 427 | #ifndef __x86_64 428 | if (nlhs > 1) 429 | pl1[i] = (unsigned int)iter->searchTree->box; /* this does not work on x86_64! */ 430 | #endif 431 | } 432 | } 433 | #ifdef _MEASURE_ 434 | else if (!strcmp(attr, "search_box")) { /* search_box */ 435 | double *pr1; 436 | SparseVector *nos; 437 | int i, n0, m0, n1, m1, depth = -1; 438 | if (nargin<2) { 439 | mexErrMsgTxt("usage: Tree.search_box(center, radius)."); 440 | } 441 | m0 = mxGetM(cell0); 442 | n0 = mxGetN(cell0); 443 | if (m0!=dim || n0!=1) 444 | mexErrMsgTxt("Tree.search_box: center has wrong dimension."); 445 | pr = mxGetPr(cell0); 446 | m1 = mxGetM(cell1); 447 | n1 = mxGetN(cell1); 448 | if (m1!=dim || n1!=1) 449 | mexErrMsgTxt("Tree.search_box: radius has wrong dimension."); 450 | pr1 = mxGetPr(cell1); 451 | 452 | if (nargin > 2) depth = (int)*mxGetPr(mxGetCell(ptr, 2)); 453 | /* VecPrint(stdout, pr, dim); */ 454 | /* VecPrint(stdout, pr1, dim); */ 455 | /* printf("depth = %d\n", depth); */ 456 | 457 | nos = TreeSearchBox(iter->searchTree, pr, pr1, depth); 458 | 459 | /* SparseVectorInfo(stdout, nos); */ 460 | plhs[0] = mxCreateDoubleMatrix(nos->nz, 1, mxREAL); 461 | pl = mxGetPr(plhs[0]); 462 | for (i=0; inz; i++) pl[i] = nos->rows[i]+1; 463 | SparseVectorFree(&nos); 464 | 465 | } 466 | #endif 467 | else if (!strcmp(attr, "save")) { /* save */ 468 | FILE *out; 469 | char *filename; 470 | if (!mxIsChar(cell0)) mexErrMsgTxt("Tree.save: file name expected."); 471 | filename = mxArrayToString(cell0); 472 | out = fopen(filename, "w"); 473 | if (!out) mexErrMsgTxt("Tree.save: could not open file for writing."); 474 | IterSave(out, iter); 475 | fclose(out); 476 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 477 | mxFree(filename); 478 | } 479 | else if (!strcmp(attr, "subdivide")) { /* subdivide */ 480 | if (dim0 > 1) mexErrMsgTxt("Tree.subdivide: scalar expected."); 481 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 482 | pr = mxGetPr(plhs[0]); 483 | pr[0] = TreeSubdivide(iter->tree, (byte)*mxGetPr(cell0)); 484 | } 485 | else if (!strcmp(attr, "subdivide_current_box")) { 486 | if (dim0 > 1) mexErrMsgTxt("Tree.subdivide: scalar expected."); 487 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 488 | pr = mxGetPr(plhs[0]); 489 | pr[0] = BoxSubdivide(iter->tree->box, (byte)*mxGetPr(cell0)); 490 | } 491 | else if (!strcmp(attr, "unsubdivide")) { /* unsubdivide */ 492 | if (dim0 > 1) mexErrMsgTxt("Tree.unsubdivide: scalar expected."); 493 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 494 | pr = mxGetPr(plhs[0]); 495 | pr[0] = TreeUnsubdivide(iter->tree, (byte)*mxGetPr(cell0)); 496 | } 497 | #ifdef _MEASURE_ 498 | else if (!strcmp(attr, "volume")) { /* volume */ 499 | int n, depth = (int)*mxGetPr(cell0); 500 | if (dim0 > 1) mexErrMsgTxt("Tree.volume: scalar expected."); 501 | n = TreeCountDepth(iter->tree, depth); 502 | plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL); 503 | pr = mxGetPr(plhs[0]); 504 | TreeVolume(iter->tree, pr, depth); 505 | } 506 | #endif 507 | else if (!strcmp(attr, "uncollapse")) { /* uncollapse */ 508 | if (dim0 > 1) mexErrMsgTxt("Tree.uncollapse: scalar expected."); 509 | plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 510 | pr = mxGetPr(plhs[0]); 511 | pr[0] = TreeUncollapse(iter->tree, (int)*mxGetPr(cell0)); 512 | } 513 | else { 514 | mexErrMsgTxt("Tree: unknown method."); 515 | } 516 | } 517 | mxFree(attr); 518 | mxFree(type); 519 | 520 | return; 521 | } 522 | 523 | --------------------------------------------------------------------------------