Advertisement
Guest User

AOC 2023, Day 24, Part 2

a guest
Dec 24th, 2023
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 1.93 KB | Source Code | 0 0
  1. %% Advent of Code 2023, Day 24, Part 2 - GLSDC (nonlinear iterated least squares)
  2. tic;
  3. Np = 3; % only need 3 points to find solution
  4. % Np = N; % but works just fine with all 300 pts too
  5. Nx = 6 + Np; % states are initial position, initial velocity, and Np collision times
  6. Ny = 3*Np; % measurements are initial hailstone positions
  7.  
  8. % normalize inputs to avoid inverting singular matrix (scale back at end)
  9. posscale = 10^-ceil(log10(max(abs(pos),[],'all')));
  10. velscale = 10^-ceil(log10(max(abs(vel),[],'all')));
  11. p = pos(1:Np,:)*posscale; % compute and cache scaled input positions
  12. v = vel(1:Np,:)*velscale; % compute and cache scaled input velocities
  13.  
  14. % preallocate arrays and initialize state estimate
  15. H = zeros(Ny,Nx); % Jacobian / linear observation matrix
  16. y = zeros(Ny,1); % actual measurements
  17. yhat = zeros(Ny,1); % predicted/estimated measurements
  18. xhat = 0.1*(1:Nx)'; % ensure initial observation matrix is full rank
  19. % xhat = randn(Nx,1);
  20.  
  21. Ni = 50; % should generally need less than 20
  22. numiters = 0;
  23. dx = Inf;
  24. while norm(dx) > 1e-9 && numiters < Ni
  25.     pidx = 1:3;
  26.     vidx = 4:6;
  27.     xs = xhat(pidx);
  28.     vs = xhat(vidx);
  29.     for i=1:Np
  30.         tidx = 6+i;
  31.         yidx = (3*(i-1))+(1:3);
  32.         ti = xhat(tidx);
  33.         xi = p(i,:)';
  34.         vi = v(i,:)';
  35.         y(yidx) = xi;
  36.         yhat(yidx) = xs + vs*ti -vi*ti;
  37.         H(yidx,pidx) = eye(3);
  38.         H(yidx,vidx) = ti*eye(3);
  39.         H(yidx,tidx) = vs - vi;
  40.     end
  41.     dy = y - yhat; % innovation
  42.     dx = (H'*H)\H'*dy; % compute correction
  43.     xhat = xhat + dx; % apply correction
  44.     numiters = numiters + 1;
  45. end
  46. if numiters < Ni
  47.     % scale back converged state and compute final answer
  48.     phat = round(xhat(1:3)/posscale);
  49.     % vhat = round(xhat(4:6)/velscale);
  50.     % that = round(xhat(7:end)*velscale/posscale);
  51.     part2 = int64(sum(phat))
  52. else
  53.     error('Could not converge on solution')
  54. end
  55. toc % approx 5 ms for 3 pts, 150 ms using all 300 pts
  56.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement