-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathquant.py
More file actions
49 lines (39 loc) · 1.49 KB
/
quant.py
File metadata and controls
49 lines (39 loc) · 1.49 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
import numpy as np
def fwht(a):
"""정규화된 Walsh-Hadamard Transform (self-inverse)"""
n = len(a)
assert (n & (n - 1)) == 0, "Length must be power of 2"
a = a.copy().astype(np.float64)
d = 1
while d < n:
a = a.reshape(-1, 2 * d)
x, y = a[:, :d].copy(), a[:, d:].copy()
a[:, :d] = x + y
a[:, d:] = x - y
d *= 2
return a.reshape(-1) / np.sqrt(n)
# comparison.py에서 import하는 이름
fwht_vectorized = fwht
def quantize_to_bits(x, bits):
levels = 2 ** bits
scale = np.max(np.abs(x)) + 1e-9
x_int = np.round(x / scale * (levels / 2)).clip(-levels / 2, levels / 2 - 1)
x_deq = x_int / (levels / 2) * scale
return x_deq, scale
def fake_quantize(x, bits, noise_level=0.0):
n = len(x)
next_pow2 = 1 << (n - 1).bit_length()
x_padded = np.pad(x, (0, next_pow2 - n))
mean_val = np.mean(x_padded)
x_centered = x_padded - mean_val
x_rotated = fwht(x_centered)
x_quantized, scale = quantize_to_bits(x_rotated, bits)
noise = np.random.normal(0, noise_level * scale, size=x_quantized.shape)
x_noisy = x_quantized + noise
meta = {'scale': scale, 'mean': mean_val, 'n_orig': n, 'n_pad': next_pow2}
return x_noisy, meta
def fake_dequantize(compressed, meta):
# fwht는 self-inverse이므로 한 번 더 적용하면 원본 복원
restored_centered = fwht(compressed)
restored_padded = restored_centered + meta['mean']
return restored_padded[:meta['n_orig']]