-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSQL_fct_epsilonBound.sql
More file actions
executable file
·149 lines (125 loc) · 3.6 KB
/
SQL_fct_epsilonBound.sql
File metadata and controls
executable file
·149 lines (125 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
-- =================================================================================
-- Copyright 2014 Wolfgang Gatterbauer, Stephan Guennemann, Danai Koutra, Christos Faloutsos
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- =================================================================================
-- =================================================================================
-- Provides function fct_epsilonBound(A_tableName,H_tableName);
-- Calculates the max eps_H according to our guarantees for convergence of LinBP
-- Wolfgang Gatterbauer
-- First version: 6/4/2014
-- This version: 6/24/2014
--
-- Execute with: select * from fct_epsilonBound('a_kron1_7','h_kron');
-- Execute with: select max_esp1 from fct_epsilonBound('a_kron1_7','h_kron');
--
-- Creates intermediate table D_temp
--
-- Returns array (see below)
-- =================================================================================
-- drop function fct_epsilonBound(varchar, varchar)
CREATE OR REPLACE FUNCTION fct_epsilonBound(
A_tableName varchar,
H_tableName varchar)
RETURNS TABLE (
A_normV double precision, -- vector p=2 (Frobenius) norm
A_normI double precision, -- induced p=1 & inf norm
H_normV double precision,
H_normI double precision,
max_eps1 double precision, -- LinBP* without second order term
max_eps2 double precision) as -- LinBP with second order term
$BODY$
DECLARE
A_normV double precision;
A_normI double precision;
A_normMin double precision;
H_normV double precision;
H_normI double precision;
H_normMin double precision;
D_norm double precision;
max_eps1 double precision;
max_eps2 double precision;
BEGIN
-- Calculate exact D_norm from bi-directional degree matrix D (allowing direction and weight)
drop table if exists D_temp cascade;
EXECUTE 'create table D_temp as
select A1.s as v,
sum(A1.w*A2.w) as degree
from ' || A_tableName || ' A1, ' || A_tableName || ' A2
where A1.t = A2.s
and A1.s = A2.t
group by A1.s';
select max (degree)
into D_norm
from D_temp;
-- Vector p=2 (Frobenius) norms for A and H
execute'
select sqrt(sum(w^2))
from ' || A_tableName ||' '
into A_normV;
execute'
select sqrt(sum(h^2))
from ' || H_tableName ||' '
into H_normV;
-- Smaller of induced p=1 and p=infty norms for A and H
execute'
select min(n)
from (
select max(w) n
from(
select sum(w) w
from ' || A_tableName ||'
group by s
) as X
union all
select max(w) n
from(
select sum(w) w
from ' || A_tableName ||'
group by t
) as Y
) as Z'
into A_normI;
execute'
select min(n)
from (
select max(h) n
from(
select sum(@h) h
from ' || H_tableName ||'
group by c1
) as X
union all
select max(h) n
from(
select sum(@h) h
from ' || H_tableName ||'
group by c2
) as Y
) as Z'
into H_normI;
-- Choose smaller norms (Vector or induced) and calculate max_esp
A_normMin = least(A_normV, A_normI);
H_normMin = least(H_normV, H_normI);
max_eps1 = 1/H_normMin/A_normMin;
max_eps2 = (sqrt(A_normMin^2 + 4*D_norm)-A_normMin)/2/D_norm/H_normMin;
return query select
A_normV,
A_normI,
H_normV,
H_normI,
max_eps1,
max_eps2;
END;
$BODY$
LANGUAGE plpgsql;