1<!DOCTYPE html> 2<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head> 3 4<meta charset="utf-8"> 5<meta name="generator" content="quarto-1.9.38"> 6 7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 8 9 10<title>Inverse Complexity Blog â Inverse Complexity Lab</title> 11<style> 12/* Default styles provided by pandoc. 13** See https://pandoc.org/MANUAL.html#variables-for-html for config info. 14*/ 15code{white-space: pre-wrap;} 16span.smallcaps{font-variant: small-caps;} 17div.columns{display: flex; gap: min(4vw, 1.5em);} 18div.column{flex: auto; overflow-x: auto;} 19div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} 20ul.task-list{list-style: none;} 21ul.task-list li input[type="checkbox"] { 22 width: 0.8em; 23 margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 24 vertical-align: middle; 25} 26</style> 27 28
29<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 29
29
30<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 30
30
31<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 31
31
32<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 32
32
33<script src="site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 33
33
34<script src="site_libs/quarto-search/quarto-search.js"></script>
34 35<meta name="quarto:offset" content="./"> 36<link href="./static/z-bob.png" rel="icon" type="image/png">
37<script src="site_libs/quarto-listing/list.min.js"></script>
vendor: 1 bytes, line 37
37
38<script src="site_libs/quarto-listing/quarto-listing.js"></script>
vendor: 1 bytes, line 38
38
39<script src="site_libs/quarto-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 39
39
40<script src="site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 40
40
41<script src="site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 41
41
42<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 42
42
43<script src="site_libs/quarto-html/anchor.min.js"></script>
43 44<link href="site_libs/quarto-html/tippy.css" rel="stylesheet"> 45<link href="site_libs/quarto-html/quarto-syntax-highlighting-15634bcf2e68342d4ad2dfa704d543f6.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles"> 46<link href="site_libs/quarto-html/quarto-syntax-highlighting-dark-0a6b7249c26820e032cb0bd839ff02b1.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
47<script src="site_libs/bootstrap/bootstrap.min.js"></script>
47 48<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet"> 49<link href="site_libs/bootstrap/bootstrap-b3ab709b0f252e93e09bc847c3e05092.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light"> 50<link href="site_libs/bootstrap/bootstrap-dark-559642fb5ad3f5d0a8c1e1b3b723f4e8.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
51<script id="quarto-search-options" type="application/json">{ 52 "location": "navbar", 53 "copy-button": false, 54 "collapse-after": 3, 55 "panel-placement": "end", 56 "type": "overlay", 57 "limit": 50, 58 "keyboard-shortcut": [ 59 "f", 60 "/", 61 "s" 62 ], 63 "show-item-context": false, 64 "language": { 65 "search-no-results-text": "No results", 66 "search-matching-documents-text": "matching documents", 67 "search-copy-link-title": "Copy link to search", 68 "search-hide-matches-text": "Hide additional matches", 69 "search-more-match-text": "more match in this document", 70 "search-more-matches-text": "more matches in this document", 71 "search-clear-button-title": "Clear", 72 "search-text-placeholder": "", 73 "search-detached-cancel-button-title": "Cancel", 74 "search-submit-button-title": "Submit", 75 "search-label": "Search" 76 } 77}</script>
vendor: 1 bytes, line 77
77
78<script> 79 80 window.document.addEventListener("DOMContentLoaded", function (_event) { 81 const listingTargetEl = window.document.querySelector('#listing-listing .list'); 82 if (!listingTargetEl) { 83 // No listing discovered, do not attach. 84 return; 85 } 86 87 const options = { 88 valueNames: ['listing-title','listing-author','listing-date','listing-image','listing-description','listing-categories',{ data: ['index'] },{ data: ['categories'] },{ data: ['listing-date-sort'] },{ data: ['listing-file-modified-sort'] }], 89 90 searchColumns: ["listing-title","listing-author","listing-date","listing-image","listing-description","listing-categories"], 91 }; 92 93 window['quarto-listings'] = window['quarto-listings'] || {}; 94 window['quarto-listings']['listing-listing'] = new List('listing-listing', options); 95 96 if (window['quarto-listing-loaded']) { 97 window['quarto-listing-loaded'](); 98 } 99 }); 100 101 window.addEventListener('hashchange',() => { 102 if (window['quarto-listing-loaded']) { 103 window['quarto-listing-loaded'](); 104 } 105 }) 106 </script>
106 107<style>html{ scroll-behavior: smooth; }</style> 108<meta name="fediverse:creator" content="@[email protected]"> 109<link rel="alternate" type="application/rss+xml" title="Inverse Complexity Lab" href="blog.xml" data-external="1"><meta property="og:title" content="Inverse Complexity Blog â Inverse Complexity Lab"> 110<meta property="og:description" content="Research group on inverse problems in complex systems and network science."> 111<meta property="og:image" content="https://skewed.de/lab/static/research/foodweb-wsbm-lognormal.png"> 112<meta property="og:site_name" content="Inverse Complexity Lab"> 113<meta property="og:image:height" content="800"> 114<meta property="og:image:width" content="800"> 115<meta name="twitter:title" content="Inverse Complexity Blog â Inverse Complexity Lab"> 116<meta name="twitter:description" content="Research group on inverse problems in complex systems and network science."> 117<meta name="twitter:image" content="https://skewed.de/lab/static/research/foodweb-wsbm-lognormal.png"> 118<meta name="twitter:creator" content="@tiagopeixoto"> 119<meta name="twitter:site" content="@tiagopeixoto"> 120<meta name="twitter:image-height" content="800"> 121<meta name="twitter:image-width" content="800"> 122<meta name="twitter:card" content="summary_large_image"> 123</head><body class="nav-fixed quarto-dark">
123<script id="quarto-html-before-body" type="application/javascript"> 124 const toggleBodyColorMode = (bsSheetEl) => { 125 const mode = bsSheetEl.getAttribute("data-mode"); 126 const bodyEl = window.document.querySelector("body"); 127 if (mode === "dark") { 128 bodyEl.classList.add("quarto-dark"); 129 bodyEl.classList.remove("quarto-light"); 130 } else { 131 bodyEl.classList.add("quarto-light"); 132 bodyEl.classList.remove("quarto-dark"); 133 } 134 } 135 const toggleBodyColorPrimary = () => { 136 const bsSheetEl = window.document.querySelector("link#quarto-bootstrap:not([rel=disabled-stylesheet])"); 137 if (bsSheetEl) { 138 toggleBodyColorMode(bsSheetEl); 139 } 140 } 141 const setColorSchemeToggle = (alternate) => { 142 const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle'); 143 for (let i=0; i < toggles.length; i++) { 144 const toggle = toggles[i]; 145 if (toggle) { 146 if (alternate) { 147 toggle.classList.add("alternate"); 148 } else { 149 toggle.classList.remove("alternate"); 150 } 151 } 152 } 153 }; 154 const toggleColorMode = (alternate) => { 155 // Switch the stylesheets 156 const primaryStylesheets = window.document.querySelectorAll('link.quarto-color-scheme:not(.quarto-color-alternate)'); 157 const alternateStylesheets = window.document.querySelectorAll('link.quarto-color-scheme.quarto-color-alternate'); 158 manageTransitions('#quarto-margin-sidebar .nav-link', false); 159 if (alternate) { 160 // note: dark is layered on light, we don't disable primary! 161 enableStylesheet(alternateStylesheets); 162 for (const sheetNode of alternateStylesheets) { 163 if (sheetNode.id === "quarto-bootstrap") { 164 toggleBodyColorMode(sheetNode); 165 } 166 } 167 } else { 168 disableStylesheet(alternateStylesheets); 169 enableStylesheet(primaryStylesheets) 170 toggleBodyColorPrimary(); 171 } 172 manageTransitions('#quarto-margin-sidebar .nav-link', true); 173 // Switch the toggles 174 setColorSchemeToggle(alternate) 175 // Hack to workaround the fact that safari doesn't 176 // properly recolor the scrollbar when toggling (#1455) 177 if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) { 178 manageTransitions("body", false); 179 window.scrollTo(0, 1); 180 setTimeout(() => { 181 window.scrollTo(0, 0); 182 manageTransitions("body", true); 183 }, 40); 184 } 185 } 186 const disableStylesheet = (stylesheets) => { 187 for (let i=0; i < stylesheets.length; i++) { 188 const stylesheet = stylesheets[i]; 189 stylesheet.rel = 'disabled-stylesheet'; 190 } 191 } 192 const enableStylesheet = (stylesheets) => { 193 for (let i=0; i < stylesheets.length; i++) { 194 const stylesheet = stylesheets[i]; 195 if(stylesheet.rel !== 'stylesheet') { // for Chrome, which will still FOUC without this check 196 stylesheet.rel = 'stylesheet'; 197 } 198 } 199 } 200 const manageTransitions = (selector, allowTransitions) => { 201 const els = window.document.querySelectorAll(selector); 202 for (let i=0; i < els.length; i++) { 203 const el = els[i]; 204 if (allowTransitions) { 205 el.classList.remove('notransition'); 206 } else { 207 el.classList.add('notransition'); 208 } 209 } 210 } 211 const isFileUrl = () => { 212 return window.location.protocol === 'file:'; 213 } 214 const hasAlternateSentinel = () => { 215 let styleSentinel = getColorSchemeSentinel(); 216 if (styleSentinel !== null) { 217 return styleSentinel === "alternate"; 218 } else { 219 return false; 220 } 221 } 222 const setStyleSentinel = (alternate) => { 223 const value = alternate ? "alternate" : "default"; 224 if (!isFileUrl()) { 225 window.localStorage.setItem("quarto-color-scheme", value); 226 } else { 227 localAlternateSentinel = value; 228 } 229 } 230 const getColorSchemeSentinel = () => { 231 if (!isFileUrl()) { 232 const storageValue = window.localStorage.getItem("quarto-color-scheme"); 233 return storageValue != null ? storageValue : localAlternateSentinel; 234 } else { 235 return localAlternateSentinel; 236 } 237 } 238 const toggleGiscusIfUsed = (isAlternate, darkModeDefault) => { 239 const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light'; 240 const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark'; 241 let newTheme = ''; 242 if(authorPrefersDark) { 243 newTheme = isAlternate ? baseTheme : alternateTheme; 244 } else { 245 newTheme = isAlternate ? alternateTheme : baseTheme; 246 } 247 const changeGiscusTheme = () => { 248 // From: https://github.com/giscus/giscus/issues/336 249 const sendMessage = (message) => { 250 const iframe = document.querySelector('iframe.giscus-frame'); 251 if (!iframe) return; 252 iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app'); 253 } 254 sendMessage({ 255 setConfig: { 256 theme: newTheme 257 } 258 }); 259 } 260 const isGiscussLoaded = window.document.querySelector('iframe.giscus-frame') !== null; 261 if (isGiscussLoaded) { 262 changeGiscusTheme(); 263 } 264 }; 265 const authorPrefersDark = true; 266 const queryPrefersDark = window.matchMedia('(prefers-color-scheme: dark)'); 267 const darkModeDefault = queryPrefersDark.matches; 268 let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default'; 269 // Dark / light mode switch 270 window.quartoToggleColorScheme = () => { 271 // Read the current dark / light value 272 let toAlternate = !hasAlternateSentinel(); 273 toggleColorMode(toAlternate); 274 setStyleSentinel(toAlternate); 275 toggleGiscusIfUsed(toAlternate, darkModeDefault); 276 window.dispatchEvent(new Event('resize')); 277 }; 278 queryPrefersDark.addEventListener("change", e => { 279 if(window.localStorage.getItem("quarto-color-scheme") !== null) 280 return; 281 const alternate = e.matches 282 toggleColorMode(alternate); 283 localAlternateSentinel = e.matches ? 'alternate' : 'default'; // this is used alongside local storage! 284 toggleGiscusIfUsed(alternate, darkModeDefault); 285 }); 286 // Switch to dark mode if need be 287 if (hasAlternateSentinel()) { 288 toggleColorMode(true); 289 } else { 290 toggleColorMode(false); 291 } 292 </script>
292<span class="syndications"><link rel="webmention" href="https://webmention.io/skewed.de/webmention"></span> 293<link rel="authorization_endpoint" href="https://indieauth.com/auth"> 294<link rel="token_endpoint" href="https://tokens.indieauth.com/token"> 295 296
296<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
296 297
297<script defer="" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" type="text/javascript"></script>
297 298
299<script type="text/javascript"> 300const typesetMath = (el) => { 301 if (window.MathJax) { 302 // MathJax Typeset 303 window.MathJax.typeset([el]); 304 } else if (window.katex) { 305 // KaTeX Render 306 var mathElements = el.getElementsByClassName("math"); 307 var macros = []; 308 for (var i = 0; i < mathElements.length; i++) { 309 var texText = mathElements[i].firstChild; 310 if (mathElements[i].tagName == "SPAN" && texText && texText.data) { 311 window.katex.render(texText.data, mathElements[i], { 312 displayMode: mathElements[i].classList.contains('display'), 313 throwOnError: false, 314 macros: macros, 315 fleqn: false 316 }); 317 } 318 } 319 } 320} 321window.Quarto = { 322 typesetMath 323}; 324</script>
324 325 326<link rel="stylesheet" href="styles.css"> 327<link rel="stylesheet" href="static/css/fonts.css"> 328<link rel="stylesheet" href="site_libs/quarto-contrib/quarto-project/bethanyhgardner/fontawesome/assets/css/all.css"> 329<link rel="stylesheet" href="site_libs/quarto-contrib/quarto-project/schochastics/academicons/assets/css/all.css"> 330 331 332 333 334<div id="quarto-search-results"></div> 335 <header id="quarto-header" class="headroom fixed-top"> 336 <nav class="navbar navbar-expand-lg " data-bs-theme="dark"> 337 <div class="navbar-container container-fluid"> 338 <div class="navbar-brand-container mx-auto"> 339 <a href="./index.html" class="navbar-brand navbar-brand-logo"> 340 <img src="./static/research/foodweb-wsbm-lognormal.svg" alt="" class="navbar-logo light-content"> 341 <img src="./static/research/foodweb-wsbm-lognormal.svg" alt="" class="navbar-logo dark-content"> 342 </a> 343 <a class="navbar-brand" href="./index.html"> 344 <span class="navbar-title">Inverse Complexity Lab</span> 345 </a> 346 </div> 347 <div id="quarto-search" class="" title="Search"></div> 348 <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }"> 349 <span class="navbar-toggler-icon"></span> 350</button> 351 <div class="collapse navbar-collapse" id="navbarCollapse"> 352 <ul class="navbar-nav navbar-nav-scroll ms-auto"> 353 <li class="nav-item"> 354 <a class="nav-link" href="./tiago.html"> 355<span class="menu-text">Tiago P. Peixoto</span></a> 356 </li> 357 <li class="nav-item"> 358 <a class="nav-link" href="./research.html"> 359<span class="menu-text">Research</span></a> 360 </li> 361 <li class="nav-item"> 362 <a class="nav-link" href="./publications.html"> 363<span class="menu-text">Publications</span></a> 364 </li> 365 <li class="nav-item"> 366 <a class="nav-link" href="./group.html"> 367<span class="menu-text">Group members</span></a> 368 </li> 369 <li class="nav-item"> 370 <a class="nav-link" href="./software.html"> 371<span class="menu-text">Software & data</span></a> 372 </li> 373 <li class="nav-item"> 374 <a class="nav-link" href="./courses.html"> 375<span class="menu-text">Courses</span></a> 376 </li> 377 <li class="nav-item"> 378 <a class="nav-link active" href="./blog.html" aria-current="page"> 379<span class="menu-text">Blog</span></a> 380 </li> 381 <li class="nav-item"> 382 <a class="nav-link" href="./manual"> 383<span class="menu-text">Manual</span></a> 384 </li> 385 <li class="nav-item compact"> 386 <a class="nav-link" href="./blog.xml"> <i class="bi bi-rss" role="img"> 387</i> 388<span class="menu-text"></span></a> 389 </li> 390 <li class="nav-item"> 391 <a class="nav-link" href="https://graph-tool.skewed.de"> 392<span class="menu-text"><img src="./static/graph-tool-logo-circle.svg" style="vertical-align: -.3em;height:1.3em"></span></a> 393 </li> 394</ul> 395 </div> <!-- /navcollapse --> 396 <div class="quarto-navbar-tools"> 397 <a href="" class="quarto-color-scheme-toggle quarto-navigation-tool px-1" onclick="window.quartoToggleColorScheme(); return false;" title="Toggle dark mode"><i class="bi"></i></a> 398</div> 399 </div> <!-- /container-fluid --> 400 </nav> 401</header> 402<!-- content --> 403<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar"> 404<!-- sidebar --> 405<!-- margin-sidebar --> 406 <div id="quarto-margin-sidebar" class="sidebar margin-sidebar"> 407 408 <h5 class="quarto-listing-category-title">Categories</h5><div class="quarto-listing-category category-default"><div class="category" data-category="">All <span class="quarto-category-count">(12)</span></div><div class="category" data-category="YXBvcGhlbmlh">apophenia <span class="quarto-category-count">(1)</span></div><div class="category" data-category="QmF5ZXM=">Bayes <span class="quarto-category-count">(8)</span></div><div class="category" data-category="Y29tbXVuaXR5JTIwZGV0ZWN0aW9u">community detection <span class="quarto-category-count">(9)</span></div><div class="category" data-category="Y29tcHJlc3Npb24=">compression <span class="quarto-category-count">(4)</span></div><div class="category" data-category="ZGVzY3JpcHRpb24=">description <span class="quarto-category-count">(2)</span></div><div class="category" data-category="ZnJlZSUyMGx1bmNo">free lunch <span class="quarto-category-count">(2)</span></div><div class="category" data-category="aGFpcmJhbGw=">hairball <span class="quarto-category-count">(1)</span></div><div class="category" data-category="aGV1cmlzdGljcw==">heuristics <span class="quarto-category-count">(1)</span></div><div class="category" data-category="aGlnaGVyLW9yZGVy">
408higher-order <span class="quarto-category-count">(1)</span></div><div class="category" data-category="aHlwZQ==">hype <span class="quarto-category-count">(1)</span></div><div class="category" data-category="aHlwZXJncmFwaHM=">hypergraphs <span class="quarto-category-count">(1)</span></div><div class="category" data-category="aHlwZXJzbG9w">hyperslop <span class="quarto-category-count">(1)</span></div><div class="category" data-category="aW5mZXJlbmNl">inference <span class="quarto-category-count">(6)</span></div><div class="category" data-category="TURM">MDL <span class="quarto-category-count">(4)</span></div><div class="category" data-category="bWVhbi1maWVsZA==">mean-field <span class="quarto-category-count">(1)</span></div><div class="category" data-category="bWVtZXM=">memes <span class="quarto-category-count">(1)</span></div><div class="category" data-category="bWV0aG9kb2xvZ2ljYWwlMjBpbXBlcmlhbGlzbQ==">methodological imperialism <span class="quarto-category-count">(1)</span></div><div class="category" data-category="bW9kdWxhcml0eQ==">modularity <span class="quarto-category-count">(2)</span></div><div class="category" data-category="bmV0d29yayUyMHZpc3VhbGl6YXRpb24=">network visualization <span class="quarto-category-count">(1)</span></div><div class="category" data-category="b3ZlcmZpdHRpbmc=">overfitting <span class="quarto-category-count">(3)</span></div><div class="category" data-category="cmVjb25zdHJ1Y3Rpb24=">reconstruction <span class="quarto-category-count">(1)</span></div><div class="category" data-category="cmlkaWN1bG9ncmFt">ridiculogram <span class="quarto-category-count">(1)</span></div><div class="category" data-category="U0JN">SBM <span class="quarto-category-count">(4)</span></div><div class="category" data-category="c3RhdGlzdGljYWwlMjBzaWduaWZpY2FuY2U=">statistical significance <span class="quarto-category-count">(1)</span></div><div class="category" data-category="c3ViamVjdGl2aXR5">subjectivity <span class="quarto-category-count">(1)</span></div></div></div> 409<!-- main --> 410<main class="content" id="quarto-document-content"> 411 412 413<header id="title-block-header" class="quarto-title-block default"> 414<div class="quarto-title"> 415<h1 class="title">Inverse Complexity Blog</h1> 416</div> 417 418 419 420<div class="quarto-title-meta"> 421 422 423 424 425 </div> 426 427 428 429</header> 430 431 432 433 434 435 436<div class="quarto-listing quarto-listing-container-grid" id="listing-listing"> 437<div class="list grid quarto-listing-cols-3"> 438<div class="g-col-1" data-index="0" data-categories="aHlwZXJzbG9wJTJDaHlwZXJncmFwaHMlMkNoaWdoZXItb3JkZXIlMkNoeXBlJTJDbWVhbi1maWVsZA==" data-listing-date-sort="1771801200000" data-listing-file-modified-sort="1777876002032" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="16" data-listing-word-count-sort="3142"> 439<a href="./posts/higher-standards/index.html" class="quarto-grid-link"> 440<div class="quarto-grid-item card h-100 card-left"> 441<p class="card-img-top"> 442<img loading="lazy" src="./posts/higher-standards/diagram_func.png" class="thumbnail-image card-img" style="height: 150px;"> 443</p> 444<div class="card-body post-contents"> 445<h5 class="no-anchor card-title listing-title"> 446Higher orders need higher standards 447</h5> 448<div class="listing-categories"> 449 450<div class="listing-category" onclick="window.quartoListingCategory('aHlwZXJzbG9w'); return false;">hyperslop</div> 451 452<div class="listing-category" onclick="window.quartoListingCategory('aHlwZXJncmFwaHM='); return false;">hypergraphs</div> 453 454<div class="listing-category" onclick="window.quartoListingCategory('aGlnaGVyLW9yZGVy'); return false;">higher-order</div> 455 456<div class="listing-category" onclick="window.quartoListingCategory('aHlwZQ=='); return false;">hype</div> 457 458<div class="listing-category" onclick="window.quartoListingCategory('bWVhbi1maWVsZA=='); return false;">mean-field</div> 459 460</div> 461<div class="card-text listing-description delink"> 462TL;DR â Contrary to widespread claims in recent years, itâs not true that graphs encode âpairwiseâ interactions. Graphs encode neighborhoodsâsets of nodes incident to otherâ¦<span class="citation" data-cites="peixoto_graphs_2026"></span> 463</div> 464<div class="card-attribution card-text-small justify"> 465<div class="listing-author"> 466Tiago P. Peixoto 467</div> 468<div class="listing-date"> 469Feb 23, 2026 470</div> 471</div> 472</div> 473</div></a> 474</div> 475<div class="g-col-1" data-index="1" data-categories="Y29tbXVuaXR5JTIwZGV0ZWN0aW9uJTJDaGV1cmlzdGljcyUyQ292ZXJmaXR0aW5nJTJDbWVtZXM=" data-listing-date-sort="1764802800000" data-listing-file-modified-sort="1767007380865" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="7" data-listing-word-count-sort="1328"> 476<a href="./posts/connected-clusters/index.html" class="quarto-grid-link"> 477<div class="quarto-grid-item card h-100 card-left"> 478<p class="card-img-top"> 479<img loading="lazy" src="./posts/connected-clusters/clusters.png" class="thumbnail-image card-img" style="height: 150px;"> 480</p> 481<div class="card-body post-contents"> 482<h5 class="no-anchor card-title listing-title"> 483The perplexing âconnected cluster axiomâ 484</h5> 485<div class="listing-categories"> 486 487<div class="listing-category" onclick="window.quartoListingCategory('Y29tbXVuaXR5JTIwZGV0ZWN0aW9u'); return false;">community detection</div> 488 489<div class="listing-category" onclick="window.quartoListingCategory('aGV1cmlzdGljcw=='); return false;">heuristics</div> 490 491<div class="listing-category" onclick="window.quartoListingCategory('b3ZlcmZpdHRpbmc='); return false;">overfitting</div> 492 493<div class="listing-category" onclick="window.quartoListingCategory('bWVtZXM='); return false;">memes</div> 494 495</div> 496<div class="card-text listing-description delink"> 497TL;DR â Thereâs no good reason to always expect communities in networks to be made of strictly connected nodes. On the contrary, doing so leads to conceptual inconsistencies⦠498</div> 499<div class="card-attribution card-text-small justify"> 500<div class="listing-author"> 501Tiago P. Peixoto 502</div> 503<div class="listing-date"> 504Dec 4, 2025 505</div> 506</div> 507</div> 508</div></a> 509</div> 510<div class="g-col-1" data-index="2" data-categories="bmV0d29yayUyMHZpc3VhbGl6YXRpb24lMkNpbmZlcmVuY2UlMkNoYWlyYmFsbCUyQ2Fwb3BoZW5pYSUyQ3JpZGljdWxvZ3JhbSUyQ21ldGhvZG9sb2dpY2FsJTIwaW1wZXJpYWxpc20=" data-listing-date-sort="1716156000000" data-listing-file-modified-sort="1756756335152" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="19" data-listing-word-count-sort="3694"> 511<a href="./posts/hairball/index.html" class="quarto-grid-link"> 512<div class="quarto-grid-item card h-100 card-left"> 513<p class="card-img-top"> 514<img loading="lazy" src="./posts/hairball/polblogs-sbm.png" class="thumbnail-image card-img" style="height: 150px;"> 515</p> 516<div class="card-body post-contents"> 517<h5 class="no-anchor card-title listing-title"> 518Untangling the hairball using statistical inference 519</h5> 520<div class="listing-categories"> 521 522<div class="listing-category" onclick="window.quartoListingCategory('bmV0d29yayUyMHZpc3VhbGl6YXRpb24='); return false;">network visualization</div> 523 524<div class="listing-category" onclick="window.quartoListingCategory('aW5mZXJlbmNl'); return false;">inference</div> 525 526<div class="listing-category" onclick="window.quartoListingCategory('aGFpcmJhbGw='); return false;">hairball</div> 527 528<div class="listing-category" onclick="window.quartoListingCategory('YXBvcGhlbmlh'); return false;">apophenia</div> 529 530<div class="listing-category" onclick="window.quartoListingCategory('cmlkaWN1bG9ncmFt'); return false;">ridiculogram</div> 531 532<div class="listing-category" onclick="window.quartoListingCategory('bWV0aG9kb2xvZ2ljYWwlMjBpbXBlcmlhbGlzbQ=='); return false;">methodological imperialism</div> 533 534</div> 535<div class="card-text listing-description delink"> 536TL;DR â Network visualization is often done in the wrong way: first a network layout is produced using a heuristic, and then follow-up analyses are performed and evaluated⦠537</div> 538<div class="card-attribution card-text-small justify"> 539<div class="listing-author"> 540Tiago P. Peixoto 541</div> 542<div class="listing-date"> 543May 20, 2024 544</div> 545</div> 546</div> 547</div></a> 548</div> 549<div class="g-col-1" data-index="3" data-categories="Y29tbXVuaXR5JTIwZGV0ZWN0aW9uJTJDQmF5ZXMlMkNjb21wcmVzc2lvbiUyQ01ETCUyQ292ZXJmaXR0aW5nJTJDZnJlZSUyMGx1bmNo" data-listing-date-sort="1711922400000" data-listing-file-modified-sort="1756757716138" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="10" data-listing-word-count-sort="1878"> 550<a href="./posts/hidden-models/index.html" class="quarto-grid-link"> 551<div class="quarto-grid-item card h-100 card-left"> 552<p class="card-img-top"> 553<img loading="lazy" src="./posts/hidden-models/diagram.png" class="thumbnail-image card-img" style="height: 150px;"> 554</p> 555<div class="card-body post-contents"> 556<h5 class="no-anchor card-title listing-title"> 557Hidden models and latent compression in community detection 558</h5> 559<div class="listing-categories"> 560 561<div class="listing-category" onclick="window.quartoListingCategory('Y29tbXVuaXR5JTIwZGV0ZWN0aW9u'); return false;">community detection</div> 562 563<div class="listing-category" onclick="window.quartoListingCategory('QmF5ZXM='); return false;">Bayes</div> 564 565<div class="listing-category" onclick="window.quartoListingCategory('Y29tcHJlc3Npb24='); return false;">compression</div> 566 567<div class="listing-category" onclick="window.quartoListingCategory('TURM'); return false;">MDL</div> 568 569<div class="listing-category" onclick="window.quartoListingCategory('b3ZlcmZpdHRpbmc='); return false;">overfitting</div> 570 571<div class="listing-category" onclick="window.quartoListingCategory('ZnJlZSUyMGx1bmNo'); return false;">free lunch</div> 572 573</div> 574<div class="card-text listing-description delink"> 575This is an overdue post on a paper published last year with Alec Kirkley, named <em>âImplicit Models, Latent Compression, Intrinsic Biases, and Cheap Lunches in Communityâ¦</em><span class="citation" data-cites="peixoto_implicit_2023"></span> 576</div> 577<div class="card-attribution card-text-small justify"> 578<div class="listing-author"> 579Tiago P. Peixoto 580</div> 581<div class="listing-date"> 582Apr 1, 2024 583</div> 584</div> 585</div> 586</div></a> 587</div> 588<div class="g-col-1" data-index="4" data-categories="Y29tbXVuaXR5JTIwZGV0ZWN0aW9uJTJDQmF5ZXMlMkNjb21wcmVzc2lvbiUyQ01ETCUyQ3N1YmplY3Rpdml0eQ==" data-listing-date-sort="1641250800000" data-listing-file-modified-sort="1724019705417" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="12" data-listing-word-count-sort="2386"> 589<a href="./posts/objective-inference/index.html" class="quarto-grid-link"> 590<div class="quarto-grid-item card h-100 card-left"> 591<p class="card-img-top"> 592<img loading="lazy" src="./posts/objective-inference/compressed.png" class="thumbnail-image card-img" style="height: 150px;"> 593</p> 594<div class="card-body post-contents"> 595<h5 class="no-anchor card-title listing-title"> 596Is Bayesian inference subjective? 597</h5> 598<div class="listing-categories"> 599 600<div class="listing-category" onclick="window.quartoListingCategory('Y29tbXVuaXR5JTIwZGV0ZWN0aW9u'); return false;">community detection</div> 601 602<div class="listing-category" onclick="window.quartoListingCategory('QmF5ZXM='); return false;">Bayes</div> 603 604<div class="listing-category" onclick="window.quartoListingCategory('Y29tcHJlc3Npb24='); return false;">compression</div> 605 606<div class="listing-category" onclick="window.quartoListingCategory('TURM'); return false;">MDL</div> 607 608<div class="listing-category" onclick="window.quartoListingCategory('c3ViamVjdGl2aXR5'); return false;">subjectivity</div> 609 610</div> 611<div class="card-text listing-description delink"> 612In a previous blog post (covering<span class="citation" data-cites="peixoto_descriptive_2023"> [1]</span>
612) I discussed how inferential approaches to community detection are based on the formulation of generative models, via the definition ofâ¦<span class="math inline"></span><span class="math inline"></span><span class="math inline"></span> 613</div> 614<div class="card-attribution card-text-small justify"> 615<div class="listing-author"> 616Tiago P. Peixoto 617</div> 618<div class="listing-date"> 619Jan 4, 2022 620</div> 621</div> 622</div> 623</div></a> 624</div> 625<div class="g-col-1" data-index="5" data-categories="Y29tbXVuaXR5JTIwZGV0ZWN0aW9uJTJDbW9kdWxhcml0eSUyQ292ZXJmaXR0aW5nJTJDc3RhdGlzdGljYWwlMjBzaWduaWZpY2FuY2U=" data-listing-date-sort="1639350000000" data-listing-file-modified-sort="1712932182257" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="5" data-listing-word-count-sort="813"> 626<a href="./posts/significant-modularity/index.html" class="quarto-grid-link"> 627<div class="quarto-grid-item card h-100 card-left"> 628<p class="card-img-top"> 629<img loading="lazy" src="./posts/significant-modularity/modularity-test.png" class="thumbnail-image card-img" style="height: 150px;"> 630</p> 631<div class="card-body post-contents"> 632<h5 class="no-anchor card-title listing-title"> 633Significant community structure via statistical tests? 634</h5> 635<div class="listing-categories"> 636 637<div class="listing-category" onclick="window.quartoListingCategory('Y29tbXVuaXR5JTIwZGV0ZWN0aW9u'); return false;">community detection</div> 638 639<div class="listing-category" onclick="window.quartoListingCategory('bW9kdWxhcml0eQ=='); return false;">modularity</div> 640 641<div class="listing-category" onclick="window.quartoListingCategory('b3ZlcmZpdHRpbmc='); return false;">overfitting</div> 642 643<div class="listing-category" onclick="window.quartoListingCategory('c3RhdGlzdGljYWwlMjBzaWduaWZpY2FuY2U='); return false;">statistical significance</div> 644 645</div> 646<div class="card-text listing-description delink"> 647In a previous blog post I explained how modularity maximization tends to overfit and find spurious community structure even in random graphs. 648</div> 649<div class="card-attribution card-text-small justify"> 650<div class="listing-author"> 651Tiago P. Peixoto 652</div> 653<div class="listing-date"> 654Dec 13, 2021 655</div> 656</div> 657</div> 658</div></a> 659</div> 660<div class="g-col-1" data-index="6" data-categories="Y29tbXVuaXR5JTIwZGV0ZWN0aW9uJTJDQmF5ZXMlMkNjb21wcmVzc2lvbiUyQ01ETA==" data-listing-date-sort="1638918000000" data-listing-file-modified-sort="1712932182401" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="4" data-listing-word-count-sort="737"> 661<a href="./posts/hypothesis-is-not-belief/index.html" class="quarto-grid-link"> 662<div class="quarto-grid-item card h-100 card-left"> 663<p class="card-img-top"> 664<img loading="lazy" src="./static/research/add_health_comm26-marginal-triadic_sbm-modesbm.png" class="thumbnail-image card-img" style="height: 150px;"> 665</p> 666<div class="card-body post-contents"> 667<h5 class="no-anchor card-title listing-title"> 668Do we need to believe in generative models? 669</h5> 670<div class="listing-categories"> 671 672<div class="listing-category" onclick="window.quartoListingCategory('Y29tbXVuaXR5JTIwZGV0ZWN0aW9u'); return false;">community detection</div> 673 674<div class="listing-category" onclick="window.quartoListingCategory('QmF5ZXM='); return false;">Bayes</div> 675 676<div class="listing-category" onclick="window.quartoListingCategory('Y29tcHJlc3Npb24='); return false;">compression</div> 677 678<div class="listing-category" onclick="window.quartoListingCategory('TURM'); return false;">MDL</div> 679 680</div> 681<div class="card-text listing-description delink"> 682In two previous blog posts (first and second) I advocated for the use of statistical inference for community detection in networks, whenever our objective is of an⦠683</div> 684<div class="card-attribution card-text-small justify"> 685<div class="listing-author"> 686Tiago P. Peixoto 687</div> 688<div class="listing-date"> 689Dec 8, 2021 690</div> 691</div> 692</div> 693</div></a> 694</div> 695<div class="g-col-1" data-index="7" data-categories="Y29tbXVuaXR5JTIwZGV0ZWN0aW9uJTJDZnJlZSUyMGx1bmNoJTJDaW5mZXJlbmNlJTJDY29tcHJlc3Npb24lMkNCYXllcw==" data-listing-date-sort="1638831600000" data-listing-file-modified-sort="1724056134274" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="18" data-listing-word-count-sort="3438"> 696<a href="./posts/free-lunch/index.html" class="quarto-grid-link"> 697<div class="quarto-grid-item card h-100 card-left"> 698<p class="card-img-top"> 699<img loading="lazy" src="./posts/free-lunch/nfl-trade-off.png" class="thumbnail-image card-img" style="height: 150px;"> 700</p> 701<div class="card-body post-contents"> 702<h5 class="no-anchor card-title listing-title"> 703No free lunch in community detection? 704</h5> 705<div class="listing-categories"> 706 707<div class="listing-category" onclick="window.quartoListingCategory('Y29tbXVuaXR5JTIwZGV0ZWN0aW9u'); return false;">community detection</div> 708 709<div class="listing-category" onclick="window.quartoListingCategory('ZnJlZSUyMGx1bmNo'); return false;">free lunch</div> 710 711<div class="listing-category" onclick="window.quartoListingCategory('aW5mZXJlbmNl'); return false;">inference</div> 712 713<div class="listing-category" onclick="window.quartoListingCategory('Y29tcHJlc3Npb24='); return false;">compression</div> 714 715<div class="listing-category" onclick="window.quartoListingCategory('QmF5ZXM='); return false;">Bayes</div> 716 717</div> 718<div class="card-text listing-description delink"> 719For a wide class of optimization and learning problems there exist so-called âno-free-lunchâ (NFL) theorems, which broadly state that when averaged over all possible problemâ¦<span class="citation" data-cites="wolpert_no_1995 wolpert_lack_1996 wolpert_no_1997"></span><em></em><span class="citation" data-cites="peel_ground_2017"></span> 720</div> 721<div class="card-attribution card-text-small justify"> 722<div class="listing-author"> 723Tiago P. Peixoto 724</div> 725<div class="listing-date"> 726Dec 7, 2021 727</div> 728</div> 729</div> 730</div></a> 731</div> 732<div class="g-col-1" data-index="8" data-categories="Y29tbXVuaXR5JTIwZGV0ZWN0aW9uJTJDbW9kdWxhcml0eSUyQ2luZmVyZW5jZSUyQ0JheWVzJTJDU0JN" data-listing-date-sort="1638745200000" data-listing-file-modified-sort="1748947679242" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="19" data-listing-word-count-sort="3780"> 733<a href="./posts/modularity-harmful/index.html" class="quarto-grid-link"> 734<div class="quarto-grid-item card h-100 card-left"> 735<p class="card-img-top"> 736<img loading="lazy" src="./posts/modularity-harmful/modularity_fail.png" class="thumbnail-image card-img" style="height: 150px;"> 737</p> 738<div class="card-body post-contents"> 739<h5 class="no-anchor card-title listing-title"> 740Modularity maximization considered harmful 741</h5> 742<div class="listing-categories"> 743 744<div class="listing-category" onclick="window.quartoListingCategory('Y29tbXVuaXR5JTIwZGV0ZWN0aW9u'); return false;">community detection</div> 745 746<div class="listing-category" onclick="window.quartoListingCategory('bW9k
746dWxhcml0eQ=='); return false;">modularity</div> 747 748<div class="listing-category" onclick="window.quartoListingCategory('aW5mZXJlbmNl'); return false;">inference</div> 749 750<div class="listing-category" onclick="window.quartoListingCategory('QmF5ZXM='); return false;">Bayes</div> 751 752<div class="listing-category" onclick="window.quartoListingCategory('U0JN'); return false;">SBM</div> 753 754</div> 755<div class="card-text listing-description delink"> 756The most widespread method for community detection is modularity maximization <span class="citation" data-cites="newman_modularity_2006"> [2]</span>, which happens also to be one of the most problematic. This method is based on the⦠757</div> 758<div class="card-attribution card-text-small justify"> 759<div class="listing-author"> 760Tiago P. Peixoto 761</div> 762<div class="listing-date"> 763Dec 6, 2021 764</div> 765</div> 766</div> 767</div></a> 768</div> 769<div class="g-col-1" data-index="9" data-categories="Y29tbXVuaXR5JTIwZGV0ZWN0aW9uJTJDZGVzY3JpcHRpb24lMkNpbmZlcmVuY2UlMkNCYXllcyUyQ01ETCUyQ1NCTQ==" data-listing-date-sort="1638486000000" data-listing-file-modified-sort="1724314341284" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="16" data-listing-word-count-sort="3160"> 770<a href="./posts/inference-compression/index.html" class="quarto-grid-link"> 771<div class="quarto-grid-item card h-100 card-left"> 772<p class="card-img-top"> 773<img loading="lazy" src="./posts/inference-compression/generative.png" class="thumbnail-image card-img" style="height: 150px;"> 774</p> 775<div class="card-body post-contents"> 776<h5 class="no-anchor card-title listing-title"> 777Inferring, explaining, and compressing 778</h5> 779<div class="listing-categories"> 780 781<div class="listing-category" onclick="window.quartoListingCategory('Y29tbXVuaXR5JTIwZGV0ZWN0aW9u'); return false;">community detection</div> 782 783<div class="listing-category" onclick="window.quartoListingCategory('ZGVzY3JpcHRpb24='); return false;">description</div> 784 785<div class="listing-category" onclick="window.quartoListingCategory('aW5mZXJlbmNl'); return false;">inference</div> 786 787<div class="listing-category" onclick="window.quartoListingCategory('QmF5ZXM='); return false;">Bayes</div> 788 789<div class="listing-category" onclick="window.quartoListingCategory('TURM'); return false;">MDL</div> 790 791<div class="listing-category" onclick="window.quartoListingCategory('U0JN'); return false;">SBM</div> 792 793</div> 794<div class="card-text listing-description delink"> 795Inferential approaches to community detection (see <span class="citation" data-cites="peixoto_bayesian_2019"> [2]</span> for a detailed introduction) are designed to provide explanations for network data in a principled manner. They areâ¦<span class="math inline"></span><span class="math inline"></span><span class="math inline"></span> 796</div> 797<div class="card-attribution card-text-small justify"> 798<div class="listing-author"> 799Tiago P. Peixoto 800</div> 801<div class="listing-date"> 802Dec 3, 2021 803</div> 804</div> 805</div> 806</div></a> 807</div> 808<div class="g-col-1" data-index="10" data-categories="Y29tbXVuaXR5JTIwZGV0ZWN0aW9uJTJDZGVzY3JpcHRpb24lMkNpbmZlcmVuY2UlMkNCYXllcyUyQ1NCTQ==" data-listing-date-sort="1638399600000" data-listing-file-modified-sort="1712932182557" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="11" data-listing-word-count-sort="2163"> 809<a href="./posts/descriptive-inferential/index.html" class="quarto-grid-link"> 810<div class="quarto-grid-item card h-100 card-left"> 811<p class="card-img-top"> 812<img loading="lazy" src="./posts/descriptive-inferential/descriptive.png" class="thumbnail-image card-img" style="height: 150px;"> 813</p> 814<div class="card-body post-contents"> 815<h5 class="no-anchor card-title listing-title"> 816Descriptive vs. inferential community detection 817</h5> 818<div class="listing-categories"> 819 820<div class="listing-category" onclick="window.quartoListingCategory('Y29tbXVuaXR5JTIwZGV0ZWN0aW9u'); return false;">community detection</div> 821 822<div class="listing-category" onclick="window.quartoListingCategory('ZGVzY3JpcHRpb24='); return false;">description</div> 823 824<div class="listing-category" onclick="window.quartoListingCategory('aW5mZXJlbmNl'); return false;">inference</div> 825 826<div class="listing-category" onclick="window.quartoListingCategory('QmF5ZXM='); return false;">Bayes</div> 827 828<div class="listing-category" onclick="window.quartoListingCategory('U0JN'); return false;">SBM</div> 829 830</div> 831<div class="card-text listing-description delink"> 832Community detection is the task of dividing a network â typically one which is large â into many smaller groups of nodes that have a similar contribution to the overall⦠833</div> 834<div class="card-attribution card-text-small justify"> 835<div class="listing-author"> 836Tiago P. Peixoto 837</div> 838<div class="listing-date"> 839Dec 2, 2021 840</div> 841</div> 842</div> 843</div></a> 844</div> 845<div class="g-col-1" data-index="11" data-categories="aW5mZXJlbmNlJTJDcmVjb25zdHJ1Y3Rpb24lMkNCYXllcyUyQ1NCTQ==" data-listing-date-sort="1635458400000" data-listing-file-modified-sort="1756755275297" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="5" data-listing-word-count-sort="977"> 846<a href="./posts/thats-unpossible/index.html" class="quarto-grid-link"> 847<div class="quarto-grid-item card h-100 card-left"> 848<p class="card-img-top"> 849<img loading="lazy" src="./posts/thats-unpossible/reconstructed.svg" class="thumbnail-image card-img" style="height: 150px;"> 850</p> 851<div class="card-body post-contents"> 852<h5 class="no-anchor card-title listing-title"> 853Is network reconstruction impossible? 854</h5> 855<div class="listing-categories"> 856 857<div class="listing-category" onclick="window.quartoListingCategory('aW5mZXJlbmNl'); return false;">inference</div> 858 859<div class="listing-category" onclick="window.quartoListingCategory('cmVjb25zdHJ1Y3Rpb24='); return false;">reconstruction</div> 860 861<div class="listing-category" onclick="window.quartoListingCategory('QmF5ZXM='); return false;">Bayes</div> 862 863<div class="listing-category" onclick="window.quartoListingCategory('U0JN'); return false;">SBM</div> 864 865</div> 866<div class="card-text listing-description delink"> 867I have been getting some questions about a 2018 paper <span class="citation" data-cites="chang_estimation_2020"> [1]</span> by Jinyuan Chang, Eric D. Kolaczyk, and Qiwei Yao that deals with reconstruction of noisy networks, i.e. networks⦠868</div> 869<div class="card-attribution card-text-small justify"> 870<div class="listing-author"> 871Tiago P. Peixoto 872</div> 873<div class="listing-date"> 874Oct 29, 2021 875</div> 876</div> 877</div> 878</div></a> 879</div> 880</div> 881<div class="listing-no-matching d-none">No matching items</div> 882</div></main> <!-- /main -->
883<script id="quarto-html-after-body" type="application/javascript"> 884 window.document.addEventListener("DOMContentLoaded", function (event) { 885 // Ensure there is a toggle, if there isn't float one in the top right 886 if (window.document.querySelector('.quarto-color-scheme-toggle') === null) { 887 const a = window.document.createElement('a'); 888 a.classList.add('top-right'); 889 a.classList.add('quarto-color-scheme-toggle'); 890 a.href = ""; 891 a.onclick = function() { try { window.quartoToggleColorScheme(); } catch {} return false; }; 892 const i = window.document.createElement("i"); 893 i.classList.add('bi'); 894 a.appendChild(i); 895 window.document.body.appendChild(a); 896 } 897 setColorSchemeToggle(hasAlternateSentinel()) 898 const icon = "î§"; 899 const anchorJS = new window.AnchorJS(); 900 anchorJS.options = { 901 placement: 'right', 902 icon: icon 903 }; 904 anchorJS.add('.anchored'); 905 const isCodeAnnotation = (el) => { 906 for (const clz of el.classList) { 907 if (clz.startsWith('code-annotation-')) { 908 return true; 909 } 910 } 911 return false; 912 } 913 const onCopySuccess = function(e) { 914 // button target 915 const button = e.trigger; 916 // don't keep focus 917 button.blur(); 918 // flash "checked" 919 button.classList.add('code-copy-button-checked'); 920 var currentTitle = button.getAttribute("title"); 921 button.setAttribute("title", "Copied!"); 922 let tooltip; 923 if (window.bootstrap) { 924 button.setAttribute("data-bs-toggle", "tooltip"); 925 button.setAttribute("data-bs-placement", "left"); 926 button.setAttribute("data-bs-title", "Copied!"); 927 tooltip = new bootstrap.Tooltip(button, 928 { trigger: "manual", 929 customClass: "code-copy-button-tooltip", 930 offset: [0, -8]}); 931 tooltip.show(); 932 } 933 setTimeout(function() { 934 if (tooltip) { 935 tooltip.hide(); 936 button.removeAttribute("data-bs-title"); 937 button.removeAttribute("data-bs-toggle"); 938 button.removeAttribute("data-bs-placement"); 939 } 940 button.setAttribute("title", currentTitle); 941 button.classList.remove('code-copy-button-checked'); 942 }, 1000); 943 // clear code selection 944 e.clearSelection(); 945 } 946 const getTextToCopy = function(trigger) { 947 const outerScaffold = trigger.parentElement.cloneNode(true); 948 const codeEl = outerScaffold.querySelector('code'); 949 for (const childEl of codeEl.children) { 950 if (isCodeAnnotation(childEl)) { 951 childEl.remove(); 952 } 953 } 954 return codeEl.innerText; 955 } 956 const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', { 957 text: getTextToCopy 958 }); 959 clipboard.on('success', onCopySuccess); 960 if (window.document.getElementById('quarto-embedded-source-code-modal')) { 961 const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', { 962 text: getTextToCopy, 963 container: window.document.getElementById('quarto-embedded-source-code-modal') 964 }); 965 clipboardModal.on('success', onCopySuccess); 966 } 967 var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); 968 var mailtoRegex = new RegExp(/^mailto:/); 969 var filterRegex = new RegExp("https:\/\/skewed\.de\/lab"); 970 var isInternal = (href) => { 971 return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); 972 } 973 // Inspect non-navigation links and adorn them if external 974 var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)'); 975 for (var i=0; i<links.length; i++) { 976 const link = links[i]; 977 if (!isInternal(link.href)) { 978 // undo the damage that might have been done by quarto-nav.js in the case of 979 // links that we want to consider external 980 if (link.dataset.originalHref !== undefined) { 981 link.href = link.dataset.originalHref; 982 } 983 } 984 } 985 function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) { 986 const config = { 987 allowHTML: true, 988 maxWidth: 500, 989 delay: 100,
990 arrow: false, 991 appendTo: function(el) { 992 return el.parentElement; 993 }, 994 interactive: true, 995 interactiveBorder: 10, 996 theme: 'quarto', 997 placement: 'bottom-start', 998 }; 999 if (contentFn) { 1000 config.content = contentFn; 1001 } 1002 if (onTriggerFn) { 1003 config.onTrigger = onTriggerFn; 1004 } 1005 if (onUntriggerFn) { 1006 config.onUntrigger = onUntriggerFn; 1007 } 1008 window.tippy(el, config); 1009 } 1010 const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); 1011 for (var i=0; i<noterefs.length; i++) { 1012 const ref = noterefs[i]; 1013 tippyHover(ref, function() { 1014 // use id or data attribute instead here 1015 let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href'); 1016 try { href = new URL(href).hash; } catch {} 1017 const id = href.replace(/^#\/?/, ""); 1018 const note = window.document.getElementById(id); 1019 if (note) { 1020 return note.innerHTML; 1021 } else { 1022 return ""; 1023 } 1024 }); 1025 } 1026 const xrefs = window.document.querySelectorAll('a.quarto-xref'); 1027 const processXRef = (id, note) => { 1028 // Strip column container classes 1029 const stripColumnClz = (el) => { 1030 el.classList.remove("page-full", "page-columns"); 1031 if (el.children) { 1032 for (const child of el.children) { 1033 stripColumnClz(child); 1034 } 1035 } 1036 } 1037 stripColumnClz(note) 1038 if (id === null || id.startsWith('sec-')) { 1039 // Special case sections, only their first couple elements 1040 const container = document.createElement("div"); 1041 if (note.children && note.children.length > 2) { 1042 container.appendChild(note.children[0].cloneNode(true)); 1043 for (let i = 1; i < note.children.length; i++) { 1044 const child = note.children[i]; 1045 if (child.tagName === "P" && child.innerText === "") { 1046 continue; 1047 } else { 1048 container.appendChild(child.cloneNode(true)); 1049 break; 1050 } 1051 } 1052 if (window.Quarto?.typesetMath) { 1053 window.Quarto.typesetMath(container); 1054 } 1055 return container.innerHTML 1056 } else { 1057 if (window.Quarto?.typesetMath) { 1058 window.Quarto.typesetMath(note); 1059 } 1060 return note.innerHTML; 1061 } 1062 } else { 1063 // Remove any anchor links if they are present 1064 const anchorLink = note.querySelector('a.anchorjs-link'); 1065 if (anchorLink) { 1066 anchorLink.remove(); 1067 } 1068 if (window.Quarto?.typesetMath) { 1069 window.Quarto.typesetMath(note); 1070 } 1071 if (note.classList.contains("callout")) { 1072 return note.outerHTML; 1073 } else { 1074 return note.innerHTML; 1075 } 1076 } 1077 } 1078 for (var i=0; i<xrefs.length; i++) { 1079 const xref = xrefs[i]; 1080 tippyHover(xref, undefined, function(instance) { 1081 instance.disable(); 1082 let url = xref.getAttribute('href'); 1083 let hash = undefined; 1084 if (url.startsWith('#')) { 1085 hash = url; 1086 } else { 1087 try { hash = new URL(url).hash; } catch {} 1088 } 1089 if (hash) { 1090 const id = hash.replace(/^#\/?/, ""); 1091 const note = window.document.getElementById(id); 1092 if (note !== null) { 1093 try { 1094 const html = processXRef(id, note.cloneNode(true)); 1095 instance.setContent(html); 1096 } finally { 1097 instance.enable(); 1098 instance.show(); 1099 } 1100 } else { 1101 // See if we can fetch this 1102 fetch(url.split('#')[0]) 1103 .then(res => res.text()) 1104 .then(html => { 1105 const parser = new DOMParser(); 1106 const htmlDoc = parser.parseFromString(html, "text/html"); 1107 const note = htmlDoc.getElementById(id); 1108 if (note !== null) { 1109 const html = processXRef(id, note); 1110 instance.setContent(html); 1111 } 1112 }).finally(() => { 1113 instance.enable(); 1114 instance.show(); 1115 }); 1116 } 1117 } else { 1118 // See if we can fetch a full url (with no hash to target)
1119 // This is a special case and we should probably do some content thinning / targeting 1120 fetch(url) 1121 .then(res => res.text()) 1122 .then(html => { 1123 const parser = new DOMParser(); 1124 const htmlDoc = parser.parseFromString(html, "text/html"); 1125 const note = htmlDoc.querySelector('main.content'); 1126 if (note !== null) { 1127 // This should only happen for chapter cross references 1128 // (since there is no id in the URL) 1129 // remove the first header 1130 if (note.children.length > 0 && note.children[0].tagName === "HEADER") { 1131 note.children[0].remove(); 1132 } 1133 const html = processXRef(null, note); 1134 instance.setContent(html); 1135 } 1136 }).finally(() => { 1137 instance.enable(); 1138 instance.show(); 1139 }); 1140 } 1141 }, function(instance) { 1142 }); 1143 } 1144 let selectedAnnoteEl; 1145 const selectorForAnnotation = ( cell, annotation) => { 1146 let cellAttr = 'data-code-cell="' + cell + '"'; 1147 let lineAttr = 'data-code-annotation="' + annotation + '"'; 1148 const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; 1149 return selector; 1150 } 1151 const selectCodeLines = (annoteEl) => { 1152 const doc = window.document; 1153 const targetCell = annoteEl.getAttribute("data-target-cell"); 1154 const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); 1155 const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); 1156 const lines = annoteSpan.getAttribute("data-code-lines").split(","); 1157 const lineIds = lines.map((line) => { 1158 return targetCell + "-" + line; 1159 }) 1160 let top = null; 1161 let height = null; 1162 let parent = null; 1163 if (lineIds.length > 0) { 1164 //compute the position of the single el (top and bottom and make a div) 1165 const el = window.document.getElementById(lineIds[0]); 1166 top = el.offsetTop; 1167 height = el.offsetHeight; 1168 parent = el.parentElement.parentElement; 1169 if (lineIds.length > 1) { 1170 const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); 1171 const bottom = lastEl.offsetTop + lastEl.offsetHeight; 1172 height = bottom - top; 1173 } 1174 if (top !== null && height !== null && parent !== null) { 1175 // cook up a div (if necessary) and position it 1176 let div = window.document.getElementById("code-annotation-line-highlight"); 1177 if (div === null) { 1178 div = window.document.createElement("div"); 1179 div.setAttribute("id", "code-annotation-line-highlight"); 1180 div.style.position = 'absolute'; 1181 parent.appendChild(div); 1182 } 1183 div.style.top = top - 2 + "px"; 1184 div.style.height = height + 4 + "px"; 1185 div.style.left = 0; 1186 let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); 1187 if (gutterDiv === null) { 1188 gutterDiv = window.document.createElement("div"); 1189 gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); 1190 gutterDiv.style.position = 'absolute'; 1191 const codeCell = window.document.getElementById(targetCell); 1192 const gutter = codeCell.querySelector('.code-annotation-gutter'); 1193 gutter.appendChild(gutterDiv); 1194 } 1195 gutterDiv.style.top = top - 2 + "px"; 1196 gutterDiv.style.height = height + 4 + "px"; 1197 } 1198 selectedAnnoteEl = annoteEl; 1199 } 1200 }; 1201 const unselectCodeLines = () => { 1202 const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; 1203 elementsIds.forEach((elId) => { 1204 const div = window.document.getElementById(elId); 1205 if (div) { 1206 div.remove(); 1207 } 1208 }); 1209 selectedAnnoteEl = undefined; 1210 }; 1211 // Handle positioning of the toggle 1212 window.addEventListener( 1213 "resize", 1214 throttle(() => { 1215 elRect = undefined; 1216 if (selectedAnnoteEl) { 1217 selectCodeLines(selectedAnnoteEl); 1218 } 1219 }, 10) 1220 ); 1221 function throttle(fn, ms) { 1222 let throttle = false;
1223 let timer; 1224 return (...args) => { 1225 if(!throttle) { // first call gets through 1226 fn.apply(this, args); 1227 throttle = true; 1228 } else { // all the others get throttled 1229 if(timer) clearTimeout(timer); // cancel #2 1230 timer = setTimeout(() => { 1231 fn.apply(this, args); 1232 timer = throttle = false; 1233 }, ms); 1234 } 1235 }; 1236 } 1237 // Attach click handler to the DT 1238 const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); 1239 for (const annoteDlNode of annoteDls) { 1240 annoteDlNode.addEventListener('click', (event) => { 1241 const clickedEl = event.target; 1242 if (clickedEl !== selectedAnnoteEl) { 1243 unselectCodeLines(); 1244 const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); 1245 if (activeEl) { 1246 activeEl.classList.remove('code-annotation-active'); 1247 } 1248 selectCodeLines(clickedEl); 1249 clickedEl.classList.add('code-annotation-active'); 1250 } else { 1251 // Unselect the line 1252 unselectCodeLines(); 1253 clickedEl.classList.remove('code-annotation-active'); 1254 } 1255 }); 1256 } 1257 const findCites = (el) => { 1258 const parentEl = el.parentElement; 1259 if (parentEl) { 1260 const cites = parentEl.dataset.cites; 1261 if (cites) { 1262 return { 1263 el, 1264 cites: cites.split(' ') 1265 }; 1266 } else { 1267 return findCites(el.parentElement) 1268 } 1269 } else { 1270 return undefined; 1271 } 1272 }; 1273 var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]'); 1274 for (var i=0; i<bibliorefs.length; i++) { 1275 const ref = bibliorefs[i]; 1276 const citeInfo = findCites(ref); 1277 if (citeInfo) { 1278 tippyHover(citeInfo.el, function() { 1279 var popup = window.document.createElement('div'); 1280 citeInfo.cites.forEach(function(cite) { 1281 var citeDiv = window.document.createElement('div'); 1282 citeDiv.classList.add('hanging-indent'); 1283 citeDiv.classList.add('csl-entry'); 1284 var biblioDiv = window.document.getElementById('ref-' + cite); 1285 if (biblioDiv) { 1286 citeDiv.innerHTML = biblioDiv.innerHTML; 1287 } 1288 popup.appendChild(citeDiv); 1289 }); 1290 return popup.innerHTML; 1291 }); 1292 } 1293 } 1294 }); 1295 </script>
1295 1296</div> <!-- /content --> 1297 1298 1299 1300
1301<script src="site_libs/quarto-html/zenscroll-min.js"></script>
1301 1302</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.