SPB Git

spb/forge-studio Public

The Instruments of LLM training — a native macOS cockpit for Forge. Train language models from scratch on Apple Silicon without a terminal.

Swift 95.7% Shell 4.3%
2.1 KB · 60 lines swift
Raw Blame History
1// Author: Simon-Pierre Boucher — contact@spboucher.ai2//3// LTTB (largest-triangle-three-buckets) downsampling: preserves the visual4// shape of a series — endpoints kept exactly, one representative point per5// bucket chosen to maximize the triangle area with its neighbors. Used to6// keep chart data at ~2× pixel width regardless of run length.7import Foundation89enum Downsampler {10    struct XY: Equatable, Sendable {11        var x: Double12        var y: Double13    }1415    static func lttb(_ points: [XY], threshold: Int) -> [XY] {16        let n = points.count17        guard threshold >= 3, n > threshold else { return points }1819        var sampled: [XY] = []20        sampled.reserveCapacity(threshold)21        sampled.append(points[0])2223        let bucketSize = Double(n - 2) / Double(threshold - 2)24        var a = 0 // index of the previously selected point2526        for i in 0..<(threshold - 2) {27            // Average of the NEXT bucket is the third triangle vertex.28            let nextStart = Int(Double(i + 1) * bucketSize) + 129            let nextEnd = min(Int(Double(i + 2) * bucketSize) + 1, n)30            var avgX = 0.0, avgY = 0.031            let span = max(nextEnd - nextStart, 1)32            for j in nextStart..<max(nextEnd, nextStart + 1) where j < n {33                avgX += points[j].x34                avgY += points[j].y35            }36            avgX /= Double(span)37            avgY /= Double(span)3839            let start = Int(Double(i) * bucketSize) + 140            let end = min(Int(Double(i + 1) * bucketSize) + 1, n - 1)4142            var maxArea = -1.043            var chosen = start44            let pa = points[a]45            for j in start..<max(end, start + 1) {46                let area = abs((pa.x - avgX) * (points[j].y - pa.y)47                    - (pa.x - points[j].x) * (avgY - pa.y))48                if area > maxArea {49                    maxArea = area50                    chosen = j51                }52            }53            sampled.append(points[chosen])54            a = chosen55        }56        sampled.append(points[n - 1])57        return sampled58    }59}60