-
-
Notifications
You must be signed in to change notification settings - Fork 467
/
spectralnorm.zep
71 lines (60 loc) · 1.27 KB
/
spectralnorm.zep
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
namespace Stub;
/**
* SpectralNorm
*
* @see https://mathworld.wolfram.com/SpectralNorm.html
*/
class SpectralNorm
{
private inline function Ax(i, j)
{
return 1/(((i + j) * (i + j + 1) / 2) + i + 1);
}
private function Au(int n, <\SplFixedArray> u, <\SplFixedArray> v)
{
int t, i, j;
for i in range(0, n - 1) {
let t = 0;
for j in range(0, n - 1) {
let t += this->Ax(i, j) * u->offsetGet(j);
}
v->offsetSet(i, t);
}
}
private function Atu(int n, <\SplFixedArray> u, <\SplFixedArray> v)
{
int t, i, j;
for i in range(0, n - 1) {
let t = 0;
for j in range(0, n - 1) {
let t += this->Ax(j, i) * u->offsetGet(j);
}
v->offsetSet(i, t);
}
}
private function AtAu(n, u, v, w)
{
this->Au(n, u, w);
this->Atu(n, w, v);
}
public function process(int n)
{
int i, vv = 0, vBv = 0;
var u, v, w;
let u = new \SplFixedArray(n), v = new \SplFixedArray(n), w = new \SplFixedArray(n);
for i in range(0, n - 1) {
u->offsetSet(i, 1);
v->offsetSet(i, 1);
w->offsetSet(i, 1);
}
for i in range(0, 9) {
this->AtAu(n, u, v, w);
this->AtAu(n, v, u, w);
}
for i in range(0, n - 1) {
let vBv += u->offsetGet(i) * v->offsetGet(i);
let vv += v->offsetGet(i) * v->offsetGet(i);
}
return sqrt(vBv / vv);
}
}