diff --git a/latest/.documenter-siteinfo.json b/latest/.documenter-siteinfo.json
index 1721311..7cb3b10 100644
--- a/latest/.documenter-siteinfo.json
+++ b/latest/.documenter-siteinfo.json
@@ -1 +1 @@
-{"documenter":{"julia_version":"1.11.0","generation_timestamp":"2024-10-11T14:36:05","documenter_version":"1.7.0"}}
\ No newline at end of file
+{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2024-12-28T15:30:03","documenter_version":"1.8.0"}}
\ No newline at end of file
diff --git a/latest/assets/documenter.js b/latest/assets/documenter.js
index 82252a1..7d68cd8 100644
--- a/latest/assets/documenter.js
+++ b/latest/assets/documenter.js
@@ -612,176 +612,194 @@ function worker_function(documenterSearchIndex, documenterBaseURL, filters) {
};
}
-// `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript!
-const filters = [
- ...new Set(documenterSearchIndex["docs"].map((x) => x.category)),
-];
-const worker_str =
- "(" +
- worker_function.toString() +
- ")(" +
- JSON.stringify(documenterSearchIndex["docs"]) +
- "," +
- JSON.stringify(documenterBaseURL) +
- "," +
- JSON.stringify(filters) +
- ")";
-const worker_blob = new Blob([worker_str], { type: "text/javascript" });
-const worker = new Worker(URL.createObjectURL(worker_blob));
-
/////// SEARCH MAIN ///////
-// Whether the worker is currently handling a search. This is a boolean
-// as the worker only ever handles 1 or 0 searches at a time.
-var worker_is_running = false;
-
-// The last search text that was sent to the worker. This is used to determine
-// if the worker should be launched again when it reports back results.
-var last_search_text = "";
-
-// The results of the last search. This, in combination with the state of the filters
-// in the DOM, is used compute the results to display on calls to update_search.
-var unfiltered_results = [];
-
-// Which filter is currently selected
-var selected_filter = "";
-
-$(document).on("input", ".documenter-search-input", function (event) {
- if (!worker_is_running) {
- launch_search();
- }
-});
-
-function launch_search() {
- worker_is_running = true;
- last_search_text = $(".documenter-search-input").val();
- worker.postMessage(last_search_text);
-}
-
-worker.onmessage = function (e) {
- if (last_search_text !== $(".documenter-search-input").val()) {
- launch_search();
- } else {
- worker_is_running = false;
- }
-
- unfiltered_results = e.data;
- update_search();
-};
+function runSearchMainCode() {
+ // `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript!
+ const filters = [
+ ...new Set(documenterSearchIndex["docs"].map((x) => x.category)),
+ ];
+ const worker_str =
+ "(" +
+ worker_function.toString() +
+ ")(" +
+ JSON.stringify(documenterSearchIndex["docs"]) +
+ "," +
+ JSON.stringify(documenterBaseURL) +
+ "," +
+ JSON.stringify(filters) +
+ ")";
+ const worker_blob = new Blob([worker_str], { type: "text/javascript" });
+ const worker = new Worker(URL.createObjectURL(worker_blob));
+
+ // Whether the worker is currently handling a search. This is a boolean
+ // as the worker only ever handles 1 or 0 searches at a time.
+ var worker_is_running = false;
+
+ // The last search text that was sent to the worker. This is used to determine
+ // if the worker should be launched again when it reports back results.
+ var last_search_text = "";
+
+ // The results of the last search. This, in combination with the state of the filters
+ // in the DOM, is used compute the results to display on calls to update_search.
+ var unfiltered_results = [];
+
+ // Which filter is currently selected
+ var selected_filter = "";
+
+ $(document).on("input", ".documenter-search-input", function (event) {
+ if (!worker_is_running) {
+ launch_search();
+ }
+ });
-$(document).on("click", ".search-filter", function () {
- if ($(this).hasClass("search-filter-selected")) {
- selected_filter = "";
- } else {
- selected_filter = $(this).text().toLowerCase();
+ function launch_search() {
+ worker_is_running = true;
+ last_search_text = $(".documenter-search-input").val();
+ worker.postMessage(last_search_text);
}
- // This updates search results and toggles classes for UI:
- update_search();
-});
+ worker.onmessage = function (e) {
+ if (last_search_text !== $(".documenter-search-input").val()) {
+ launch_search();
+ } else {
+ worker_is_running = false;
+ }
-/**
- * Make/Update the search component
- */
-function update_search() {
- let querystring = $(".documenter-search-input").val();
+ unfiltered_results = e.data;
+ update_search();
+ };
- if (querystring.trim()) {
- if (selected_filter == "") {
- results = unfiltered_results;
+ $(document).on("click", ".search-filter", function () {
+ if ($(this).hasClass("search-filter-selected")) {
+ selected_filter = "";
} else {
- results = unfiltered_results.filter((result) => {
- return selected_filter == result.category.toLowerCase();
- });
+ selected_filter = $(this).text().toLowerCase();
}
- let search_result_container = ``;
- let modal_filters = make_modal_body_filters();
- let search_divider = `
`;
+ // This updates search results and toggles classes for UI:
+ update_search();
+ });
- if (results.length) {
- let links = [];
- let count = 0;
- let search_results = "";
-
- for (var i = 0, n = results.length; i < n && count < 200; ++i) {
- let result = results[i];
- if (result.location && !links.includes(result.location)) {
- search_results += result.div;
- count++;
- links.push(result.location);
- }
- }
+ /**
+ * Make/Update the search component
+ */
+ function update_search() {
+ let querystring = $(".documenter-search-input").val();
- if (count == 1) {
- count_str = "1 result";
- } else if (count == 200) {
- count_str = "200+ results";
+ if (querystring.trim()) {
+ if (selected_filter == "") {
+ results = unfiltered_results;
} else {
- count_str = count + " results";
+ results = unfiltered_results.filter((result) => {
+ return selected_filter == result.category.toLowerCase();
+ });
}
- let result_count = `
${count_str}
`;
- search_result_container = `
+ let search_result_container = ``;
+ let modal_filters = make_modal_body_filters();
+ let search_divider = ``;
+
+ if (results.length) {
+ let links = [];
+ let count = 0;
+ let search_results = "";
+
+ for (var i = 0, n = results.length; i < n && count < 200; ++i) {
+ let result = results[i];
+ if (result.location && !links.includes(result.location)) {
+ search_results += result.div;
+ count++;
+ links.push(result.location);
+ }
+ }
+
+ if (count == 1) {
+ count_str = "1 result";
+ } else if (count == 200) {
+ count_str = "200+ results";
+ } else {
+ count_str = count + " results";
+ }
+ let result_count = `
`;
+function waitUntilSearchIndexAvailable() {
+ // It is possible that the documenter.js script runs before the page
+ // has finished loading and documenterSearchIndex gets defined.
+ // So we need to wait until the search index actually loads before setting
+ // up all the search-related stuff.
+ if (typeof documenterSearchIndex !== "undefined") {
+ runSearchMainCode();
+ } else {
+ console.warn("Search Index not available, waiting");
+ setTimeout(waitUntilSearchIndexAvailable, 1000);
+ }
}
+// The actual entry point to the search code
+waitUntilSearchIndexAvailable();
+
})
////////////////////////////////////////////////////////////////////////////////
require(['jquery'], function($) {
diff --git a/latest/compute/index.html b/latest/compute/index.html
index 1384999..1d04702 100644
--- a/latest/compute/index.html
+++ b/latest/compute/index.html
@@ -1,2 +1,2 @@
-On Solvers and Computation Time · Circuitscape.jl Documentation
We have tested this code on landscapes with up to 437 million cells. Increasing numbers of connections using diagonal (eight neighbor) connections will decrease the size of landscapes that can be analyzed. Also, increasing landscape size or numbers of focal nodes will increase computation time. We anticipate future improvements will increase the program's speed. Note that due to the matrix algebra involved with solving many pairs of focal nodes, Circuitscape will run much faster when focal points (each focal node falls within only one grid cell), rather than focal regions (at least one focal node occupies multiple grid cells), are used.
There are several ways to increase the solvable grid size. These include closing all other programs (especially those that require lots of RAM such as ArcGIS), setting impermeable areas of your resistance map to NODATA, using focal points instead of regions in pairwise mode, connecting cells to their four neighbors only, and not creating current maps. Also, the one-to-all and all- to-one modes typically use less memory (and run more quickly) than the pairwise mode. In particular, the all-to-one mode can be an alternative to the pairwise mode when the goal is to produce a cumulative map of important connectivity areas among multiple source/target patches. Still, coarsening your grids (using larger cell sizes) may be necessary; doing so often produces results that are qualitatively similar to those obtained with smaller cell sizes. See McRae et al. 2008 for details of effects of using coarser grids.
Settings
This document was generated with Documenter.jl version 1.7.0 on Friday 11 October 2024. Using Julia version 1.11.0.
+On Solvers and Computation Time · Circuitscape.jl Documentation
We have tested this code on landscapes with up to 437 million cells. Increasing numbers of connections using diagonal (eight neighbor) connections will decrease the size of landscapes that can be analyzed. Also, increasing landscape size or numbers of focal nodes will increase computation time. We anticipate future improvements will increase the program's speed. Note that due to the matrix algebra involved with solving many pairs of focal nodes, Circuitscape will run much faster when focal points (each focal node falls within only one grid cell), rather than focal regions (at least one focal node occupies multiple grid cells), are used.
There are several ways to increase the solvable grid size. These include closing all other programs (especially those that require lots of RAM such as ArcGIS), setting impermeable areas of your resistance map to NODATA, using focal points instead of regions in pairwise mode, connecting cells to their four neighbors only, and not creating current maps. Also, the one-to-all and all- to-one modes typically use less memory (and run more quickly) than the pairwise mode. In particular, the all-to-one mode can be an alternative to the pairwise mode when the goal is to produce a cumulative map of important connectivity areas among multiple source/target patches. Still, coarsening your grids (using larger cell sizes) may be necessary; doing so often produces results that are qualitatively similar to those obtained with smaller cell sizes. See McRae et al. 2008 for details of effects of using coarser grids.
Settings
This document was generated with Documenter.jl version 1.8.0 on Saturday 28 December 2024. Using Julia version 1.11.2.
diff --git a/latest/index.html b/latest/index.html
index 15efc14..9e8e942 100644
--- a/latest/index.html
+++ b/latest/index.html
@@ -11,4 +11,4 @@
author = {Ranjan Anantharaman and Kimberly Hall and Viral B. Shah and Alan Edelman},
title = {Circuitscape in Julia: High Performance Connectivity Modelling to Support Conservation Decisions},
journal = {Proceedings of the JuliaCon Conferences}
-}
The new Circuitscape is built entirely in the Julia language, a new programming language for technical computing. Julia is built from the ground up to be fast. As such, this offers a number of advantages over the previous version, and these are detailed below.
We benchmarked Circuitscape.jl (v0.1.0) with the Python version (v4.0.5) to obtain the following results. We started up Circuitscape with 16 parallel processes, and used benchmark problems from the standard Circuitscape benchmark suite.
These benchmarks were run on a Linux (Ubuntu) server machine with the following specs:
Name: Intel(R) Xeon(R) Silver 4114 CPU
Clock Speed: 2.20GHz
Number of cores: 20
RAM: 384 GB
From the benchmark, we see that the new version is upto 4x faster on 16 processes. However, the best performing bar in the chart is Julia-CHOLMOD, which is a new feature introduced.
Julia-CHOLMOD is a new solver mode used in the new Circuitscape. It performs a cholesky decomposition on the graph constructed, and performs a batched back substitution to compute the voltages. It plugs into the CHOLMOD library, which is part of the SuiteSparse collection of high performance sparse matrix algorithms.
To use the this new mode, include a line in your Circuitscape INI file:
solver = cholmod
The cholesky decomposition is a direct solver method, unlike the algebraic multigrid method used by default in both the old and the new version. The advantage with this new direct method is that it can be much faster than the iterative solution, within a particular problem size.
Word of caution: The cholesky decomposition is not practical to use beyond a certain problem size because of phenomenon called fill-in, which results in loss of sparsity and large memory consumption.
The old Circuitscape had limited support for parallelism, which worked on Mac and Linux, but didn't work on Windows.
Julia as a programming language is built from the ground up to be parallel, and as a result the new Circuitscape natively supports parallelism on all three platforms.
Beier, P., W. Spencer, R. Baldwin, and B.H. McRae. 2011. Best science practices for developing regional connectivity maps. Conservation Biology 25(5): 879-892
Dickson B.G., G.W. Roemer, B.H. McRae, and J.M. Rundall. 2013. Models of regional habitat quality and connectivity for pumas (Puma concolor) in the southwestern United States. PLoS ONE 8(12): e81898. doi:10.1371/journal.pone.0081898
McRae, B.H. 2006. Isolation by resistance. Evolution 60:1551-1561.
McRae, B.H. and P. Beier. 2007. Circuit theory predicts Gene flow in plant and animal populations. Proceedings of the National Academy of Sciences of the USA 104:19885-19890.
McRae, B.H., B.G. Dickson, T.H. Keitt, and V.B. Shah. 2008. Using circuit theory to model connectivity in ecology and conservation. Ecology 10: 2712-2724.
Shah, V.B. 2007. An Interactive System for Combinatorial Scientific Computing with an Emphasis on Programmer Productivity. PhD thesis, University of California, Santa Barbara.
Shah,V.B. and B.H. McRae. 2008. Circuitscape: a tool for landscape ecology. In: G. Varoquaux, T. Vaught, J. Millman (Eds.). Proceedings of the 7th Python in Science Conference (SciPy 2008), pp. 62-66.
Spear, S.F., N. Balkenhol, M.-J. Fortin, B.H. McRae and K. Scribner. 2010. Use of resistance surfaces for landscape genetic studies: Considerations of parameterization and analysis. Molecular Ecology 19(17): 3576-3591.
Zeller K.A., McGarigal K., and Whiteley A.R. 2012. Estimating landscape resistance to movement: a review. Landscape Ecology 27: 777-797.
Settings
This document was generated with Documenter.jl version 1.7.0 on Friday 11 October 2024. Using Julia version 1.11.0.