
{"id":2155,"date":"2026-10-03T11:30:00","date_gmt":"2026-10-03T09:30:00","guid":{"rendered":"https:\/\/www.pcjv.de\/?p=2155"},"modified":"2026-10-04T19:43:20","modified_gmt":"2026-10-04T17:43:20","slug":"qmc-evenly-spread-points-for-go","status":"publish","type":"post","link":"https:\/\/www.pcjv.de\/?p=2155","title":{"rendered":"qmc: evenly spread points for Go"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Many programs need random points: to estimate an integral, to sample a parameter space, or to send rays through a room. Random points are easy to make, but they clump and leave gaps. Quasi-Monte Carlo sequences such as Sobol and Halton place points so that they fill the space evenly, and for many problems that gives the same accuracy with far fewer points. <a href=\"https:\/\/github.com\/CWBudde\/qmc\" target=\"_blank\" rel=\"noopener\">qmc<\/a> is a small Go library for these sequences, with no dependencies. I started it in August and have just given it a thorough review.<\/p>\n\n\n<!--more-->\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"\/wordpress\/wp-content\/uploads\/qmc-points.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"427\" src=\"\/wordpress\/wp-content\/uploads\/qmc-points.png\" alt=\"Three squares with 256 points each: random points with clumps and gaps, Halton and Sobol points spread evenly\" class=\"wp-image-2153\" srcset=\"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/qmc-points.png 1200w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/qmc-points-300x107.png 300w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/qmc-points-1024x364.png 1024w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/qmc-points-768x273.png 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><figcaption class=\"wp-element-caption\">256 points each, over a 16 \u00d7 16 grid. The random points leave 100 of the 256 cells empty, Halton leaves 44, and Sobol puts exactly one point in every cell.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Using it<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A generator is created for a number of dimensions and then hands out points with coordinates between 0 and 1:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>g, err := qmc.NewSobol(2, qmc.WithOwenScrambling(seed))\nif err != nil {\n    return err\n}\nfor i := 0; i &lt; 1024; i++ {\n    p := g.Next() \/\/ p[0], p[1] in [0,1)\n    \/\/ use p\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sobol works up to 1,024 dimensions with the built-in Joe\u2013Kuo direction numbers. Halton has no fixed limit. Both can be scrambled with a seed, which keeps the even spread but gives a different point set for each seed, so you can run several and see how much the result varies. <code>At(i)<\/code> returns the i-th point directly, and several goroutines can call it at once.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Does it help?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The classic toy example: throw points into the unit square and count how many land inside the quarter circle. Four times that fraction approximates &pi;. The plot shows the mean error over 20 runs, with random points and with scrambled Sobol points:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"\/wordpress\/wp-content\/uploads\/qmc-pi.png\"><img loading=\"lazy\" decoding=\"async\" width=\"853\" height=\"533\" src=\"\/wordpress\/wp-content\/uploads\/qmc-pi.png\" alt=\"Log-log plot of the error when estimating pi: the Sobol line falls much faster than the random line\" class=\"wp-image-2154\" srcset=\"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/qmc-pi.png 853w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/qmc-pi-300x187.png 300w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/qmc-pi-768x480.png 768w\" sizes=\"auto, (max-width: 853px) 100vw, 853px\" \/><\/a><figcaption class=\"wp-element-caption\">With 1,024 Sobol points the error is about as small as with 16,000 to 65,000 random points. The gap grows with the number of points.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The gain depends on the problem. It is largest for smooth functions in few dimensions, and it shrinks in many dimensions or with sharp edges. So it is worth measuring on your own problem before switching.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Trying it<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/cwbudde.github.io\/qmc\/\" target=\"_blank\" rel=\"noopener\">web demo<\/a> runs the library as WebAssembly in your browser. Its Point Lab starts with a guided tour through scatter plots, scrambling, correlation and convergence, and a second page compares the sequences by discrepancy, a number for how evenly points are spread. The library itself is one <code>go get github.com\/cwbudde\/qmc<\/code> away.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Many programs need random points: to estimate an integral, to sample a parameter space, or to send rays through a room. Random points are easy to make, but they clump and leave gaps. Quasi-Monte Carlo sequences such as Sobol and Halton place points so that they fill the space evenly, and for many problems that [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":2168,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[],"class_list":["post-2155","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-go"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>qmc: evenly spread points for Go - Christian&#039;s private site<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.pcjv.de\/?p=2155\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"qmc: evenly spread points for Go\",\"datePublished\":\"2026-10-03T09:30:00+00:00\",\"dateModified\":\"2026-10-04T17:43:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155\"},\"wordCount\":354,\"image\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pcjv.de\\\/wordpress\\\/wp-content\\\/uploads\\\/teaser-qmc.jpg\",\"articleSection\":[\"Go\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155\",\"url\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155\",\"name\":\"qmc: evenly spread points for Go - Christian&#039;s private site\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pcjv.de\\\/wordpress\\\/wp-content\\\/uploads\\\/teaser-qmc.jpg\",\"datePublished\":\"2026-10-03T09:30:00+00:00\",\"dateModified\":\"2026-10-04T17:43:20+00:00\",\"author\":{\"@id\":\"\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.pcjv.de\\\/?p=2155\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155#primaryimage\",\"url\":\"https:\\\/\\\/www.pcjv.de\\\/wordpress\\\/wp-content\\\/uploads\\\/teaser-qmc.jpg\",\"contentUrl\":\"https:\\\/\\\/www.pcjv.de\\\/wordpress\\\/wp-content\\\/uploads\\\/teaser-qmc.jpg\",\"width\":480,\"height\":360},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2155#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.pcjv.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"qmc: evenly spread points for Go\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/#website\",\"url\":\"https:\\\/\\\/www.pcjv.de\\\/\",\"name\":\"Christian&#039;s private site\",\"description\":\"Private site of Christian-W. Budde\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.pcjv.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"qmc: evenly spread points for Go - Christian&#039;s private site","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.pcjv.de\/?p=2155","twitter_misc":{"Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.pcjv.de\/?p=2155#article","isPartOf":{"@id":"https:\/\/www.pcjv.de\/?p=2155"},"author":{"name":"","@id":""},"headline":"qmc: evenly spread points for Go","datePublished":"2026-10-03T09:30:00+00:00","dateModified":"2026-10-04T17:43:20+00:00","mainEntityOfPage":{"@id":"https:\/\/www.pcjv.de\/?p=2155"},"wordCount":354,"image":{"@id":"https:\/\/www.pcjv.de\/?p=2155#primaryimage"},"thumbnailUrl":"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/teaser-qmc.jpg","articleSection":["Go"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.pcjv.de\/?p=2155","url":"https:\/\/www.pcjv.de\/?p=2155","name":"qmc: evenly spread points for Go - Christian&#039;s private site","isPartOf":{"@id":"https:\/\/www.pcjv.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.pcjv.de\/?p=2155#primaryimage"},"image":{"@id":"https:\/\/www.pcjv.de\/?p=2155#primaryimage"},"thumbnailUrl":"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/teaser-qmc.jpg","datePublished":"2026-10-03T09:30:00+00:00","dateModified":"2026-10-04T17:43:20+00:00","author":{"@id":""},"breadcrumb":{"@id":"https:\/\/www.pcjv.de\/?p=2155#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.pcjv.de\/?p=2155"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pcjv.de\/?p=2155#primaryimage","url":"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/teaser-qmc.jpg","contentUrl":"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/teaser-qmc.jpg","width":480,"height":360},{"@type":"BreadcrumbList","@id":"https:\/\/www.pcjv.de\/?p=2155#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.pcjv.de\/"},{"@type":"ListItem","position":2,"name":"qmc: evenly spread points for Go"}]},{"@type":"WebSite","@id":"https:\/\/www.pcjv.de\/#website","url":"https:\/\/www.pcjv.de\/","name":"Christian&#039;s private site","description":"Private site of Christian-W. Budde","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.pcjv.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/posts\/2155","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2155"}],"version-history":[{"count":1,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/posts\/2155\/revisions"}],"predecessor-version":[{"id":2156,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/posts\/2155\/revisions\/2156"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/media\/2168"}],"wp:attachment":[{"href":"https:\/\/www.pcjv.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2155"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2155"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2155"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}