diff --git a/chunkie/@chunkgraph/build_v2emat.m b/chunkie/@chunkgraph/build_v2emat.m new file mode 100644 index 0000000..0357754 --- /dev/null +++ b/chunkie/@chunkgraph/build_v2emat.m @@ -0,0 +1,42 @@ +function A = build_v2emat(obj) +%V2EMAT get a "vertex to edge" matrix for the chunkgraph object +% +% input: obj - a chunkgraph object +% +% output: A - a nedges x nverts sparse matrix +% A(i,j) = 1 if edge i starts at vertex j +% A(i,j) = -1 if edge i ends at vertex j +% A(i,j) = 2 if edge i starts and ends at vertex j +% + +nverts = size(obj.verts,2); +nedges = size(obj.edgesendverts,2); + + +ii = zeros(2*nedges,1); +jj = zeros(2*nedges,1); +vv = zeros(2*nedges,1); +nf = 0; + +for i = 1:nedges + j1 = obj.edgesendverts(1,i); + j2 = obj.edgesendverts(2,i); + if j1 == j2 + nf = nf + 1; + ii(nf) = i; + jj(nf) = j1; + vv(nf) = 2; + else + nf = nf + 1; + ii(nf) = i; + jj(nf) = j1; + vv(nf) = -1; + nf = nf + 1; + ii(nf) = i; + jj(nf) = j2; + vv(nf) = 1; + end +end + +A = sparse(ii(1:nf),jj(1:nf),vv(1:nf),nedges,nverts); + diff --git a/chunkie/@chunkgraph/chunkgraph.m b/chunkie/@chunkgraph/chunkgraph.m index e3eeb23..7552ebe 100644 --- a/chunkie/@chunkgraph/chunkgraph.m +++ b/chunkie/@chunkgraph/chunkgraph.m @@ -15,10 +15,11 @@ % properties(SetAccess=public) verts - edge2verts + edgesendverts echnks regions vstruc + v2emat end properties(SetAccess=public) @@ -33,15 +34,31 @@ end methods - function obj = chunkgraph(verts,edge2verts,fchnks,cparams) + function obj = chunkgraph(verts,edgesendverts,fchnks,cparams) if (nargin == 0) return end if (numel(verts)==0) return end - obj.verts = verts; - obj.edge2verts = edge2verts; + obj.verts = verts; + + nverts = size(verts(:,:),2); + assert(nverts == size(edgesendverts,2),'edge specification not compatible with number of vertices'); + if (size(edgesendverts,1) ~= 2) + nedge = size(edgesendverts,1); + edgevertends_new = zeros(2,nedge); + nedge = size(edgesendverts,1); + for i = 1:nedge + edgevertends_new(1,i) = find(edgesendverts(i,:) == -1); + edgevertends_new(2,i) = find(edgesendverts(i,:) == 1); + end + edgesendverts = edgevertends_new; + assert(all(edgesendverts(:) ~= 0),'edge specification had an error'); + end + + obj.edgesendverts = edgesendverts; + obj.v2emat = build_v2emat(obj); obj.echnks = chunker.empty; if nargin < 3 @@ -78,15 +95,11 @@ pref.nchmax = 10000; pref.k = 16; - if (size(verts,2) ~= size(edge2verts,2)) - error('Incompatible vertex and edge sizes'); - end - echnks = chunker.empty(); - for i=1:size(edge2verts,1) + for i=1:size(edgesendverts,2) if (numel(fchnks)1) - e2vtmp = e2v(:,iverts); - [iinds,jinds] = find(e2vtmp ~= 0); + v2etmp = obj.v2emat(:,iverts); + [iinds,jinds] = find(v2etmp ~= 0); iinds = unique(iinds); edges = [iinds,-iinds]; +else + % each edge belongs to two regions (going in opposite directions) + edges = [1:nedge,-(1:nedge)]; end regions = {}; @@ -56,8 +55,14 @@ estart = enum; ecycle = [enum]; - iv0 = find(e2v(abs(enum),:)==-sign(enum)); - ivc = find(e2v(abs(enum),:)== sign(enum)); + if enum > 0 + iv0 = obj.edgesendverts(1,abs(enum)); + ivc = obj.edgesendverts(2,abs(enum)); + else + iv0 = obj.edgesendverts(2,abs(enum)); + ivc = obj.edgesendverts(1,abs(enum)); + end + ifdone = false; while (~ifdone) @@ -72,7 +77,11 @@ esign = vstruc{ivc}{2}(1); end enum = -esign*enext; - ivc = find(e2v(abs(enum),:)== sign(enum)); + if enum > 0 + ivc = obj.edgesendverts(2,abs(enum)); + else + ivc = obj.edgesendverts(1,abs(enum)); + end if (enum == estart) ifdone = true; else diff --git a/chunkie/@chunkgraph/vertextract.m b/chunkie/@chunkgraph/vertextract.m index 6c00a8a..7721b91 100644 --- a/chunkie/@chunkgraph/vertextract.m +++ b/chunkie/@chunkgraph/vertextract.m @@ -25,10 +25,14 @@ % author: Jeremy Hoskins +irel = find(cgrph.v2emat(:,ivert) ~= 0); % extract the indices of the edges which terminate at ivert. -ieplus = find(cgrph.edge2verts(:,ivert) == 1); +ieplus = find(cgrph.edgesendverts(2,irel) == ivert); +ieplus = irel(ieplus); ieplus = ieplus(:).'; % extract the indices of the edges which begin at ivert. -ieminus = find(cgrph.edge2verts(:,ivert) == -1); +ieminus = find(cgrph.edgesendverts(1,irel) == ivert); +ieminus = irel(ieminus); ieminus = ieminus(:).'; + % for each incoming edge, get the tangent vector near the end (at the % last discretization node) @@ -50,8 +54,8 @@ [angs,isrtededges] = sort(angs); % compute inds and isgn using isrtedges -inds = [ieplus',ieminus']; -isgn = [ones(size(ieplus')),-ones(size(ieminus'))]; +inds = [ieplus,ieminus]; +isgn = [ones(size(ieplus)),-ones(size(ieminus))]; inds = inds(isrtededges); isgn = isgn(isrtededges); end diff --git a/chunkie/chunkgraphinit.m b/chunkie/chunkgraphinit.m index 01ffde6..044b426 100644 --- a/chunkie/chunkgraphinit.m +++ b/chunkie/chunkgraphinit.m @@ -1,100 +1,7 @@ function [cgrph] = chunkgraphinit(verts,edge2verts,fchnks,cparams) warning('This method is deprecated. Use the chunkgraph constructor instead.'); - prefs = []; - cgrph = chunkgraph(prefs); - cgrph.verts = verts; - cgrph.edge2verts = edge2verts; - cgrph.echnks = chunker.empty; - - if (nargin < 4) - cploc = []; - cploc.ta = 0; - cploc.tb = 1; - cploc.ifclosed = 0; - cploc.nover = 1; - cploc.eps = 1.0d-10; - cploc.lvlr = 'a'; - else - cploc = cparams; - %mandatory settings - cploc.ta = 0; - cploc.tb = 1; - cploc.ifclosed = 0; - if (~isfield(cparams,'lvlr')) - cploc.lvlr = 'a'; - end - if (~isfield(cparams,'eps')) - cploc.eps = 1.0d-10; - end - if (~isfield(cparams,'nover')) - cploc.nover = 1; - end - end - - - pref = []; - pref.nchmax = 10000; - pref.k = 16; - - if (size(verts,2) ~= size(edge2verts,2)) - error('Incompatible vertex and edge sizes'); - end - - echnks = chunker.empty(); - for i=1:size(edge2verts,1) - if (numel(fchnks)