spb/metrika Public
Stata-class statistics, GPU-accelerated by Apple Silicon. Native Swift — no Electron, no Python runtime, no compromises.
Swift 92.4%
HTML 3.3%
R 3%
Shell 1.3%
1//2// MarginsTests.swift3// Metrika4//5// Author: Simon-Pierre Boucher6// Contact: contact@spboucher.ai7// Copyright © 2026 Simon-Pierre Boucher. All rights reserved.8//910import Foundation11import Testing12import ZQEngine1314@Suite("margins", .serialized)15struct MarginsTests {16 let fixtures: Fixtures17 let session: ZQSession1819 init() async throws {20 self.fixtures = try Fixtures()21 self.session = try ZQSession(discoverUserCommands: false)22 _ = try await session.execute("use \(fixtures.datasetURL.path)")23 _ = try await session.execute("gen log_rev = ln(revenue)")24 }2526 @Test("OLS marginal effect is the coefficient with its SE")27 func olsMargins() async throws {28 let fit = try await session.execute("reg log_rev price")29 let margins = try await session.execute("margins, dydx(price)")30 #expect(margins.scalars["dydx_price"] == fit.scalars["b_price"])31 #expect(margins.scalars["se_price"] == fit.scalars["se_price"])32 }3334 @Test("logit AME and delta-method SE match R")35 func logitMargins() async throws {36 _ = try await session.execute("logit purchase price")37 let margins = try await session.execute("margins, dydx(price)")38 expectClose(39 try #require(margins.scalars["dydx_price"]),40 fixtures["margins_logit_price"], "logit AME"41 )42 expectClose(43 try #require(margins.scalars["se_price"]),44 fixtures["margins_logit_se"], "logit delta SE"45 )46 }4748 @Test("poisson AME and delta-method SE match R")49 func poissonMargins() async throws {50 _ = try await session.execute("poisson orders price")51 let margins = try await session.execute("margins, dydx(price)")52 expectClose(53 try #require(margins.scalars["dydx_price"]),54 fixtures["margins_pois_price"], "poisson AME"55 )56 expectClose(57 try #require(margins.scalars["se_price"]),58 fixtures["margins_pois_se"], "poisson delta SE"59 )60 }6162 @Test("dydx over factor terms is rejected for now")63 func factorRejected() async throws {64 _ = try await session.execute("reg log_rev price i.region")65 await #expect(throws: ZQEngineError.self) {66 _ = try await session.execute("margins, dydx(region)")67 }68 // Continuous term of the same model still works.69 let margins = try await session.execute("margins, dydx(price)")70 #expect(margins.scalars["dydx_price"] != nil)71 }7273 @Test("margins requires estimation results and a dydx() option")74 func validation() async throws {75 let fresh = try ZQSession(discoverUserCommands: false)76 _ = try await fresh.execute("use \(fixtures.datasetURL.path)")77 await #expect(throws: ZQEngineError.self) {78 _ = try await fresh.execute("margins, dydx(price)")79 }80 _ = try await session.execute("reg log_rev price")81 await #expect(throws: ZQEngineError.self) {82 _ = try await session.execute("margins")83 }84 await #expect(throws: ZQEngineError.self) {85 _ = try await session.execute("margins, dydx(nonexistent)")86 }87 }88}89