nx_uv_stretch_derivative_gate_t281.nx source
↩ module page · 30 lines · 3359 B
1import "nx_uv_stretch_candidate_t281.nx"
2import "nx_gate_verdict.nx"
3func main()->i64{
4 let ctr:*i64=gv_ctr();let m:*i64=ncp_model_new(5,4)
5 uv_set_vert(m,0,0,0,0);uv_set_vert(m,1,1000,0,0);uv_set_vert(m,2,1000,1000,0);uv_set_vert(m,3,0,1000,0);uv_set_vert(m,4,500,500,0)
6 uv_set_tri(m,0,0,1,4);uv_set_tri(m,1,1,2,4);uv_set_tri(m,2,2,3,4);uv_set_tri(m,3,3,0,4);gv_check_eq("fixture charts",uv_chart_build(m),UV_OK,ctr)
7 let s:*UvGramSolve=uls_begin(m,0,0.00000001);if s==(0 as *UvGramSolve){return 2};s.result=UV_OK;var i:i64=0;var center:i64=0
8 while i<s.n{let v:i64=m[m[UV_O_UVSRC]+s.classes[i]];s.x[i]=__f64_from_i64(uv_vx(m,v));s.x[s.n+i]=__f64_from_i64(uv_vy(m,v));if v==4{center=i};i=i+1}
9 let q:*UvStretch=ust_begin(s);gv_check_eq("isometric context",q!=(0 as *UvStretch),1,ctr);if q==(0 as *UvStretch){return 3}
10 gv_check_eq("isometric energy equals four times area",ust_abs(q.energy-4000000.0)<0.000001,1,ctr)
11 s.x[center]=300.0;s.x[s.n+center]=400.0;let before:f64=ust_energy(q)
12 q.gu=0.0;q.gv=0.0;q.h00=0.0;q.h01=0.0;q.h11=0.0;q.base=0.0;var fi:i64=q.offset[center]
13 while fi<q.offset[center+1]{ust_face(q,q.incident[fi],center,s.x[center],s.x[s.n+center],1);fi=fi+1}
14 let gu:f64=q.gu;let gvv:f64=q.gv;let h00:f64=q.h00;let h01:f64=q.h01;let h11:f64=q.h11
15 let eps:f64=0.1;let ux:f64=s.x[center];let vy:f64=s.x[s.n+center]
16 s.x[center]=ux+eps;let up:f64=ust_energy(q);s.x[center]=ux-eps;let um:f64=ust_energy(q);s.x[center]=ux
17 s.x[s.n+center]=vy+eps;let vp:f64=ust_energy(q);s.x[s.n+center]=vy-eps;let vm:f64=ust_energy(q);s.x[s.n+center]=vy
18 s.x[center]=ux+eps;s.x[s.n+center]=vy+eps;let pp:f64=ust_energy(q);s.x[s.n+center]=vy-eps;let pm:f64=ust_energy(q)
19 s.x[center]=ux-eps;let mm:f64=ust_energy(q);s.x[s.n+center]=vy+eps;let mp:f64=ust_energy(q);s.x[center]=ux;s.x[s.n+center]=vy
20 gv_check_eq("analytic gradient U central difference",ust_abs((up-um)/(2.0*eps)-gu)/(1.0+ust_abs(gu))<0.00001,1,ctr)
21 gv_check_eq("analytic gradient V central difference",ust_abs((vp-vm)/(2.0*eps)-gvv)/(1.0+ust_abs(gvv))<0.00001,1,ctr)
22 gv_check_eq("analytic Hessian UU central difference",ust_abs((up+um-2.0*before)/(eps*eps)-h00)/(1.0+ust_abs(h00))<0.00001,1,ctr)
23 gv_check_eq("analytic Hessian VV central difference",ust_abs((vp+vm-2.0*before)/(eps*eps)-h11)/(1.0+ust_abs(h11))<0.00001,1,ctr)
24 gv_check_eq("analytic Hessian UV central difference",ust_abs((pp-pm-mp+mm)/(4.0*eps*eps)-h01)/(1.0+ust_abs(h01))<0.00001,1,ctr)
25 let cancel:*i64=sys_mmap_try(8) as *i64;cancel[0]=1;gv_check_eq("cancel returns before updates",ust_step(q,10,16,cancel),ULS_CANCELLED,ctr);gv_check_eq("cancel updates none",q.accepted,0,ctr);cancel[0]=0
26 gv_check_eq("refinement runs",ust_step(q,10,16,cancel),UV_OK,ctr);gv_check_eq("distorted planar energy improves",q.energy<before,1,ctr);gv_check_eq("positive faces retained",q.energy>0.0,1,ctr)
27 gv_check_eq("budget remains exact",q.sweeps,10,ctr);gv_check_eq("invalid budget rejected",ust_step(q,0,16,cancel),UV_E_ARGS,ctr)
28 ust_restore_scale(q);ust_free(q);sys_munmap_direct(cancel as *u8,8)
29 s.x[center]=2000.0;let bad:*UvStretch=ust_begin(s);gv_check_eq("folded initialization rejected",bad==(0 as *UvStretch),1,ctr);if bad!=(0 as *UvStretch){ust_free(bad)}
30 uls_free(s);ncp_model_free(m);return gv_verdict("UV-STRETCH-T281",ctr,"Native symmetric Dirichlet coordinate refinement; local orientation only, not atlas acceptance")
31}