Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new connectivity spec #62

Merged
merged 5 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions chunkie/@chunkgraph/build_v2emat.m
Original file line number Diff line number Diff line change
@@ -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);

56 changes: 37 additions & 19 deletions chunkie/@chunkgraph/chunkgraph.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
%
properties(SetAccess=public)
verts
edge2verts
edgesendverts
echnks
regions
vstruc
v2emat
end

properties(SetAccess=public)
Expand All @@ -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
Expand Down Expand Up @@ -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)<i || isempty(fchnks{i}))
i1 = find(edge2verts(i,:)==-1);
i2 = find(edge2verts(i,:)==1);
i1 = edgesendverts(1,i);
i2 = edgesendverts(2,i);
v1 = verts(:,i1);
v2 = verts(:,i2);
fcurve = @(t) chnk.curves.linefunc(t,v1,v2);
Expand All @@ -98,8 +111,10 @@
[vs,~,~] =fchnks{i}([0,1]);
chnkr = chunkerfunc(fchnks{i},cploc,pref);
chnkr = sort(chnkr);
vfin0 = verts(:,find(edge2verts(i,:)==-1));
vfin1 = verts(:,find(edge2verts(i,:)== 1));
i1 = edgesendverts(1,i);
i2 = edgesendverts(2,i);
vfin0 = verts(:,i1);
vfin1 = verts(:,i2);
r0 = vs(:,1);
r1 = vfin0;
scale = norm(vfin1-vfin0,'fro')/norm(vs(:,2)-vs(:,1),'fro');
Expand All @@ -119,9 +134,8 @@
obj.wts = weights(obj);
%[regions] = findregions(obj);
%obj.regions = regions;

adjmat = edge2verts'*edge2verts;
g = graph(adjmat);

g = graph(edgesendverts(1,:),edgesendverts(2,:));
ccomp = conncomp(g);

chnkcomp = {};
Expand Down Expand Up @@ -208,10 +222,10 @@
validateattributes(val,classes,{})
obj.verts = val;
end
function obj = set.edge2verts(obj,val)
function obj = set.edgesendverts(obj,val)
classes = {'numeric'};
validateattributes(val,classes,{})
obj.edge2verts = val;
obj.edgesendverts = val;
end
function obj = set.echnks(obj,val)
classes = {'chunker'};
Expand Down Expand Up @@ -275,7 +289,11 @@
sourceinfo.d2= d2s;
sourceinfo.w = ws;
end
end

% defined in other files
spmat = build_v2emat(obj)
end

methods(Static)

end
Expand Down
29 changes: 19 additions & 10 deletions chunkie/@chunkgraph/findregions.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,17 @@
else
vstruc = procverts(obj);
end
nedge = size(obj.edge2verts,1);
e2v = obj.edge2verts;

% each edge belongs to two regions (going in opposite directions)
edges = [1:nedge,-(1:nedge)];
nedge = size(obj.edgesendverts,2);

% if the user has provided iverts, get the reduced edge list
if (nargin >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 = {};
Expand All @@ -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)
Expand All @@ -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
Expand Down
12 changes: 8 additions & 4 deletions chunkie/@chunkgraph/vertextract.m
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
99 changes: 3 additions & 96 deletions chunkie/chunkgraphinit.m
Original file line number Diff line number Diff line change
@@ -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)<i || isempty(fchnks{i}))
i1 = find(edge2verts(i,:)==-1);
i2 = find(edge2verts(i,:)==1);
v1 = verts(:,i1);
v2 = verts(:,i2);
fcurve = @(t) chnk.curves.linefunc(t,v1,v2);
chnkr = chunkerfunc(fcurve,cploc,pref);
chnkr = sort(chnkr);
%chnkr.vert = [v1,v2];
echnks(i) = chnkr;
elseif (~isempty(fchnks{i}) && isa(fchnks{i},'function_handle'))
[vs,~,~] =fchnks{i}([0,1]);
chnkr = chunkerfunc(fchnks{i},cploc,pref);
chnkr = sort(chnkr);
vfin0 = verts(:,find(edge2verts(i,:)==-1));
vfin1 = verts(:,find(edge2verts(i,:)== 1));
r0 = vs(:,1);
r1 = vfin0;
scale = norm(vfin1-vfin0,'fro')/norm(vs(:,2)-vs(:,1),'fro');
xdfin = vfin1(1)-vfin0(1);
ydfin = vfin1(2)-vfin0(2);
tfin = atan2(ydfin,xdfin);
xdini = vs(1,2)-vs(1,1);
ydini = vs(2,2)-vs(2,1);
tini = atan2(ydini,xdini);
trotat = tfin - tini;
chnkr = move(chnkr,r0,r1,trotat,scale);
echnks(i) = chnkr;
end
end
cgrph.echnks = echnks;
cgrph.vstruc = procverts(cgrph);

%[regions] = findregions(cgrph);
%cgrph.regions = regions;

adjmat = edge2verts'*edge2verts;
g = graph(adjmat);
ccomp = conncomp(g);

chnkcomp = {};
regions = {};

for i=1:max(ccomp)
inds = find(ccomp==i);
chnkcomp{i} = inds;
[region_comp] = findregions(cgrph,inds);
[region_comp] = findunbounded(cgrph,region_comp);
regions{i} = region_comp;
end

cgrph.regions = regions;
cgrph.wts = weights(cgrph);


cgrph = chunkgraph(verts,edge2verts,fchnks,cparams);

end
4 changes: 2 additions & 2 deletions chunkie/mergeregions.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
rgnout = {};

e2 = rgn2{1}{1}(1);
v2 = find(cgrph.edge2verts(:,abs(e2))==1);
v2 = cgrph.edgesendverts(2,abs(e2));
v2 = cgrph.verts(:,v2);

irgn = 0;
Expand All @@ -27,7 +27,7 @@

if (irgn == 0)
e1 = rgn1{1}{1}(1);
v1 = find(cgrph.edge2verts(:,abs(e1))==1);
v1 = cgrph.edgesendverts(2,abs(e1));
v1 = cgrph.verts(:,v1);

irgn = 0;
Expand Down
2 changes: 1 addition & 1 deletion chunkie/regioninside.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function [isinside] = regioninside(cgrph,rgn1,rgn2)

e2 = rgn2{1}{1}(1);
v2 = find(cgrph.edge2verts(:,abs(e2))==1);
v2 = cgrph.edgesendverts(2,abs(e2));
v2 = cgrph.verts(:,v2);
irgn = 0;
for ii=2:numel(rgn1)
Expand Down
Loading
Loading