-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathCheapLinAlg.py
123 lines (91 loc) · 3.41 KB
/
CheapLinAlg.py
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
import torch
gpu = False
class CheapVector:
def __init__(self):
self.index = {}
self.zero_val = 0
# returns value of e^th coordinate of self
def get_entry(self, e):
if e in self.index.keys():
return self.index[e]
return self.zero_val
# updates value of e^th coordinate of self
def update_entry(self, e, val):
if val == self.zero_val:
if e in self.index.keys():
self.index.pop(e)
else:
self.index.update({e: val})
# returns json-serializable representation of self
def to_json(self):
out = {
'zero_val': self.zero_val,
'index': self.index
}
return out
# re-creates row vector from dictionary loaded from json file
def from_json(self, f):
self.zero_val = f['zero_val']
for k in f['index'].keys():
self.index.update({int(k): f['index'][k]})
class CheapSquareMatrix:
def __init__(self, elems=None):
self.elems = elems
self.row_index = {}
self.zero_val = 0
# change value of <x, y>^th entry of self (x = row, y = column)
def update_entry(self, x, y, val):
if x in self.row_index.keys():
self.row_index[x].update_entry(y, val)
elif not val == self.zero_val:
new_vec = CheapVector()
new_vec.zero_val = self.zero_val
new_vec.update_entry(y, val)
self.row_index.update({x: new_vec})
# outputs value of <x, y>^th entry of self
def get_entry(self, x, y):
if x in self.row_index.keys():
return self.row_index[x].get_entry(y)
return self.zero_val
# outputs result of multiplying vector v with self:
# right=True ==> (self)*(v), right=False ==> (v)*(self)
def as_linear_map(self, v, right=True):
get_vec = self.get_row_vec if right else self.get_col_vec
vec = torch.tensor([torch.vdot(v, get_vec(self.elems[i])).item() for i in range(len(self.elems))], dtype=torch.float32)
if gpu:
vec.cuda()
return vec
# returns e^th row vector
def get_row_vec(self, e):
vec = torch.tensor([self.get_entry(e, self.elems[i]) for i in range(len(self.elems))], dtype=torch.float32)
if gpu:
vec.cuda()
return vec
# returns e^th column vector
def get_col_vec(self, e):
vec = torch.tensor([self.get_entry(self.elems[i], e) for i in range(len(self.elems))], dtype=torch.float32)
if gpu:
vec.cuda()
return vec
# returns json-serializable representation of self
def to_json(self):
out = {
'zero_val': self.zero_val,
'elems': self.elems,
'index': [(x, self.row_index[x].to_json()) for x in self.row_index.keys()]
}
return out
# re-creates matrix from dictionary loaded from json file
def from_json(self, f):
self.zero_val = f['zero_val']
self.elems = f['elems']
for x in f['index']:
new_vec = CheapVector()
new_vec.from_json(x[1])
self.row_index.update({int(x[0]): new_vec})
# re-creates state vector from json file
def vec_from_json(vlist):
vec = torch.tensor(vlist, dtype=torch.float32)
if gpu:
vec.cuda()
return vec