Skip to content
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
69 changes: 69 additions & 0 deletions src/merge.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export merge_graphs;
export split_lincomb!;

# Change a symbol name using prefix & postfix
function translate_keyname(key, prefix, postfix, skip_basic, input)
Expand Down Expand Up @@ -115,3 +116,71 @@ function merge_graphs(

return Compgraph{T}(operations, parents, coeffs, outputs)
end


"""
(g,cref_modified,new_crefs)=split_lincomb!(g,node,ind2;
newnode=node_new,
cref_list=[])

Takes the lincomb operation in node and splits it into two lincombs, by
creating a new node newnode. The new node consists of the linear combination
of the coefficients moving (node, ind2[1]),... (node,ind2[end]) and the
old lincomb object has the old coefficients and an additional term pointing
to newnode. The cref_list is updated to the new coefficient pointers. The
new_crefs list contains all the new coefficient pointers.


In this way, the graph is unchanged but one of the linear combinations is
split up into two.

"""
function split_lincomb!(g,node,ind2;
newnode=Symbol("$(node)_new"),
cref_list=[])

@show newnode
# get ind1 = complement of ind2
nof_lincombs=size(g.coeffs[node],1);
@show nof_lincombs
ind1=map(i -> !(i in ind2), 1:nof_lincombs)

org_parents=g.parents[node];
org_coeffs=g.coeffs[node];

@show org_coeffs

# Move ind2 to a new lincomb
add_lincomb!(g,newnode,org_coeffs[ind2],org_parents[ind2])

@show newnode
# Store ind1 lincomb info
new_parents1=[org_parents[ind1];newnode]
new_coeffs1=[org_coeffs[ind1];1]

# Update the node lincomb data to point ind2 + newnode
empty!(g.coeffs[node]);
push!(g.coeffs[node], new_coeffs1...)
empty!(g.parents[node]);
push!(g.parents[node], new_parents1...)


# Update the cref_list

new_crefs=[];
replace_list=Dict();
for (j,i)=enumerate(ind2);
replace_list[(node,i)]=(newnode,j)
push!(new_crefs,(newnode,j));
end


for (cref_old,cref_new) in replace_list
@show cref_old
@show cref_new
ii=findall( [cref_old] .== cref_list )
map(j -> cref_list[j]=cref_new, ii);
end

return (g,cref_list,new_crefs)
end
45 changes: 45 additions & 0 deletions test/merge_graphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,48 @@ using LinearAlgebra
)
@test eval_graph(graph_4, A) ≈ eval_graph(graph, eval_graph(graph, A))
end
@testset "split_lincomb" begin

A=[
0.196064 -1.18798 0.0 0.0 0.0 0.0 0.0
0.342678 0.793844 0.684638 0.0 0.0 0.0 0.0
1.26005 0.819614 -1.21473 -0.16794 0.0 0.0 0.0
-0.10478 1.50713 0.138891 0.652377 -0.580547 0.0 0.0
-0.803933 -1.96458 0.679152 -0.0471995 -0.0454885 -0.715895 0.0
-0.327724 -1.89847 -0.435685 1.44764 -0.928145 3.06844 1.19071];
B=[1.46284 0.594921 0.0 0.0 0.0 0.0 0.0
0.71404 -0.492136 -0.481715 0.0 0.0 0.0 0.0
0.237897 -0.946491 0.0070323 1.87826 0.0 0.0 0.0
0.0444275 -1.77078 -0.772886 0.89719 1.55139 0.0 0.0
-0.310057 -1.13217 1.40868 0.864775 -1.14717 -0.662986 0.0
-0.160165 -0.525442 0.676407 -0.934459 0.259851 -0.608684 -0.381333];
c=[-0.5210883864869685
-0.5011935108466905
0.9989082416364822
1.1643621428307982
-1.4603489516355923
2.405378746857791
1.7841340060684932
0.233340850959019];

degopt=Degopt(A,B,c);
n=size(A,1);
(g,cref)=graph_degopt(degopt);
g_org=deepcopy(g);
node=cref[50][1];;
ind2=[3;6];
(g,crefs,new_crefs)=split_lincomb!(g,node,ind2;
newnode=Symbol("$(node)_new"),
cref_list=[])

# Check that it is unmodified
@test eval_graph(g,0.1) ≈ eval_graph(g_org,0.1)


# Check that changing a variable has the same effect
set_coeffs!(g_org,[3.3],[(node,ind2[1])])
set_coeffs!(g,[3.3],[new_crefs[1]])

@test eval_graph(g,0.3) ≈ eval_graph(g_org,0.3)

end
Loading