diff --git a/.github/htmldocs/index.html b/.github/htmldocs/index.html index b39f850..85484c6 100644 --- a/.github/htmldocs/index.html +++ b/.github/htmldocs/index.html @@ -58,6 +58,10 @@
+
+ 📖 User Guide
+
+
📚 Docs |
📊 Benchmarks
diff --git a/.github/workflows/docs-and-testcov.yml b/.github/workflows/docs-and-testcov.yml
index 3b40067..7f15bfc 100644
--- a/.github/workflows/docs-and-testcov.yml
+++ b/.github/workflows/docs-and-testcov.yml
@@ -153,7 +153,6 @@ jobs:
echo "" > target/doc/rustframe/index.html
- mkdir output
cp tarpaulin-report.html target/doc/docs/
cp tarpaulin-report.json target/doc/docs/
cp tarpaulin-badge.json target/doc/docs/
@@ -166,16 +165,32 @@ jobs:
# copy the benchmark report to the output directory
cp -r benchmark-report target/doc/
+ mkdir output
+ cp -r target/doc/* output/
+
+ - name: Build user guide
+ run: |
+ cargo binstall mdbook -q
+ cd docs
+ ./build.sh
+ cd ..
+
+ - name: Copy user guide to output directory
+ run: |
+ mkdir output/user-guide
+ cp -r docs/book/* output/user-guide/
+
- name: Add index.html to output directory
run: |
- cp .github/htmldocs/index.html target/doc/index.html
- cp .github/rustframe_logo.png target/doc/rustframe_logo.png
+ cp .github/htmldocs/index.html output/index.html
+ cp .github/rustframe_logo.png output/rustframe_logo.png
- name: Upload Pages artifact
# if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: actions/upload-pages-artifact@v3
with:
- path: target/doc/
+ # path: target/doc/
+ path: output/
- name: Deploy to GitHub Pages
# if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
diff --git a/.github/workflows/run-unit-tests.yml b/.github/workflows/run-unit-tests.yml
index 0f4ae0b..b62f02a 100644
--- a/.github/workflows/run-unit-tests.yml
+++ b/.github/workflows/run-unit-tests.yml
@@ -78,3 +78,10 @@ jobs:
uses: codecov/test-results-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
+
+ - name: Test build user guide
+ run: |
+ cargo binstall mdbook -q
+ cd docs
+ ./build.sh
+ cd ..
diff --git a/.gitignore b/.gitignore
index ac6b27b..5198bcf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,4 +16,6 @@ data/
tarpaulin-report.*
-.github/htmldocs/rustframe_logo.png
\ No newline at end of file
+.github/htmldocs/rustframe_logo.png
+
+docs/book/
\ No newline at end of file
diff --git a/docs/book.toml b/docs/book.toml
new file mode 100644
index 0000000..2de58a0
--- /dev/null
+++ b/docs/book.toml
@@ -0,0 +1,7 @@
+[book]
+title = "RustFrame User Guide"
+author = ["RustFrame Contributors"]
+description = "Guided journey through RustFrame capabilities."
+
+[build]
+build-dir = "book"
diff --git a/docs/build.sh b/docs/build.sh
new file mode 100755
index 0000000..e67049f
--- /dev/null
+++ b/docs/build.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env sh
+# Build and test the RustFrame user guide using mdBook.
+set -e
+# Ensure the library is compiled so examples can link against it.
+
+cargo clean
+
+cargo build --manifest-path ../Cargo.toml
+# Run embedded code examples as tests.
+mdbook test -L ../target/debug/deps "$@"
+# Finally, render the book.
+mdbook build "$@"
+
+cargo build
+cargo build --release
diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md
new file mode 100644
index 0000000..4479e5d
--- /dev/null
+++ b/docs/src/SUMMARY.md
@@ -0,0 +1,7 @@
+# Summary
+
+- [Introduction](./introduction.md)
+- [Data Manipulation](./data-manipulation.md)
+- [Compute Features](./compute.md)
+- [Machine Learning](./machine-learning.md)
+- [Utilities](./utilities.md)
diff --git a/docs/src/compute.md b/docs/src/compute.md
new file mode 100644
index 0000000..33b9d6e
--- /dev/null
+++ b/docs/src/compute.md
@@ -0,0 +1,31 @@
+# Compute Features
+
+The `compute` module provides statistical routines like descriptive
+statistics and correlation measures.
+
+## Basic Statistics
+
+```rust
+# extern crate rustframe;
+use rustframe::compute::stats::{mean, stddev};
+use rustframe::matrix::Matrix;
+
+let m = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
+let mean_val = mean(&m);
+let std_val = stddev(&m);
+```
+
+## Correlation
+
+```rust
+# extern crate rustframe;
+use rustframe::compute::stats::pearson;
+use rustframe::matrix::Matrix;
+
+let x = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
+let y = Matrix::from_vec(vec![2.0, 4.0, 6.0, 8.0], 2, 2);
+let corr = pearson(&x, &y);
+```
+
+With the basics covered, explore predictive models in the
+[machine learning](./machine-learning.md) chapter.
diff --git a/docs/src/data-manipulation.md b/docs/src/data-manipulation.md
new file mode 100644
index 0000000..34aa99c
--- /dev/null
+++ b/docs/src/data-manipulation.md
@@ -0,0 +1,43 @@
+# Data Manipulation
+
+RustFrame's `Frame` type couples tabular data with
+column labels and a typed row index.
+
+## Creating a Frame
+
+```rust
+# extern crate rustframe;
+use rustframe::frame::{Frame, RowIndex};
+use rustframe::matrix::Matrix;
+
+let data = Matrix::from_cols(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
+let frame = Frame::new(data, vec!["A", "B"], None);
+assert_eq!(frame["A"], vec![1.0, 2.0]);
+```
+
+## Indexing Rows
+
+```rust
+# extern crate rustframe;
+use rustframe::frame::{Frame, RowIndex};
+use rustframe::matrix::Matrix;
+
+let data = Matrix::from_cols(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
+let index = RowIndex::Int(vec![10, 20]);
+let frame = Frame::new(data, vec!["A", "B"], Some(index));
+assert_eq!(frame.get_row(20)["B"], 4.0);
+```
+
+## Aggregations
+
+```rust
+# extern crate rustframe;
+use rustframe::frame::Frame;
+use rustframe::matrix::{Matrix, SeriesOps};
+
+let frame = Frame::new(Matrix::from_cols(vec![vec![1.0, 2.0]]), vec!["A"], None);
+assert_eq!(frame.sum_vertical(), vec![3.0]);
+```
+
+When you're ready to run analytics, continue to the
+[compute features](./compute.md) chapter.
diff --git a/docs/src/introduction.md b/docs/src/introduction.md
new file mode 100644
index 0000000..f3b49b6
--- /dev/null
+++ b/docs/src/introduction.md
@@ -0,0 +1,15 @@
+# Introduction
+
+Welcome to the **RustFrame User Guide**. This book provides a tour of
+RustFrame's capabilities from basic data handling to advanced machine learning
+workflows. Each chapter contains runnable snippets so you can follow along.
+
+To build this guide locally run `./build.sh` in the `docs/` directory. The
+chapters are arranged sequentially:
+
+1. [Data manipulation](./data-manipulation.md) for loading and transforming data.
+2. [Compute features](./compute.md) for statistics and analytics.
+3. [Machine learning](./machine-learning.md) for predictive models.
+4. [Utilities](./utilities.md) for supporting helpers and upcoming modules.
+
+Let's begin with some tabular data!
diff --git a/docs/src/machine-learning.md b/docs/src/machine-learning.md
new file mode 100644
index 0000000..1694da8
--- /dev/null
+++ b/docs/src/machine-learning.md
@@ -0,0 +1,39 @@
+# Machine Learning
+
+RustFrame ships with several algorithms:
+
+- Linear and logistic regression
+- K-means clustering
+- Principal component analysis (PCA)
+- Naive Bayes and dense neural networks
+
+## Linear Regression
+
+```rust
+# extern crate rustframe;
+use rustframe::compute::models::linreg::LinReg;
+use rustframe::matrix::Matrix;
+
+let x = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0], 4, 1);
+let y = Matrix::from_vec(vec![2.0, 3.0, 4.0, 5.0], 4, 1);
+let mut model = LinReg::new(1);
+model.fit(&x, &y, 0.01, 100);
+let preds = model.predict(&x);
+assert_eq!(preds.rows(), 4);
+```
+
+## K-means Walkthrough
+
+```rust
+# extern crate rustframe;
+use rustframe::compute::models::k_means::KMeans;
+use rustframe::matrix::Matrix;
+
+let data = Matrix::from_vec(vec![1.0, 1.0, 5.0, 5.0], 2, 2);
+let (model, _labels) = KMeans::fit(&data, 2, 10, 1e-4);
+let new_point = Matrix::from_vec(vec![0.0, 0.0], 1, 2);
+let cluster = model.predict(&new_point)[0];
+```
+
+For helper functions and upcoming modules, visit the
+[utilities](./utilities.md) section.
diff --git a/docs/src/utilities.md b/docs/src/utilities.md
new file mode 100644
index 0000000..1bed694
--- /dev/null
+++ b/docs/src/utilities.md
@@ -0,0 +1,24 @@
+# Utilities
+
+Utilities provide handy helpers around the core library. Existing tools
+include:
+
+- Date utilities for generating calendar sequences.
+
+## Date Helpers
+
+```rust
+# extern crate rustframe;
+use rustframe::utils::dateutils::{DatesList, DateFreq};
+
+let list = DatesList::new("2024-01-01".into(), "2024-01-03".into(), DateFreq::Daily);
+assert_eq!(list.count().unwrap(), 3);
+```
+
+Upcoming utilities will cover:
+
+- Data import/export helpers
+- Visualization adapters
+- Streaming data interfaces
+
+Contributions to these sections are welcome!