mirror of
https://github.com/boostorg/website-v2-docs.git
synced 2026-01-19 04:42:17 +00:00
Scenarios in User Guide - nits and minutia (#430)
This commit is contained in:
@@ -49,7 +49,7 @@ Here are some Boost libraries that might be useful when planning and building yo
|
||||
|
||||
A database engine requires efficient data structures for handling indexes, caches, and storage layouts. The boost:container[] library provides drop-in replacements for standard containers like `std::vector`, `std::map`, and `std::unordered_map`, but optimized for memory efficiency and performance.
|
||||
|
||||
In the following sample code, we will use in-memory indexing as the basis of a database engine. The boost:container[] `flat_map` feature is used to store a sorted index for quick lookups, and the `stable_vector` feature to store persistent records with stable pointers. The sample simulates inserting and retrieving records efficiently.
|
||||
In the following sample code, we will use in-memory indexing as the basis of a database engine. The boost:container[] `flat_map` feature is used to store a sorted index for quick lookups, and the `stable_vector` feature to store persistent records with stable pointers. The sample demonstrates inserting and retrieving records efficiently.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
@@ -330,7 +330,7 @@ Note:: The sample now avoids manual memory management, prevents race conditions
|
||||
|
||||
== Create a Thread-safe Queue for Inter-thread Communication
|
||||
|
||||
With multiple apps or processes now accessing our database, would seem like a good idea to avoid locks or bottlenecks. boost:lockfree[] offers message queues and pre-allocated ring buffers for this purpose.
|
||||
With multiple apps or processes now accessing our database, would seem like a good idea to avoid locks or bottlenecks. boost:lockfree[] offers _message queues_ and _pre-allocated ring buffers_ for this purpose.
|
||||
|
||||
|
||||
[source,cpp]
|
||||
|
||||
@@ -74,7 +74,7 @@ Here are some widely used and robust algorithms, each having its own strengths a
|
||||
The following sample demonstrating the use of boost:numeric/ublas[] for matrix operations and boost:multiprecision[] for high-precision arithmetic (ensures 50-digit precision for matrix calculations). This is useful in machine learning applications where precision is critical, such as when dealing with ill-conditioned matrices or when high numerical accuracy is needed.
|
||||
|
||||
[#footnote3-location]
|
||||
Randomized values are commonly used in machine language algorithms, such as Stochastic Gradient Descent (Neural networks and logistic regression), Monte Carlo simulations (simulating stochastic processes like Bayesian inference or Markov chains link:#footnote3[(3)]), and neural network weight initialization. So we'll also engage the features of boost:random[].
|
||||
Randomized values are commonly used in machine language algorithms, such as _Stochastic Gradient Descent_ (Neural networks and logistic regression), _Monte Carlo simulations_ (simulating stochastic processes like _Bayesian inference_ or _Markov chains_ link:#footnote3[(3)]), and neural network weight initialization. So we'll also engage the features of boost:random[].
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
@@ -131,7 +131,7 @@ The weight update rule is:
|
||||
image::stochastic-equation.png[Stochastic Gradient Descent]
|
||||
|
||||
[#footnote4-location]
|
||||
Neural networks train with SGD and the many variants of the algorithm (such as Adam, RMSprop, and the alternative Batch Gradient Descent link:#footnote4[(4)]). This approach is efficient for big data and real-time learning.
|
||||
Neural networks train with SGD and the many variants of the algorithm (such as _Adam_, _RMSprop_, and the alternative _Batch Gradient Descent_ link:#footnote4[(4)]). This approach is efficient for big data and real-time learning.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
@@ -202,7 +202,7 @@ int main() {
|
||||
|
||||
== Add K-Means Clustering with a Real Dataset
|
||||
|
||||
Let's add K-Means Clustering to group data points into clusters. The statistical functions of boost:math[] measure Euclidean distances that are the basis of K-Means clustering, a centroid-based clustering algorithm that partitions data into K clusters based on the nearest mean (centroid).
|
||||
Let's add _K-Means Clustering_ to group data points into clusters. The statistical functions of boost:math[] measure Euclidean distances that are the basis of K-Means clustering, which is a centroid-based clustering algorithm that partitions data into K clusters based on the nearest mean (centroid).
|
||||
|
||||
The clustering algorithm goes through the following cycle:
|
||||
|
||||
@@ -211,7 +211,7 @@ The clustering algorithm goes through the following cycle:
|
||||
. Recalculates centroids
|
||||
. Repeats (go back to step 2) until convergence
|
||||
|
||||
We'll use the Iris dataset, a well-known sample dataset in machine learning containing 150 flower samples with four features (sepal length, sepal width, petal length, petal width) and three species. This dataset is loaded from a CSV file.
|
||||
We'll use the Iris dataset, a well-known sample dataset in machine learning containing 150 flower samples with four features (sepal length, sepal width, petal length, petal width) and three species (setosa, versicolor, and virginica). This dataset is loaded from a CSV file.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
@@ -358,7 +358,7 @@ int main() {
|
||||
|
||||
Save the following as *iris_data.csv*, a test sample, (or download https://archive.ics.uci.edu/dataset/53/iris[Iris]):
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
5.1,3.5,1.4,0.2,setosa
|
||||
4.9,3.0,1.4,0.2,setosa
|
||||
|
||||
@@ -189,7 +189,7 @@ The beauty of this approach is that you can just add more types to the tuple, an
|
||||
|
||||
Let's extend the sample to integrate boost:type-traits[] to determine if a type is serializable at compile time. The functions we will use are `is_arithmetic<T>` to check if `T` is a number type (`int`, `double`, etc.), and `is_class<T>` to check if `T` is a user-defined class (`Person`, etc.). The idea is that the compile-time filtering ensures that the code can only process serializable types.
|
||||
|
||||
Note:: `void` is an example of a non-serializable type.
|
||||
Note:: A `void` is an example of a non-serializable type.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
@@ -284,7 +284,7 @@ boost:hana[] adds efficient tuple handling at runtime (for example, easier acces
|
||||
| Better Compile-Time Speed | Yes | No, Slower
|
||||
|===
|
||||
|
||||
Let's update our sample to include tag dispatching, so each type is classified at compile time, and runtime tuple processing, so the sample iterates over heterogeneous types at runtime.
|
||||
Let's update our sample to include _tag dispatching_, so each type is classified at compile time, and _runtime tuple processing_, so the sample iterates over heterogeneous types at runtime.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
@@ -364,7 +364,7 @@ Serializing (Custom Struct) -> { Name: Alice, Age: 30 }
|
||||
|
||||
== Add Type-traits Filtering
|
||||
|
||||
Type filtering will allow us to selectively process elements of the tuple based on type traits, filtering out elements that don't match a given criterion.
|
||||
_Type filtering_ will allow us to selectively process elements of the tuple based on type traits, filtering out elements that don't match a given criterion.
|
||||
|
||||
In the following code, `hana::filter` removes non-serializable types, for example the `nullptr` value is ignored. Only arithmetic, `std::string`, and custom structs are processed.
|
||||
|
||||
@@ -477,7 +477,7 @@ using my_types = boost::mp11::mp_list<int, double, std::string>;
|
||||
|
||||
This `mp_list` is a type-level tuple that can be manipulated without creating runtime instances.
|
||||
|
||||
Unlike `std::tuple`, which holds actual values, metaprogramming tuples operate entirely at the type level, making them essential for zero-runtime-cost template metaprogramming.
|
||||
Unlike `std::tuple`, which holds actual values, metaprogramming tuples operate entirely at the type level, making them invaluable for zero-runtime-cost template metaprogramming.
|
||||
|
||||
== See Also
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ Natural language parsing (NLP) is a foundational technology that powers many mo
|
||||
|
||||
== Simple English Parsing Sample
|
||||
|
||||
Say we wanted to parse a subset of the English language, only sentence of the form: The <adjective> <noun> <verb>. Example sentences could be "The quick fox jumps." or "The lazy dog sleeps."
|
||||
Say we wanted to parse a subset of the English language, only sentences of the form: The <adjective> <noun> <verb>. Example sentences could be "The quick fox jumps." or "The lazy dog sleeps."
|
||||
|
||||
If the input matches this grammar, the following parser will accept it. Otherwise, it rejects the input.
|
||||
|
||||
@@ -112,7 +112,7 @@ int main() {
|
||||
|
||||
The following shows a successful parse:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence (format: The <adjective> <noun> <verb>.)
|
||||
The happy cat purrs.
|
||||
@@ -122,7 +122,7 @@ Valid sentence!
|
||||
|
||||
And the following shows an unsuccessful parse:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence (format: The <adjective> <noun> <verb>.)
|
||||
A small dog runs.
|
||||
@@ -134,7 +134,7 @@ Our subset is clearly very limited, as simply replacing the word "The" with "A"
|
||||
|
||||
== Add a Dictionary of Valid Words
|
||||
|
||||
We can extend the simple example to use a dictionary of valid words, allow multiple adjectives, and use https://www.boost.org/doc/libs/1_82_0/doc/html/string_algo.html[Boost.String_Algo] for some string processing tasks (trimming spaces, converting to lowercase).
|
||||
We can extend the simple example to use a dictionary of valid words, allow multiple adjectives, and use boost:algorithm[] for some string processing tasks (trimming spaces, converting to lowercase).
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
@@ -210,7 +210,7 @@ int main() {
|
||||
|
||||
The following shows a successful parse:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence (e.g., The big brown fox jumps.):
|
||||
The big brown fox jumps.
|
||||
@@ -220,7 +220,7 @@ The big brown fox jumps.
|
||||
|
||||
And the following shows an unsuccessful parse:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence (e.g., The big brown fox jumps.):
|
||||
The huge blue dragon flies.
|
||||
@@ -230,6 +230,8 @@ The huge blue dragon flies.
|
||||
|
||||
== Add Detailed Error Reporting
|
||||
|
||||
Let's not forget to provide useful error messages:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
#include <iostream>
|
||||
@@ -327,7 +329,7 @@ int main() {
|
||||
|
||||
The following shows a successful parse:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence (e.g., The big brown fox jumps.):
|
||||
The big brown fox jumps.
|
||||
@@ -337,7 +339,7 @@ The big brown fox jumps.
|
||||
|
||||
And the following shows several unsuccessful parses:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence (e.g., The big brown fox jumps.):
|
||||
The huge blue dragon flies.
|
||||
@@ -357,7 +359,7 @@ The big brown fox flies.
|
||||
|
||||
----
|
||||
|
||||
You will notice how adding more features to a natural language parser starts to considerably increase the code length. This is a normal feature of language parsing - a lot of code can be required to cover all the options of something as flexible as language. For an example of a simpler approach to parsing well-formatted input, refer to the sample code in xref:task-text-processing.adoc[].
|
||||
You will notice how adding more features to a natural language parser starts to considerably increase the code length. This is a normal feature of language parsing - a lot of code can be required to cover all the options of something as flexible as language. For an example of a simpler approach to parsing _well-formatted_ input, refer to the sample code in xref:task-text-processing.adoc[].
|
||||
|
||||
== See Also
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ Here are the libraries that are most directly applicable to a networking app:
|
||||
|
||||
The following code is a simple networking chat application using boost:asio[] that allows two computers to send messages to each other over TCP.
|
||||
|
||||
This example assumes that you know the IP addresses (URLs) of both computers, and can set one as the server and the other as the client. The server listens for incoming connections, the client must connect to the server to communicate, and messages are exchanged asynchronously between the two computers.
|
||||
This example assumes that you know the IP address (URL) of one of the computers - to set as the server - and the other computer will act as the client. The server listens for incoming connections, the client must connect to the server to communicate, and messages are exchanged asynchronously between the two computers.
|
||||
|
||||
=== Server App
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ int main() {
|
||||
|
||||
== Thread-pool Sample
|
||||
|
||||
Starting with the multi-threaded code above. If we engage the thread management features of boost:asio[], and the thread-safe counting of boost:atomic[], we reduce the need to manually handle the management of threads. In particular the updated sample:
|
||||
Starting with the multi-threaded code above. If we engage the thread management features of boost:asio[], and the thread-safe counting of boost:atomic[], we reduce the need to manually handle the management of threads. In particular, the updated sample:
|
||||
|
||||
* Uses `boost::asio::thread_pool` instead of manually managing threads.
|
||||
* Handles atomic operations with `boost::atomic` for thread-safe counters.
|
||||
@@ -302,7 +302,7 @@ int main() {
|
||||
|
||||
If you compile and run this sample, the following would be a typical session!
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Foreground: Type 'quit' to exit, 'add' to add a task, 'msg <text>' to send a message.
|
||||
add
|
||||
@@ -317,6 +317,8 @@ All tasks completed. Program shutting down.
|
||||
|
||||
----
|
||||
|
||||
Parallel computing is an exciting challenge - success should come from focusing on problems that are inherently parallel.
|
||||
|
||||
== See Also
|
||||
|
||||
* https://www.boost.org/doc/libs/1_87_0/libs/libraries.htm#Concurrent[Category: Concurrent Programming]
|
||||
|
||||
@@ -378,7 +378,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
----
|
||||
|
||||
Note:: Measures execution time in microseconds for each operation.
|
||||
Note:: This code measures execution time in microseconds for each operation.
|
||||
|
||||
The following is example output from running our sample.
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ Here are some Boost libraries that might assist you in processing text:
|
||||
|
||||
== Sample of Regular Expression Parsing
|
||||
|
||||
If the text you are parsing is well-formatted then you can use boost:regex[], rather than a full-blown parser implementation using boost:spirit[].
|
||||
If the text you are parsing is well-formatted then you can use boost:regex[] which we will base our sample on here, rather than a full-blown parser implementation using boost:spirit[].
|
||||
|
||||
We'll write a program that scans a string for dates in the format "YYYY-MM-DD" and validates them. The code:
|
||||
|
||||
@@ -117,7 +117,7 @@ int main() {
|
||||
|
||||
The following shows a successful parse:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence containing dates (YYYY-MM-DD format):
|
||||
Today is 2024-02-19, and tomorrow is 2024-02-20.
|
||||
@@ -128,7 +128,7 @@ Today is 2024-02-19, and tomorrow is 2024-02-20.
|
||||
|
||||
And the following shows several unsuccessful parses:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence containing dates (YYYY-MM-DD format):
|
||||
The deadline is 2024-02-30.
|
||||
@@ -142,7 +142,7 @@ There are no dates in this sentence.
|
||||
|
||||
== Add Robust Date and Time Parsing
|
||||
|
||||
The date validation in the sample above can be improved integrating boost:date_time[], which provides tools for handling dates and times correctly.
|
||||
The clunky date validation in the sample above can be improved by integrating boost:date_time[], which provides functions for handling dates and times correctly.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
@@ -209,7 +209,7 @@ Note:: The code handles leap years correctly, and invalid dates throw an excepti
|
||||
|
||||
The following shows a successful parse:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence containing dates (YYYY-MM-DD format):
|
||||
Today is 2024-02-29, and tomorrow is 2024-03-01.
|
||||
@@ -222,7 +222,7 @@ Note:: The "Valid date found" output now includes text for the month name.
|
||||
|
||||
And the following shows several unsuccessful parses:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence containing dates (YYYY-MM-DD format):
|
||||
The deadline is 2024-02-30.
|
||||
@@ -326,7 +326,7 @@ int main() {
|
||||
|
||||
The following shows successful parses:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence containing dates (YYYY-MM-DD format):
|
||||
The meeting is on 2024-03-15.
|
||||
@@ -344,7 +344,7 @@ Enter your preferred locale (e.g., en_US.UTF-8, fr_FR.UTF-8, de_DE.UTF-8): fr_FR
|
||||
|
||||
And the following shows an unsuccessful parse:
|
||||
|
||||
[source,bash]
|
||||
[source,text]
|
||||
----
|
||||
Enter a sentence containing dates (YYYY-MM-DD format):
|
||||
The deadline is 2024-02-30.
|
||||
|
||||
Reference in New Issue
Block a user