code wiki / (root) / nx_fieldfit_verified_r2_t333.nx

nx_fieldfit_verified_r2_t333.nx source

↩ module page · 500 lines · 20995 B

1// nx_fieldfit_lib.nx -- FIT A PARAMETRIC IMPLICIT FIELD TO A SCANNED ORACLE. The machinery nx_skullsdf's `tune` grew 2// (anatomy AN17, 2026-09-18/19), extracted so any anatomy field -- a skull, an arm, a foot, a muscle belly, a tissue 3// layer -- is fitted by ONE optimiser with ONE objective and ONE fit-file contract, and a defect fixed here is fixed for 4// every field at once. The consumer hands over three functions as VALUES (NishiLang func-pointer locals and fields, 5// indirect calls up to six arguments): 6// field(px, py, pz, a, b, P) -> signed distance at `fq` units per millimetre (negative inside) for parameter vector P, 7// with a and b the consumer's two policy knobs (the skull passes sex and robusticity) 8// region(x, y, z) -> 0 .. nreg-1, the named anatomical region a point belongs to 9// live(k) -> 1 for a station the field reads, 0 for a retired one (the descent skips it: two 10// evaluations spent on a dead station are a pass that cannot move anything) 11// 12// THE OBJECTIVE IS TWO-SIDED, AND IT HAS TO BE. A one-directional score -- how far is each ORACLE point from my surface -- 13// is trivially gamed by DELETING GEOMETRY: the skull's first tuning run shrank its orbits from 22 mm to 8 and its 14// maxilla from 30 mm to 13, improving the number 40 percent by filling in the eye sockets, because surface that does not 15// exist cannot be wrong. The REVERSE term charges every lattice point on OUR zero level its distance to the nearest 16// oracle sample, so a deleted feature is EXPENSIVE by construction. (The reverse term uses the nearest oracle VERTEX from 17// a spatial hash: an upper bound on the true point-to-surface distance -- it can overstate, never understate, the safe 18// direction for a penalty.) 19// THE OBJECTIVE IS REGION-BALANCED. A plain mean is dominated by whatever region has the most samples (the skull's vault 20// and base held 9,335 + 8,672 of ~31,000, so a 49 mm muzzle and 4 mm drilled orbits read as a 4 mm skull and the 21// surface objective fell 629 -> 531 while the chin moved +4 -> +19.6 mm). Each side is the mean of the PER-REGION means 22// (a region with no samples abstains), so the smallest region weighs what the largest does. No weight is typed: the 23// population decides. 24// THE DESCENT is coordinate descent: per live station try +step then -step, keep a move only if the MEASURED objective 25// falls; the step halves per pass, floor 1. No change is ever kept on the strength of looking better. 26// THE FIT FILE is newline-separated integers, loaded as a PREFIX: a file shorter than the vector applies to its first 27// entries and the rest keep their defaults, so growing a parametrisation never discards banked convergence; a file 28// shorter than `minlen` changes nothing (parsed into a temp and applied only when long enough, so a truncated write 29// cannot half-poison a field). Written whole by ff_save. 30// UNITS: objectives are reported in centi-millimetres; `lat` (the reverse lattice spacing), `ext` (the half-extent the 31// hash covers) and `dim` (cells per axis) are the consumer's, taken from the resource it fits. 32// LIB, no main. license_tier: ORIGINAL. No hw writes (Rule 26). 33import "nx_syscalls.nx" 34 35const FF_I64: i64 = 8 36const FF_CENTI: i64 = 100 // objectives are centi-millimetres 37const FF_CTX_BYTES: i64 = 256 // FfCtx: 21 fields of 8 bytes, one page-rounded map 38const FF_LOAD_HDR: i64 = 16 // the two-word length record sys_read_file fills 39const FF_SAVE_DIGITS: i64 = 16 // bytes reserved per integer on save (sign + 19 digits fits a page-rounded map) 40const FF_SAVE_SLACK: i64 = 64 41const FF_MODE644: i64 = 420 42 43// THE THIRD TERM, OPTIONAL: `extra(P)` returns a further mean error in centi-millimetres the consumer derives from its 44// own stations against the ruler's ORACLE readings (a landmark term: where the field PLACES its features against 45// where the ruler FOUND them on the oracle). MEASURED NEED (skull, 2026-09-19): with the two surface terms alone the 46// descent closed the orbit sockets to 2 mm slits and deepened the aperture to a 35 mm tunnel, because a surface 47// objective cannot see an opening; the ruler read 4 of 15 quantities in band. With has_extra = 1 the objective is the 48// three-way mean of the three error means (all centi-mm, no weight typed); the consumer's REAL ruler still judges the 49// emitted mesh outside the loop, so the term is a surrogate with a stated error, never the verdict. 50struct FfCtx { field: func(i64,i64,i64,i64,i64,*i64) -> i64, region: func(i64,i64,i64) -> i64, live: func(i64) -> i64, RX: *i64, RY: *i64, RZ: *i64, RG: *i64, n: i64, head: *i64, next: *i64, ext: i64, dim: i64, lat: i64, a: i64, b: i64, fq: i64, nreg: i64, sum: *i64, cnt: *i64, np: i64, cap: i64, extra: func(*i64) -> i64, has_extra: i64 } 51 52// a context sized for `cap` oracle samples, `np` stations, `nreg` regions, a dim^3 hash over +/- ext mm, lattice lat mm 53func ff_ctx_new(np: i64, nreg: i64, cap: i64, ext: i64, dim: i64, lat: i64, fq: i64) -> *FfCtx { 54 let c: *FfCtx = (sys_mmap(FF_CTX_BYTES)) as *FfCtx 55 c.np = np; c.nreg = nreg; c.cap = cap; c.ext = ext; c.dim = dim; c.lat = lat; c.fq = fq 56 c.RX = sys_mmap(cap*FF_I64) as *i64 57 c.RY = sys_mmap(cap*FF_I64) as *i64 58 c.RZ = sys_mmap(cap*FF_I64) as *i64 59 c.RG = sys_mmap(cap*FF_I64) as *i64 60 c.next = sys_mmap(cap*FF_I64) as *i64 61 c.head = sys_mmap(dim*dim*dim*FF_I64) as *i64 62 c.sum = sys_mmap(nreg*FF_I64) as *i64 63 c.cnt = sys_mmap(nreg*FF_I64) as *i64 64 c.n = 0; c.a = 0; c.b = 0; c.has_extra = 0 65 return c 66} 67 68// ==== the spatial hash over the oracle samples ==== 69func ff_cell(c: *FfCtx, x: i64, y: i64, z: i64) -> i64 { 70 let d: i64 = c.dim 71 let e: i64 = c.ext 72 var i: i64 = (x + e) * d / (e*2) 73 var j: i64 = (y + e) * d / (e*2) 74 var k: i64 = (z + e) * d / (e*2) 75 if i < 0 { i = 0 } 76 if j < 0 { j = 0 } 77 if k < 0 { k = 0 } 78 if i >= d { i = d-1 } 79 if j >= d { j = d-1 } 80 if k >= d { k = d-1 } 81 return (i*d + j)*d + k 82} 83// bucket the oracle samples so the reverse term does not scan all of them per query 84func ff_bin(c: *FfCtx) -> i64 { 85 let d: i64 = c.dim 86 let head: *i64 = c.head 87 let next: *i64 = c.next 88 var q: i64 = 0 89 while q < d*d*d { head[q] = 0-1; q = q + 1 } 90 var i: i64 = 0 91 while i < c.n { 92 let h: i64 = ff_cell(c, c.RX[i], c.RY[i], c.RZ[i]) 93 next[i] = head[h] 94 head[h] = i 95 i = i + 1 96 } 97 return 0 98} 99// nearest oracle sample to (x,y,z) in whole millimetres, searching the home cell then one ring out; ext when none 100func ff_near(c: *FfCtx, x: i64, y: i64, z: i64) -> i64 { 101 let d: i64 = c.dim 102 let e: i64 = c.ext 103 let RX: *i64 = c.RX 104 let RY: *i64 = c.RY 105 let RZ: *i64 = c.RZ 106 let head: *i64 = c.head 107 let next: *i64 = c.next 108 var ci: i64 = (x + e) * d / (e*2) 109 var cj: i64 = (y + e) * d / (e*2) 110 var ck: i64 = (z + e) * d / (e*2) 111 var best: i64 = 0-1 112 var r: i64 = 0 113 while r <= 1 { 114 var di: i64 = 0 - r 115 while di <= r { 116 var dj: i64 = 0 - r 117 while dj <= r { 118 var dk: i64 = 0 - r 119 while dk <= r { 120 let ii: i64 = ci+di 121 let jj: i64 = cj+dj 122 let kk: i64 = ck+dk 123 if ii >= 0 { if ii < d { if jj >= 0 { if jj < d { if kk >= 0 { if kk < d { 124 var p: i64 = head[(ii*d + jj)*d + kk] 125 while p >= 0 { 126 let ddx: i64 = x-RX[p] 127 let ddy: i64 = y-RY[p] 128 let ddz: i64 = z-RZ[p] 129 let d2: i64 = ddx*ddx + ddy*ddy + ddz*ddz 130 if best < 0 { best = d2 } else { if d2 < best { best = d2 } } 131 p = next[p] 132 } 133 } } } } } } 134 dk = dk + 1 135 } 136 dj = dj + 1 137 } 138 di = di + 1 139 } 140 if best >= 0 { r = 2 } else { r = r + 1 } 141 } 142 if best < 0 { return e } 143 return ff_isqrt(best) 144} 145func ff_isqrt(v: i64) -> i64 { if v<=0 { return 0 } var x: i64=v; var y: i64=(x+1)/2; while y<x { x=y; y=(x+v/x)/2 } return x } 146 147// each oracle sample's region, classified ONCE per fit (the consumer's boxes may follow its loaded vector; they hold 148// for the run) 149func ff_regions(c: *FfCtx) -> i64 { 150 var i: i64 = 0 151 while i < c.n { c.RG[i] = c.region(c.RX[i], c.RY[i], c.RZ[i]); i = i + 1 } 152 return 0 153} 154 155// ==== the region tables: the mean of the per-region means ==== 156func ff_rtab_reset(c: *FfCtx) -> i64 { 157 var r: i64 = 0 158 while r < c.nreg { c.sum[r] = 0; c.cnt[r] = 0; r = r + 1 } 159 return 0 160} 161// centi-mm from sums carried at `fq` units per mm; no region at all is the worst answer (ext mm) 162func ff_rtab_mean(c: *FfCtx, fq: i64) -> i64 { 163 var acc: i64 = 0 164 var nr: i64 = 0 165 var r: i64 = 0 166 while r < c.nreg { 167 if c.cnt[r] > 0 { acc = acc + c.sum[r]*FF_CENTI/(c.cnt[r]*fq); nr = nr + 1 } 168 r = r + 1 169 } 170 if nr == 0 { return c.ext*FF_CENTI } 171 return acc/nr 172} 173// forward: each oracle sample's |field|, balanced over regions 174func ff_score_fwd(c: *FfCtx, P: *i64) -> i64 { 175 ff_rtab_reset(c) 176 var i: i64 = 0 177 while i < c.n { 178 var d: i64 = c.field(c.RX[i], c.RY[i], c.RZ[i], c.a, c.b, P) 179 if d < 0 { d = 0 - d } 180 let r: i64 = c.RG[i] 181 c.sum[r] = c.sum[r] + d 182 c.cnt[r] = c.cnt[r] + 1 183 i = i + 1 184 } 185 if c.n == 0 { return 0 } 186 return ff_rtab_mean(c, c.fq) 187} 188// reverse: every lattice point within half a step of our zero level, charged its distance to the nearest oracle sample 189func ff_score_rev(c: *FfCtx, P: *i64) -> i64 { 190 ff_rtab_reset(c) 191 let e: i64 = c.ext 192 let step: i64 = c.lat 193 let bq: i64 = step*c.fq 194 var cnt: i64 = 0 195 var x: i64 = 0 - e 196 while x <= e { 197 var y: i64 = 0 - e 198 while y <= e { 199 var z: i64 = 0 - e 200 while z <= e { 201 let d: i64 = c.field(x, y, z, c.a, c.b, P) 202 if d > 0 - bq { if d < bq { 203 let r: i64 = c.region(x, y, z) 204 c.sum[r] = c.sum[r] + ff_near(c, x, y, z) 205 c.cnt[r] = c.cnt[r] + 1 206 cnt = cnt + 1 207 } } 208 z = z + step 209 } 210 y = y + step 211 } 212 x = x + step 213 } 214 if cnt == 0 { return e*FF_CENTI } 215 return ff_rtab_mean(c, 1) 216} 217// the objective: the mean of both directions, so neither can be gamed alone; with a consumer's extra term, the mean 218// of the three (every term a mean error in centi-mm, so no weight is typed) 219func ff_score2(c: *FfCtx, P: *i64) -> i64 { 220 let f: i64 = ff_score_fwd(c, P) 221 let r: i64 = ff_score_rev(c, P) 222 if c.has_extra == 1 { 223 let e: i64 = c.extra(P) 224 return (f + r + e)/3 225 } 226 return (f + r)/2 227} 228func ff_live_count(c: *FfCtx) -> i64 { 229 var lv: i64 = 0 230 var k: i64 = 0 231 while k < c.np { lv = lv + c.live(k); k = k + 1 } 232 return lv 233} 234func ff_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 235func ff_pn(v: i64) -> i64 { 236 let b: *u8 = sys_mmap(32) 237 let o: i64 = ff_wint(b, 0, v) 238 sys_write(1, b, o) 239 return 0 240} 241// COORDINATE DESCENT from P: returns the best objective; P holds the accepted vector. Convergence is PRINTED per pass 242// when verbose ({"pass":k,"step":s,"best_centi":b}), never assumed 243func ff_descend(c: *FfCtx, P: *i64, passes: i64, step0: i64, verbose: i64) -> i64 { 244 var best: i64 = ff_score2(c, P) 245 var step: i64 = step0 246 if step < 1 { step = 8 } 247 var pass: i64 = 0 248 while pass < passes { 249 var k: i64 = 0 250 while k < c.np { 251 if c.live(k) == 1 { 252 let orig: i64 = P[k] 253 P[k] = orig + step 254 let up: i64 = ff_score2(c, P) 255 P[k] = orig - step 256 let dn: i64 = ff_score2(c, P) 257 P[k] = orig 258 if up < best { if up <= dn { best = up; P[k] = orig + step } } 259 if dn < best { if dn < up { best = dn; P[k] = orig - step } } 260 } 261 k = k + 1 262 } 263 if verbose == 1 { 264 ff_puts("{\x22pass\x22:" as *u8); ff_pn(pass) 265 ff_puts(",\x22step\x22:" as *u8); ff_pn(step) 266 ff_puts(",\x22best_centi\x22:" as *u8); ff_pn(best) 267 ff_puts("}\n" as *u8) 268 } 269 step = step/2 270 if step < 1 { step = 1 } 271 pass = pass + 1 272 } 273 return best 274} 275 276// ==== the fit file ==== 277// integer -> ascii into a buffer at offset o; returns the new offset (iterative, no allocation) 278func ff_wint(b: *u8, o: i64, v: i64) -> i64 { 279 var x: i64 = v 280 var oo: i64 = o 281 if x < 0 { b[oo] = 45 as u8; oo = oo + 1; x = 0 - x } 282 var tmp: i64 = x 283 var nd: i64 = 1 284 while tmp >= 10 { tmp = tmp/10; nd = nd + 1 } 285 var k: i64 = nd 286 while k > 0 { 287 var div: i64 = 1 288 var q: i64 = 1 289 while q < k { div = div*10; q = q + 1 } 290 b[oo] = (48 + (x/div) % 10) as u8 291 oo = oo + 1 292 k = k - 1 293 } 294 return oo 295} 296// load a PREFIX of P from a newline-separated integer file: returns the count applied (0 when absent or shorter than minlen) 297func ff_load_prefix(path: *u8, P: *i64, np: i64, minlen: i64) -> i64 { 298 let ln: *i64 = sys_mmap(FF_LOAD_HDR) as *i64 299 let buf: *u8 = sys_read_file(path, ln) 300 if (buf as i64) == 0 { return 0 } 301 let n: i64 = ln[0] 302 let T: *i64 = sys_mmap(np*FF_I64) as *i64 303 var i: i64 = 0 304 var got: i64 = 0 305 while i < n { 306 var c: i64 = buf[i] as i64 307 var neg: i64 = 0 308 if c == 45 { 309 neg = 1 310 i = i + 1 311 if i < n { c = buf[i] as i64 } else { c = 0 } 312 } 313 var isd: i64 = 0 314 if c >= 48 { if c <= 57 { isd = 1 } } 315 if isd == 1 { 316 var v: i64 = 0 317 var run: i64 = 1 318 while run == 1 { 319 v = v*10 + (c-48) 320 i = i + 1 321 if i < n { c = buf[i] as i64 } else { c = 0 } 322 var still: i64 = 0 323 if c >= 48 { if c <= 57 { still = 1 } } 324 if still == 0 { run = 0 } 325 } 326 if neg == 1 { v = 0-v } 327 if got < np { T[got] = v; got = got + 1 } 328 } else { 329 i = i + 1 330 } 331 } 332 if got >= minlen { 333 var lim: i64 = got 334 if lim > np { lim = np } 335 var q: i64 = 0 336 while q < lim { P[q] = T[q]; q = q + 1 } 337 return lim 338 } 339 return 0 340} 341// write the whole vector, one integer per line 342func ff_save(path: *u8, P: *i64, np: i64) -> i64 { 343 let fb: *u8 = sys_mmap(np*FF_SAVE_DIGITS + FF_SAVE_SLACK) 344 var fo: i64 = 0 345 var w: i64 = 0 346 while w < np { 347 fo = ff_wint(fb, fo, P[w]) 348 fb[fo] = 10 as u8 349 fo = fo + 1 350 w = w + 1 351 } 352 let fd: i64 = sys_openat_wr(path, FF_MODE644) 353 if fd < 0 { return 0 - 1 } 354 sys_write(fd, fb, fo) 355 sys_close(fd) 356 return fo 357} 358 359 360// Versioned checked path. Existing legacy entry points remain explicitly unverified. 361const FF_FIT_LEGACY_UNVERIFIED: i64 = 0 - 2 362const FF_FIT_CONTRACT_MISMATCH: i64 = 0 - 3 363const FF_FIT_MALFORMED: i64 = 0 - 4 364const FF_FIT_INVALID: i64 = 0 - 5 365const FF_FIT_IO: i64 = 0 - 6 366const FF_FIT_MAGIC_BYTES: i64 = 7 367const FF_FIT_I64_DIGITS: i64 = 21 368const FF_FIT_I64_POS_LIMIT: i64 = 9223372036854775807 369struct FfFitContract { header: *u8, header_bytes: i64, np: i64, valid: func(*i64,i64) -> i64 } 370// header is the caller's exact versioned schema/frame/producer/reference/objective identity. 371// It starts NXFFIT2 and ends newline; all identities are part of byte equality, never parsed as numbers. 372func ff_contract_ok(C: *FfFitContract) -> i64 { 373 if C.np <= 0 { return 0 } 374 if C.header_bytes < 0 { return 0 } 375 if C.np > (FF_FIT_I64_POS_LIMIT - C.header_bytes) / FF_FIT_I64_DIGITS { return 0 } 376 if C.header_bytes <= FF_FIT_MAGIC_BYTES { return 0 } 377 let magic: *u8 = "NXFFIT2" as *u8 378 var i: i64 = 0 379 while i < FF_FIT_MAGIC_BYTES { if C.header[i] != magic[i] { return 0 } i = i + 1 } 380 if C.header[C.header_bytes - 1] != 10 { return 0 } 381 return 1 382} 383func ff_load_verified(path: *u8, P: *i64, C: *FfFitContract) -> i64 { 384 if ff_contract_ok(C) != 1 { return FF_FIT_CONTRACT_MISMATCH } 385 let fd: i64 = sys_openat_rd(path) 386 if fd < 0 { return FF_FIT_IO } 387 let n: i64 = sys_lseek(fd, 0, 2) 388 let limit: i64 = C.header_bytes + C.np * FF_FIT_I64_DIGITS 389 if n < 0 { sys_close(fd); return FF_FIT_IO } 390 if n > limit { sys_close(fd); return FF_FIT_MALFORMED } 391 if sys_lseek(fd, 0, 0) != 0 { sys_close(fd); return FF_FIT_IO } 392 let b: *u8 = sys_mmap(n + 1) 393 if (b as i64) <= 0 { sys_close(fd); return FF_FIT_IO } 394 var total: i64 = 0 395 while total < n { 396 let got: i64 = sys_read(fd, ((b as i64) + total) as *u8, n - total) 397 if got <= 0 { sys_close(fd); return FF_FIT_IO } 398 total = total + got 399 } 400 let extra: i64 = sys_read(fd, ((b as i64) + n) as *u8, 1) 401 sys_close(fd) 402 if extra != 0 { return FF_FIT_MALFORMED } 403 if n < FF_FIT_MAGIC_BYTES { return FF_FIT_LEGACY_UNVERIFIED } 404 var i: i64 = 0 405 while i < FF_FIT_MAGIC_BYTES { if b[i] != C.header[i] { return FF_FIT_LEGACY_UNVERIFIED } i = i + 1 } 406 if n < C.header_bytes { return FF_FIT_CONTRACT_MISMATCH } 407 i = 0 408 while i < C.header_bytes { if b[i] != C.header[i] { return FF_FIT_CONTRACT_MISMATCH } i = i + 1 } 409 let T: *i64 = sys_mmap(C.np * FF_I64) as *i64 410 var k: i64 = 0 411 while k < C.np { 412 if i >= n { return FF_FIT_MALFORMED } 413 var neg: i64 = 0 414 if b[i] == 45 { neg = 1; i = i + 1 } 415 var digits: i64 = 0 416 var v: i64 = 0 417 var run: i64 = 1 418 while run == 1 { 419 if i >= n { run = 0 } else { 420 let c: i64 = b[i] as i64 421 if c < 48 { run = 0 } else { if c > 57 { run = 0 } else { 422 let d: i64 = c - 48 423 if v > (FF_FIT_I64_POS_LIMIT - d) / 10 { return FF_FIT_MALFORMED } 424 v = v * 10 + d; digits = digits + 1; i = i + 1 425 } } 426 } 427 } 428 if digits == 0 { return FF_FIT_MALFORMED } 429 if i >= n { return FF_FIT_MALFORMED } 430 if b[i] != 10 { return FF_FIT_MALFORMED } 431 i = i + 1 432 if neg == 1 { v = 0 - v } 433 T[k] = v; k = k + 1 434 } 435 if i != n { return FF_FIT_MALFORMED } 436 if C.valid(T, C.np) != 1 { return FF_FIT_INVALID } 437 k = 0 438 while k < C.np { P[k] = T[k]; k = k + 1 } 439 return C.np 440} 441func ff_save_verified(path: *u8, P: *i64, C: *FfFitContract) -> i64 { 442 if ff_contract_ok(C) != 1 { return FF_FIT_CONTRACT_MISMATCH } 443 if C.valid(P, C.np) != 1 { return FF_FIT_INVALID } 444 let b: *u8 = sys_mmap(C.header_bytes + C.np * FF_FIT_I64_DIGITS) 445 var o: i64 = 0 446 while o < C.header_bytes { b[o] = C.header[o]; o = o + 1 } 447 var k: i64 = 0 448 while k < C.np { 449 if P[k] < (0 - FF_FIT_I64_POS_LIMIT) { return FF_FIT_MALFORMED } 450 o = ff_wint(b, o, P[k]); b[o] = 10 as u8; o = o + 1; k = k + 1 451 } 452 let fd: i64 = sys_openat_wr(path, FF_MODE644) 453 if fd < 0 { return FF_FIT_IO } 454 let wrote: i64 = sys_write(fd, b, o) 455 sys_close(fd) 456 if wrote != o { return FF_FIT_IO } 457 return wrote 458} 459 460func ff_descend_checked(c: *FfCtx, P: *i64, passes: i64, step0: i64, verbose: i64, valid: func(*i64,i64) -> i64) -> i64 { 461 if valid(P, c.np) != 1 { return FF_FIT_INVALID } 462 if step0 <= 0 { return FF_FIT_INVALID } 463 if passes < 0 { return FF_FIT_INVALID } 464 var best: i64 = ff_score2(c, P) 465 var step: i64 = step0 466 if step < 1 { step = 8 } 467 var pass: i64 = 0 468 while pass < passes { 469 var k: i64 = 0 470 while k < c.np { 471 if c.live(k) == 1 { 472 let orig: i64 = P[k] 473 var up: i64 = best 474 if orig <= FF_FIT_I64_POS_LIMIT - step { 475 P[k] = orig + step 476 if valid(P, c.np) == 1 { up = ff_score2(c, P) } 477 } 478 var dn: i64 = best 479 if orig >= (0 - FF_FIT_I64_POS_LIMIT) + step { 480 P[k] = orig - step 481 if valid(P, c.np) == 1 { dn = ff_score2(c, P) } 482 } 483 P[k] = orig 484 if up < best { if up <= dn { best = up; P[k] = orig + step } } 485 if dn < best { if dn < up { best = dn; P[k] = orig - step } } 486 } 487 k = k + 1 488 } 489 if verbose == 1 { 490 ff_puts("{\x22pass\x22:" as *u8); ff_pn(pass) 491 ff_puts(",\x22step\x22:" as *u8); ff_pn(step) 492 ff_puts(",\x22best_centi\x22:" as *u8); ff_pn(best) 493 ff_puts("}\n" as *u8) 494 } 495 step = step/2 496 if step < 1 { step = 1 } 497 pass = pass + 1 498 } 499 return best 500}