-
Notifications
You must be signed in to change notification settings - Fork 274
Description
I was taking a peek at compute_angular_endpoints_1plane, it seems like the current algorithm:
- For a valid weight range/grid size
$Q$ (e.g. a step size 1/8 would yield a grid size/# steps of 9) - Calculate the optimal phase / shift for this particular grid using the
compute_angular_offsetsalgorithm (essentially the phase of the DFT of the weights at the frequency Q hz) - Perform a shifted transform of the weights
$\hat w = w + \mathsf{offset}$ - Solve for
$P_0', P_1'$ with the new shifted weights
I believe you can do a little bit better by incorporating more degrees of freedom in your search space. In particular, by taking into account the observation that the weights are invariant not just under shifting, but also scaling.
E.g. for any affine function
s.t.
The intuition here is that it's the fundamental ratio of the weights (e.g. the ratio between
For example, to quantize the weights {0.3, 0.4, 0.6, 0.7} on the the 0, 1/8, ..., 8/8:
- It can undergo the scale+shift of
$f(w) = \frac{w - 0.1}{0.8}$ to yield{0.3 -> 0.25, 0.4 -> 0.375, 0.6 -> 0.625, 0.7 -> 0.75}which can be fitted perfectly on the grid. - On the other hand, if we're limited to just shifts, then the best offset is
$-\frac{1}{16}$ , which yields{0.3 -> 0.3625, 0.4 -> 0.4625, 0.6 -> 0.6625, 0.7 -> 0.7625}which has a 50% lower error than just quantizing{0.3, 0.4, 0.6, 0.7}, but not a perfect fit.
The question is how to calculate the scale factor.
The shift/offset compute_angular_offsets algorithm (the
The scaling factor itself is a function of the fundamental frequency of the weights, which you can calculate from the autocorrelation of the DFT of the weights. For example, the fundamental frequency of {0.3, 0.4, 0.6, 0.7} is any multiple of 10, since the step size of
Since our DFT is defined as
the fundamental frequency
Now, if we transform
This then gives us a way to calculate the best scale+shift transform to minimize the quantization error:
- Fix a quantization grid
$Q$ - Perform autocorrelation on the weights to find its fundamental frequencies/periods
$k_{peak} / \lambda_{peak}$ , and sort them in descending order - For each
$k_{peak}$ : - Calculate the scale factor
$a = \frac{k_{peak}}{Q-1}$ - Calculate the shift/offset of the scaled weights
$b = \mathsf{atan2}(\cdots)$ using thecompute_angular_offsetson the scaled weights - Calculate the new
$\hat w_i = a w_i + b$ ,$P_0' = \mathsf{lerp}(P_0, P_1, -\frac{b}{a})$ , and$P_1' = \mathsf{lerp}(P_0, P_1, \frac{1-b}{a})$ - Do a bounds check on
$0 \le \hat w_i, P_0', P_1' \le 1$ , if out of bound, go to the next best fundamental frequency$f_{peak}'$ , if exhausted all of them, use the scale factor$a = 1$ - [Optional] Solve for
$P_0', P_1'$ linear algebraically minimizing against the ground truth (instead of the stationary condition $\mathsf{lerp}(P_0, P_1, w_i) = \mathsf{lerp}(P_0', P_1', a w_i + b)$)
This works best when the true fundamental frequency of the weights are close to / smaller than the current quantization frequency being checked against, otherwise the bounds check will likely cause a rejection.
The autocorrelation could be done directly, or cheaply using a sweep (on a small integer frequency grid) + a few newton's iterations to get the top K peak frequencies.