diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..735c6d00
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,33 @@
+# Sphinx documentation build
+#
+# Usage:
+# make html Build HTML docs
+# make clean Remove build output
+# make help Show all targets
+#
+# First-time setup:
+# python3 -m venv venv
+# source venv/bin/activate
+# pip install -r requirements.txt
+
+PYTHON_BINARY = ./venv/bin/python
+
+# You can set these variables from the command line.
+SPHINXOPTS = -j auto
+SPHINXBUILD = $(PYTHON_BINARY) -m sphinx
+SOURCEDIR = docs
+BUILDDIR = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile clean
+
+clean:
+ rm -rf $(BUILDDIR)
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/_static/images/gauss26-ide-overview.png b/docs/_static/images/gauss26-ide-overview.png
new file mode 100644
index 00000000..63613e17
Binary files /dev/null and b/docs/_static/images/gauss26-ide-overview.png differ
diff --git a/docs/_static/images/getting-started-ts-video.jpg b/docs/_static/images/getting-started-ts-video.jpg
new file mode 100644
index 00000000..7ba3d91a
Binary files /dev/null and b/docs/_static/images/getting-started-ts-video.jpg differ
diff --git a/docs/_static/pygments-custom.css b/docs/_static/pygments-custom.css
index 3dae5646..f85be5c4 100644
--- a/docs/_static/pygments-custom.css
+++ b/docs/_static/pygments-custom.css
@@ -1,77 +1,77 @@
-.highlight .hll { background-color: #ffffcc }
-.highlight { background: #f8f8f8; }
-.highlight .c { color: #007f00; font-style: italic } /* Comment */
-.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */
-.highlight .g { color: #444 } /* Generic */
-.highlight .k { color: #0000ff; font-weight: normal; } /* Keyword */
-.highlight .l { color: #00007f } /* Literal */
-.highlight .n { color: #444 } /* Name */
-.highlight .o { color: #444 } /* Operator */
-.highlight .x { color: #444 } /* Other */
-.highlight .p { color: #444 } /* Punctuation */
-.highlight .ch { color: #007f00; font-style: italic } /* Comment.Hashbang */
-.highlight .cm { color: #007f00; font-style: italic } /* Comment.Multiline */
-.highlight .cp { color: #7f7f00 } /* Comment.Preproc */
-.highlight .cpf { color: #7f7f00; font-style: italic } /* Comment.PreprocFile */
-.highlight .c1 { color: #007f00; font-style: italic } /* Comment.Single */
-.highlight .cs { color: #007f00; font-style: italic } /* Comment.Special */
-.highlight .gd { color: #a40000 } /* Generic.Deleted */
-.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */
-.highlight .gr { color: #ef2929 } /* Generic.Error */
-.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
-.highlight .gi { color: #00A000 } /* Generic.Inserted */
-.highlight .go { color: #888888 } /* Generic.Output */
-.highlight .gp { color: #745334 } /* Generic.Prompt */
-.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */
-.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */
-.highlight .kc { color: #0000ff; } /* Keyword.Constant */
-.highlight .kd { color: #0000ff; } /* Keyword.Declaration */
-.highlight .kn { color: #0000ff; } /* Keyword.Namespace */
-.highlight .kp { color: #0000ff; } /* Keyword.Pseudo */
-.highlight .kr { color: #0000ff; } /* Keyword.Reserved */
-.highlight .kt { color: #0000ff; } /* Keyword.Type */
-.highlight .ld { color: #000000 } /* Literal.Date */
-.highlight .m { color: #00007f } /* Literal.Number */
-.highlight .s { color: #7f007f } /* Literal.String */
-.highlight .na { color: #444 } /* Name.Attribute */
-.highlight .nb { color: #00557f } /* Name.Builtin */
-.highlight .nc { color: #606 } /* Name.Class */
-.highlight .no { color: #00557f } /* Name.Constant */
-.highlight .nd { color: #00557f } /* Name.Decorator */
-.highlight .ni { color: #00557f } /* Name.Entity */
-.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */
-.highlight .nf { color: #00557f; font-weight: bold } /* Name.Function */
-.highlight .nl { color: #00557f } /* Name.Label */
-.highlight .nn { color: #00557f } /* Name.Namespace */
-.highlight .nx { color: #00557f } /* Name.Other */
-.highlight .py { color: #00557f } /* Name.Property */
-.highlight .nt { color: #00557f; font-weight: bold } /* Name.Tag */
-.highlight .nv { color: #660 } /* Name.Variable */
-.highlight .ow { color: #0000ff } /* Operator.Word */
-.highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */
-.highlight .mb { color: #00007f } /* Literal.Number.Bin */
-.highlight .mf { color: #00007f } /* Literal.Number.Float */
-.highlight .mh { color: #00007f } /* Literal.Number.Hex */
-.highlight .mi { color: #00007f } /* Literal.Number.Integer */
-.highlight .mo { color: #00007f } /* Literal.Number.Oct */
-.highlight .sa { color: #7f007f } /* Literal.String.Affix */
-.highlight .sb { color: #7f007f } /* Literal.String.Backtick */
-.highlight .sc { color: #7f007f } /* Literal.String.Char */
-.highlight .dl { color: #7f007f } /* Literal.String.Delimiter */
-.highlight .sd { color: #007f00; font-style: italic } /* Literal.String.Doc */
-.highlight .s2 { color: #7f007f } /* Literal.String.Double */
-.highlight .se { color: #7f007f } /* Literal.String.Escape */
-.highlight .sh { color: #7f007f } /* Literal.String.Heredoc */
-.highlight .si { color: #7f007f } /* Literal.String.Interpol */
-.highlight .sx { color: #7f007f } /* Literal.String.Other */
-.highlight .sr { color: #7f007f } /* Literal.String.Regex */
-.highlight .s1 { color: #7f007f } /* Literal.String.Single */
-.highlight .ss { color: #7f007f } /* Literal.String.Symbol */
-.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */
-.highlight .fm { color: #000000 } /* Name.Function.Magic */
-.highlight .vc { color: #000000 } /* Name.Variable.Class */
-.highlight .vg { color: #000000 } /* Name.Variable.Global */
-.highlight .vi { color: #000000 } /* Name.Variable.Instance */
-.highlight .vm { color: #000000 } /* Name.Variable.Magic */
-.highlight .il { color: #990000 } /* Literal.Number.Integer.Long */
+html[data-theme="light"] .highlight .hll { background-color: #ffffcc }
+html[data-theme="light"] .highlight { background: #f8f8f8; }
+html[data-theme="light"] .highlight .c { color: #007f00; font-style: italic } /* Comment */
+html[data-theme="light"] .highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */
+html[data-theme="light"] .highlight .g { color: #444 } /* Generic */
+html[data-theme="light"] .highlight .k { color: #0000ff; font-weight: normal; } /* Keyword */
+html[data-theme="light"] .highlight .l { color: #00007f } /* Literal */
+html[data-theme="light"] .highlight .n { color: #444 } /* Name */
+html[data-theme="light"] .highlight .o { color: #444 } /* Operator */
+html[data-theme="light"] .highlight .x { color: #444 } /* Other */
+html[data-theme="light"] .highlight .p { color: #444 } /* Punctuation */
+html[data-theme="light"] .highlight .ch { color: #007f00; font-style: italic } /* Comment.Hashbang */
+html[data-theme="light"] .highlight .cm { color: #007f00; font-style: italic } /* Comment.Multiline */
+html[data-theme="light"] .highlight .cp { color: #7f7f00 } /* Comment.Preproc */
+html[data-theme="light"] .highlight .cpf { color: #7f7f00; font-style: italic } /* Comment.PreprocFile */
+html[data-theme="light"] .highlight .c1 { color: #007f00; font-style: italic } /* Comment.Single */
+html[data-theme="light"] .highlight .cs { color: #007f00; font-style: italic } /* Comment.Special */
+html[data-theme="light"] .highlight .gd { color: #a40000 } /* Generic.Deleted */
+html[data-theme="light"] .highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */
+html[data-theme="light"] .highlight .gr { color: #ef2929 } /* Generic.Error */
+html[data-theme="light"] .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+html[data-theme="light"] .highlight .gi { color: #00A000 } /* Generic.Inserted */
+html[data-theme="light"] .highlight .go { color: #888888 } /* Generic.Output */
+html[data-theme="light"] .highlight .gp { color: #745334 } /* Generic.Prompt */
+html[data-theme="light"] .highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */
+html[data-theme="light"] .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+html[data-theme="light"] .highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */
+html[data-theme="light"] .highlight .kc { color: #0000ff; } /* Keyword.Constant */
+html[data-theme="light"] .highlight .kd { color: #0000ff; } /* Keyword.Declaration */
+html[data-theme="light"] .highlight .kn { color: #0000ff; } /* Keyword.Namespace */
+html[data-theme="light"] .highlight .kp { color: #0000ff; } /* Keyword.Pseudo */
+html[data-theme="light"] .highlight .kr { color: #0000ff; } /* Keyword.Reserved */
+html[data-theme="light"] .highlight .kt { color: #0000ff; } /* Keyword.Type */
+html[data-theme="light"] .highlight .ld { color: #000000 } /* Literal.Date */
+html[data-theme="light"] .highlight .m { color: #00007f } /* Literal.Number */
+html[data-theme="light"] .highlight .s { color: #7f007f } /* Literal.String */
+html[data-theme="light"] .highlight .na { color: #444 } /* Name.Attribute */
+html[data-theme="light"] .highlight .nb { color: #00557f } /* Name.Builtin */
+html[data-theme="light"] .highlight .nc { color: #606 } /* Name.Class */
+html[data-theme="light"] .highlight .no { color: #00557f } /* Name.Constant */
+html[data-theme="light"] .highlight .nd { color: #00557f } /* Name.Decorator */
+html[data-theme="light"] .highlight .ni { color: #00557f } /* Name.Entity */
+html[data-theme="light"] .highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */
+html[data-theme="light"] .highlight .nf { color: #00557f; font-weight: bold } /* Name.Function */
+html[data-theme="light"] .highlight .nl { color: #00557f } /* Name.Label */
+html[data-theme="light"] .highlight .nn { color: #00557f } /* Name.Namespace */
+html[data-theme="light"] .highlight .nx { color: #00557f } /* Name.Other */
+html[data-theme="light"] .highlight .py { color: #00557f } /* Name.Property */
+html[data-theme="light"] .highlight .nt { color: #00557f; font-weight: bold } /* Name.Tag */
+html[data-theme="light"] .highlight .nv { color: #660 } /* Name.Variable */
+html[data-theme="light"] .highlight .ow { color: #0000ff } /* Operator.Word */
+html[data-theme="light"] .highlight .w { color: #f8f8f8 } /* Text.Whitespace */
+html[data-theme="light"] .highlight .mb { color: #00007f } /* Literal.Number.Bin */
+html[data-theme="light"] .highlight .mf { color: #00007f } /* Literal.Number.Float */
+html[data-theme="light"] .highlight .mh { color: #00007f } /* Literal.Number.Hex */
+html[data-theme="light"] .highlight .mi { color: #00007f } /* Literal.Number.Integer */
+html[data-theme="light"] .highlight .mo { color: #00007f } /* Literal.Number.Oct */
+html[data-theme="light"] .highlight .sa { color: #7f007f } /* Literal.String.Affix */
+html[data-theme="light"] .highlight .sb { color: #7f007f } /* Literal.String.Backtick */
+html[data-theme="light"] .highlight .sc { color: #7f007f } /* Literal.String.Char */
+html[data-theme="light"] .highlight .dl { color: #7f007f } /* Literal.String.Delimiter */
+html[data-theme="light"] .highlight .sd { color: #007f00; font-style: italic } /* Literal.String.Doc */
+html[data-theme="light"] .highlight .s2 { color: #7f007f } /* Literal.String.Double */
+html[data-theme="light"] .highlight .se { color: #7f007f } /* Literal.String.Escape */
+html[data-theme="light"] .highlight .sh { color: #7f007f } /* Literal.String.Heredoc */
+html[data-theme="light"] .highlight .si { color: #7f007f } /* Literal.String.Interpol */
+html[data-theme="light"] .highlight .sx { color: #7f007f } /* Literal.String.Other */
+html[data-theme="light"] .highlight .sr { color: #7f007f } /* Literal.String.Regex */
+html[data-theme="light"] .highlight .s1 { color: #7f007f } /* Literal.String.Single */
+html[data-theme="light"] .highlight .ss { color: #7f007f } /* Literal.String.Symbol */
+html[data-theme="light"] .highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */
+html[data-theme="light"] .highlight .fm { color: #000000 } /* Name.Function.Magic */
+html[data-theme="light"] .highlight .vc { color: #000000 } /* Name.Variable.Class */
+html[data-theme="light"] .highlight .vg { color: #000000 } /* Name.Variable.Global */
+html[data-theme="light"] .highlight .vi { color: #000000 } /* Name.Variable.Instance */
+html[data-theme="light"] .highlight .vm { color: #000000 } /* Name.Variable.Magic */
+html[data-theme="light"] .highlight .il { color: #990000 } /* Literal.Number.Integer.Long */
diff --git a/docs/a.rst b/docs/a.rst
index ac6a8297..c66f1062 100644
--- a/docs/a.rst
+++ b/docs/a.rst
@@ -7,6 +7,8 @@ A
abs
acf
+ addition
+ address-operator
aconcat
aeye
aggregate
@@ -44,6 +46,7 @@ A
arraytomat
asciiload
asclabel
+ assignment
asdate
asdf
asmatrix
diff --git a/docs/abs.rst b/docs/abs.rst
index e0aafd57..20867a5b 100644
--- a/docs/abs.rst
+++ b/docs/abs.rst
@@ -45,3 +45,5 @@ The code above assigns the variables as follows:
In this example, a 2x2 matrix of Normal random
numbers is generated and the absolute value of the
matrix is computed.
+
+.. seealso:: Functions :func:`ceil`, :func:`floor`, :func:`round`
diff --git a/docs/aggregate.rst b/docs/aggregate.rst
index bfe0547c..2acc02b3 100644
--- a/docs/aggregate.rst
+++ b/docs/aggregate.rst
@@ -190,4 +190,4 @@ The above code will print:
Sun Dinner 48.170000 6.5000000
-.. seealso:: Functions :func:`meanc`, :func:`modec`, :func:`selif`
+.. seealso:: Functions :func:`meanc`, :func:`modec`, :func:`selif`, :func:`tsAggregate`
diff --git a/docs/amult.rst b/docs/amult.rst
index bd700106..bd0ff739 100644
--- a/docs/amult.rst
+++ b/docs/amult.rst
@@ -96,3 +96,4 @@ The multiplication operator, ``*``, performs the same operation for arrays as :f
All leading dimensions must be strictly conformable, and the two
trailing dimensions of each array must be matrix-product conformable.
+.. seealso:: Functions :func:`areshape`, :func:`aconcat`
diff --git a/docs/annotationsetlinepen.rst b/docs/annotationsetlinepen.rst
index 48348dbe..2b4e9803 100644
--- a/docs/annotationsetlinepen.rst
+++ b/docs/annotationsetlinepen.rst
@@ -10,8 +10,8 @@ Format
----------------
.. function:: annotationSetLinePen(&myAnnotation, width [, clr, style])
- :param myAnnotation: A pointer to an instance of a :class:`plotAnnotation` structure
- :type myAnnotation: struct
+ :param &myAnnotation: A pointer to an instance of a :class:`plotAnnotation` structure
+ :type &myAnnotation: struct pointer
:param width: the width of the line in pixels.
:type width: scalar
diff --git a/docs/annualtradingdays.rst b/docs/annualtradingdays.rst
index 83b8f28e..f850e365 100644
--- a/docs/annualtradingdays.rst
+++ b/docs/annualtradingdays.rst
@@ -31,6 +31,25 @@ Globals
.. data:: _fin_holidays
+Examples
+--------
+
+::
+
+ // Get the number of NYSE trading days in 2023
+ n = annualTradingDays(2023);
+ print (n);
+
+The above code sets *n* to 250.
+
+::
+
+ // Compare trading days across years
+ for i (2020, 2024, 1);
+ n = annualTradingDays(i);
+ print i;; print " trading days: ";; print n;
+ endfor;
+
Source
------
diff --git a/docs/arccos.rst b/docs/arccos.rst
index 75839ff8..c1d9bf74 100644
--- a/docs/arccos.rst
+++ b/docs/arccos.rst
@@ -62,4 +62,4 @@ Source
trig.src
-
+.. seealso:: Functions :func:`cos`, :func:`arcsin`, :func:`atan`
diff --git a/docs/arcsin.rst b/docs/arcsin.rst
index 73eea0ff..7b7c26ce 100644
--- a/docs/arcsin.rst
+++ b/docs/arcsin.rst
@@ -47,3 +47,4 @@ Source
trig.src
+.. seealso:: Functions :func:`sin`, :func:`arccos`, :func:`atan`
diff --git a/docs/asdf.rst b/docs/asdf.rst
index 68d1c092..604d0add 100644
--- a/docs/asdf.rst
+++ b/docs/asdf.rst
@@ -66,4 +66,4 @@ Remarks
--------------
-.. seealso:: Functions :func:`asMatrix`, :func:`asDate`, :func:`dfname`, :func:`dftype`
+.. seealso:: Functions :func:`asMatrix`, :func:`asDate`, :func:`dfaddcol`, :func:`dfname`, :func:`dftype`
diff --git a/docs/b.rst b/docs/b.rst
index 07b3da23..66fa40cd 100644
--- a/docs/b.rst
+++ b/docs/b.rst
@@ -21,6 +21,7 @@ B
beta
between
blendcolorpalette
+ bookkeeping-transpose
blockdiag
boxcox
box
diff --git a/docs/balance.rst b/docs/balance.rst
index 9c7bd1ce..30a601b7 100644
--- a/docs/balance.rst
+++ b/docs/balance.rst
@@ -62,3 +62,4 @@ In particular,
:func:`balance` uses the `BALANC` function from `EISPACK`
+.. seealso:: Functions :func:`eig`, :func:`eigv`
diff --git a/docs/bandsolpd.rst b/docs/bandsolpd.rst
index ad54846f..643d0b20 100644
--- a/docs/bandsolpd.rst
+++ b/docs/bandsolpd.rst
@@ -5,19 +5,19 @@ bandsolpd
Purpose
----------------
-Solves the system of equations :math:`Ax = b` for *x*, where *A* is a positive definite banded matrix.
+Solves the system of equations :math:`Ax = b` for *x*, where *A* is a positive definite banded matrix stored in compact form. Banded matrices arise in spline interpolation, finite difference methods, and time series models where each variable depends only on nearby neighbors.
Format
----------------
.. function:: x = bandsolpd(b, A)
- :param b:
+ :param b: right-hand side vector or matrix. If *b* has multiple columns, the system is solved for each column independently.
:type b: KxM matrix
- :param A:
+ :param A: positive definite banded matrix in compact form, where *N* is the number of bands (including the diagonal). See :func:`band` for how to convert a full matrix to compact form.
:type A: KxN compact form matrix
- :return x:
+ :return x: the solution vector(s). Each column of *x* is the solution corresponding to the matching column of *b*.
:rtype x: KxM matrix
@@ -32,4 +32,34 @@ column. That is,
.. math:: A*x[.,i] = b[.,i]
+Examples
+--------
+
+::
+
+ // Create a 4x4 tridiagonal positive definite system
+ // In compact banded form:
+ // col 1 = sub-diagonal elements (first element is 0, no element above row 1)
+ // col 2 = main diagonal elements
+ A_compact = { 0 4,
+ 1 5,
+ 1 6,
+ 1 7 };
+
+ // Right-hand side vector
+ b = { 8, 11, 13, 14 };
+
+ // Solve Ax = b
+ x = bandsolpd(b, A_compact);
+ print x;
+
+The above code produces:
+
+::
+
+ 1.6111851
+ 1.5552597
+ 1.6125166
+ 1.7696405
+
.. seealso:: Functions :func:`band`, :func:`bandchol`, :func:`bandcholsol`, :func:`bandltsol`, :func:`bandrv`
diff --git a/docs/base10.rst b/docs/base10.rst
index c211b51c..685c1ddf 100644
--- a/docs/base10.rst
+++ b/docs/base10.rst
@@ -47,3 +47,5 @@ Source
------------
base10.src
+
+.. seealso:: Functions :func:`log`, :func:`ln`
diff --git a/docs/bessely.rst b/docs/bessely.rst
index f280f9e5..1c397b22 100644
--- a/docs/bessely.rst
+++ b/docs/bessely.rst
@@ -38,7 +38,7 @@ Examples
** NOTE: The '~' provides horizontal concatenation
*/
ord = { 1 3 };
- y = bessely(n, x~x2);
+ y = bessely(ord, x~x2);
After the code above:
diff --git a/docs/between.rst b/docs/between.rst
index 9aa7bd5f..e9ee1ec0 100644
--- a/docs/between.rst
+++ b/docs/between.rst
@@ -11,8 +11,8 @@ Format
----------------
.. function:: mask = between(X, left, right [, inclusive])
- :param x: Data.
- :type x: NxK matrix or dataframe.
+ :param X: Data.
+ :type X: NxK matrix or dataframe.
:param left: Lower limit of the range.
:type left: 1x1 matrix or dataframe.
diff --git a/docs/bhatlib/example-mnpfit-baseline.rst b/docs/bhatlib/example-mnpfit-baseline.rst
index d51c86d3..b1906ac0 100644
--- a/docs/bhatlib/example-mnpfit-baseline.rst
+++ b/docs/bhatlib/example-mnpfit-baseline.rst
@@ -51,7 +51,7 @@ Step Three: Specifying choice variables and restrictions
---------------------------------------------------------
In this step, we will specify the choice variables and any restrictions that apply to the model. The choice variables are the alternatives available to the decision-maker, and the restrictions define which alternatives are available in each observation.
-These are specified in a string format, where each alternative should be represented by a column in the data. In our example the three choices, Drive Alone (DA), Shared Ride (SR), and Transit (TR) are contained in the `"Alt1_ch"`, `"Alt2_ch"`, and `"Alt3_ch"` columns. We input these as the `dvunordname` varible.
+These are specified in a string format, where each alternative should be represented by a column in the data. In our example the three choices, Drive Alone (DA), Shared Ride (SR), and Transit (TR) are contained in the `"Alt1_ch"`, `"Alt2_ch"`, and `"Alt3_ch"` columns. We input these as the ``dvunordname`` varible.
::
diff --git a/docs/bhatlib/linearmdecvfit.rst b/docs/bhatlib/linearmdecvfit.rst
index 300fe6e9..d8097eef 100644
--- a/docs/bhatlib/linearmdecvfit.rst
+++ b/docs/bhatlib/linearmdecvfit.rst
@@ -30,10 +30,10 @@ Format
:type weight_var: string, default = ``"uno"``
:param varnam: Optional input. Names of variables in the baseline utility specification.
- :type varnam: string vector, default = auto-generated from `dvunordname` and `ivmt`
+ :type varnam: string vector, default = auto-generated from ``dvunordname`` and `ivmt`
:param varngam: Optional input. Names of variables in the translation specification.
- :type varngam: string vector, default = auto-generated from `dvunordname` and `ivgt`
+ :type varngam: string vector, default = auto-generated from ``dvunordname`` and `ivgt`
:return beta_hat: Estimated model coefficients including baseline utility, translation, and scale parameters.
:rtype beta_hat: column vector
diff --git a/docs/binaryclassquality.rst b/docs/binaryclassquality.rst
index 627cd422..f0f79e78 100644
--- a/docs/binaryclassquality.rst
+++ b/docs/binaryclassquality.rst
@@ -15,13 +15,13 @@ Format
:type y_true: Nx1 binary vector.
:param y_predict: That represents the predicted class labels.
- :type y_true: Nx1 binary vector.
+ :type y_predict: Nx1 binary vector.
:param df_true: That represents the true class labels.
:type df_true: Nx1 dataframe, or string array.
- :param y_predict: That represents the predicted class labels.
- :type y_true: Nx1 dataframe, or string array.
+ :param df_predict: That represents the predicted class labels.
+ :type df_predict: Nx1 dataframe, or string array.
:param classes: The first element of ``classes`` indicates which class should be treated as the positive case. This input is required if the ``true`` and ``predict`` inputs are string arrays or categorical dataframes.
:type classes: String, 1x1 or 2x1 categorical dataframe, or string array.
diff --git a/docs/blendcolorpalette.rst b/docs/blendcolorpalette.rst
index a8f914c3..fe43b127 100644
--- a/docs/blendcolorpalette.rst
+++ b/docs/blendcolorpalette.rst
@@ -20,7 +20,7 @@ Format
:rtype color_blend: n_colorsx1 string array
-Format
+Examples
----------------
::
diff --git a/docs/box.rst b/docs/box.rst
index 055978e9..1f5fb423 100644
--- a/docs/box.rst
+++ b/docs/box.rst
@@ -75,6 +75,16 @@ Remarks
-------
If missing values are encountered in the *y* data, they will be ignored
+Example
+-------
+
+::
+
+ // Box plot of 3 groups, each with 50 observations
+ y = rndn(50, 3);
+ grp = { 1 2 3 };
+ box(grp, y);
+
Source
------
pbox.src
diff --git a/docs/boxcox.rst b/docs/boxcox.rst
index b3b40959..266ccb4a 100644
--- a/docs/boxcox.rst
+++ b/docs/boxcox.rst
@@ -49,3 +49,4 @@ The :func:`boxcox` function computes:
.. math:: boxcox(x) = (xλ - 1)/λ
+.. seealso:: Functions :func:`ln`, :func:`log`
diff --git a/docs/c.rst b/docs/c.rst
index 228667f1..44d99d12 100644
--- a/docs/c.rst
+++ b/docs/c.rst
@@ -71,6 +71,7 @@ C
closeall
close
cls
+ cmlmtinversewaldlimits
clusterse
codedataloop
code
@@ -88,6 +89,7 @@ C
conscore
contains
continue
+ contingency
contour
convertsatostr
convertstrtosa
diff --git a/docs/cc/data-cleaning.rst b/docs/cc/data-cleaning.rst
index c9ce6fe0..91528a3f 100644
--- a/docs/cc/data-cleaning.rst
+++ b/docs/cc/data-cleaning.rst
@@ -21,6 +21,8 @@ Selection
:doc:`../delif` Removes rows of data based on a logical expression.
:doc:`../delrows` Removes observations (rows) from a dataframe by index.
:doc:`../diag` Extracts the diagonal of a matrix.
+:doc:`../diagmat` Creates a diagonal matrix from a vector.
+:doc:`../findidx` Returns the indices of elements where a condition is true.
:doc:`../getmatrix` Gets a contiguous matrix from an N-dimensional array.
:doc:`../head` Returns the first ``n`` rows of a matrix, dataframe or string array.
:doc:`../selif` Keeps rows of data based on a logical expression.
@@ -33,6 +35,7 @@ Selection
Merging
-------------------
===================== ===========================================
+:doc:`../dfaddcol` Adds a new named column to a dataframe.
:doc:`../dfappend` Vertically concatenates (or stacks) two dataframes.
:doc:`../innerjoin` Performs a left, or full, outer join on two matrices based upon user-specified key columns.
:doc:`../insertcols` Inserts one or more new columns into a matrix or dataframe at a specified location.
@@ -139,6 +142,7 @@ Transform
:doc:`../reclassify` Replaces specified values of a matrix, array or string array
:doc:`../reclassifycuts` Replaces values of a matrix or array within specified ranges
:doc:`../rev` Reverses the order of rows of a matrix.
+:doc:`../repmat` Tiles (repeats) a matrix to create a larger matrix.
:doc:`../reshape` Reshapes a dataframe, matrix or string array to new dimensions.
:doc:`../rotater` Rotates the rows of a matrix, wrapping elements as necessary.
:doc:`../shiftc` Shifts, lags or leads, columns of a matrix, filling in holes with a specified value.
diff --git a/docs/cc/data-types.rst b/docs/cc/data-types.rst
index 06289b7a..514885ba 100644
--- a/docs/cc/data-types.rst
+++ b/docs/cc/data-types.rst
@@ -11,6 +11,7 @@ General
========================= ==========================================================================
:doc:`../asdf` Converts a matrix or string array to a dataframe, and optionally sets the column names.
:doc:`../asmatrix` Converts a dataframe to a matrix.
+:doc:`../dfaddcol` Adds a new named column to a dataframe.
:doc:`../dfappend` Vertically conacatenates (or stacks) two dataframes.
:doc:`../dfname` Sets the variable names of the columns of a dataframe.
:doc:`../dftype` Sets the types (numeric, categorical, date or string) of a dataframe.
diff --git a/docs/cc/descriptive-statistics.rst b/docs/cc/descriptive-statistics.rst
index 005b0482..d63a218a 100644
--- a/docs/cc/descriptive-statistics.rst
+++ b/docs/cc/descriptive-statistics.rst
@@ -6,7 +6,7 @@ Descriptive statistics and computation
Descriptive statistics
--------------------------
-==================== ===========================================
+====================== ===========================================
:doc:`../aggregate` Aggregates the data in the columns of a matrix based upon a column containing group ids with a choice of method.
:doc:`../contingency` Computes statistics and measures of association for contingency tables.
:doc:`../dstatmt` Computes descriptive statistics of a dataset, dataframe, or matrix.
@@ -26,7 +26,7 @@ Descriptive statistics
:doc:`../stdc` Computes the sample standard deviation of the elements in each column of a matrix.
:doc:`../tabulate` Computes and returns two-way tables of frequencies.
:doc:`../vcmvcx` Computes an unbiased estimate of a variance-covariance matrix from a matrix :math:`x` or a moment matrix, :math:`x'x`.
-==================== ===========================================
+====================== ===========================================
Computation
diff --git a/docs/cdfbinomialinv.rst b/docs/cdfbinomialinv.rst
index bb0b44b6..370176b7 100644
--- a/docs/cdfbinomialinv.rst
+++ b/docs/cdfbinomialinv.rst
@@ -37,7 +37,7 @@ For our example we will define a reasonable range as falling between the top and
trials = 82;
// Probabiliy of success
- prob = 0.6
+ prob = 0.6;
// Call cdfBinomialInv
s = cdfBinomialInv(range, trials, prob);
diff --git a/docs/cdfchic.rst b/docs/cdfchic.rst
index 555d08c9..c60c19ce 100644
--- a/docs/cdfchic.rst
+++ b/docs/cdfchic.rst
@@ -33,7 +33,7 @@ Examples
df = 3;
// Call cdfChic
- p = cdfChic(x, n);
+ p = cdfChic(x, df);
print "p = " p;
After running the above code,
diff --git a/docs/cdfgam.rst b/docs/cdfgam.rst
index 41cb4a5c..12f651b4 100644
--- a/docs/cdfgam.rst
+++ b/docs/cdfgam.rst
@@ -13,8 +13,8 @@ Format
:param x: Values at which to evaluate the regularized lower incomplete gamma function. :math:`x > 0`.
:type x: NxK matrix
- :param int_lim: ExE compatible with *x*, containing the integration limit. :math:`int\_lim > 0`.
- :type int_lim: LxM matrix
+ :param intlim: ExE compatible with *x*, containing the integration limit. :math:`intlim > 0`.
+ :type intlim: LxM matrix
:return p: Each element in *p* is the regularized lower incomplete gamma function evaluated at the corresponding element in *x*.
@@ -44,15 +44,15 @@ Matrix example
x = { 0.5 1 3 10 };
// Create a 6x1 column vector: 0, 0.2, 0.4, ..., 1.0
- int_lim = seqa(0,.2,6);
+ intlim = seqa(0,.2,6);
/*
** Compute for all combinations of the elements
- ** of 'x' and 'int_lim'
+ ** of 'x' and 'intlim'
*/
- p = cdfGam(x, int_lim);
+ p = cdfGam(x, intlim);
- print "intlim = " int_lim;
+ print "intlim = " intlim;
print "p = " p;
After the code above:
@@ -82,7 +82,7 @@ Remarks
The regularized lower incomplete gamma function returns the integral
-.. math:: \text{cdfGam(x, int_lim)} = \int_{0}^{int\_lim} \frac{e^{-t}t^{(x-1)}}{\Gamma(x)}dt
+.. math:: \text{cdfGam(x, intlim)} = \int_{0}^{int\_lim} \frac{e^{-t}t^{(x-1)}}{\Gamma(x)}dt
A -1 is returned for those elements with invalid inputs.
diff --git a/docs/cdfmvte.rst b/docs/cdfmvte.rst
index 0e3cbb9e..57d4364e 100644
--- a/docs/cdfmvte.rst
+++ b/docs/cdfmvte.rst
@@ -21,7 +21,7 @@ Format
:type ctl: struct
- :param x: Lower limits at which to evaluate the Student's t cumulative distribution function. If *x* has more than one row, each row will be treated as a separate set of upper limits. K is the dimension of the multivariate Student's t distribution. N is the number of MVT cdf integrals.
+ :param x: Upper limits at which to evaluate the Student's t cumulative distribution function. If *x* has more than one row, each row will be treated as a separate set of upper limits. K is the dimension of the multivariate Student's t distribution. N is the number of MVT cdf integrals.
:type x: NxK matrix
:param corr: correlation matrix.
diff --git a/docs/cdftnc.rst b/docs/cdftnc.rst
index 693215ce..5efe66ec 100644
--- a/docs/cdftnc.rst
+++ b/docs/cdftnc.rst
@@ -75,6 +75,8 @@ After running above code,
Remarks
------------
+.. note:: The *nonc* parameter is the **square root** of the noncentrality parameter sometimes denoted :math:`\lambda` in the literature. If your source provides :math:`\lambda` directly, pass :math:`\sqrt{\lambda}` to :func:`cdfTnc`.
+
::
cdfTc(x, df) = 1 - cdfTnc(x, df, 0)
diff --git a/docs/cdftruncnorm.rst b/docs/cdftruncnorm.rst
index 47bb28a2..9766aa89 100644
--- a/docs/cdftruncnorm.rst
+++ b/docs/cdftruncnorm.rst
@@ -13,20 +13,20 @@ Format
:param x: Values at which to evaluate the cumulative distribution function of the normal distribution.
:type x: NxK matrix
- :param l_lim: lower limit of the integration window.
- :type l_lim: Scalar
+ :param a: lower limit of the integration window.
+ :type a: Scalar
- :param u_lim: upper limit of the integration window.
- :type u_lim: Scalar
+ :param b: upper limit of the integration window.
+ :type b: Scalar
:param mu_bar: mean parameter.
:type mu_bar: Scalar
- :param std_bar: standard deviation parameter.
- :type std_bar: Scalar
+ :param sigma_bar: standard deviation parameter.
+ :type sigma_bar: Scalar
:return p: the probability density
- of the cumulative distribution over the interval from *l_lim* to *u_lim*.
+ of the cumulative distribution over the interval from *a* to *b*.
:rtype p: scalar or NxK matrix or N-dimensional array
@@ -39,23 +39,23 @@ Examples
x = 0.6;
//Lower limit
- l_lim = -1;
+ a = -1;
// Upper limit
- u_lim = 1;
+ b = 1;
// Mean parameter
mu_bar = 2.3;
// Standard deviation parameter
- std_bar = 1;
+ sigma_bar = 1;
/*
** Compute the CDF at x = 0.6
** over the closed region [-1,1]
** of the distribution N ~ (2.3, 1)
*/
- p = cdfTruncNorm(x, l_lim, u_lim, mu_bar, std_bar);
+ p = cdfTruncNorm(x, a, b, mu_bar, sigma_bar);
After the above code, *p* equals:
diff --git a/docs/cdfweibullinv.rst b/docs/cdfweibullinv.rst
index 71925f33..95dd6c64 100644
--- a/docs/cdfweibullinv.rst
+++ b/docs/cdfweibullinv.rst
@@ -24,4 +24,32 @@ Format
:rtype x: NxK matrix, Nx1 vector or scalar
+Examples
+--------
+
+::
+
+ // Compute the median of a Weibull(2, 1) distribution
+ x_median = cdfWeibullInv(0.5, 2, 1);
+ print (x_median);
+
+The above code sets *x_median* to 0.8326.
+
+::
+
+ // Compute multiple quantiles at once
+ p = { 0.1, 0.25, 0.5, 0.75, 0.9 };
+ x = cdfWeibullInv(p, 2, 1);
+ print (p~x);
+
+produces:
+
+::
+
+ 0.10000000 0.32459285
+ 0.25000000 0.53636002
+ 0.50000000 0.83255461
+ 0.75000000 1.1774100
+ 0.90000000 1.5174271
+
.. seealso:: :func:`pdfWeibull`, :func:`cdfWeibull`
diff --git a/docs/cdir.rst b/docs/cdir.rst
index ede034c5..523271b9 100644
--- a/docs/cdir.rst
+++ b/docs/cdir.rst
@@ -62,4 +62,4 @@ end with a backslash, otherwise it will not.
A null string or scalar zero can be passed in as an argument to obtain
the current drive and path name.
-
+.. seealso:: Functions :func:`changedir`, :func:`chdir`
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 97bb4da7..a25ae48e 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -4,10 +4,48 @@ Change Log
The following is a list of changes from the previous version of GAUSS.
+26.1.1
+------
+
+#. New feature: Autocomplete calltips for library procedures. Typing ``varFit(`` now shows the full argument signature with keyword defaults in a tooltip, e.g., ``varFit(y, p = 1, const = 1, xreg = {}, quiet = 0, ctl = {})``. Works for all procedures in active libraries and for libraries referenced by ``library`` statements in the current file, even before the code is run.
+#. Enhanced functionality: Struct type inference now works for procedures that use ``proc (N) = name(...)`` headers without typed return declarations. The compiler scans the procedure body for ``struct`` local declarations and ``retp()`` calls to infer return types automatically.
+#. Enhanced functionality: ``plotGetDefaults`` return type is now inferred automatically. ``plt = plotGetDefaults("xy")`` works without first declaring ``struct plotControl plt``.
+#. Enhanced functionality: External links (http/https) in the help viewer now open in the system browser instead of the internal help panel.
+#. Bug fix: Keyword argument calls at the beginning of a statement (e.g., ``simulate(4, nvars=2);``) were incorrectly identified as assignment statements, producing G0156 and G0136 errors.
+#. Bug fix: Library procedures called with keyword argument syntax produced G0165 "undefined symbol" errors at runtime because the eager-parse stub prevented the library source from being compiled.
+#. Enhanced functionality: ``gpkg`` package installer now accepts zip files with an extra wrapper folder, which occurs when browsers auto-extract a download and the user re-zips it.
+#. Enhanced functionality: ``gpkg`` package installer security and robustness improvements, including path validation, write-error detection, and platform file filtering.
+#. Bug fix: Keyword argument calls that omit a required positional argument (e.g., ``f(x, name=val)`` when ``f`` requires two positional arguments) now produce a clear error message (G0744) instead of the misleading G0029 "Missing left parenthesis."
+#. Bug fix: :func:`minimize` now reports the correct number of function evaluations when using numerical gradients. Previously, only the base evaluations were counted and the evaluations for finite-difference gradient approximation were omitted.
+#. Enhanced functionality: :func:`minimize` numerical gradient computation now checks for non-finite objective values before computing the gradient, and falls back to one-sided finite differences when a perturbed evaluation returns NaN or Inf instead of aborting. Produces a clear diagnostic when bounds should be tightened.
+#. Bug fix: Struct return type inference for library procedures with multi-line ``proc`` headers (declaration spanning multiple lines) now works correctly.
+
+26.1.0
+------
+
+#. New feature: Keyword arguments for procedure calls. Arguments can be passed by name in any order: ``result = arimaFit(y, order = 1|1|1, season = 12)``. Keyword parameters are declared in the procedure signature with ``name = default`` syntax. Omitted keywords use their declared defaults. The compiler rewrites keyword calls as positional calls with zero runtime overhead. Typos produce "did you mean?" suggestions using fuzzy matching.
+#. New feature: Struct type inference. Procedures that return structs no longer require callers to declare the receiving variable. ``result = arimaFit(y)`` now works without first writing ``struct arimaResult result``. The compiler automatically infers the struct type from the procedure's return type. Works for single assignments, multi-return assignments (``{ result, n } = proc()``), and nested return expressions (``retp(arimaFit(y))``).
+#. New feature: Matrix literals in expression context. ``{1, 2, 3}`` and ``{1 2, 3 4}`` can now be used directly as function arguments, in expressions, and as keyword argument defaults: ``print sumc({1, 2, 3})``, ``y = foo({1 2, 3 4})``, ``proc (1) = bar(x, opts={})``.
+#. New feature: String array literals in expression context. ``{"a", "b", "c"}`` now produces a proper string array (type 15) instead of a packed-byte character matrix. Single-element ``{"hello"}`` produces a string (type 13).
+#. New feature: Typed return declarations for procedures. Procedure headers can now declare their return types: ``proc (struct arimaResult) = arimaFit(y)``. For multi-return procedures, list each return type: ``proc (struct mleResult, matrix) = mleEstimate(y, ctl)``. The ``lib`` command automatically detects typed return declarations and records them in ``.lcg`` library files, enabling struct type inference for library procedures without manual configuration.
+#. Enhanced functionality: Struct type mismatch errors (G0506) now display both struct type names (e.g., "Cannot assign struct 'typeB' to variable declared as struct 'typeA'").
+#. Enhanced functionality: Undefined struct member errors (G0504) now display the struct type name alongside the member name.
+#. Enhanced functionality: :func:`minimize` output structure now includes a ``varNames`` member. When the starting vector ``x0`` is a dataframe with column names, :func:`minimize` automatically extracts the names and uses them in printed parameter tables instead of generic ``x[1]``, ``x[2]`` labels.
+#. Enhanced functionality: :func:`minimize` numerical gradients now respect bound constraints, using one-sided finite differences when parameters are at boundaries.
+#. Enhanced functionality: :func:`minimize` error messages now identify the return type when the objective function returns an incorrect type (e.g., "Objective function returned a struct (arimaResult), expected a real scalar").
+#. Bug fix: :func:`norm` with 2-norm or nuclear norm on matrices containing missing values no longer produces spurious parameter warnings.
+#. Bug fix: High-DPI display scaling on Windows with fractional scale factors (125%, 150%) now renders UI elements at the correct size instead of falling back to 1x scaling.
+#. Bug fix: :func:`ttest` no longer crashes when called without an optional control structure (e.g., ``ttest(y1, y2)``).
+#. Bug fix: :func:`contingency` no longer crashes when called without an optional control structure.
+#. Bug fix: :func:`contingency` now accepts raw string arrays as input vectors. Previously, passing string arrays (type 15) instead of dataframe columns caused a type mismatch error.
+#. New example datasets: ``fred_macro.csv`` (quarterly U.S. macro data 1960-2025), ``clinical_trial.csv`` (200-row RCT), ``employee_survey.csv`` (500-row categorical survey), ``wage_returns.csv`` (1000-row Mincer equation), ``state_crime_panel.csv`` (50 states x 15 years panel).
+#. New example programs: ``minimize_rosenbrock.e``, ``minimize_mle.e``, ``ttest_clinical.e``, ``contingency_survey.e``, ``mvntest_residuals.e``, ``colon_operator.e``, ``getting_started_macro.e``, ``getting_started_finance.e``, ``getting_started_wages.e``, ``getting_started_panel.e``.
+
26.0.1
------
#. New feature: Profiler GUI with "Profile Main File" menu item (Shift+F5) in Debug menu. Dockable profiler panel displays Hot Spots (line-level timing sorted by self time), Call Tree (hierarchical procedure call graph), and Output tabs. Double-click any entry to navigate to source.
+#. New function: :func:`dfaddcol`, adds a new named column to a dataframe. ``auto2 = dfaddcol(auto2, "price_k", auto2[., "price"] ./ 1000)`` adds a ``price_k`` column computed from an existing column.
#. New feature: The colon operator now creates vectors outside of indexing context. ``x = 1:5`` creates a 5x1 column vector ``{1, 2, 3, 4, 5}``, equivalent to ``seqa(1, 1, 5)``. Works with variables (``a:b``), expressions (``(n-1):(n+1)``), and function calls (``minc(x):maxc(x)``). Inside brackets, the colon continues to work as an index range (``x[1:5]``).
#. New feature: Stepped colon operator ``start:step:end`` creates sequences with custom step sizes. ``1:2:10`` creates ``{1, 3, 5, 7, 9}``, ``10:-2:1`` creates ``{10, 8, 6, 4, 2}``, and ``0:0.5:2`` creates ``{0, 0.5, 1, 1.5, 2}``. Works both outside brackets (creates a vector) and inside brackets for stepped indexing (``m[1:2:10]`` selects every other element).
#. New function: :func:`minimize`, bound-constrained optimization using the L-BFGS-B algorithm, the gold standard for smooth unconstrained and bound-constrained problems. Supports passing data arguments to the objective function and returns detailed output including solution, gradient, convergence status, and iteration count.
@@ -15,6 +53,9 @@ The following is a list of changes from the previous version of GAUSS.
#. New function: :func:`mvnTest`, multivariate normality testing using Henze-Zirkler (default), Mardia's skewness/kurtosis, Doornik-Hansen, or Royston methods.
#. New function: :func:`shapiroWilk`, Shapiro-Wilk W test for univariate normality.
#. New function: :func:`contingency`, comprehensive statistics for contingency tables including chi-squared tests, Fisher's exact test, odds ratios, relative risk, and measures of association (Cramer's V, Gamma, Kendall's tau-b, Kappa).
+#. New function: :func:`repmat`, tiles (repeats) a matrix to create a larger matrix. ``repmat(A, m, n)`` creates an output containing *m* x *n* copies of *A*.
+#. New function: :func:`findIdx`, returns the indices of elements where a condition is true. ``findIdx(x .> 0)`` returns row indices where *x* is positive.
+#. New function: :func:`diagmat`, creates a diagonal or off-diagonal matrix from a vector. ``diagmat(v)`` returns an NxN matrix with *v* on the main diagonal; ``diagmat(v, k)`` places *v* on the *k*-th super- or subdiagonal.
#. Enhanced functionality: :func:`sqpSolveMT` improved robustness for challenging optimization problems, including better handling of difficult starting points, adaptive trust region management, and improved numerical stability.
#. Enhanced functionality: :func:`quantileFit` improved input validation with clear error messages for invalid quantile levels, collinear predictors, and mismatched input dimensions.
#. Enhanced functionality: :func:`quantileFit` now reports convergence diagnostics via new output members ``qOut.converged`` and ``qOut.iterations``.
@@ -28,6 +69,8 @@ The following is a list of changes from the previous version of GAUSS.
#. New feature: Global variables used inside procedures are highlighted with an orange box overlay in the editor. Hover over a highlighted variable to see its name in a tooltip. Can be toggled via the "Highlight globals in procs" checkbox in Edit preferences.
#. Enhanced functionality: Parser error messages are now more descriptive, showing the unexpected token and what was expected (e.g., ``syntax error, unexpected ';', expecting identifier or 'endp'``).
#. New feature: :func:`dllcall` now supports a ``-o`` flag for read-only optimization. When specified, ``dllcall -o`` skips the defensive copy normally performed for local variables and function parameters, passing the original data pointer directly to the C function. This provides significant performance improvements for large matrices (up to 135x faster for 800KB data). Should only be used when the C function does not modify input data.
+#. Performance improvement: :func:`eigv` now uses a fast closed-form solution for 2x2 matrices, providing 2.6x speedup for complex matrices and 1.8x speedup for real matrices. Automatically falls back to standard algorithm for near-repeated eigenvalues where iterative methods are more accurate.
+#. Enhanced functionality: ``print`` now supports expressions with binary operators. ``print a + b;`` evaluates and prints the sum instead of producing a G0064 error. All arithmetic (``+ - * / % ^``), comparison (``< > <= >= == !=``), element-wise (``.* ./ .^``), and string (``$+ $== $< $| $~``) operators are supported. The existing whitespace-sensitive behavior is preserved: ``print a -b;`` still prints two items (``a`` and ``-b``), while ``print a - b;`` prints the difference.
26.0.0
------
diff --git a/docs/chibarsquare.rst b/docs/chibarsquare.rst
index dadd4ea9..a13e2c5a 100644
--- a/docs/chibarsquare.rst
+++ b/docs/chibarsquare.rst
@@ -90,3 +90,5 @@ Source
------------
hypotest.src
+
+.. seealso:: Functions :func:`cdfChic`, :func:`cdfChinc`
diff --git a/docs/chol.rst b/docs/chol.rst
index 85a7d4e5..987dbb79 100644
--- a/docs/chol.rst
+++ b/docs/chol.rst
@@ -59,7 +59,7 @@ order bit of the trap flag:
:widths: auto
"**trap 0**", "Print error message and terminate program."
- "**trap 1**", "Print error message and terminate program."
+ "**trap 1**", "Return scalar error code (10)."
See :func:`scalerr` and `trap` for more details about error codes.
diff --git a/docs/classificationmetrics.rst b/docs/classificationmetrics.rst
index 9008d7de..b2dfd632 100644
--- a/docs/classificationmetrics.rst
+++ b/docs/classificationmetrics.rst
@@ -200,3 +200,4 @@ We can access any of the structure members from the ``classQuality`` structure u
versicolor 0.93750000
virginica 1.0000000
+.. seealso:: Functions :func:`binaryClassMetrics`
diff --git a/docs/clearg.rst b/docs/clearg.rst
index 02c99fc4..8ae5e85c 100644
--- a/docs/clearg.rst
+++ b/docs/clearg.rst
@@ -36,5 +36,33 @@ initialize symbols not previously referenced. This command can be used
inside of procedures to clear global matrices. It will ignore any locals
by the same name.
+Examples
+--------
+
+::
+
+ x = 5;
+ y = rndn(3, 3);
+ z = "hello";
+
+ print (x);
+
+::
+
+ 5.0000000
+
+::
+
+ // Reset all three globals to scalar 0
+ clearg x, y, z;
+
+ print (x);
+
+::
+
+ 0.0000000
+
+After calling ``clearg``, each variable is reset to a scalar zero regardless of its previous type or dimensions.
+
.. seealso:: `clear`, `delete`, `new`, `show`, `local`
diff --git a/docs/cls.rst b/docs/cls.rst
index 5d2177dc..8f889ab3 100644
--- a/docs/cls.rst
+++ b/docs/cls.rst
@@ -19,4 +19,14 @@ hand corner of the window. It is sometimes useful to put a :func:`cls` statement
at the beginning of a program that prints a report to the screen so that
you have fewer lines of data to look at.
+Example
+-------
+
+::
+
+ // Clear the screen before printing a report
+ cls;
+ print "Monthly Sales Report";
+ print "====================";
+
.. seealso:: `locate`
diff --git a/docs/clusterse.rst b/docs/clusterse.rst
index 6a8274f1..142daae6 100644
--- a/docs/clusterse.rst
+++ b/docs/clusterse.rst
@@ -27,7 +27,7 @@ Format
:param dataset: name of dataset.
:type dataset: string
- :param formula: `formula string` of the independent variables.
+ :param formula: ``formula string`` of the independent variables.
E.g :code:`"X1 + X2"`, '*X1*' and '*X2*' are names of independent variables;
:type formula: String
diff --git a/docs/cmlmtinversewaldlimits.rst b/docs/cmlmtinversewaldlimits.rst
index 37479193..67bf9db2 100644
--- a/docs/cmlmtinversewaldlimits.rst
+++ b/docs/cmlmtinversewaldlimits.rst
@@ -114,3 +114,5 @@ The following is a complete example demonstrating the use of :func:`cmlmtInverse
// Print results
call cmlmtPrt(out1);
+
+.. seealso:: Functions :func:`cmlmt`
diff --git a/docs/coming-to-gauss/intro-gauss-for-eviews-users.rst b/docs/coming-to-gauss/intro-gauss-for-eviews-users.rst
new file mode 100644
index 00000000..1da5017d
--- /dev/null
+++ b/docs/coming-to-gauss/intro-gauss-for-eviews-users.rst
@@ -0,0 +1,868 @@
+
+Introduction to GAUSS for EViews Users
+======================================
+
+This guide helps EViews users do the same things in GAUSS. If you're comfortable with workfiles, VAR models, IRFs, and ARIMA estimation, you'll find equivalent tools in GAUSS -- with more flexibility for custom models and reproducible workflows.
+
+.. note::
+
+ This guide is written for GAUSS 26. Time series functions (ARIMA, VAR, GARCH) require the **TSMT** add-on.
+
+How GAUSS Differs from EViews
+------------------------------
+
+- **Your analysis is code.** EViews blends GUI dialogs, command window entries, and program files. In GAUSS, your entire workflow is a program file -- reproducible, version-controlled, and shareable. No clicking through dialogs to re-estimate.
+- **No workfile -- load data directly.** EViews requires creating a workfile first, then importing series into it. GAUSS loads data directly into a dataframe with :func:`loadd` -- no workfile setup step.
+- **Multiple datasets at once.** EViews ties your analysis to one workfile at a time. GAUSS can hold many datasets in memory simultaneously.
+- **Results in structures, not object views.** EViews stores results in "equation" and "VAR" objects that you view in windows. GAUSS returns results in structures with named members (``out.b``, ``out.sigma``) that you access in code.
+- **Full programming language.** EViews handles loops and basic logic. GAUSS is a complete matrix programming language -- you can write custom estimators, simulation studies, and bootstrap procedures.
+
+**Where to type code:**
+
+.. figure:: ../_static/images/gauss26-ide-overview.png
+ :alt: GAUSS 26 IDE showing editor with sample program, project
+ folders on the left, and command output below.
+
+ The GAUSS IDE workspace.
+
+① **Toolbar** — Shows your current working directory and the **Run button** (green arrow). Click it or press F5 to execute. ② **Project Folders** — File browser, similar to EViews' Workfile contents. ③ **Editor** — Write programs here, similar to EViews' program editor. ④ **Command Window** — Output appears here, similar to EViews' output window. You can also type single lines at the ``>>`` prompt.
+
+**Debugging:** Errors appear in the Output window with a line number -- click it to jump to the error. Use the Variables panel (View > Variables) to inspect values at runtime. You can set breakpoints by clicking in the left margin of the editor, then step through code with the Debug menu. For quick debugging, insert ``print varname;`` statements.
+
+Key Syntax Differences
+-----------------------
+
++-------------------+---------------------------+---------------------------+
+| Feature | EViews | GAUSS |
++===================+===========================+===========================+
+| Statement end | Newline | Required ``;`` |
++-------------------+---------------------------+---------------------------+
+| Indexing | 1-based (series obs) | 1-based |
++-------------------+---------------------------+---------------------------+
+| String quotes | ``" "`` | ``" "`` only |
++-------------------+---------------------------+---------------------------+
+| Assignment | ``=`` | ``=`` (same) |
++-------------------+---------------------------+---------------------------+
+| All rows/cols | (implicit in series) | ``.`` |
++-------------------+---------------------------+---------------------------+
+| Comments | ``' comment`` | ``// comment`` |
++-------------------+---------------------------+---------------------------+
+| String concat | ``+`` | ``$+`` |
++-------------------+---------------------------+---------------------------+
+| String equality | ``=`` | ``$==`` |
++-------------------+---------------------------+---------------------------+
+
+Operators
+---------
+
+**Matrix vs element-wise multiplication:**
+
+::
+
+ // GAUSS
+ A * B; // Matrix multiplication
+ A .* B; // Element-wise multiplication
+ A .^ 2; // Element-wise power
+ A ./ B; // Element-wise division
+ A'; // Transpose
+
+.. warning::
+
+ **``*`` is matrix multiplication in GAUSS.** EViews handles this behind the scenes. In GAUSS, ``A * B`` is matrix multiplication and ``A .* B`` is element-wise. Using the wrong one produces wrong results silently.
+
+**Comparison operators have two forms.** Without a dot, ``A > 0`` returns a scalar -- true only if ALL elements satisfy the condition. With a dot, ``A .> 0`` tests each element individually:
+
+::
+
+ // GAUSS
+ A .> 0; // Element-wise: returns 1/0 for each element
+ A .== B; // Element-wise equality
+ A .and B; // Element-wise AND
+ A .or B; // Element-wise OR
+
+.. warning::
+
+ ``A > 0`` is true only if every element is positive (like EViews's ``@all``). ``A .> 0`` tests each element. Both forms exist for: ``>``/``.>``, ``<``/``.<``, ``>=``/``.>=``, ``<=``/``.<=``, ``==``/``.==``, ``!=``/``.!=``.
+
+Concatenation
+-------------
+
+::
+
+ // GAUSS
+ A ~ B; // Horizontal concatenation (tilde)
+ A | B; // Vertical concatenation (pipe)
+ a $+ b; // String concatenation
+
+.. warning::
+
+ **``|`` is vertical concatenation, not logical OR.** ``condition1 | condition2`` stacks two vectors vertically. Use ``.or`` for logical OR and ``.and`` for logical AND.
+
+For string arrays, use ``$~`` (horizontal) and ``$|`` (vertical): ``"Domestic" $| "Foreign"`` creates a 2x1 string array.
+
+**String operators use the ``$`` prefix.** In EViews, ``+`` concatenates strings and ``=`` compares them. In GAUSS: ``$+`` (concatenation), ``$==`` (equality), ``$~`` (horizontal join), ``$|`` (vertical join).
+
+Indexing
+--------
+
+EViews manages series by name within a workfile. In GAUSS, you index dataframes directly by row and column:
+
+::
+
+ // GAUSS
+ data = loadd("gdp_data.xlsx");
+
+ data[., "gdp"]; // Column by name (dot = all rows)
+ data[., "gdp" "cpi"]; // Multiple columns (space-separated names)
+ data[., 1]; // Column by position
+ data[1, 1]; // First row, first column
+ data[1:10, .]; // Rows 1 through 10 (inclusive)
+ data[rows(data), .]; // Last row (no negative indexing)
+
+**Key points:**
+
+- GAUSS uses ``.`` for "all rows" or "all columns"
+- Slices are inclusive: ``data[1:5, .]`` gets rows 1 through 5
+- No negative indexing. Use ``rows(data)`` for the last row.
+
+.. note::
+
+ Most examples below use the ``auto2`` dataset bundled with GAUSS. To run them, load it first:
+
+ ::
+
+ auto2 = loadd(getGAUSSHome("examples/auto2.dta"));
+
+Data: Workfiles vs. Dataframes
+------------------------------
+
+In EViews, you create a workfile and import series:
+
+.. code-block:: none
+
+ ' EViews
+ wfcreate q 1960Q1 2020Q4
+ import "gdp_data.xlsx"
+
+In GAUSS, you load data directly into a dataframe -- no workfile setup:
+
+::
+
+ // GAUSS - one function reads CSV, Excel, Stata, SAS, SPSS, HDF5
+ data = loadd("gdp_data.xlsx");
+
+ // Check what you loaded
+ print getcolnames(data)'; // Column names
+ print rows(data) "observations";
+ head(data); // First 5 rows (like EViews's spreadsheet view)
+
+**Loading specific variables** uses a formula string with ``+``:
+
+::
+
+ // Load only these variables
+ data = loadd("macro_data.csv", "gdp + cpi + unrate");
+
+ // Load all variables except one
+ data = loadd("macro_data.csv", ". -date_str");
+
+**Accessing variables:**
+
+.. code-block:: none
+
+ ' EViews - reference by name
+ show gdp
+
+::
+
+ // GAUSS - index by column name
+ gdp = data[., "gdp"];
+
+**Creating new variables:**
+
+.. code-block:: none
+
+ ' EViews
+ series gdp_growth = dlog(gdp)
+ series lgdp = log(gdp)
+
+::
+
+ // GAUSS - use lagn() for lags, ln() for natural log
+ lgdp = ln(data[., "gdp"]);
+ gdp_growth = lgdp - lagn(lgdp, 1); // lagn fills the first obs with missing
+
+.. warning::
+
+ **log vs ln**: EViews's ``log()`` is the natural logarithm. GAUSS's ``log()`` is **base 10**. Use ``ln()`` in GAUSS. Forgetting this will silently corrupt every model that uses logged variables.
+
+**Generating lags and differences:**
+
+.. code-block:: none
+
+ ' EViews
+ series y_lag1 = y(-1)
+ series y_lag2 = y(-2)
+ series dy = d(y)
+
+::
+
+ // GAUSS
+ y_lag1 = lagn(y, 1); // Lag 1 (first obs becomes missing)
+ y_lag2 = lagn(y, 2); // Lag 2 (first two obs become missing)
+ dy = y - lagn(y, 1); // First difference
+ dlog_y = ln(y) - lagn(ln(y), 1); // Log difference (like EViews's dlog)
+
+.. note::
+
+ :func:`lagn` fills lagged observations with ``miss()``. Use :func:`packr` to drop rows with missing values after creating lags or differences.
+
+Data Import/Export
+------------------
+
+::
+
+ // GAUSS - loadd handles all formats
+ data = loadd("data.csv");
+ data = loadd("data.dta"); // Stata
+ data = loadd("data.sas7bdat"); // SAS
+ data = loadd("data.xlsx"); // Excel
+
+ // Export
+ saved(data, "output.csv");
+ saved(data, "output.xlsx");
+
+**Formula string quick reference:** GAUSS uses formula strings in several contexts:
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Context
+ - Example
+ - Separator
+ * - :func:`loadd` (loading)
+ - ``"gdp + cpi + unrate"``
+ - ``+`` lists variables
+ * - :func:`olsmt` (models)
+ - ``"price ~ mpg + weight"``
+ - ``~`` separates y from X
+ * - Bracket indexing
+ - ``data[., "gdp" "cpi"]``
+ - Space separates names
+ * - Type overrides
+ - ``"date($Date) + cat(x)"``
+ - Keywords wrap variable names
+
+Data Manipulation
+-----------------
+
+.. code-block:: none
+
+ ' EViews
+ smpl if foreign = 0
+ sort mpg
+
+::
+
+ // GAUSS
+ domestic = selif(auto2, auto2[., "foreign"] .== 0); // Filter rows
+ sorted = sortc(auto2, "mpg"); // Sort by column
+
+.. warning::
+
+ **GAUSS does not support boolean indexing.** Use :func:`selif` to filter rows: ``selif(df, condition)``. Passing a boolean vector to brackets will not filter -- it interprets the 0s and 1s as row numbers.
+
+**Common operations:**
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - EViews
+ - GAUSS
+ * - ``smpl if x > 5``
+ - ``selif(df, df[., "x"] .> 5)``
+ * - ``sort x``
+ - ``sortc(df, "x")``
+ * - ``series z = x + y``
+ - ``dfaddcol(df, "z", df[., "x"] + df[., "y"])``
+ * - ``group mygrp x y``
+ - ``df[., "x" "y"]``
+ * - (manual in EViews)
+ - ``aggregate(df, "mean", "group_var")``
+
+Missing Values
+--------------
+
+EViews handles missing values within the workfile automatically. In GAUSS, you manage them explicitly:
+
+.. code-block:: none
+
+ ' EViews
+ series y_clean = @nan(y, 0)
+ smpl if y <> NA
+
+::
+
+ // GAUSS
+ miss(); // Creates a missing value (like EViews's NA)
+ ismiss(x); // Returns 1 if ANY element is missing (scalar)
+ x .== miss(); // Element-wise check (returns 1/0 vector)
+ packr(data); // Drop rows with any missing value
+ missrv(x, 0); // Replace missing with 0
+
+.. warning::
+
+ **ismiss is NOT element-wise.** ``ismiss(x)`` returns a **scalar** (1 if any element is missing, 0 otherwise). For element-wise missing detection, use ``x .== miss()``.
+
+Descriptive Statistics
+----------------------
+
+.. code-block:: none
+
+ ' EViews
+ gdp.stats
+
+::
+
+ // GAUSS - dstatmt prints a summary table (like EViews's stats view)
+ call dstatmt(auto2[., "price" "mpg" "weight"]);
+
+Output::
+
+ ------------------------------------------------------------------------------------------
+ Variable Mean Std Dev Variance Minimum Maximum Valid Missing
+ ------------------------------------------------------------------------------------------
+ price 6165.26 2949.50 8699530.9 3291 15906 74 0
+ mpg 21.30 5.79 33.47 12 41 74 0
+ weight 3019.46 777.19 604021.4 1760 4840 74 0
+
+**Column-wise statistics:**
+
+::
+
+ // GAUSS
+ meanc(x); // Column mean (the 'c' suffix = column-wise)
+ stdc(x); // Column standard deviation (uses N-1)
+ sumc(x); // Column sum
+ minc(x); // Column min
+ maxc(x); // Column max
+ median(x); // Median
+
+ // Row-wise
+ meanr(X); // Row mean (the 'r' suffix = row-wise)
+ sumr(X); // Row sum
+
+OLS Regression
+--------------
+
+.. code-block:: none
+
+ ' EViews
+ equation eq1.ls price c mpg weight
+
+::
+
+ // GAUSS - print formatted summary (like EViews's equation view)
+ call olsmt(auto2, "price ~ mpg + weight");
+
+Output::
+
+ Valid cases: 74 Dependent variable: price
+ Missing cases: 0 Deletion method: None
+ Total SS: 634007042 Degrees of freedom: 71
+ R-squared: 0.2926 Rbar-squared: 0.2727
+ Residual SS: 448544672 Std error of est: 2514.3269
+ F(2,71): 14.6874 Probability of F: 0.0000
+
+ Standard Prob Standardized Cor with
+ Variable Estimate Error t-value >|t| Estimate Dep Var
+ -------------------------------------------------------------------------------
+ CONSTANT 1946.069 3597.0496 0.54101 0.5902 --- ---
+ mpg -49.5122 86.1560 -0.57464 0.5674 -0.09717 -0.4559
+ weight 1.7466 0.3712 4.70402 0.0000 0.46030 0.5386
+
+.. tip::
+
+ Use ``call olsmt(...)`` to print a formatted summary without saving results. The ``call`` keyword discards return values -- useful for quick exploration.
+
+**Accessing results:**
+
+.. code-block:: none
+
+ ' EViews
+ eq1.@coefs
+ eq1.@se
+ eq1.@r2
+
+::
+
+ // GAUSS
+ struct olsmtOut out;
+ out = olsmt(auto2, "price ~ mpg + weight");
+
+ print out.b; // Coefficient estimates
+ print out.stderr; // Standard errors
+ print out.rsq; // R-squared
+ print out.resid; // Residuals
+ print out.vc; // Variance-covariance of estimates
+
+Key :class:`olsmtOut` members: ``b`` (coefficients), ``stderr`` (standard errors), ``vc`` (variance-covariance matrix), ``rsq`` (R-squared), ``resid`` (residuals), ``dwstat`` (Durbin-Watson), ``sigma`` (residual std dev).
+
+Time Series Analysis (TSMT)
+----------------------------
+
+GAUSS's time series tools are in the **TSMT** add-on. Add this line at the top of your script:
+
+::
+
+ library tsmt;
+
+If this produces an error, contact Aptech to add TSMT to your license. All examples in this section require TSMT.
+
+ARIMA
+^^^^^
+
+.. code-block:: none
+
+ ' EViews
+ equation eq1.ls d(gdp) c ar(1) ma(1)
+
+::
+
+ // GAUSS
+ library tsmt;
+
+ // Load unemployment rate data
+ data = loadd(getGAUSSHome("examples/UNRATE.csv"));
+ y = data[., "UNRATE"];
+
+ // Fit ARIMA(1,1,1)
+ struct arimamtOut aOut;
+ aOut = arimaFit(y, 1, 1, 1);
+
+Output::
+
+ ================================================================================
+ Coefficient Estimate Std. Err. T-Ratio Prob |>| t
+ ================================================================================
+
+ AR[1,1] -0.722 0.167 -4.333 0.000
+ MA[1,1] -0.798 0.143 -5.580 0.000
+ Constant -0.001 0.695 -0.001 0.999
+ ================================================================================
+
+VAR Estimation
+^^^^^^^^^^^^^^
+
+.. code-block:: none
+
+ ' EViews
+ var myvar.ls 1 2 dln_inv dln_inc dln_consump
+
+::
+
+ // GAUSS
+ library tsmt;
+
+ // Load Lutkepohl data (included with TSMT)
+ data = loadd(getGAUSSHome("pkgs/tsmt/examples/lutkepohl2.gdat"));
+
+ // Select variables and estimate VAR
+ y = data[., "dln_inv" "dln_inc" "dln_consump"];
+
+ struct svarOut sout;
+ sout = svarFit(y);
+
+**Accessing VAR results:**
+
+.. code-block:: none
+
+ ' EViews
+ myvar.@coefs
+ myvar.@residcov
+
+::
+
+ // GAUSS - results stored in structure members
+ print sout.coefficients; // Coefficient matrix
+ print sout.residuals; // Residuals
+ print sout.aic; // Information criteria
+ print sout.sbc;
+
+Impulse Response Functions
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: none
+
+ ' EViews
+ myvar.impulse(10, a, m) dln_inv dln_inc dln_consump
+
+::
+
+ // GAUSS - IRF computed as part of svarFit, just plot it
+ plotIRF(sout);
+
+ // Access the IRF matrices directly
+ print sout.irf;
+
+Forecast Error Variance Decomposition
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: none
+
+ ' EViews
+ myvar.decomp(10) dln_inv dln_inc dln_consump
+
+::
+
+ // GAUSS
+ plotFEVD(sout); // Plot variance decomposition
+
+ // Historical decomposition
+ plotHD(sout);
+
+GARCH
+^^^^^
+
+.. code-block:: none
+
+ ' EViews
+ equation eq1.arch(1,1) y c
+
+::
+
+ // GAUSS
+ library tsmt;
+
+ y = loadd(getGAUSSHome("pkgs/tsmt/examples/garch.dat"));
+
+ struct garchEstimation gOut;
+ gOut = garchFit(y, 1, 1);
+
+Output::
+
+ ================================================================================
+ Model: GARCH(1,1) Dependent variable: Y
+ Time Span: Unknown Valid cases: 300
+ ================================================================================
+ Coefficient Upper CI Lower CI
+
+ beta0[1,1] 0.01208 -0.00351 0.02768
+ garch[1,1] 0.15215 -0.46226 0.76655
+ arch[1,1] 0.18499 0.01761 0.35236
+ omega[1,1] 0.01429 0.00182 0.02675
+ ================================================================================
+
+ AIC: 315.54085
+ LRS: 307.54085
+
+For GJR-GARCH (asymmetric), use :func:`garchGJRFit`. For IGARCH, use :func:`igarchFit`.
+
+Unit Root Tests
+^^^^^^^^^^^^^^^
+
+.. code-block:: none
+
+ ' EViews
+ y.uroot(adf, 4)
+ y.uroot(kpss)
+
+::
+
+ // GAUSS (TSMT)
+ library tsmt;
+
+ // DF-GLS test (Elliott, Rothenberg, Stock 1996)
+ { tstat, crit } = dfgls(y, 4); // max 4 lags
+
+ // KPSS stationarity test
+ { tstat, crit } = kpss(y, 4); // max 4 lags
+
+TSMT includes :func:`dfgls` (DF-GLS), :func:`kpss` (KPSS stationarity test), and the Zivot-Andrews structural break test. Results include test statistics and critical values at standard significance levels.
+
+Forecasting
+^^^^^^^^^^^
+
+.. code-block:: none
+
+ ' EViews
+ myvar.forecast(e) 12
+
+::
+
+ // GAUSS - forecast from a VARMA model
+ library tsmt;
+
+ // Estimate and forecast
+ struct varmamtOut vOut;
+ vOut = varmaFit(y, 2, 0); // VAR(2)
+ fcast = varmaPredict(vOut, y, 0, 12); // 12 periods ahead (y=data, 0=no exog)
+
+Plotting
+--------
+
+EViews has rich graph objects. GAUSS's graphics library covers the same ground:
+
+::
+
+ // GAUSS
+ plotXY(x, y); // Line plot
+ plotScatter(x, y); // Scatter plot
+ plotHist(x, 20); // Histogram with 20 bins
+ plotBox(data, "val ~ group"); // Box plot
+ plotBar(labels, heights); // Bar chart
+ plotTS(1960, 4, data[., "gdp"]); // Time series plot (start year, frequency, data)
+
+**Customizing plots** uses a :class:`plotControl` structure -- think of it as configuring chart options before drawing:
+
+::
+
+ // Create a scatter plot with title and labels
+ struct plotControl myPlot;
+ myPlot = plotGetDefaults("scatter");
+
+ plotSetTitle(&myPlot, "MPG vs Weight");
+ plotSetXLabel(&myPlot, "Weight (lbs)");
+ plotSetYLabel(&myPlot, "Miles per gallon");
+ plotSetLegend(&myPlot, "Domestic" $| "Foreign");
+
+ plotScatter(myPlot, auto2[., "weight"], auto2[., "mpg"]);
+
+**Subplots and saving:**
+
+::
+
+ plotLayout(2, 1, 1); // 2 rows, 1 col, position 1
+ plotSave("plot.png", 640|480); // Save with size (width|height in pixels)
+
+Functions and Procedures
+------------------------
+
+EViews subroutines are limited to basic operations. GAUSS has a full procedure system:
+
+.. code-block:: none
+
+ ' EViews
+ subroutine my_func(scalar x, scalar y)
+ %result = x + y
+ endsub
+
+::
+
+ // GAUSS
+ proc (1) = my_func(x, y);
+ local result;
+ result = x + y;
+ retp(result);
+ endp;
+
+ answer = my_func(3, 4); // answer = 7
+
+**Key points:**
+
+- ``proc (n) =`` declares the number of return values
+- ``local`` declares variables scoped to this procedure (see warning below)
+- ``retp()`` returns values
+- ``endp`` ends the procedure
+- Procedures can be defined anywhere in the file -- before or after the code that calls them
+
+**Multiple outputs:**
+
+::
+
+ proc (2) = stats(x);
+ local mn, sd;
+ mn = meanc(x);
+ sd = stdc(x);
+ retp(mn, sd);
+ endp;
+
+ { my_mean, my_std } = stats(rndn(100, 1));
+
+.. warning::
+
+ **Variables are global by default.** In GAUSS, you must declare variables with ``local`` inside ``proc`` or they become globals that persist after the procedure returns. Forgetting ``local`` creates hard-to-find bugs where procedures silently modify variables in the calling scope. Make it a habit to declare ``local`` for every variable inside a ``proc``.
+
+Control Flow
+------------
+
+.. code-block:: none
+
+ ' EViews
+ for !i = 1 to 10
+ ' do something
+ next
+
+ if condition then
+ ' do something
+ endif
+
+::
+
+ // GAUSS
+ for i (1, 10, 1);
+ print i;
+ endfor;
+
+ if x > 0;
+ print "positive";
+ elseif x < 0;
+ print "negative";
+ else;
+ print "zero";
+ endif;
+
+ do while x > 0;
+ x = x - 1;
+ endo;
+
+**Note:** GAUSS requires semicolons after control statements (``if``, ``for``, ``else``, etc.). Inside a ``proc``, remember to declare loop variables with ``local``.
+
+Common Operations: Quick Reference
+-----------------------------------
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Task
+ - EViews
+ - GAUSS
+ * - Load file
+ - ``import "file.xlsx"``
+ - ``loadd("file.xlsx")``
+ * - Natural log
+ - ``log(y)``
+ - ``ln(y)``
+ * - Log base 10
+ - ``@log10(y)``
+ - ``log(y)``
+ * - First difference
+ - ``d(y)``
+ - ``y - lagn(y, 1)``
+ * - Lag
+ - ``y(-1)``
+ - ``lagn(y, 1)``
+ * - OLS
+ - ``equation.ls y c x1 x2``
+ - ``olsmt(data, "y ~ x1 + x2")``
+ * - ARIMA
+ - ``eq.ls y c ar(1) ma(1)``
+ - ``arimaFit(y, 1, 0, 1)``
+ * - VAR
+ - ``var.ls 1 2 y1 y2``
+ - ``svarFit(data[., "y1" "y2"])``
+ * - GARCH(1,1)
+ - ``eq.arch(1,1) y c``
+ - ``garchFit(y, 1, 1)``
+ * - Unit root test
+ - ``y.uroot(adf, 4)``
+ - ``dfgls(y, 4)``
+ * - Stationarity test
+ - ``y.uroot(kpss)``
+ - ``kpss(y, 4)``
+ * - IRF plot
+ - ``var.impulse(10)``
+ - ``plotIRF(sout)``
+ * - Descriptive stats
+ - ``y.stats``
+ - ``call dstatmt(y)``
+ * - Scatter plot
+ - ``scat x y``
+ - ``plotScatter(x, y)``
+ * - Export
+ - ``write "output.xlsx"``
+ - ``saved(data, "output.xlsx")``
+ * - Sort
+ - ``sort x``
+ - ``sortc(df, "x")``
+ * - Filter
+ - ``smpl if x > 5``
+ - ``selif(df, df[., "x"] .> 5)``
+ * - Drop missing
+ - ``smpl if y <> NA``
+ - ``packr(df)``
+ * - Print
+ - ``show x``
+ - ``print x;``
+ * - Comment
+ - ``' comment``
+ - ``// comment``
+
+.. note::
+
+ **Reminder:** EViews's ``log()`` is natural log. GAUSS's ``log()`` is base 10. Use ``ln()``. See the full warning in the `Data <#data-workfiles-vs-dataframes>`__ section above.
+
+Common Gotchas
+--------------
+
+1. **Semicolons required.** Every statement ends with ``;``. This is the first thing EViews users forget.
+
+2. **log() is base 10, ln() is natural log.** EViews's ``log`` = GAUSS's ``ln``.
+
+3. **Operators are explicit.** ``*`` is matrix multiply, ``.*`` is element-wise. ``>`` is a scalar test, ``.>`` is element-wise.
+
+4. **``|`` is concatenation, not OR.** Use ``.or`` for logical OR, ``.and`` for AND.
+
+5. **No boolean indexing.** ``df[condition, .]`` does not filter. Use ``selif(df, condition)``.
+
+6. **Declare ``local`` in procedures.** Without ``local``, variables leak to the global scope.
+
+7. **String operators need ``$``.** Use ``$+`` for concatenation, ``$==`` for equality.
+
+8. **The ``call`` keyword.** Use ``call functionName(...)`` to run a function and discard its return value. This is useful for printing summaries: ``call olsmt(data, "y ~ x1");`` prints without saving.
+
+9. **No negative indexing.** Use ``rows(x)`` for the last row, ``cols(x)`` for the last column.
+
+Putting It Together
+-------------------
+
+Here is a complete, runnable example that loads data, creates variables, plots, and runs a regression. Press F5 to run it.
+
+::
+
+ // Load the auto2 dataset bundled with GAUSS
+ auto2 = loadd(getGAUSSHome("examples/auto2.dta"));
+
+ // Summary statistics
+ call dstatmt(auto2[., "price" "mpg" "weight"]);
+
+ // Keep only domestic cars
+ domestic = selif(auto2, auto2[., "foreign"] .== 0);
+
+ // Add a new variable
+ domestic = dfaddcol(domestic, "price_k", domestic[., "price"] ./ 1000);
+
+ // Scatter plot with title
+ struct plotControl myPlot;
+ myPlot = plotGetDefaults("scatter");
+ plotSetTitle(&myPlot, "Weight vs MPG (Domestic Cars)");
+ plotSetXLabel(&myPlot, "Weight (lbs)");
+ plotSetYLabel(&myPlot, "Miles per gallon");
+ plotScatter(myPlot, domestic[., "weight"], domestic[., "mpg"]);
+
+ // OLS regression: how does weight affect fuel efficiency?
+ struct olsmtOut out;
+ out = olsmt(domestic, "mpg ~ weight");
+
+ // Print key results
+ print "Coefficients:"; print out.b;
+ print "Standard errors:"; print out.stderr;
+ print "R-squared:"; print out.rsq;
+
+What's Next?
+------------
+
+- :doc:`../getting-started/quickstart` -- 10-minute introduction to GAUSS basics
+- :doc:`../getting-started/running-existing-code` -- If you inherited GAUSS code and need to get it running
+- :doc:`../data-management` -- Loading, cleaning, and reshaping data
+- :doc:`../textbook-examples/index` -- Worked examples from Greene (*Econometric Analysis*) and Brooks (*Introductory Econometrics for Finance*)
+- `Command Reference <../command-reference.html>`__ -- Browse all 1,000+ built-in functions
+- `Econometrics blog `__ -- Fully worked examples covering regression, panel data, hypothesis testing, and more
+- `Time series blog `__ -- ARIMA, VAR, GARCH, cointegration, and forecasting tutorials with complete code
+
+.. seealso::
+
+ :func:`loadd`, :func:`olsmt`, :func:`selif`, :func:`plotXY`, :func:`packr`, :func:`arimaFit`, :func:`svarFit`, :func:`garchFit`, :func:`dfgls`, :func:`kpss`, :func:`plotIRF`
diff --git a/docs/coming-to-gauss/intro-gauss-for-matlab-users.rst b/docs/coming-to-gauss/intro-gauss-for-matlab-users.rst
new file mode 100644
index 00000000..9ab6df8b
--- /dev/null
+++ b/docs/coming-to-gauss/intro-gauss-for-matlab-users.rst
@@ -0,0 +1,771 @@
+
+Introduction to GAUSS for MATLAB Users
+======================================
+
+If you work with matrices, optimization, and numerical computing in MATLAB, you'll find GAUSS handles these the same way -- with differences in syntax and a stronger focus on econometrics and statistics. This guide maps MATLAB concepts, syntax, and workflows to their GAUSS equivalents.
+
+.. note::
+
+ This guide is written for GAUSS 26. Some features (such as :func:`repmat`, :func:`findIdx`, :func:`diagmat`, and the colon operator for sequences) require GAUSS 26.0.1 or later.
+
+**Where to type code:**
+
+.. figure:: ../_static/images/gauss26-ide-overview.png
+ :alt: GAUSS 26 IDE showing editor with sample program, project
+ folders on the left, and command output below.
+
+ The GAUSS IDE workspace.
+
+① **Toolbar** — Shows your current working directory and the **Run button** (green arrow). Click it or press F5 to execute. ② **Project Folders** — File browser, similar to MATLAB's Current Folder. ③ **Editor** — Write programs here, similar to the MATLAB Editor. ④ **Command Window** — Output appears here, similar to MATLAB's Command Window. You can also type single lines at the ``>>`` prompt.
+
+**Debugging:** Errors appear in the Output window with a line number -- click it to jump to the error. Use the Variables panel (View > Variables) to inspect values at runtime. You can set breakpoints by clicking in the left margin of the editor, then step through code with the Debug menu. For quick debugging, insert ``print varname;`` statements.
+
+**Inspecting structures:** To see what fields an output structure contains, use ``print`` -- for example, ``print out;`` displays all members and their values. To see just the field names, check the structure definition in the Command Reference (press F1 on the function name).
+
+How GAUSS Differs from MATLAB
+-----------------------------
+
+GAUSS shares MATLAB's matrix-first philosophy but is oriented around statistics and econometrics rather than engineering. Here are the practical differences that affect your daily coding:
+
+- **Dataframes are matrices**: Named columns and typed variables, but you can do matrix algebra on them directly -- no ``table2array`` conversion step.
+- **Column-wise by default**: Statistical functions operate on columns (``meanc``, ``stdc``, ``sumc``), matching the convention that columns are variables and rows are observations.
+- **Formula strings for estimation**: Model specification uses ``"y ~ x1 + x2"`` syntax (similar to R). Categorical variables are handled automatically.
+- **Structures for output**: Estimation results are returned in structures with named members (``out.b``, ``out.stderr``), similar to MATLAB structs.
+- **No toolbox fees**: OLS, GLM, quantile regression, optimization, and plotting are all included in the base package -- no extra toolboxes required.
+
+Key Syntax Differences
+----------------------
+
++-------------------+---------------------------+---------------------------+
+| Feature | MATLAB | GAUSS |
++===================+===========================+===========================+
+| Indexing | 1-based | 1-based (same) |
++-------------------+---------------------------+---------------------------+
+| Matrix delimiter | ``[ ]`` | ``{ }`` |
++-------------------+---------------------------+---------------------------+
+| Row separator | ``;`` or newline | ``,`` |
++-------------------+---------------------------+---------------------------+
+| String quotes | ``" "`` or ``' '`` | ``" "`` only |
++-------------------+---------------------------+---------------------------+
+| Statement end | Optional ``;`` | Required ``;`` |
++-------------------+---------------------------+---------------------------+
+| All rows/cols | ``:`` | ``.`` |
++-------------------+---------------------------+---------------------------+
+| Concatenate horiz | ``[A B]`` | ``A~B`` |
++-------------------+---------------------------+---------------------------+
+| Concatenate vert | ``[A; B]`` | ``A|B`` |
++-------------------+---------------------------+---------------------------+
+| Solve ``Ax = b`` | ``A\b`` | ``b/A`` |
++-------------------+---------------------------+---------------------------+
+
+.. note::
+
+ Most examples below use the ``auto2`` dataset bundled with GAUSS. To run them, load it first:
+
+ ::
+
+ auto2 = loadd(getGAUSSHome("examples/auto2.dta"));
+
+Matrix Creation
+---------------
+
+.. code-block:: matlab
+
+ % MATLAB
+ A = [1 2 3; 4 5 6; 7 8 9]
+
+::
+
+ // GAUSS
+ A = { 1 2 3, 4 5 6, 7 8 9 };
+
+**Note:** GAUSS uses braces ``{ }`` and commas between rows. Semicolons end statements, not rows. Unlike MATLAB, newlines are not row separators -- you must use commas.
+
+Special matrices:
+
+.. code-block:: matlab
+
+ % MATLAB
+ zeros(3,3)
+ ones(3,3)
+ eye(3)
+ rand(3,3)
+ randn(3,3)
+
+::
+
+ // GAUSS
+ zeros(3, 3);
+ ones(3, 3);
+ eye(3);
+ rndu(3, 3); // Uniform [0,1]
+ rndn(3, 3); // Standard normal
+
+Sequences:
+
+.. code-block:: matlab
+
+ % MATLAB
+ 1:5 % Row vector [1 2 3 4 5]
+ 1:0.5:3 % [1 1.5 2 2.5 3]
+ linspace(0,1,5)
+
+::
+
+ // GAUSS
+ 1:5; // Column vector {1, 2, 3, 4, 5} (NOTE: MATLAB gives a row vector)
+ 1:0.5:3; // Column vector {1, 1.5, 2, 2.5, 3}
+ seqa(1, 1, 5); // Column vector, start=1, inc=1, n=5
+ seqa(0, 0.25, 5); // Column vector {0, 0.25, 0.5, 0.75, 1}
+
+**Note:** MATLAB's colon operator produces row vectors; GAUSS produces column vectors. MATLAB's ``linspace(0, 1, 5)`` takes start, end, and count. GAUSS's :func:`seqa` takes start, increment, and count -- you must compute the step size yourself: ``seqa(0, (1-0)/(5-1), 5)``.
+
+Indexing
+--------
+
+Both languages use 1-based indexing, but the "all elements" syntax differs:
+
+.. code-block:: matlab
+
+ % MATLAB
+ A(1,1) % Element
+ A(1,:) % First row
+ A(:,1) % First column
+ A(1:2,:) % Rows 1-2
+ A(end,:) % Last row
+ A(end-2:end,:) % Last 3 rows
+
+::
+
+ // GAUSS
+ A[1, 1]; // Element
+ A[1, .]; // First row (dot = all)
+ A[., 1]; // First column
+ A[1:2, .]; // Rows 1-2
+ A[rows(A), .]; // Last row (no 'end' keyword)
+ A[rows(A)-2:rows(A), .]; // Last 3 rows
+
+GAUSS dataframes also support indexing by column name:
+
+::
+
+ auto2[., "mpg"]; // One column by name
+ auto2[., "mpg" "weight"]; // Multiple columns (space-separated)
+ auto2[1:10, "mpg"]; // First 10 rows of mpg
+
+**Key difference:** MATLAB uses ``:`` for "all", GAUSS uses ``.``. Use ``rows(A)`` and ``cols(A)`` where MATLAB uses ``end``.
+
+Operators
+---------
+
+Element-wise vs. matrix operations:
+
+.. code-block:: matlab
+
+ % MATLAB
+ A * B % Matrix multiplication
+ A .* B % Element-wise multiplication
+ A .^ 2 % Element-wise power
+ A' % Transpose
+
+::
+
+ // GAUSS
+ A * B; // Matrix multiplication (same)
+ A .* B; // Element-wise multiplication (same)
+ A .^ 2; // Element-wise power (same)
+ A'; // Transpose (same)
+
+Element-wise arithmetic operators (``.* ./ .^``) and transpose (``'``) work the same in both languages.
+
+**Comparison operators are different.** GAUSS uses dot-prefixed operators for element-wise comparison:
+
+.. code-block:: matlab
+
+ % MATLAB
+ A > 0 % Element-wise comparison
+ A == B % Element-wise equality
+ A ~= B % Element-wise not-equal
+ A & B % Element-wise AND
+ A | B % Element-wise OR (also vertical concat in GAUSS!)
+
+::
+
+ // GAUSS
+ A .> 0; // Element-wise comparison (dot prefix required)
+ A .== B; // Element-wise equality
+ A .!= B; // Element-wise not-equal (.ne also works)
+ A .and B; // Element-wise AND
+ A .or B; // Element-wise OR
+
+.. warning::
+
+ **Comparison operators need dots.** In MATLAB, ``A > 0`` is element-wise. In GAUSS, ``A > 0`` without the dot tests whether *all* elements satisfy the condition (returns a scalar). Use ``.>`` for element-wise results. This is the most common source of bugs for MATLAB migrants.
+
+Concatenation
+-------------
+
+.. code-block:: matlab
+
+ % MATLAB
+ [A B] % Horizontal concatenation
+ [A; B] % Vertical concatenation
+
+::
+
+ // GAUSS
+ A ~ B; // Horizontal concatenation (tilde)
+ A | B; // Vertical concatenation (pipe)
+
+For strings, use ``$~`` (horizontal) and ``$|`` (vertical): ``"Domestic" $| "Foreign"`` creates a 2x1 string array.
+
+Example:
+
+::
+
+ A = { 1 2, 3 4 };
+ B = { 5, 6 };
+
+ print A ~ B; // [1 2 5; 3 4 6]
+ print A | B'; // [1 2; 3 4; 5 6]
+
+Filtering and Selection
+-----------------------
+
+MATLAB uses logical indexing directly. GAUSS uses :func:`selif` with element-wise comparison operators:
+
+.. code-block:: matlab
+
+ % MATLAB
+ A(A(:,1) > 5, :) % Rows where column 1 > 5
+ data(data.price > 10000, :) % Filter table by condition
+
+::
+
+ // GAUSS
+ selif(A, A[., 1] .> 5); // Rows where column 1 > 5
+ selif(auto2, auto2[., "price"] .> 10000); // Filter by condition
+
+ // Combine conditions
+ mask = auto2[., "mpg"] .> 20 .and auto2[., "price"] .< 8000;
+ cheap_efficient = selif(auto2, mask);
+
+Note the ``.>`` operator: GAUSS requires the dot prefix for element-wise comparison (see `Operators`_ above).
+
+**Missing values:** MATLAB uses ``NaN`` and ``isnan``; GAUSS uses ``.`` (dot) and provides several tools:
+
+.. code-block:: matlab
+
+ % MATLAB
+ clean = rmmissing(data); % Drop rows with any NaN
+ data(isnan(data)) = 0; % Replace NaN with 0
+ mask = ~isnan(data(:,3)); % Rows where column 3 is not NaN
+
+::
+
+ // GAUSS
+ clean = packr(data); // Drop rows with any missing value
+ data = missrv(data, 0); // Replace missings with 0
+ mask = data[., 3] .!= miss(1, 1); // Rows where column 3 is not missing
+
+:func:`packr` is the workhorse -- it removes any row containing a missing value. Use :func:`missrv` to replace missings with a specific value. For element-wise missing detection, use ``x .== miss(1, 1)`` (see the `Common Function Translations`_ table).
+
+Data Import/Export
+------------------
+
+.. code-block:: matlab
+
+ % MATLAB
+ data = readtable('file.csv');
+ data = xlsread('file.xlsx');
+ writetable(data, 'output.csv')
+
+::
+
+ // GAUSS - loadd reads CSV, Excel, Stata, SAS, SPSS, HDF5
+ data = loadd("file.csv");
+ data = loadd("file.xlsx");
+ data = loadd("auto2.dta"); // Stata
+ data = loadd("survey.sas7bdat"); // SAS
+
+ // Load specific variables with a formula string
+ data = loadd("auto2.dta", "mpg + rep78 + price");
+
+ // Load all variables except one
+ data = loadd("auto2.dta", ". -rep78");
+
+ // Export
+ saved(data, "output.csv");
+ saved(data, "output.xlsx");
+ saved(data, "output.gdat"); // GAUSS format
+
+:func:`getGAUSSHome` returns the path to GAUSS's installation directory. Use it to access bundled example datasets: ``loadd(getGAUSSHome("examples/auto2.dta"))``.
+
+**Formula string quick reference:** GAUSS uses formula strings in several contexts with slightly different syntax:
+
++--------------------------+----------------------------+--------------------------------+
+| Context | Example | Separator |
++==========================+============================+================================+
+| :func:`loadd` (loading) | ``"mpg + weight + price"`` | ``+`` lists variables |
++--------------------------+----------------------------+--------------------------------+
+| :func:`olsmt` (models) | ``"price ~ mpg + weight"`` | ``~`` separates y from X |
++--------------------------+----------------------------+--------------------------------+
+| Bracket indexing | ``auto2[., "mpg" "wt"]`` | Space separates names |
++--------------------------+----------------------------+--------------------------------+
+| Type overrides | ``"date($Date) + cat(x)"`` | Keywords wrap variable names |
++--------------------------+----------------------------+--------------------------------+
+
+Statistics and Econometrics
+---------------------------
+
+Unlike MATLAB, where ``fitlm``, ``fitglm``, and optimization functions require the Statistics or Optimization Toolbox, GAUSS includes all of these in the base package.
+
+Basic statistics:
+
+.. code-block:: matlab
+
+ % MATLAB
+ mean(x) % Column means
+ std(x) % Column std devs
+ sum(x) % Column sums
+ cov(x) % Covariance matrix
+
+::
+
+ // GAUSS
+ meanc(x); // Column means (the 'c' suffix = column-wise)
+ stdc(x); // Column std devs
+ sumc(x); // Column sums
+ vcx(x); // Covariance matrix
+
+OLS regression:
+
+.. code-block:: matlab
+
+ % MATLAB (Statistics Toolbox)
+ mdl = fitlm(X, y);
+ mdl.Coefficients
+ mdl.Residuals.Raw
+
+::
+
+ // GAUSS
+ struct olsmtOut out;
+ out = olsmt(auto2, "price ~ mpg + weight");
+
+ // Access results through the output structure
+ print out.b; // Coefficient estimates
+ print out.stderr; // Standard errors
+ print out.rsq; // R-squared
+
+Key :class:`olsmtOut` members: ``b`` (coefficients), ``stderr`` (standard errors), ``vc`` (variance-covariance matrix), ``rsq`` (R-squared), ``resid`` (residuals), ``dwstat`` (Durbin-Watson), ``sigma`` (residual std dev), ``stb`` (standardized coefficients). To compute t-statistics and p-values: ``t = out.b ./ out.stderr``. See the :func:`olsmt` reference for the full list.
+
+.. tip::
+
+ Use ``call olsmt(...)`` (with ``call``) to print a formatted summary table to the screen without saving results to a variable. The ``call`` keyword discards return values.
+
+Logistic regression (GLM):
+
+.. code-block:: matlab
+
+ % MATLAB (Statistics Toolbox)
+ mdl = fitglm(X, y, 'Distribution', 'binomial');
+
+::
+
+ // GAUSS
+ struct glmOut out;
+ out = glm(data, "admit ~ gre + gpa + rank", "binomial");
+
+Quantile regression:
+
+::
+
+ // GAUSS (no MATLAB built-in equivalent)
+ struct qfitOut out;
+ out = quantileFit(data, "y ~ x1 + x2", 0.25 | 0.5 | 0.75);
+
+For robust or clustered standard errors, pass an :class:`olsmtControl` structure -- see the :func:`olsmt` reference for details.
+
+Plotting
+--------
+
+MATLAB users expect rich plotting. GAUSS has a full graphics library:
+
+.. code-block:: matlab
+
+ % MATLAB
+ plot(x, y)
+ scatter(x, y)
+ histogram(x, 20)
+ bar(labels, heights)
+ surf(X, Y, Z)
+ subplot(2, 1, 1)
+ title('My Plot')
+ xlabel('X axis')
+ saveas(fig, 'plot.png')
+
+::
+
+ // GAUSS
+ plotXY(x, y);
+ plotScatter(x, y);
+ plotHist(x, 20);
+ plotBar(labels, heights);
+ plotSurface(x, y, z);
+ plotLayout(2, 1, 1);
+ // Title and labels use a plotControl structure (see below)
+ plotSave("plot.png");
+
+**Setting titles, labels, and legends** uses a :class:`plotControl` structure:
+
+::
+
+ // Create a plot with title, labels, and legend
+ struct plotControl myPlot;
+ myPlot = plotGetDefaults("xy");
+
+ plotSetTitle(&myPlot, "MPG vs Weight");
+ plotSetXLabel(&myPlot, "Weight (lbs)");
+ plotSetYLabel(&myPlot, "Miles per gallon");
+ plotSetLegend(&myPlot, "Domestic" $| "Foreign");
+
+ plotXY(myPlot, auto2[., "weight"], auto2[., "mpg"]);
+
+Quick plotting example:
+
+::
+
+ // Sine wave -- no plotControl needed for simple plots
+ x = seqa(0, 0.1, 63); // 0 to ~2*pi
+ plotXY(x, sin(x));
+
+Optimization
+------------
+
+GAUSS includes unconstrained and constrained optimization in the base package.
+
++-------------------------------+-----------------------------------+
+| MATLAB | GAUSS |
++===============================+===================================+
+| ``fminunc(f, x0)`` | ``minimize(&f, x0)`` |
++-------------------------------+-----------------------------------+
+| ``fmincon(f, x0, ...)`` | ``sqpSolve(&f, x0)`` |
++-------------------------------+-----------------------------------+
+| ``fsolve(f, x0)`` | ``eqSolve(&f, x0)`` |
++-------------------------------+-----------------------------------+
+
+**Key difference:** MATLAB uses anonymous functions (``@(x) ...``) to pass objectives. GAUSS uses the ``&`` operator to pass a pointer to a named procedure. Extra data arguments are passed after the starting values:
+
+.. code-block:: matlab
+
+ % MATLAB -- anonymous function captures Y, X via closure
+ f = @(beta) sum((Y - X*beta).^2);
+ result = fminunc(f, x0);
+
+::
+
+ // GAUSS -- named procedure; extra data passed as arguments
+ proc (1) = myObj(beta, Y, X);
+ local resid;
+ resid = Y - X * beta;
+ retp(resid'resid); // resid' * resid = sum of squared residuals
+ endp;
+
+ struct minimizeOut out;
+ out = minimize(&myObj, x0, Y, X);
+
+For constrained optimization with linear or nonlinear constraints, see :func:`sqpSolve`. For systems of nonlinear equations, see :func:`eqSolve`.
+
+Linear Algebra
+--------------
+
+.. code-block:: matlab
+
+ % MATLAB
+ inv(A)
+ det(A)
+ eig(A)
+ [V,D] = eig(A)
+ svd(A)
+ chol(A)
+ rank(A)
+ A \ b % Solve Ax = b
+
+::
+
+ // GAUSS
+ inv(A);
+ invpd(A); // Inverse (positive definite, faster)
+ det(A);
+ eig(A); // Returns eigenvalues only
+ { val, vec } = eigv(A); // Eigenvalues and vectors
+ { u, s, v } = svdcusv(A);
+ chol(A);
+ rank(A);
+ b / A; // Solve Ax = b
+
+**Solving linear systems:** GAUSS uses the ``/`` operator: ``b / A`` solves ``Ax = b``. Use :func:`solpd` for positive definite systems or :func:`olsqr` for QR-based least squares.
+
+.. warning::
+
+ **eigv return order is reversed.** MATLAB's ``[V, D] = eig(A)`` returns eigenvectors first, then eigenvalues. GAUSS's ``{ val, vec } = eigv(A)`` returns eigenvalues first, then eigenvectors. Swapping these produces wrong results silently.
+
+.. note::
+
+ **svdcusv returns a diagonal matrix.** Both MATLAB's ``svd`` and GAUSS's :func:`svdcusv` return ``S``/``s`` as a diagonal matrix. GAUSS's plain :func:`svd` (no ``cusv``) returns only a vector of singular values.
+
+Functions and Procedures
+------------------------
+
+.. code-block:: matlab
+
+ % MATLAB
+ function y = square(x)
+ y = x.^2;
+ end
+
+::
+
+ // GAUSS
+ proc (1) = square(x);
+ local y; // Must declare local variables (see Gotcha #8)
+ y = x.^2;
+ retp(y);
+ endp;
+
+**Key differences:**
+
+- GAUSS uses ``proc`` / ``endp`` instead of ``function`` / ``end``
+- Return values use ``retp()`` not assignment
+- Number of outputs declared in ``proc (n) =``
+
+Multiple outputs:
+
+.. code-block:: matlab
+
+ % MATLAB
+ function [a, b] = myFunc(x)
+ a = x + 1;
+ b = x - 1;
+ end
+
+::
+
+ // GAUSS
+ proc (2) = myFunc(x);
+ local a, b;
+ a = x + 1;
+ b = x - 1;
+ retp(a, b);
+ endp;
+
+ // Call it
+ { result1, result2 } = myFunc(5);
+
+Control Flow
+------------
+
+Loops and conditionals are similar:
+
+.. code-block:: matlab
+
+ % MATLAB
+ for i = 1:10
+ disp(i)
+ end
+
+ if x > 0
+ disp('positive')
+ elseif x < 0
+ disp('negative')
+ else
+ disp('zero')
+ end
+
+::
+
+ // GAUSS
+ for i (1, 10, 1);
+ print i;
+ endfor;
+
+ if x > 0;
+ print "positive";
+ elseif x < 0;
+ print "negative";
+ else;
+ print "zero";
+ endif;
+
+While loops:
+
+.. code-block:: matlab
+
+ % MATLAB
+ while x > 0
+ x = x - 1;
+ end
+
+::
+
+ // GAUSS
+ do while x > 0;
+ x = x - 1;
+ endo;
+
+**Note:** GAUSS requires semicolons after control statements (``if``, ``for``, ``else``, etc.). Inside a ``proc``, remember to declare loop variables with ``local`` (see Gotcha #9) or they become globals: ``local i; for i (1, 10, 1); ... endfor;``
+
+Common Function Translations
+-----------------------------
+
+**Functions with different names:**
+
++-------------------------+---------------------------+---------------------------+
+| Description | MATLAB | GAUSS |
++=========================+===========================+===========================+
+| Natural log | ``log(x)`` | ``ln(x)`` |
++-------------------------+---------------------------+---------------------------+
+| Log base 10 | ``log10(x)`` | ``log(x)`` |
++-------------------------+---------------------------+---------------------------+
+| Sort rows by column | ``sortrows(x, 1)`` | ``sortc(x, 1)`` |
++-------------------------+---------------------------+---------------------------+
+| Find indices | ``find(x > 0)`` | ``findIdx(x .> 0)`` |
++-------------------------+---------------------------+---------------------------+
+| Check NaN (any) | ``any(isnan(x),'all')`` | ``ismiss(x)`` |
++-------------------------+---------------------------+---------------------------+
+| Check NaN (element) | ``isnan(x)`` | ``x .== miss(1,1)`` |
++-------------------------+---------------------------+---------------------------+
+| NaN / missing value | ``NaN`` | ``.`` (dot) |
++-------------------------+---------------------------+---------------------------+
+| Cumulative sum | ``cumsum(x)`` | ``cumsumc(x)`` |
++-------------------------+---------------------------+---------------------------+
+| Flip rows | ``flipud(x)`` | ``rev(x)`` |
++-------------------------+---------------------------+---------------------------+
+| Create diagonal matrix | ``diag(v)`` | ``diagmat(v)`` |
++-------------------------+---------------------------+---------------------------+
+| Full SVD | ``[U,S,V] = svd(A)`` | ``{u,s,v} = svdcusv(A)`` |
++-------------------------+---------------------------+---------------------------+
+| Number to string | ``num2str(x)`` | ``ntos(x)`` |
++-------------------------+---------------------------+---------------------------+
+| String compare | ``strcmp(a,b)`` | ``a $== b`` |
++-------------------------+---------------------------+---------------------------+
+| String concatenation | ``strcat(a,b)`` | ``a $+ b`` |
++-------------------------+---------------------------+---------------------------+
+| Formatted output | ``fprintf(fmt, x)`` | ``print sprintf(fmt, x)`` |
++-------------------------+---------------------------+---------------------------+
+| Random uniform | ``rand(m,n)`` | ``rndu(m, n)`` |
++-------------------------+---------------------------+---------------------------+
+| Random normal | ``randn(m,n)`` | ``rndn(m, n)`` |
++-------------------------+---------------------------+---------------------------+
+| Print to console | ``disp(x)`` | ``print x;`` |
++-------------------------+---------------------------+---------------------------+
+| Comment | ``% comment`` | ``// comment`` |
++-------------------------+---------------------------+---------------------------+
+| FFT | ``fft(x)`` | ``fft(x)`` |
++-------------------------+---------------------------+---------------------------+
+| Inverse FFT | ``ifft(x)`` | ``ffti(x)`` |
++-------------------------+---------------------------+---------------------------+
+
+**Functions with the same name:** ``repmat``, ``unique``, ``abs``, ``exp``, ``ceil``, ``floor``, ``round``, ``rank``, ``inv``, ``det``, ``chol``, ``eye``, ``zeros``, ``ones``, ``fft``
+
+.. warning::
+
+ **reshape fill order differs.** MATLAB's ``reshape`` fills column-major (down columns first). GAUSS's ``reshape`` fills row-major (across rows first). The same input will produce different matrix layouts -- silently, with no error.
+
+.. note::
+
+ **diag vs diagmat**: MATLAB's ``diag`` both creates and extracts diagonal matrices. In GAUSS, ``diag(A)`` only *extracts* the diagonal. To *create* a diagonal matrix from a vector, use ``diagmat(v)``.
+
+.. warning::
+
+ **log vs ln**: In MATLAB, ``log`` is the natural logarithm. In GAUSS, ``log`` is base 10 and ``ln`` is natural. This will silently give wrong results if you don't catch it.
+
+Toolbox-to-Package Mapping
+---------------------------
+
+MATLAB functionality is split across paid toolboxes. GAUSS includes most of it in the base package:
+
++-------------------------------------+-----------------------------------------------+
+| MATLAB Toolbox | GAUSS Equivalent |
++=====================================+===============================================+
+| Statistics & Machine Learning | Base GAUSS (OLS, GLM, quantile reg, etc.) |
++-------------------------------------+-----------------------------------------------+
+| Optimization Toolbox | Base GAUSS (``minimize``, ``sqpSolve``) |
++-------------------------------------+-----------------------------------------------+
+| Econometrics Toolbox | Base GAUSS + TSMT (time series add-on) |
++-------------------------------------+-----------------------------------------------+
+| Signal Processing Toolbox | ``fft``, ``ffti``, ``rfft`` (built-in) |
++-------------------------------------+-----------------------------------------------+
+| Financial Toolbox | Fanpac (add-on) |
++-------------------------------------+-----------------------------------------------+
+
+**Time series users:** If your work involves ARIMA, VAR, GARCH, impulse response functions, or forecasting, you will use the **TSMT** add-on. Key functions: :func:`arimaFit`, :func:`svarFit` (structural VAR), :func:`varmaFit`, :func:`varmaPredict`. For maximum likelihood estimation, see :func:`maxlikmt`. See the `time series blog `__ for complete worked examples.
+
+Common Gotchas
+--------------
+
+1. **Semicolons are required.** Every statement must end with ``;``
+
+2. **Braces not brackets.** Matrices use ``{ }`` not ``[ ]``
+
+3. **Dot not colon for "all".** "All rows" is ``A[.,1]`` not ``A(:,1)``. But ``:`` works for ranges: ``A[1:5, .]``.
+
+4. **Comparison operators need dots.** Element-wise comparison uses ``.>``, ``.<``, ``.==``, ``.!=``. Without the dot, ``>`` tests if *all* elements satisfy the condition. This is the most common bug for MATLAB migrants.
+
+5. **Slash not backslash.** Use ``b/A`` instead of ``A\b``
+
+6. **log means base 10.** MATLAB ``log`` = natural log. GAUSS ``log`` = base 10. Use ``ln`` for natural log.
+
+7. **String quotes.** Only double quotes ``"string"`` work
+
+8. **Procedure syntax.** Use ``proc``/``endp``/``retp`` not ``function``/``end``/``return``
+
+9. **Local variables are not automatic.** In MATLAB, function variables are local by default. In GAUSS, you must declare them with ``local`` inside ``proc`` or they become global. Forgetting ``local`` creates hard-to-find bugs where procedures silently read or modify variables from the calling scope.
+
+10. **No ``end`` keyword for indexing.** Use ``rows(A)`` instead of ``end``. For the last 5 rows: ``A[rows(A)-4:rows(A), .]``
+
+11. **The ``call`` keyword.** Use ``call functionName(...)`` to run a function and discard its return value. This is common for estimation functions: ``call olsmt(data, "y ~ x")`` prints the summary table without saving results.
+
+Putting It Together
+-------------------
+
+Here is a complete, runnable example that loads data, filters it, plots it, runs a regression, and prints the results:
+
+::
+
+ // Load the auto2 dataset bundled with GAUSS
+ auto2 = loadd(getGAUSSHome("examples/auto2.dta"));
+
+ // Keep only domestic cars (foreign == 0)
+ domestic = selif(auto2, auto2[., "foreign"] .== 0);
+
+ // Quick scatter plot
+ plotScatter(domestic[., "weight"], domestic[., "mpg"]);
+
+ // Run OLS: how does weight affect fuel efficiency?
+ struct olsmtOut out;
+ out = olsmt(domestic, "mpg ~ weight");
+
+ print out.b; // Coefficient estimates
+ print out.stderr; // Standard errors
+ print out.rsq; // R-squared
+
+What's Next?
+------------
+
+- :doc:`../getting-started/quickstart` -- 10-minute introduction to GAUSS basics
+- :doc:`../getting-started/running-existing-code` -- If you inherited GAUSS code and need to get it running
+- :doc:`../data-management` -- Loading, cleaning, and reshaping data
+- :doc:`../textbook-examples/index` -- Worked examples from Greene (*Econometric Analysis*) and Brooks (*Introductory Econometrics for Finance*)
+- `Command Reference <../command-reference.html>`__ -- Browse all 1,000+ built-in functions
+- `Graphics documentation <../graphics.html>`__ -- Plotting functions, customization, and export
+- :func:`saved` -- Export data to CSV, Excel, or other formats
+- `User Guide `__ -- Installing and managing add-on modules
+- `Econometrics blog `__ -- Fully worked examples covering regression, panel data, hypothesis testing, and more
+- `Time series blog `__ -- ARIMA, VAR, GARCH, cointegration, and forecasting tutorials with complete code
+- `Programming blog `__ -- Loops, string handling, data manipulation, and general GAUSS programming
+
+.. seealso::
+
+ :func:`loadd`, :func:`olsmt`, :func:`glm`, :func:`quantileFit`, :func:`minimize`, :func:`plotXY`, :func:`fft`
diff --git a/docs/coming-to-gauss/intro-gauss-for-python-users.rst b/docs/coming-to-gauss/intro-gauss-for-python-users.rst
new file mode 100644
index 00000000..2c71f779
--- /dev/null
+++ b/docs/coming-to-gauss/intro-gauss-for-python-users.rst
@@ -0,0 +1,985 @@
+
+Introduction to GAUSS for Python/NumPy Users
+=============================================
+
+This guide assumes you know Python with NumPy/pandas and shows you how to do the same things in GAUSS.
+
+.. note::
+
+ This guide is written for GAUSS 26.
+
+How GAUSS Differs from Python
+------------------------------
+
+- **Core statistics are built in**: OLS, GLM, quantile regression, optimization, plotting, and file I/O ship with base GAUSS. No ``pip install``, no dependency conflicts, no assembling Jupyter + conda + virtual environments.
+- **Fast without setup**: No Cython, Numba, or careful vectorization needed -- GAUSS compiles to native code and is optimized out of the box.
+- **Dataframes are matrices**: Named columns and typed variables, but you can do matrix algebra on them directly -- no ``df.values`` or ``df.to_numpy()`` conversion step.
+- **Columns are variables**: Statistical functions operate on columns by default. NumPy's ``np.mean(X, axis=0)`` is ``meanc(X)``, ``np.sum(X, axis=0)`` is ``sumc(X)``.
+- **Results come back in structures**: Estimation output is a structure with named members (``out.b``, ``out.stderr``), similar to statsmodels' result objects. GAUSS uses ``struct`` types to group related inputs and outputs -- think of them as Python dataclasses or named tuples.
+
+**Where to type code:**
+
+.. figure:: ../_static/images/gauss26-ide-overview.png
+ :alt: GAUSS 26 IDE showing editor with sample program, project
+ folders on the left, and command output below.
+
+ The GAUSS IDE workspace.
+
+① **Toolbar** — Shows your current working directory and the **Run button** (green arrow). Click it or press F5 to execute. ② **Project Folders** — File browser, similar to VS Code's Explorer or Jupyter's file browser. ③ **Editor** — Write programs here, similar to a VS Code editor tab or Jupyter code cell. ④ **Command Window** — Output appears here, similar to a terminal or Jupyter cell output. You can also type single lines at the ``>>`` prompt.
+
+**Debugging:** Errors appear in the Output window with a line number -- click it to jump to the error. Use the Variables panel (View > Variables) to inspect values at runtime. You can set breakpoints by clicking in the left margin of the editor, then step through code with the Debug menu. For quick debugging, insert ``print varname;`` statements.
+
+Key Syntax Differences
+-----------------------
+
++-------------------+---------------------------+---------------------------+
+| Feature | Python/NumPy | GAUSS |
++===================+===========================+===========================+
+| Indexing | 0-based | 1-based |
++-------------------+---------------------------+---------------------------+
+| Slicing end | Exclusive ``[0:3]`` | Inclusive ``[1:3]`` |
++-------------------+---------------------------+---------------------------+
+| Assignment | ``=`` | ``=`` (same) |
++-------------------+---------------------------+---------------------------+
+| Matrix delimiter | ``np.array([[...]])`` | ``{ }`` |
++-------------------+---------------------------+---------------------------+
+| String quotes | ``" "`` or ``' '`` | ``" "`` only |
++-------------------+---------------------------+---------------------------+
+| Statement end | Newline | Required ``;`` |
++-------------------+---------------------------+---------------------------+
+| All rows/cols | ``:`` or omit | ``.`` |
++-------------------+---------------------------+---------------------------+
+| String concat | ``+`` or f-strings | ``$+`` |
++-------------------+---------------------------+---------------------------+
+| String equality | ``==`` | ``$==`` |
++-------------------+---------------------------+---------------------------+
+
+Array/Matrix Creation
+---------------------
+
+.. code-block:: python
+
+ # Python/NumPy
+ import numpy as np
+
+ A = np.array([[1, 2, 3],
+ [4, 5, 6]])
+
+ zeros = np.zeros((3, 3))
+ ones = np.ones((3, 3))
+ identity = np.eye(3)
+ rand_uniform = np.random.rand(3, 3)
+ rand_normal = np.random.randn(3, 3)
+
+::
+
+ // GAUSS
+ A = { 1 2 3,
+ 4 5 6 };
+
+ zeros_mat = zeros(3, 3);
+ ones_mat = ones(3, 3);
+ identity = eye(3);
+ rand_uniform = rndu(3, 3);
+ rand_normal = rndn(3, 3);
+
+**Sequences:**
+
+.. code-block:: python
+
+ # Python/NumPy
+ np.arange(1, 6) # [1, 2, 3, 4, 5]
+ np.arange(1, 3, 0.5) # [1, 1.5, 2, 2.5]
+ np.linspace(0, 1, 5) # 5 points from 0 to 1
+
+::
+
+ // GAUSS
+ seqa(1, 1, 5); // Column: start, increment, count
+ seqa(1, 0.5, 4); // {1, 1.5, 2, 2.5}
+ seqa(0, 0.25, 5); // {0, 0.25, 0.5, 0.75, 1}
+
+Note: ``seqa`` takes (start, increment, count), not (start, stop). It always returns a column vector.
+
+Operators
+---------
+
+**Matrix vs element-wise is reversed!**
+
+.. code-block:: python
+
+ # Python/NumPy
+ A * B # Element-wise multiplication
+ A @ B # Matrix multiplication
+ A ** 2 # Element-wise power
+ A / B # Element-wise division
+ A.T # Transpose
+
+::
+
+ // GAUSS
+ A .* B; // Element-wise multiplication (Python uses *)
+ A * B; // Matrix multiplication (Python uses @)
+ A .^ 2; // Element-wise power
+ A ./ B; // Element-wise division
+ A'; // Transpose
+
+.. warning::
+
+ **Operators are reversed!** Python's ``*`` is element-wise; GAUSS's ``*`` is matrix multiplication. Python's ``@`` is matrix multiply; GAUSS uses plain ``*``. This will produce wrong results silently if you forget.
+
+**GAUSS has two forms of comparison operators.** Without a dot, ``A > 0`` returns a scalar -- like Python's ``np.all(A > 0)``. With a dot, ``A .> 0`` returns an element-wise result -- like Python's ``A > 0``:
+
+.. code-block:: python
+
+ # Python/NumPy
+ A > 0 # Element-wise comparison
+ A == B # Element-wise equality
+ A != B # Element-wise not-equal
+ A & B # Element-wise AND (for arrays)
+ A | B # Element-wise OR (for arrays)
+
+::
+
+ // GAUSS
+ A .> 0; // Element-wise comparison (like Python's A > 0)
+ A .== B; // Element-wise equality
+ A .!= B; // Element-wise not-equal
+ A .and B; // Element-wise AND
+ A .or B; // Element-wise OR
+
+.. warning::
+
+ **Two forms of comparison.** ``A > 0`` returns a scalar (1 if all elements satisfy the condition) -- equivalent to Python's ``np.all(A > 0)``. ``A .> 0`` returns an element-wise array -- equivalent to Python's ``A > 0``. Both forms exist for all comparison operators: ``>``/``.>``, ``<``/``.<``, ``>=``/``.>=``, ``<=``/``.<=``, ``==``/``.==``, ``!=``/``.!=``.
+
+.. warning::
+
+ **Python's ``|`` is OR. GAUSS's ``|`` is vertical concatenation.** Writing ``condition1 | condition2`` in GAUSS does NOT give you logical OR -- it stacks the two vectors vertically. Use ``.or`` for element-wise OR and ``.and`` for element-wise AND. This will silently produce wrong results, not an error.
+
+Concatenation
+-------------
+
+.. code-block:: python
+
+ # Python/NumPy
+ np.hstack([A, B]) # Horizontal
+ np.vstack([A, B]) # Vertical
+ "hello" + " world" # String concatenation
+
+::
+
+ // GAUSS
+ A ~ B; // Horizontal concatenation (tilde)
+ A | B; // Vertical concatenation (pipe)
+ a $+ b; // String concatenation
+
+For string arrays, use ``$~`` (horizontal) and ``$|`` (vertical): ``"Domestic" $| "Foreign"`` creates a 2x1 string array.
+
+**String operators use the ``$`` prefix.** In Python, ``==`` and ``+`` work on both strings and numbers. In GAUSS, string operations need a ``$`` prefix: ``$+`` (concatenation), ``$==`` (equality), ``$~`` (horizontal join), ``$|`` (vertical join). Using ``==`` to compare strings will not work as expected.
+
+Indexing
+--------
+
+**This is the biggest difference.** Python is 0-indexed; GAUSS is 1-indexed. Python slices are half-open ``[start:end)``; GAUSS slices are closed ``[start:end]``.
+
+.. code-block:: python
+
+ # Python/NumPy
+ A = np.array([[1, 2, 3],
+ [4, 5, 6]])
+
+ A[0, 0] # First element: 1
+ A[0, :] # First row
+ A[:, 0] # First column
+ A[0:2, :] # Rows 0 and 1 (not 2!)
+ A[-1, :] # Last row
+
+::
+
+ // GAUSS
+ A = { 1 2 3,
+ 4 5 6 };
+
+ A[1, 1]; // First element: 1
+ A[1, .]; // First row (dot = all columns)
+ A[., 1]; // First column (dot = all rows)
+ A[1:2, .]; // Rows 1 and 2 (inclusive!)
+ A[rows(A), .]; // Last row (no negative indexing)
+
+**Key differences:**
+
+- GAUSS uses ``.`` for "all", Python uses ``:`` or omits the index
+- GAUSS slices are inclusive: ``A[1:3, .]`` gets rows 1, 2, and 3
+- Python slices are half-open: ``A[0:3, :]`` gets rows 0, 1, and 2
+- No negative indexing in GAUSS. Use ``rows(A)`` for last row, ``rows(A)-1`` for second-to-last.
+
+.. note::
+
+ Most examples below use the ``auto2`` dataset bundled with GAUSS. To run them, load it first:
+
+ ::
+
+ auto2 = loadd(getGAUSSHome("examples/auto2.dta"));
+
+Data Frames
+-----------
+
+GAUSS dataframes are similar to pandas DataFrames -- tabular data with named columns of different types.
+
+**Creating:**
+
+.. code-block:: python
+
+ # Python/pandas
+ import pandas as pd
+ df = pd.DataFrame({
+ "name": ["Alice", "Bob", "Charlie"],
+ "age": [25, 30, 35],
+ "score": [85.5, 92.0, 78.5]
+ })
+
+::
+
+ // GAUSS
+ name = "Alice" $| "Bob" $| "Charlie";
+ age = { 25, 30, 35 };
+ score = { 85.5, 92.0, 78.5 };
+
+ // Build a dataframe by concatenating single-column dataframes
+ df = asDF(name, "name") ~ asDF(age, "age") ~ asDF(score, "score");
+
+**Loading data:** GAUSS's :func:`loadd` reads CSV, Excel, Stata, SAS, SPSS, and HDF5 files -- see `Data Import/Export`_ below.
+
+**Viewing:**
+
+.. code-block:: python
+
+ # Python/pandas
+ df.head()
+ df.shape
+ df.columns
+ df.dtypes
+
+::
+
+ // GAUSS
+ head(df); // First 5 rows (same concept as pandas)
+ print rows(df) cols(df); // Dimensions
+ print getcolnames(df)'; // Column names (column vector, transposed with ' for display)
+ getcoltypes(df); // Column types (like df.dtypes)
+
+Column and Row Selection
+------------------------
+
+.. code-block:: python
+
+ # Python/pandas
+ df["price"] # Column by name
+ df[["price", "mpg"]] # Multiple columns
+ df.iloc[:, 2] # Column by position
+
+::
+
+ // GAUSS
+ df[., "price"]; // Column by name (dot = all rows)
+ df[., "price" "mpg"]; // Multiple columns (space-separated names)
+ df[., 3]; // Column by position
+
+.. code-block:: python
+
+ # Python/pandas
+ df.iloc[0:5] # First 5 rows
+ df[df["age"] > 30] # Filter by condition
+ df.iloc[[0, 2, 4]] # Specific rows
+
+::
+
+ // GAUSS
+ df[1:5, .]; // First 5 rows
+ selif(df, df[., "age"] .> 30); // Filter by condition (use selif, not brackets)
+ df[1|3|5, .]; // Specific rows (| concatenates index values)
+
+.. warning::
+
+ **GAUSS does not support boolean indexing in brackets.** In Python, ``df[condition]`` filters rows using a boolean array. In GAUSS, you must use :func:`selif`: ``selif(df, condition)``. Passing a boolean vector to brackets will not filter -- it will try to use the 0s and 1s as row numbers.
+
+Data Manipulation
+-----------------
+
+**No method chaining -- use intermediate variables.** Python users chain operations with ``.method().method()``. GAUSS has no chaining. Store intermediate results in variables:
+
+.. code-block:: python
+
+ # Python/pandas
+ result = (auto2
+ .query("foreign == 0")
+ .assign(price_k = lambda x: x["price"] / 1000)
+ .sort_values("mpg")
+ [["mpg", "price_k", "weight"]])
+
+::
+
+ // GAUSS -- same workflow, intermediate variables
+ domestic = selif(auto2, auto2[., "foreign"] .== 0);
+ domestic = dfaddcol(domestic, "price_k", domestic[., "price"] ./ 1000); // Add named column
+ domestic = sortc(domestic, "mpg");
+ result = domestic[., "mpg" "price_k" "weight"];
+
+**pandas method mapping:**
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Python (pandas)
+ - GAUSS
+ * - ``df.query("x > 5")`` or ``df[df["x"] > 5]``
+ - ``selif(df, df[., "x"] .> 5)``
+ * - ``df[["a", "b"]]``
+ - ``df[., "a" "b"]``
+ * - ``df.assign(c = df["a"] + df["b"])``
+ - ``dfaddcol(df, "c", df[., "a"] + df[., "b"])``
+ * - ``df.sort_values("x")``
+ - ``sortc(df, "x")``
+ * - ``df.groupby("g").mean()``
+ - ``aggregate(df, "mean", "g")``
+ * - ``pd.concat([a, b])``
+ - ``a | b``
+ * - ``pd.concat([a, b], axis=1)``
+ - ``a ~ b``
+
+Data Import/Export
+------------------
+
+.. code-block:: python
+
+ # Python/pandas
+ df = pd.read_csv("file.csv")
+ df = pd.read_stata("file.dta")
+ df = pd.read_excel("file.xlsx")
+ df.to_csv("output.csv")
+
+::
+
+ // GAUSS - one function reads everything
+ data = loadd("file.csv");
+ data = loadd("file.dta"); // Stata
+ data = loadd("file.sas7bdat"); // SAS
+ data = loadd("file.xlsx"); // Excel
+
+ // Load specific variables with a formula string
+ data = loadd("auto2.dta", "mpg + rep78 + price");
+
+ // Load all variables except one
+ data = loadd("auto2.dta", ". -rep78");
+
+ // Export
+ saved(data, "output.csv");
+ saved(data, "output.xlsx");
+
+**Formula string quick reference:** GAUSS uses formula strings in several contexts with different syntax:
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Context
+ - Example
+ - Separator
+ * - :func:`loadd` (loading)
+ - ``"mpg + weight + price"``
+ - ``+`` lists variables
+ * - :func:`olsmt` (models)
+ - ``"price ~ mpg + weight"``
+ - ``~`` separates y from X
+ * - Bracket indexing
+ - ``auto2[., "mpg" "wt"]``
+ - Space separates names
+ * - Type overrides
+ - ``"date($Date) + cat(x)"``
+ - Keywords wrap variable names
+
+.. note::
+
+ GAUSS formula strings are **quoted strings** (``"y ~ x1 + x2"``), not bare expressions like statsmodels' ``ols("y ~ x1 + x2", data=df)``. The ``~`` separator works the same way in model formulas, but ``+`` in :func:`loadd` means "include this variable," not "add to model."
+
+Missing Values
+--------------
+
+Python uses ``np.nan`` (or ``None`` in pandas); GAUSS uses ``.`` (dot).
+
+.. code-block:: python
+
+ # Python/NumPy/pandas
+ np.isnan(x) # Element-wise check
+ df.isna().any() # Any missing?
+ df.dropna() # Drop rows with any NaN
+ x[~np.isnan(x)] # Keep non-missing
+ df.fillna(0) # Replace NaN with 0
+
+::
+
+ // GAUSS
+ x .== miss(); // Element-wise check (returns 1/0 vector)
+ ismiss(x); // Any missing? (returns scalar 1 or 0)
+ packr(df); // Drop rows with any missing value
+ selif(x, x .!= miss()); // Keep non-missing
+ missrv(x, 0); // Replace missing with 0
+
+.. warning::
+
+ **ismiss is NOT element-wise.** Python's ``np.isnan(x)`` returns an array. GAUSS's ``ismiss(x)`` returns a **scalar** (1 if any element is missing, 0 otherwise). For element-wise missing detection, use ``x .== miss()``.
+
+Statistics
+----------
+
+.. code-block:: python
+
+ # Python/NumPy
+ np.mean(x)
+ np.std(x, ddof=1)
+ np.sum(x)
+ np.min(x); np.max(x)
+ np.median(x)
+
+ # Column-wise on matrix
+ np.mean(X, axis=0)
+ np.sum(X, axis=0)
+
+::
+
+ // GAUSS
+ meanc(x); // Column mean (the 'c' suffix = column-wise)
+ stdc(x); // Column std dev
+ sumc(x); // Column sum
+ minc(x); // Column min
+ maxc(x); // Column max
+ median(x); // Median
+
+ // Row-wise
+ meanr(X); // Row mean (the 'r' suffix = row-wise)
+ sumr(X); // Row sum
+
+**Descriptive statistics:** Python's ``df.describe()`` is :func:`dstatmt` in GAUSS:
+
+::
+
+ call dstatmt(auto2[., "price" "mpg" "weight"]);
+
+.. warning::
+
+ **stdc uses N-1, not N.** Python's ``np.std(x)`` defaults to ``ddof=0`` (population std dev). GAUSS's ``stdc(x)`` always uses N-1 (sample std dev), equivalent to ``np.std(x, ddof=1)``. This will give different numbers if you forget.
+
+**Correlation:**
+
+.. code-block:: python
+
+ # Python
+ np.corrcoef(x, y) # 2x2 correlation matrix
+ np.corrcoef(X.T) # Full correlation matrix
+
+::
+
+ // GAUSS
+ corrx(x ~ y); // 2x2 correlation matrix (~ is horizontal concat here)
+ corrx(X); // Full correlation matrix of all columns
+
+.. note::
+
+ Like ``np.corrcoef``, :func:`corrx` always returns a matrix. The difference is input format: ``np.corrcoef(x, y)`` takes two separate arrays, while ``corrx(x ~ y)`` takes a single concatenated matrix. To get a scalar correlation: ``corrx(x ~ y)[1, 2]``.
+
+Linear Regression
+-----------------
+
+.. code-block:: python
+
+ # Python/statsmodels
+ import statsmodels.api as sm
+ X = sm.add_constant(df[["mpg", "weight"]])
+ model = sm.OLS(df["price"], X).fit()
+ print(model.summary())
+
+ # Python/sklearn
+ from sklearn.linear_model import LinearRegression
+ model = LinearRegression().fit(X, y)
+
+::
+
+ // GAUSS - print formatted summary (like model.summary())
+ call olsmt(auto2, "price ~ mpg + weight");
+
+.. tip::
+
+ Use ``call olsmt(...)`` (with ``call``) to print a formatted summary table to the screen without saving results to a variable. The ``call`` keyword discards return values.
+
+**Accessing results:**
+
+.. code-block:: python
+
+ # Python/statsmodels
+ model.params # Coefficients
+ model.bse # Standard errors
+ model.rsquared # R-squared
+ model.resid # Residuals
+ model.cov_params() # Variance-covariance
+
+::
+
+ // GAUSS
+ struct olsmtOut out;
+ out = olsmt(auto2, "price ~ mpg + weight");
+
+ print out.b; // Coefficient estimates
+ print out.stderr; // Standard errors
+ print out.rsq; // R-squared
+ print out.resid; // Residuals
+ print out.vc; // Variance-covariance of estimates
+
+Key :class:`olsmtOut` members: ``b`` (coefficients), ``stderr`` (standard errors), ``vc`` (variance-covariance matrix), ``rsq`` (R-squared), ``resid`` (residuals), ``dwstat`` (Durbin-Watson), ``sigma`` (residual std dev), ``stb`` (standardized coefficients). See the :func:`olsmt` reference for the full list.
+
+For robust or clustered standard errors, pass an :class:`olsmtControl` structure -- see the :func:`olsmt` reference for details.
+
+Logistic regression (GLM):
+
+.. code-block:: python
+
+ # Python/statsmodels
+ import statsmodels.api as sm
+ model = sm.GLM(y, X, family=sm.families.Binomial()).fit()
+
+::
+
+ // GAUSS
+ struct glmOut out;
+ out = glm(data, "admit ~ gre + gpa + rank", "binomial");
+
+Quantile regression:
+
+.. code-block:: python
+
+ # Python/statsmodels
+ import statsmodels.formula.api as smf
+ mod = smf.quantreg("y ~ x1 + x2", df)
+ res = mod.fit(q=0.5)
+
+::
+
+ // GAUSS (no package install needed)
+ struct qfitOut out;
+ out = quantileFit(data, "y ~ x1 + x2", 0.25 | 0.5 | 0.75); // | builds a vector
+
+Plotting
+--------
+
+Python users expect rich plotting from matplotlib/seaborn. GAUSS has a full graphics library:
+
+.. code-block:: python
+
+ # Python (matplotlib)
+ import matplotlib.pyplot as plt
+ plt.scatter(x, y)
+ plt.hist(x, bins=20)
+ plt.boxplot(data)
+
+ # Python (seaborn)
+ import seaborn as sns
+ sns.scatterplot(data=df, x="weight", y="mpg")
+
+::
+
+ // GAUSS
+ plotXY(x, y);
+ plotScatter(x, y);
+ plotHist(x, 20);
+ plotBox(data, "value ~ group");
+ plotBar(labels, heights);
+ plotSurface(x, y, z);
+
+**Setting titles, labels, and legends** uses a :class:`plotControl` structure. Think of it as GAUSS's equivalent of matplotlib's ``plt.xlabel()`` / ``plt.title()`` calls, but configured before the plot call:
+
+::
+
+ // Create a plot with title, labels, and legend
+ struct plotControl myPlot;
+ myPlot = plotGetDefaults("scatter");
+
+ plotSetTitle(&myPlot, "MPG vs Weight");
+ plotSetXLabel(&myPlot, "Weight (lbs)");
+ plotSetYLabel(&myPlot, "Miles per gallon");
+ plotSetLegend(&myPlot, "Domestic" $| "Foreign");
+
+ plotScatter(myPlot, auto2[., "weight"], auto2[., "mpg"]);
+
+**Subplots and saving:**
+
+.. code-block:: python
+
+ # Python (matplotlib)
+ fig, axes = plt.subplots(2, 1)
+ plt.savefig("plot.png")
+
+::
+
+ // GAUSS
+ plotLayout(2, 1, 1); // 2 rows, 1 col, position 1
+ plotSave("plot.png", 640|480); // Save with size (width|height in pixels)
+
+Linear Algebra
+--------------
+
+.. code-block:: python
+
+ # Python/NumPy
+ np.linalg.inv(A)
+ np.linalg.det(A)
+ np.linalg.eig(A)
+ np.linalg.svd(A)
+ np.linalg.cholesky(A)
+ np.linalg.solve(A, b)
+
+::
+
+ // GAUSS
+ inv(A);
+ invpd(A); // Inverse (positive definite, faster)
+ det(A);
+ { val, vec } = eigv(A); // Eigenvalues and vectors (like np.linalg.eig)
+ eig(A); // Eigenvalues only (like np.linalg.eigvals)
+ { u, s, v } = svdcusv(A);
+ chol(A); // Upper triangular (NumPy returns lower triangular)
+ b / A; // Solve Ax = b (like np.linalg.solve(A, b))
+
+.. warning::
+
+ **``/`` is matrix division, not element-wise division.** ``b / A`` solves the system ``Ax = b``. Note the operand order is reversed from ``np.linalg.solve(A, b)``. For element-wise division, use ``./``. Python's ``/`` is always element-wise on arrays; GAUSS's ``/`` is not.
+
+Optimization
+------------
+
+Python users doing custom optimization use ``scipy.optimize``. GAUSS includes unconstrained and constrained optimization in the base package:
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Python (scipy)
+ - GAUSS
+ * - ``minimize(fn, x0)``
+ - ``minimize(&fn, x0)``
+ * - ``minimize(fn, x0, method="L-BFGS-B", bounds=...)``
+ - ``minimize(&fn, x0, ctl)`` with ``ctl.bounds``
+ * - ``scipy.optimize.root(fn, x0)``
+ - ``eqSolve(&fn, x0)``
+
+**Key difference:** Python passes functions as objects. GAUSS uses the ``&`` operator to pass a *pointer* to a named procedure. The ``&`` tells GAUSS to pass the procedure itself, not its result, so the optimizer can call it repeatedly with different parameter values:
+
+.. code-block:: python
+
+ # Python
+ from scipy.optimize import minimize
+
+ def my_obj(beta):
+ resid = Y - X @ beta
+ return resid @ resid
+
+ result = minimize(my_obj, x0)
+
+::
+
+ // GAUSS -- named procedure; extra data passed as arguments
+ proc (1) = myObj(beta, Y, X);
+ local resid;
+ resid = Y - X * beta;
+ retp(resid'resid); // resid' * resid = sum of squared residuals
+ endp;
+
+ struct minimizeOut out;
+ out = minimize(&myObj, x0, Y, X);
+
+For maximum likelihood estimation, the **MLMT** add-on provides :func:`maxlikmt` -- a full MLE framework with standard errors, constraints, and convergence diagnostics.
+
+In GAUSS, extra data arguments (``Y`` and ``X`` above) are passed directly after the starting values and forwarded to your objective function automatically -- no ``args=`` keyword needed.
+
+Functions and Procedures
+------------------------
+
+.. code-block:: python
+
+ # Python
+ def my_func(x, y):
+ result = x + y
+ return result
+
+::
+
+ // GAUSS
+ proc (1) = my_func(x, y);
+ local result;
+ result = x + y;
+ retp(result);
+ endp;
+
+**Key differences from Python:**
+
+- ``proc (n) =`` declares the number of return values
+- ``local`` declares variables scoped to this procedure (required -- see warning below)
+- ``retp()`` returns values
+- ``endp`` ends the procedure
+- No default argument values. All arguments are positional.
+- No lambda functions. Use named procedures.
+
+**Multiple outputs:**
+
+.. code-block:: python
+
+ # Python
+ def my_func(x):
+ return x + 1, x - 1
+
+ a, b = my_func(5)
+
+::
+
+ // GAUSS
+ proc (2) = my_func(x);
+ local a, b;
+ a = x + 1;
+ b = x - 1;
+ retp(a, b);
+ endp;
+
+ { result_a, result_b } = my_func(5);
+
+.. warning::
+
+ **Variables are global by default.** In Python, function variables are automatically local. In GAUSS, you must declare them with ``local`` inside ``proc`` or they become globals that persist after the procedure returns. Forgetting ``local`` creates hard-to-find bugs where procedures silently read or modify variables from the calling scope. This is a common beginner mistake -- just make it a habit to declare ``local`` for every variable inside a ``proc``.
+
+Unlike Python, GAUSS procedures can be defined anywhere in your file -- before or after the code that calls them. GAUSS compiles procedures in a separate pass.
+
+Control Flow
+------------
+
+.. code-block:: python
+
+ # Python
+ for i in range(1, 11):
+ print(i)
+
+ if x > 0:
+ print("positive")
+ elif x < 0:
+ print("negative")
+ else:
+ print("zero")
+
+ while x > 0:
+ x -= 1
+
+::
+
+ // GAUSS
+ for i (1, 10, 1);
+ print i;
+ endfor;
+
+ if x > 0;
+ print "positive";
+ elseif x < 0;
+ print "negative";
+ else;
+ print "zero";
+ endif;
+
+ do while x > 0;
+ x = x - 1;
+ endo;
+
+**Note:** GAUSS requires semicolons after control statements (``if``, ``for``, ``else``, etc.). Inside a ``proc``, remember to declare loop variables with ``local`` (see the warning above) or they become globals.
+
+Common Function Translations
+-----------------------------
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Description
+ - Python/NumPy
+ - GAUSS
+ * - Natural log
+ - ``np.log(x)``
+ - ``ln(x)``
+ * - Log base 10
+ - ``np.log10(x)``
+ - ``log(x)``
+ * - Column mean
+ - ``np.mean(X, axis=0)``
+ - ``meanc(X)``
+ * - Row mean
+ - ``np.mean(X, axis=1)``
+ - ``meanr(X)``
+ * - Column sum
+ - ``np.sum(X, axis=0)``
+ - ``sumc(X)``
+ * - Cumulative sum
+ - ``np.cumsum(x)``
+ - ``cumsumc(x)``
+ * - Sort by column
+ - ``df.sort_values("x")``
+ - ``sortc(df, "x")``
+ * - Find indices
+ - ``np.where(x > 0)``
+ - ``findIdx(x .> 0)``
+ * - Filter rows
+ - ``df[condition]``
+ - ``selif(df, condition)``
+ * - Remove missing rows
+ - ``df.dropna()``
+ - ``packr(df)``
+ * - Replace missing
+ - ``df.fillna(0)``
+ - ``missrv(x, 0)``
+ * - Check NaN (any)
+ - ``np.any(np.isnan(x))``
+ - ``ismiss(x)``
+ * - Check NaN (element)
+ - ``np.isnan(x)``
+ - ``x .== miss()``
+ * - Flip rows
+ - ``np.flip(x)``
+ - ``rev(x)``
+ * - Create diagonal matrix
+ - ``np.diag(v)``
+ - ``diagmat(v)``
+ * - Reshape
+ - ``x.reshape(r, c)``
+ - ``reshape(x, r, c)``
+ * - Flatten to column
+ - ``x.ravel()``
+ - ``vecr(x)``
+ * - Full SVD
+ - ``np.linalg.svd(A)``
+ - ``{ u,s,v } = svdcusv(A)``
+ * - Number to string
+ - ``str(x)``
+ - ``ntos(x)``
+ * - Formatted output
+ - ``f"{x:.2f}"``
+ - ``sprintf("%.2f", x)``
+ * - Random uniform
+ - ``np.random.rand(n, 1)``
+ - ``rndu(n, 1)``
+ * - Random normal
+ - ``np.random.randn(n, 1)``
+ - ``rndn(n, 1)``
+ * - Set seed
+ - ``np.random.seed(42)``
+ - ``rndseed 42``
+ * - Print
+ - ``print(x)``
+ - ``print x;``
+ * - Comment
+ - ``# comment``
+ - ``// comment``
+
+.. warning::
+
+ **log vs ln**: In Python, ``np.log`` is the natural logarithm. In GAUSS, ``log`` is base 10 and ``ln`` is natural. This will silently give wrong results if you don't catch it.
+
+Python Package to GAUSS Mapping
+---------------------------------
+
+Python assembles workflows from packages. GAUSS includes most of this in the base installation:
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Python Package
+ - GAUSS Equivalent
+ * - ``statsmodels`` (OLS, GLM, logit)
+ - Base GAUSS (``olsmt``, ``glm``)
+ * - ``scipy.optimize``
+ - Base GAUSS (``minimize``, ``sqpSolveMT``)
+ * - ``scipy.stats``
+ - Base GAUSS (``cdfN``, ``ttest``, ``shapiroWilk``)
+ * - ``pandas``
+ - Base GAUSS (``loadd``, ``selif``, ``aggregate``)
+ * - ``matplotlib`` / ``seaborn``
+ - Base GAUSS (``plotXY``, ``plotControl``)
+ * - ``numpy.linalg``
+ - Base GAUSS (``eigv``, ``svdcusv``, ``chol``)
+ * - ``statsmodels.tsa`` (ARIMA, VAR)
+ - TSMT add-on
+ * - ``arch`` (GARCH)
+ - TSMT add-on
+
+**Time series users:** If your work involves ARIMA, VAR, GARCH, impulse response functions, or forecasting, you will use the **TSMT** add-on. Key functions: :func:`arimaFit`, :func:`svarFit` (structural VAR), :func:`varmaFit`, :func:`varmaPredict`. See the `time series blog `__ for complete worked examples.
+
+Common Gotchas
+--------------
+
+1. **Indexing starts at 1.** The first element is ``A[1, 1]``, not ``A[0, 0]``.
+
+2. **Slices are inclusive.** ``A[1:3, .]`` includes rows 1, 2, AND 3. Python's ``A[0:3]`` excludes index 3.
+
+3. **Operators are reversed.** ``*`` is matrix multiply, ``.*`` is element-wise (opposite of NumPy!).
+
+4. **Semicolons required.** Every statement ends with ``;``.
+
+5. **Dot not colon for "all".** "All rows" is ``df[., 1]`` not ``df[:, 0]``. But ``:`` works for ranges: ``df[1:5, .]``.
+
+6. **String quotes.** Only double quotes ``"string"`` work.
+
+7. **No negative indexing.** Use ``rows(A)`` and ``cols(A)`` instead.
+
+8. **The ``call`` keyword.** Use ``call functionName(...)`` to run a function and discard its return value. This is the GAUSS equivalent of running a function for its side effects (like printing).
+
+9. **String operators need ``$``.** ``==`` won't compare strings. Use ``$==`` for string equality, ``$+`` for concatenation.
+
+For operator gotchas (``*`` vs ``.*``, ``|`` vs ``.or``, dotted comparisons, ``/`` vs ``./``, ``log`` vs ``ln``), variable scoping (``local``), and boolean indexing (``selif``), see the inline warnings throughout this guide.
+
+Putting It Together
+-------------------
+
+Here is a complete, runnable example that loads data, filters it, plots it, runs a regression, and prints the results. Running this prints the OLS summary to the Output window and opens a scatter plot.
+
+::
+
+ // Load the auto2 dataset bundled with GAUSS
+ auto2 = loadd(getGAUSSHome("examples/auto2.dta"));
+
+ // Keep only domestic cars (foreign == 0)
+ domestic = selif(auto2, auto2[., "foreign"] .== 0);
+
+ // Quick scatter plot with title and labels
+ struct plotControl myPlot;
+ myPlot = plotGetDefaults("scatter");
+ plotSetTitle(&myPlot, "Weight vs MPG (Domestic Cars)");
+ plotSetXLabel(&myPlot, "Weight (lbs)");
+ plotSetYLabel(&myPlot, "Miles per gallon");
+ plotScatter(myPlot, domestic[., "weight"], domestic[., "mpg"]);
+
+ // Run OLS: how does weight affect fuel efficiency?
+ struct olsmtOut out;
+ out = olsmt(domestic, "mpg ~ weight");
+
+ // Print key results
+ print out.b; // Coefficient estimates
+ print out.stderr; // Standard errors
+ print out.rsq; // R-squared
+
+What's Next?
+------------
+
+- :doc:`../getting-started/quickstart` -- 10-minute introduction to GAUSS basics
+- :doc:`../getting-started/running-existing-code` -- If you inherited GAUSS code and need to get it running
+- :doc:`../data-management` -- Loading, cleaning, and reshaping data
+- :doc:`../textbook-examples/index` -- Worked examples from Greene (*Econometric Analysis*) and Brooks (*Introductory Econometrics for Finance*)
+- `Command Reference <../command-reference.html>`__ -- Browse all 1,000+ built-in functions
+- `Econometrics blog `__ -- Fully worked examples covering regression, panel data, hypothesis testing, and more
+- `Time series blog `__ -- ARIMA, VAR, GARCH, cointegration, and forecasting tutorials with complete code
+
+.. seealso::
+
+ :func:`loadd`, :func:`olsmt`, :func:`glm`, :func:`quantileFit`, :func:`minimize`, :func:`plotXY`, :func:`packr`, :func:`selif`
diff --git a/docs/coming-to-gauss/intro-gauss-for-r-users.rst b/docs/coming-to-gauss/intro-gauss-for-r-users.rst
new file mode 100644
index 00000000..71943a10
--- /dev/null
+++ b/docs/coming-to-gauss/intro-gauss-for-r-users.rst
@@ -0,0 +1,872 @@
+
+Introduction to GAUSS for R Users
+=================================
+
+This guide assumes you know R and shows you how to do the same things in GAUSS.
+
+.. note::
+
+ This guide is written for GAUSS 26.
+
+How GAUSS Differs from R
+-------------------------
+
+- **Core statistics are built in**: OLS, GLM, quantile regression, optimization, plotting, and file I/O ship with base GAUSS. No ``install.packages()``, no dependency conflicts. Time series methods (ARIMA, VAR, GARCH) are available as add-ons.
+- **Dataframes are matrices**: Named columns and typed variables, but you can do matrix algebra on them directly -- no ``as.matrix()`` conversion step. String columns are stored as integers with a lookup table, so they participate in matrix operations too.
+- **Columns are variables**: Statistical functions operate on columns by default. R's ``colMeans(X)`` is ``meanc(X)``, ``apply(X, 2, sd)`` is ``stdc(X)``, ``colSums(X)`` is ``sumc(X)``.
+- **Results come back in structures**: Estimation output is a structure with named members (``out.b``, ``out.stderr``), similar to R's named lists.
+
+**Where to type code:**
+
+.. figure:: ../_static/images/gauss26-ide-overview.png
+ :alt: GAUSS 26 IDE showing editor with sample program, project
+ folders on the left, and command output below.
+
+ The GAUSS IDE workspace.
+
+① **Toolbar** — Shows your current working directory and the **Run button** (green arrow). Click it or press F5 to execute. ② **Project Folders** — File browser, similar to RStudio's Files pane. ③ **Editor** — Write programs here, similar to RStudio's Source pane. ④ **Command Window** — Output appears here, similar to the R Console. You can also type single lines at the ``>>`` prompt.
+
+**Debugging:** Errors appear in the Output window with a line number -- click it to jump to the error. Use the Variables panel (View > Variables) to inspect values at runtime. You can set breakpoints by clicking in the left margin of the editor, then step through code with the Debug menu. For quick debugging, insert ``print varname;`` statements.
+
+**Inspecting structures:** To see what fields an output structure contains, use ``print`` -- for example, ``print out;`` displays all members and their values. To see just the field names, check the structure definition in the Command Reference (press F1 on the function name).
+
+Key Syntax Differences
+----------------------
+
++-------------------+---------------------------+---------------------------+
+| Feature | R | GAUSS |
++===================+===========================+===========================+
+| Indexing | 1-based | 1-based (same) |
++-------------------+---------------------------+---------------------------+
+| Assignment | ``<-`` or ``=`` | ``=`` only |
++-------------------+---------------------------+---------------------------+
+| Matrix delimiter | ``matrix(c(...))`` | ``{ }`` |
++-------------------+---------------------------+---------------------------+
+| String quotes | ``" "`` or ``' '`` | ``" "`` only |
++-------------------+---------------------------+---------------------------+
+| Statement end | Optional ``;`` | Required ``;`` |
++-------------------+---------------------------+---------------------------+
+| All rows/cols | leave blank or ``,`` | ``.`` |
++-------------------+---------------------------+---------------------------+
+| String concat | ``paste()`` | ``$+`` |
++-------------------+---------------------------+---------------------------+
+| Pipe | ``%>%`` or ``|>`` | None (use intermediate |
+| | | variables) |
++-------------------+---------------------------+---------------------------+
+
+Operators
+---------
+
+**Arithmetic operators:**
+
+.. code-block:: r
+
+ # R
+ A %*% B # Matrix multiplication
+ A * B # Element-wise multiplication
+ t(A) # Transpose
+
+::
+
+ // GAUSS
+ A * B; // Matrix multiplication (R uses %*%)
+ A .* B; // Element-wise multiplication (R uses *)
+ A'; // Transpose
+
+.. warning::
+
+ **Operators are reversed!** R's ``*`` is element-wise; GAUSS's ``*`` is matrix multiplication. R's ``%*%`` is matrix multiply; GAUSS uses plain ``*``. This will produce wrong results silently if you forget.
+
+**GAUSS has two forms of comparison operators.** Without a dot, ``A > 0`` returns a scalar -- like R's ``all(A > 0)``. With a dot, ``A .> 0`` returns an element-wise result -- like R's ``A > 0``:
+
+.. code-block:: r
+
+ # R
+ A > 0 # Element-wise comparison
+ A == B # Element-wise equality
+ A != B # Element-wise not-equal
+ A & B # Element-wise AND
+ A | B # Element-wise OR
+
+::
+
+ // GAUSS
+ A .> 0; // Element-wise comparison (like R's A > 0)
+ A .== B; // Element-wise equality
+ A .!= B; // Element-wise not-equal (.ne also works)
+ A .and B; // Element-wise AND
+ A .or B; // Element-wise OR
+
+.. warning::
+
+ **Two forms of comparison.** ``A > 0`` returns a scalar (1 if all elements satisfy the condition) -- equivalent to R's ``all(A > 0)``. ``A .> 0`` returns an element-wise vector -- equivalent to R's ``A > 0``. Both forms exist for all comparison operators: ``>``/``.>``, ``<``/``.<``, ``>=``/``.>=``, ``<=``/``.<=``, ``==``/``.==``, ``!=``/``.!=``.
+
+.. warning::
+
+ **R's ``|`` is OR. GAUSS's ``|`` is vertical concatenation.** Writing ``condition1 | condition2`` in GAUSS does NOT give you logical OR -- it stacks the two vectors vertically. Use ``.or`` for element-wise OR and ``.and`` for element-wise AND. This will silently produce wrong results, not an error.
+
+Concatenation
+-------------
+
+.. code-block:: r
+
+ # R
+ cbind(A, B) # Horizontal (column bind)
+ rbind(A, B) # Vertical (row bind)
+ paste(a, b) # String concatenation
+
+::
+
+ // GAUSS
+ A ~ B; // Horizontal concatenation (tilde)
+ A | B; // Vertical concatenation (pipe)
+ a $+ b; // String concatenation
+
+For string arrays, use ``$~`` (horizontal) and ``$|`` (vertical): ``"Domestic" $| "Foreign"`` creates a 2x1 string array.
+
+.. note::
+
+ Most examples below use the ``auto2`` dataset bundled with GAUSS. To run them, load it first:
+
+ ::
+
+ auto2 = loadd(getGAUSSHome("examples/auto2.dta"));
+
+Data Frames
+-----------
+
+R's ``data.frame`` and GAUSS dataframes are similar -- tabular data with named columns of different types.
+
+**Creating:**
+
+.. code-block:: r
+
+ # R
+ df <- data.frame(
+ name = c("Alice", "Bob", "Charlie"),
+ age = c(25, 30, 35),
+ score = c(85.5, 92.0, 78.5)
+ )
+
+::
+
+ // GAUSS
+ name = "Alice" $| "Bob" $| "Charlie";
+ age = { 25, 30, 35 };
+ score = { 85.5, 92.0, 78.5 };
+
+ // Build a dataframe by concatenating single-column dataframes
+ df = asDF(name, "name") ~ asDF(age, "age") ~ asDF(score, "score");
+
+**Loading data:** GAUSS's :func:`loadd` reads CSV, Excel, Stata, SAS, SPSS, and HDF5 files -- see `Data Import/Export`_ below.
+
+**Viewing:**
+
+.. code-block:: r
+
+ # R
+ head(df)
+ str(df)
+ names(df)
+ nrow(df); ncol(df)
+
+::
+
+ // GAUSS
+ head(df); // First 5 rows (same as R)
+ print df[1:6, .]; // First 6 rows (manual)
+ print rows(df) cols(df); // Dimensions
+ print getcolnames(df)'; // Column names (transposed for horizontal display)
+
+:func:`getGAUSSHome` returns the path to GAUSS's installation directory. Use it to access bundled datasets: ``loadd(getGAUSSHome("examples/auto2.dta"))``.
+
+Column and Row Selection
+------------------------
+
+.. code-block:: r
+
+ # R
+ df$price # Column by name
+ df[, "price"] # Column by name
+ df[, 3] # Column by position
+ df[, c("a", "b")] # Multiple columns
+
+::
+
+ // GAUSS
+ df[., "price"]; // Column by name (dot = all rows)
+ df[., "price"]; // Same
+ df[., 3]; // Column by position
+ df[., "a" "b"]; // Multiple columns (space-separated names)
+
+.. code-block:: r
+
+ # R
+ df[1:5, ] # First 5 rows
+ df[df$age > 30, ] # Filter by condition
+ df[c(1, 3, 5), ] # Specific rows
+
+::
+
+ // GAUSS
+ df[1:5, .]; // First 5 rows
+ selif(df, df[., "age"] .> 30); // Filter by condition (use selif, not brackets)
+ df[1|3|5, .]; // Specific rows (| concatenates index values)
+
+.. warning::
+
+ **GAUSS does not support boolean indexing in brackets.** In R, ``df[condition, ]`` filters rows using a logical vector. In GAUSS, you must use :func:`selif`: ``selif(df, condition)``. Passing a boolean vector to brackets will not filter -- it will try to use the 0s and 1s as row numbers.
+
+**Key difference:** R uses blank or ``,`` for "all", GAUSS uses ``.`` (dot). R's ``df$col`` becomes ``df[., "col"]``.
+
+Data Manipulation
+-----------------
+
+**No pipes -- use intermediate variables.** R users chain operations with ``%>%`` or ``|>``. GAUSS has no pipe operator. Store intermediate results in variables:
+
+.. code-block:: r
+
+ # R (tidyverse)
+ result <- auto2 %>%
+ filter(foreign == 0) %>%
+ mutate(price_k = price / 1000) %>%
+ arrange(mpg) %>%
+ select(mpg, price_k, weight)
+
+::
+
+ // GAUSS -- same workflow, intermediate variables
+ domestic = selif(auto2, auto2[., "foreign"] .== 0);
+ domestic = dfaddcol(domestic, "price_k", domestic[., "price"] ./ 1000);
+ domestic = sortc(domestic, "mpg");
+ result = domestic[., "mpg" "price_k" "weight"];
+
+**Tidyverse verb mapping:**
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - R (dplyr)
+ - GAUSS
+ * - ``filter(df, x > 5)``
+ - ``selif(df, df[., "x"] .> 5)``
+ * - ``select(df, a, b)``
+ - ``df[., "a" "b"]``
+ * - ``mutate(df, c = a + b)``
+ - ``dfaddcol(df, "c", sumr(df[., "a" "b"]))`` (``sumr`` = row-wise sum)
+ * - ``arrange(df, x)``
+ - ``sortc(df, "x")``
+ * - ``group_by + summarize``
+ - ``aggregate(df, "mean", "group")``
+ * - ``bind_rows(a, b)``
+ - ``a | b``
+ * - ``bind_cols(a, b)``
+ - ``a ~ b``
+
+Data Import/Export
+------------------
+
+.. code-block:: r
+
+ # R
+ df <- read.csv("file.csv")
+ df <- haven::read_dta("file.dta")
+ df <- haven::read_sas("file.sas7bdat")
+ write.csv(df, "output.csv")
+
+::
+
+ // GAUSS - one function reads everything
+ data = loadd("file.csv");
+ data = loadd("file.dta"); // Stata
+ data = loadd("file.sas7bdat"); // SAS
+ data = loadd("file.xlsx"); // Excel
+
+ // Load specific variables with a formula string
+ data = loadd("auto2.dta", "mpg + rep78 + price");
+
+ // Load all variables except one
+ data = loadd("auto2.dta", ". -rep78");
+
+ // Export
+ saved(data, "output.csv");
+ saved(data, "output.xlsx");
+
+**Formula string quick reference:** GAUSS uses formula strings in several contexts with different syntax:
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Context
+ - Example
+ - Separator
+ * - :func:`loadd` (loading)
+ - ``"mpg + weight + price"``
+ - ``+`` lists variables
+ * - :func:`olsmt` (models)
+ - ``"price ~ mpg + weight"``
+ - ``~`` separates y from X
+ * - Bracket indexing
+ - ``auto2[., "mpg" "wt"]``
+ - Space separates names
+ * - Type overrides
+ - ``"date($Date) + cat(x)"``
+ - Keywords wrap variable names
+
+.. note::
+
+ GAUSS formula strings are **quoted strings** (``"y ~ x1 + x2"``), not bare expressions like R formulas (``y ~ x1 + x2``). The ``~`` separator works the same way in model formulas, but ``+`` in :func:`loadd` means "include this variable," not "add to model."
+
+Missing Values
+--------------
+
+R uses ``NA``; GAUSS uses ``.`` (dot).
+
+.. code-block:: r
+
+ # R
+ is.na(x) # Element-wise check
+ any(is.na(x)) # Any missing?
+ na.omit(df) # Drop rows with any NA
+ x[!is.na(x)] # Keep non-missing
+ x[is.na(x)] <- 0 # Replace NA with 0
+
+::
+
+ // GAUSS
+ x .== miss(); // Element-wise check (returns 1/0 vector)
+ ismiss(x); // Any missing? (returns scalar 1 or 0)
+ packr(df); // Drop rows with any missing value
+ selif(x, x .!= miss()); // Keep non-missing
+ missrv(x, 0); // Replace missing with 0
+
+.. warning::
+
+ **ismiss is NOT element-wise.** R's ``is.na(x)`` returns a vector. GAUSS's ``ismiss(x)`` returns a **scalar** (1 if any element is missing, 0 otherwise). For element-wise missing detection, use ``x .== miss()``.
+
+Statistics
+----------
+
+.. code-block:: r
+
+ # R
+ mean(x)
+ sd(x)
+ sum(x)
+ min(x); max(x)
+ median(x)
+ var(x)
+ cor(x, y)
+
+::
+
+ // GAUSS
+ meanc(x); // Column mean (the 'c' suffix = column-wise)
+ stdc(x); // Column std dev
+ sumc(x); // Column sum
+ minc(x); // Column min
+ maxc(x); // Column max
+ median(x); // Median
+ stdc(x)^2; // Column variance (scalar, like R's var(x) for a vector)
+ vcx(x); // Full variance-covariance matrix (like R's cov(X) for a matrix)
+
+**Correlation:**
+
+.. code-block:: r
+
+ # R
+ cor(x, y) # Scalar correlation
+ cor(X) # Correlation matrix of all columns
+
+::
+
+ // GAUSS
+ corrx(x ~ y); // 2x2 correlation matrix (~ is horizontal concat here, not a formula)
+ corrx(X); // Full correlation matrix of all columns
+
+.. note::
+
+ Unlike R's ``cor(x, y)`` which returns a scalar, :func:`corrx` always returns a matrix. To get a single correlation coefficient: ``corrx(x ~ y)[1, 2]``.
+
+Linear Regression
+-----------------
+
+.. code-block:: r
+
+ # R
+ model <- lm(price ~ mpg + weight, data = auto2)
+ summary(model)
+
+::
+
+ // GAUSS - print formatted summary (like summary(model) in R)
+ call olsmt(auto2, "price ~ mpg + weight");
+
+.. tip::
+
+ Use ``call olsmt(...)`` (with ``call``) to print a formatted summary table to the screen without saving results to a variable. This is the GAUSS equivalent of ``summary(lm(...))``. The ``call`` keyword discards return values.
+
+**Accessing results:**
+
+.. code-block:: r
+
+ # R
+ coef(model)
+ summary(model)$coefficients[, "Std. Error"]
+ summary(model)$r.squared
+ residuals(model)
+ vcov(model)
+
+::
+
+ // GAUSS
+ struct olsmtOut out;
+ out = olsmt(auto2, "price ~ mpg + weight");
+
+ print out.b; // Coefficient estimates (like coef(model))
+ print out.stderr; // Standard errors
+ print out.rsq; // R-squared
+ print out.resid; // Residuals
+ print out.vc; // Variance-covariance of estimates (like vcov(model))
+
+Key :class:`olsmtOut` members: ``b`` (coefficients), ``stderr`` (standard errors), ``vc`` (variance-covariance matrix), ``rsq`` (R-squared), ``resid`` (residuals), ``dwstat`` (Durbin-Watson), ``sigma`` (residual std dev), ``stb`` (standardized coefficients). To compute t-statistics and p-values: ``t = out.b ./ out.stderr``. See the :func:`olsmt` reference for the full list.
+
+For robust or clustered standard errors, pass an :class:`olsmtControl` structure -- see the :func:`olsmt` reference for details.
+
+Logistic regression (GLM):
+
+.. code-block:: r
+
+ # R
+ model <- glm(admit ~ gre + gpa + rank, data = df, family = binomial)
+
+::
+
+ // GAUSS
+ struct glmOut out;
+ out = glm(data, "admit ~ gre + gpa + rank", "binomial");
+
+Quantile regression:
+
+.. code-block:: r
+
+ # R
+ library(quantreg)
+ rq(y ~ x1 + x2, data = df, tau = c(0.25, 0.5, 0.75))
+
+::
+
+ // GAUSS (no package install needed)
+ struct qfitOut out;
+ out = quantileFit(data, "y ~ x1 + x2", 0.25 | 0.5 | 0.75); // | builds a vector
+
+Plotting
+--------
+
+R users expect rich plotting. GAUSS has a full graphics library:
+
+.. code-block:: r
+
+ # R (base)
+ plot(x, y)
+ hist(x, breaks = 20)
+ boxplot(value ~ group, data = df)
+
+ # R (ggplot2)
+ ggplot(df, aes(x, y)) + geom_point() + labs(title = "Title")
+
+::
+
+ // GAUSS
+ plotXY(x, y);
+ plotScatter(x, y);
+ plotHist(x, 20);
+ plotBox(data, "value ~ group");
+ plotBar(labels, heights);
+ plotSurface(x, y, z);
+
+**Setting titles, labels, and legends** uses a :class:`plotControl` structure. Think of it as GAUSS's equivalent of ggplot's ``+ labs() + theme()``, but configured before the plot call:
+
+::
+
+ // Create a plot with title, labels, and legend
+ struct plotControl myPlot;
+ myPlot = plotGetDefaults("scatter");
+
+ plotSetTitle(&myPlot, "MPG vs Weight");
+ plotSetXLabel(&myPlot, "Weight (lbs)");
+ plotSetYLabel(&myPlot, "Miles per gallon");
+ plotSetLegend(&myPlot, "Domestic" $| "Foreign");
+
+ plotScatter(myPlot, auto2[., "weight"], auto2[., "mpg"]);
+
+**Subplots and saving:**
+
+.. code-block:: r
+
+ # R
+ par(mfrow = c(2, 1)) # 2 rows, 1 column
+ ggsave("plot.png")
+
+::
+
+ // GAUSS
+ plotLayout(2, 1, 1); // 2 rows, 1 col, position 1
+ plotSave("plot.png");
+
+Linear Algebra
+--------------
+
+.. code-block:: r
+
+ # R
+ solve(A) # Inverse
+ det(A) # Determinant
+ eigen(A) # Eigenvalues and vectors
+ svd(A) # Singular value decomposition
+ chol(A) # Cholesky decomposition
+ qr.solve(A, b) # QR-based solve
+ solve(A, b) # Solve Ax = b
+
+::
+
+ // GAUSS
+ inv(A);
+ invpd(A); // Inverse (positive definite, faster)
+ det(A);
+ eig(A); // Eigenvalues only
+ { val, vec } = eigv(A); // Eigenvalues and vectors
+ { u, s, v } = svdcusv(A);
+ chol(A);
+ olsqr(b, A); // QR-based solve (note: argument order is reversed from R)
+ b / A; // Solve Ax = b
+
+.. warning::
+
+ **eigv return order differs from R.** R's ``eigen(A)`` returns ``$vectors`` then ``$values``. GAUSS's ``{ val, vec } = eigv(A)`` returns eigenvalues first, then eigenvectors. Swapping these produces wrong results silently.
+
+.. warning::
+
+ **``/`` is matrix division, not element-wise division.** ``b / A`` solves the system ``Ax = b``. For element-wise division, use ``./``. R's ``/`` is always element-wise; GAUSS's ``/`` is not.
+
+Optimization
+------------
+
+R users doing custom MLE use ``optim()``. GAUSS includes unconstrained and constrained optimization in the base package:
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - R
+ - GAUSS
+ * - ``optim(par, fn)``
+ - ``minimize(&fn, par)``
+ * - ``optim(..., method="L-BFGS-B", lower=..., upper=...)``
+ - ``sqpSolve(&fn, par)``
+ * - ``nleqslv(par, fn)``
+ - ``eqSolve(&fn, par)``
+
+**Key difference:** R uses anonymous functions or named functions passed directly. GAUSS uses the ``&`` operator to pass a *pointer* to a named procedure. The ``&`` tells GAUSS to pass the procedure itself, not its result, so the optimizer can call it repeatedly with different parameter values:
+
+.. code-block:: r
+
+ # R
+ my_obj <- function(beta) {
+ resid <- Y - X %*% beta
+ return(sum(resid^2))
+ }
+ result <- optim(x0, my_obj)
+
+::
+
+ // GAUSS -- named procedure; extra data passed as arguments
+ proc (1) = myObj(beta, Y, X);
+ local resid;
+ resid = Y - X * beta;
+ retp(resid'resid); // resid' * resid = sum of squared residuals
+ endp;
+
+ struct minimizeOut out;
+ out = minimize(&myObj, x0, Y, X);
+
+For maximum likelihood estimation, see :func:`maxlikmt`, which provides a full MLE framework with standard errors, constraints, and convergence diagnostics.
+
+Functions and Procedures
+------------------------
+
+.. code-block:: r
+
+ # R
+ my_func <- function(x, y) {
+ result <- x + y
+ return(result)
+ }
+
+::
+
+ // GAUSS
+ proc (1) = my_func(x, y);
+ local result;
+ result = x + y;
+ retp(result);
+ endp;
+
+**Key differences from R:**
+
+- ``proc (n) =`` declares the number of return values
+- ``local`` declares variables scoped to this procedure (required -- see warning below)
+- ``retp()`` returns values
+- ``endp`` ends the procedure
+- No default argument values. All arguments are positional.
+
+**Multiple outputs:**
+
+.. code-block:: r
+
+ # R
+ my_func <- function(x) list(a = x + 1, b = x - 1)
+ result <- my_func(5)
+ result$a; result$b
+
+::
+
+ // GAUSS
+ proc (2) = my_func(x);
+ local a, b;
+ a = x + 1;
+ b = x - 1;
+ retp(a, b);
+ endp;
+
+ { result_a, result_b } = my_func(5);
+
+.. warning::
+
+ **Variables are global by default.** In R, function variables are automatically local. In GAUSS, you must declare them with ``local`` inside ``proc`` or they become globals that persist after the procedure returns. Forgetting ``local`` creates hard-to-find bugs where procedures silently read or modify variables from the calling scope.
+
+Control Flow
+------------
+
+.. code-block:: r
+
+ # R
+ for (i in 1:10) {
+ print(i)
+ }
+
+ if (x > 0) {
+ print("positive")
+ } else if (x < 0) {
+ print("negative")
+ } else {
+ print("zero")
+ }
+
+ while (x > 0) {
+ x <- x - 1
+ }
+
+::
+
+ // GAUSS
+ for i (1, 10, 1);
+ print i;
+ endfor;
+
+ if x > 0;
+ print "positive";
+ elseif x < 0;
+ print "negative";
+ else;
+ print "zero";
+ endif;
+
+ do while x > 0;
+ x = x - 1;
+ endo;
+
+**Note:** GAUSS requires semicolons after control statements (``if``, ``for``, ``else``, etc.). Inside a ``proc``, remember to declare loop variables with ``local`` (see the warning above) or they become globals: ``local i; for i (1, 10, 1); ... endfor;``
+
+Common Function Translations
+-----------------------------
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Description
+ - R
+ - GAUSS
+ * - Natural log
+ - ``log(x)``
+ - ``ln(x)``
+ * - Log base 10
+ - ``log10(x)``
+ - ``log(x)``
+ * - Column mean
+ - ``mean(x)``
+ - ``meanc(x)``
+ * - Row mean
+ - ``rowMeans(X)``
+ - ``meanr(X)``
+ * - Column sum
+ - ``sum(x)``
+ - ``sumc(x)``
+ * - Cumulative sum
+ - ``cumsum(x)``
+ - ``cumsumc(x)``
+ * - Sort by column
+ - ``df[order(df$x), ]``
+ - ``sortc(df, "x")``
+ * - Find indices
+ - ``which(x > 0)``
+ - ``findIdx(x .> 0)``
+ * - Filter rows
+ - ``df[condition, ]``
+ - ``selif(df, condition)``
+ * - Remove missing rows
+ - ``na.omit(df)``
+ - ``packr(df)``
+ * - Replace missing
+ - ``x[is.na(x)] <- 0``
+ - ``missrv(x, 0)``
+ * - Check NaN (any)
+ - ``any(is.na(x))``
+ - ``ismiss(x)``
+ * - Check NaN (element)
+ - ``is.na(x)``
+ - ``x .== miss(1,1)``
+ * - Flip rows
+ - ``rev(x)``
+ - ``rev(x)``
+ * - Create diagonal matrix
+ - ``diag(v)``
+ - ``diagmat(v)``
+ * - Full SVD
+ - ``svd(A)``
+ - ``{ u,s,v } = svdcusv(A)``
+ * - Number to string
+ - ``as.character(x)``
+ - ``ntos(x)``
+ * - String compare
+ - ``a == b``
+ - ``a $== b``
+ * - Formatted output
+ - ``sprintf(fmt, x)``
+ - ``sprintf(fmt, x)``
+ * - Random uniform
+ - ``runif(n)``
+ - ``rndu(n, 1)``
+ * - Random normal
+ - ``rnorm(n)``
+ - ``rndn(n, 1)``
+ * - Set seed
+ - ``set.seed(42)``
+ - ``rndseed 42``
+ * - Print
+ - ``print(x)``
+ - ``print x;``
+ * - Comment
+ - ``# comment``
+ - ``// comment``
+
+.. warning::
+
+ **log vs ln**: In R, ``log`` is the natural logarithm. In GAUSS, ``log`` is base 10 and ``ln`` is natural. This will silently give wrong results if you don't catch it.
+
+R Package to GAUSS Mapping
+---------------------------
+
+R assembles workflows from packages. GAUSS includes most of this in the base installation:
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - R Package
+ - GAUSS Equivalent
+ * - ``stats`` (lm, glm, optim)
+ - Base GAUSS (``olsmt``, ``glm``, ``minimize``)
+ * - ``quantreg``
+ - Base GAUSS (``quantileFit``)
+ * - ``sandwich`` / ``lmtest``
+ - Base GAUSS (``olsmtControl.cov``)
+ * - ``haven`` / ``foreign``
+ - Base GAUSS (``loadd`` reads Stata/SAS/SPSS)
+ * - ``ggplot2``
+ - Base GAUSS (``plotXY``, ``plotControl``)
+ * - ``Matrix`` (linear algebra)
+ - Base GAUSS (``eigv``, ``svdcusv``, ``chol``)
+ * - ``vars`` / ``forecast``
+ - TSMT add-on
+ * - ``rugarch`` / ``rmgarch``
+ - TSMT add-on
+ * - ``urca`` (unit root, cointegration)
+ - TSMT add-on
+
+**Time series users:** If your work involves ARIMA, VAR, GARCH, impulse response functions, or forecasting, you will use the **TSMT** add-on. Key functions: :func:`arimaFit`, :func:`svarFit` (structural VAR), :func:`varmaFit`, :func:`varmaPredict`. For maximum likelihood estimation, see :func:`maxlikmt`. See the `time series blog `__ for complete worked examples.
+
+Common Gotchas
+--------------
+
+1. **Semicolons are required.** Every statement must end with ``;``
+
+2. **Assignment uses ``=`` not ``<-``.** GAUSS does not support ``<-``.
+
+3. **Dot not colon for "all".** "All rows" is ``df[., 1]`` not ``df[, 1]``. But ``:`` works for ranges: ``df[1:5, .]``.
+
+4. **String quotes.** Only double quotes ``"string"`` work.
+
+5. **No piping.** No ``%>%`` or ``|>`` -- use intermediate variables or nested calls.
+
+6. **The ``call`` keyword.** Use ``call functionName(...)`` to run a function and discard its return value. This is the GAUSS equivalent of running ``summary(lm(...))`` in R without assigning it.
+
+For operator gotchas (``*`` vs ``.*``, ``|`` vs ``.or``, dotted comparisons, ``log`` vs ``ln``), variable scoping (``local``), boolean indexing (``selif``), and procedure ordering, see the inline warnings throughout this guide.
+
+Putting It Together
+-------------------
+
+Here is a complete, runnable example that loads data, filters it, plots it, runs a regression, and prints the results. Running this prints the OLS summary to the Output window and opens a scatter plot.
+
+::
+
+ // Load the auto2 dataset bundled with GAUSS
+ auto2 = loadd(getGAUSSHome("examples/auto2.dta"));
+
+ // Keep only domestic cars (foreign == 0)
+ domestic = selif(auto2, auto2[., "foreign"] .== 0);
+
+ // Quick scatter plot with title and labels
+ struct plotControl myPlot;
+ myPlot = plotGetDefaults("scatter");
+ plotSetTitle(&myPlot, "Weight vs MPG (Domestic Cars)");
+ plotSetXLabel(&myPlot, "Weight (lbs)");
+ plotSetYLabel(&myPlot, "Miles per gallon");
+ plotScatter(myPlot, domestic[., "weight"], domestic[., "mpg"]);
+
+ // Run OLS: how does weight affect fuel efficiency?
+ struct olsmtOut out;
+ out = olsmt(domestic, "mpg ~ weight");
+
+ // Print key results
+ print out.b; // Coefficient estimates
+ print out.stderr; // Standard errors
+ print out.rsq; // R-squared
+
+What's Next?
+------------
+
+- :doc:`../getting-started/quickstart` -- 10-minute introduction to GAUSS basics
+- :doc:`../getting-started/running-existing-code` -- If you inherited GAUSS code and need to get it running
+- :doc:`../data-management` -- Loading, cleaning, and reshaping data
+- :doc:`../textbook-examples/index` -- Worked examples from Greene (*Econometric Analysis*) and Brooks (*Introductory Econometrics for Finance*)
+- `Command Reference <../command-reference.html>`__ -- Browse all 1,000+ built-in functions
+- `Econometrics blog `__ -- Fully worked examples covering regression, panel data, hypothesis testing, and more
+- `Time series blog `__ -- ARIMA, VAR, GARCH, cointegration, and forecasting tutorials with complete code
+
+.. seealso::
+
+ :func:`loadd`, :func:`olsmt`, :func:`glm`, :func:`quantileFit`, :func:`minimize`, :func:`plotXY`, :func:`packr`, :func:`selif`
diff --git a/docs/coming-to-gauss/intro-gauss-for-stata-users.rst b/docs/coming-to-gauss/intro-gauss-for-stata-users.rst
deleted file mode 100644
index 1fa93d73..00000000
--- a/docs/coming-to-gauss/intro-gauss-for-stata-users.rst
+++ /dev/null
@@ -1,1143 +0,0 @@
-Introduction to GAUSS for Stata Users
-=======================================
-This page provides a basic overview of how common Stata operations can be implemented in GAUSS. It is not meant to serve as a comprehensive GAUSS guide. However, we do provide references for those who wish to explore topics in greater depth.
-
-Data Storage
------------------------------------------------------------
-GAUSS stores data in matrices, string arrays, and dataframes. One of the key differences between data storage in GAUSS and Stata is that GAUSS allows you to store data from multiple sources simultaneously.
-
-In Stata, people are most familiar with working with a single dataset in memory. Stata does allow you to store multiple datasets in memory using specified dataframes but special commands must be used to switch between frames.
-
-+--------------------+-----------------------+--------------------+
-| Reference | GAUSS | Stata |
-+====================+=======================+====================+
-|Data structure | Dataframe or matrix | Data set |
-+--------------------+-----------------------+--------------------+
-|Series of data | Column | Variable |
-+--------------------+-----------------------+--------------------+
-|Single occurrence | Row | Observation |
-+--------------------+-----------------------+--------------------+
-|Missing Values | `.` | `.` |
-+--------------------+-----------------------+--------------------+
-
-
-What is a GAUSS dataframe?
-++++++++++++++++++++++++++++++
-.. figure:: ../_static/images/data-import-window-1.jpg
- :width: 80%
-
-A GAUSS dataframe is used to store two-dimensional data and allows you to store:
-
- * Data in rows and columns.
- * Information about the data type and type-related properties.
- * Different variables together, including categorical data, strings, and dates.
-
-Many internal functions are designed to work intelligently with dataframes to use variable names and types for estimation and reporting.
-
-For example, :func:`olsmt` will use the information stored in a dataframe during estimation to:
-
- * Properly include dummy variables when categorical independent variables are present.
- * Include variable names in output reports.
-
-Variables
-^^^^^^^^^^^^^^^^
-Each column of a GAUSS dataframe contains a series of data for a single variable. Variables are stored as strings, numbers, categories, or dates.
-
-In Stata, variables are referenced directly by name.
-
-.. code-block:: Stata
-
- list mpg
-
-In GAUSS, variables can be referenced by indexing with variable name or by column number. However, we must tell GAUSS which dataframe to look for the variable in.
-
-For example, if the variable ``mpg`` is stored in the fourth column of the dataframe ``auto2`` we could use either
-
-::
-
- auto2[., "mpg"];
-
-or
-
-::
-
- auto2[., 4];
-
-to reference the variable.
-
-.. note:: The ``.`` indicates to GAUSS that all rows are being indexed. This will be discussed in more detail in the indexing section.
-
-
-+--------------------+---------------------------------------------+------------------------------------+
-| Variable | Description | Examples |
-| Type | | |
-+====================+=============================================+====================================+
-|String |The string data type can contain letters, | Customer names, product names, |
-| |numbers, and other characters. | or book titles. |
-+--------------------+---------------------------------------------+------------------------------------+
-|Number |Analogous to the data stored in | Daily temperatures, real GDP, |
-| |GAUSS matrices. | stock prices. |
-+--------------------+---------------------------------------------+------------------------------------+
-|Categories |Houses discrete variables that capture | Marriage status, performance |
-| |qualitative data. | ratings, transportation modes. |
-+--------------------+---------------------------------------------+------------------------------------+
-|Dates |Houses and displays dates and times. | Purchase date, shipping date, |
-| | | observation date. |
-+--------------------+---------------------------------------------+------------------------------------+
-
-Observations
-^^^^^^^^^^^^^^^^
-Each row of a GAUSS dataframe contains simultaneous observations of variables. In `time series data `_ or `panel data `_ , this may correspond to dates of observations. In cross-sectional data, this may correspond to some other identifier such as identification number, observation number, or name.
-
-Rows of data are indexed by row number. For example, if we want to access the data stored in the fourth row we use
-
-::
-
- auto2[4, .];
-
-Data Input/Output
---------------------
-
-Constructing a dataframe from values
-+++++++++++++++++++++++++++++++++++++
-In Stata, the ``input`` statement is used to build datasets from specified values and column names:
-
-.. code-block:: Stata
-
- input x y
- 1 2
- 3 4
- 5 6
- end
-
-In GAUSS, a dataframe can be created from a manually entered matrix and variable names using the :func:`asDF` procedure:
-
-::
-
- // Create a 3 x 2 matrix
- mat = { 1 2,
- 3 4,
- 5 6 };
-
- // Convert matrix to a dataframe
- // and name the first column "X"
- // and the second column "Y"
- df = asDF(mat, "X", "Y");
-
-Reading external datasets
-+++++++++++++++++++++++++++++++++++++
-GAUSS can directly read and load data from most data formats, including:
-
- * CSV
- * Excel (XLS, XLSX)
- * HDF 5
- * GAUSS matrices (FMT)
- * GAUSS datasets (DAT)
- * Stata datasets (DTA)
- * SAS datasets (SAS7BDAT, SAS7BCAT)
- * SPSS datasets (SAV)
-
-In Stata, the ``import`` command is used to import non-Stata datasets. Additional information must be provided to specify what type of file is being imported.
-
-.. code-block:: Stata
-
- import excel "nba_ht_wt.xls", clear
-
-Alternatively, the ``tips2.csv`` dataset is loaded into Stata using the import delimited command
-
-.. code-block:: Stata
-
- import delimited "tips2.csv", clear
-
-.. note:: The use of the ``clear`` option is necessary in Stata if the data is already loaded into the workspace. In GAUSS, this is not necessary because multiple data sets can be loaded into the work space simultaneously.
-
-In GAUSS, all data files are usually loaded using the :func:`loadd` procedure. For example, consider loading the ``auto2.dta`` dataset:
-
-::
-
- // Load all variables from the file 'auto2.dta'
- // using their default types
- auto2 = loadd(getGAUSSHome $+ "examples/auto2.dta");
-
-This loads all the variables in the dataset and auto-detects their type.
-
-.. figure:: ../_static/images/data-import-window-1.jpg
- :width: 80%
-
-Sometimes, you may need to specify the type and/or variables that you wish to load. This is done using a `formula string `_:
-
-For example, let’s consider loading the ``nba_ht_wt.xls`` file in GAUSS
-
-::
-
- // Create filename
- fname = getGAUSSHome $+ "examples/nba_ht_wt.xls";
-
- // Load the file 'nba_ht_wt.xls'
- // using a formula string to select variables
- // and specify variable types
- nba_ht_wt = loadd(fname, "str(Player) + cat(Pos) + Height + Weight + str(School)");
-
-Similarly, the ``tips2.csv`` data file:
-
-::
-
- // Create filename
- fname = getGAUSSHome $+ "examples/tips2.csv";
-
- // Load the file 'tips2.csv'
- // using a formula string to select variables
- // and specify variable types
- tips2 = loadd(fname, "id + total_bill + tip + cat(sex) + cat(time)");
-
-.. note:: The :func:`getGAUSSHome` function is a convenience function that returns the full path to the GAUSS home directory.
-
-Formula strings accept a number of operators and keywords which allow you to:
-
-* Specify variable types.
-* Perform data transformations.
-
-+--------------------+---------------------------------------------+
-|Operator | Purpose |
-+====================+=============================================+
-| ``.`` |Represents all variables. |
-+--------------------+---------------------------------------------+
-| ``+`` |Adds a variable. |
-+--------------------+---------------------------------------------+
-| ``-`` |Removes a variable. |
-+--------------------+---------------------------------------------+
-| ``1`` |Represents an intercept term. |
-+--------------------+---------------------------------------------+
-| ``*`` |Adds an interaction term and includes both |
-| |original variables. |
-+--------------------+---------------------------------------------+
-| ``:`` |Adds an interaction term between two |
-| |variables but does not include either |
-| |of the original variables. |
-+--------------------+---------------------------------------------+
-
-+--------------------+---------------------------------------------+
-|Keyword | Purpose |
-+====================+=============================================+
-| ``cat`` |Load a variable as a categorical column. |
-+--------------------+---------------------------------------------+
-| ``date`` |Load a variable as a date column. |
-+--------------------+---------------------------------------------+
-| ``str`` |Load a variable as a string column. |
-+--------------------+---------------------------------------------+
-| ``$`` |Indicate that a variable is stored in the |
-| |file as a string as should be passed to the |
-| |keyword or procedure as a string column. |
-+--------------------+---------------------------------------------+
-
-The GAUSS Data Management guide provides a complete guide to `Programmatic Data Import `_.
-
-Interactively loading data
-+++++++++++++++++++++++++++++++++++++
-The GAUSS **Data Import** window is a completely interactive environment for loading data and performing preliminary data cleaning. It can be used to:
-
-* Select variables and change types.
-* Select observation by range or logic filtering.
-* Manage date formats and category labels.
-* Preview data.
-
-The **Data Import** window offers a data import experience similar to Stata’s menu driven data import. Like Stata, the GAUSS **Data Import** window auto-generates code that can be reused.
-
-.. figure:: ../_static/images/data-import-code-generation.png
- :width: 80%
-
-You can open the **Data Import** window in three ways:
-
-* Select **File > Import Data** from the main GAUSS menu bar.
-* From the **Project Folders** window:
-
- * Double-click on the name of the data file.
- * Right-click the file and select **Import Data**.
-
-A complete `guide to interactively loading data `_ is available in the GAUSS Data Management guide.
-
-Viewing Data
-+++++++++++++++++
-Data can be viewed in GAUSS a number of ways:
-
-* Using the **GAUSS Data Editor**.
-.. figure:: ../_static/images/data-cleaning-open-symbol-editor-filter.jpg
- :width: 80%
-* Opening a floating **Symbols Editor** window using `Ctrl+E`.
-* Printing data to the **Command Window**.
-
-For a quick preview, portions of a dataframe can be printed directly to screen using indexing. For example, the first five rows the `auto2` dataframe can be printed to screen by entering
-
-::
-
- auto2[1:5, .];
-
-This is equivalent to using the ``list`` command in Stata
-
-.. code-block:: Stata
-
- list 1/5
-
-If we only wanted to view the first five rows of the variable ``mpg`` from the ``auto2`` dataframe, we would use
-
-::
-
- auto2[1:5, "mpg"];
-
-which is equivalent to
-
-.. code-block:: Stata
-
- list mpg 1/5
-
-In GAUSS, you can also preview the beginning or end of your data using the :func:`head` or :func:`tail` functions, respectively.
-
-For example, to view the first five rows of ``make``, ``price``, and ``mpg`` in the dataframe ``auto2``:
-
-::
-
- head(auto2[., "make" "price" "mpg"]);
-
-This prints
-
-::
-
- make price mpg
- AMC Concord 4099.0000 22.000000
- AMC Pacer 4749.0000 17.000000
- AMC Spirit 3799.0000 22.000000
- Buick Century 4816.0000 20.000000
- Buick Electra 7827.0000 15.000000
-
-We can include an optional input to indicate how many rows to include. A positive number specifies how many rows to print. For example, to print the first ten rows:
-
-::
-
- head(auto2[., "make" "price" "mpg"], 10);
-
-This prints the first ten rows:
-
-::
-
- make price mpg
- AMC Pacer 4749.0000 17.000000
- Buick Century 4816.0000 20.000000
- Buick Electra 7827.0000 15.000000
- Buick LeSabre 5788.0000 18.000000
- Buick Opel 4453.0000 26.000000
- Buick Regal 5189.0000 20.000000
- Buick Riviera 10372.000 16.000000
- Buick Skylark 4082.0000 19.000000
-
-A negative number indicates how many rows to skip before beginning printing. For example, to print everything after the first 10 rows of data:
-
-::
-
- head(auto2[., "make" "price" "mpg"], -10);
-
-
-Data Operations
---------------------
-
-Indexing matrices and dataframes
-++++++++++++++++++++++++++++++++++++
-
-GAUSS uses square brackets ``[]`` for indexing matrices. The indices are listed row first, then column, with a comma separating the two. For example, to index the element in the 3rd row and 7th column of the matrix ``x``, we use:
-
-::
-
- x[3, 7];
-
-To select a range of columns or rows with numeric indices, GAUSS uses the `:` operator:
-
-::
-
- x[3:6, 7];
-
-GAUSS also allows you to use variable names in a dataframe for indexing. As an example, if we want to access the 3rd observation of the variable ``mpg`` in the ``auto2`` dataframe, we use:
-
-::
-
- auto2[3, "mpg"];
-
-You can also select multiple variables using a space separated list:
-
-::
-
- auto2[3, "mpg" "make"];
-
-Finally, GAUSS allows you index an entire column or row using the ``.`` operator. For example, to see all observations of the variable ``mpg`` in the ``auto2`` dataframe, we use:
-
-::
-
- auto2[., "mpg"];
-
-Operations on variables
-+++++++++++++++++++++++++
-In Stata, ``generate`` and ``replace`` are required to either transform existing variables or generate new variables using existing variables:
-
-.. code-block:: Stata
-
- replace total_bill = total_bill - 2
- generate new_bill = total_bill / 2
-
-In GAUSS, these operations are performed using operators. For example, GAUSS uses:
-
-* The ``-`` operator to subtract values.
-* The ``/`` operator to divide values.
-* The ``=`` to assign the new values to a storage location.
-* The ``~`` to add new columns to a matrix or dataframe.
-
-::
-
- // Subtract 2 from all observations of the
- // variable 'total_bill' in the 'tips2' dataframe
- tips2[., "total_bill"] = tips2[., "total_bill"] - 2;
-
- // Divide all observations of the variable
- // 'total_bill' in the 'tips2' dataframe by 2
- tips2[., "total_bill"] = tips2[., "total_bill"] / 2;
-
- // Divide all observations of the variable
- // 'total_bill' in the 'tips2' dataframe by 2
- // and generate 'new_bill'
- tips2 = tips2 ~ dfname(tips2[.,"total_bill"] / 2, "new_bill");
-
-Matrix operations
-+++++++++++++++++++
-GAUSS is a matrix based language and matrix operations play a fundamental role in GAUSS computations.
-
-**Common Matrix Operators**
-
-+--------------------+-----------------------+-------------------------+
-|Description | GAUSS | Stata |
-+====================+=======================+=========================+
-|Matrix multiply | ``z = x * y;`` | ``matrix z = x*y`` |
-+--------------------+-----------------------+-------------------------+
-|Solve system of | ``b = y / x;`` | ``matrix b = y*inv(x)`` |
-|linear equations | | |
-+--------------------+-----------------------+-------------------------+
-|Kronecker product | ``z = x .*. y;`` | ``matrix z = x#y`` |
-+--------------------+-----------------------+-------------------------+
-|Matrix transpose | ``z = x';`` | ``matrix z = x’`` |
-+--------------------+-----------------------+-------------------------+
-
-When dealing with matrices, it is important to distinguish matrix operations from element-by-element operations. In Stata, element-by-element operations are specified with a colon ``:``. In GAUSS, element-by-element operations are specified by a dot ``.``.
-
-**Element-by-element (ExE) Operators**
-
-+---------------------------------+-----------------------+-------------------------+
-|Description | GAUSS | Stata |
-+=================================+=======================+=========================+
-|Element-by-element multiply | ``z = x .* y;`` | ``matrix z = x:*y`` |
-+---------------------------------+-----------------------+-------------------------+
-|Element-by-element divide | ``z = y ./ x;`` | ``matrix z = y:/x`` |
-+---------------------------------+-----------------------+-------------------------+
-|Element-by-element exponentiation| ``z = x .^ y;`` | ``matrix z = x:^y`` |
-+---------------------------------+-----------------------+-------------------------+
-|Element-by-element addition | ``z = x + y;`` | ``matrix z = x + y`` |
-+---------------------------------+-----------------------+-------------------------+
-|Element-by-element subtraction | ``z = x - y;`` | ``matrix z = x - y`` |
-+---------------------------------+-----------------------+-------------------------+
-
-For a more in depth look at how matrix operation works in GAUSS you may want to review our blogs:
-
-* `GAUSS Basics 3: Intro to Matrices `_
-* `GAUSS Basics 4: Matrix Operations `_
-* `GAUSS Basics 5: Element-by-Element Conformability `_
-
-Filtering
-+++++++++++++++++++
-In Stata, data is filtered using an ``if`` clause when using other commands. For example, to keep all observations where ``total_bill`` is greater than 10 we use:
-
-.. code-block:: Stata
-
- keep if total_bill > 10
-
-In GAUSS this can be done interactively with the **Data Management Tool**:
-
-.. figure:: ../_static/images/filtering-tips.jpg
- :width: 80%
-
-Programmatically this is done using the :func:`selif` procedure:
-
-::
-
- // Select observations from the tips2 dataframe
- // where the total_bill variable is greater than 10
- tips2 = selif(tips2, tips2[., "total_bill"] .> 10);
-
-More information about filtering data can be found in:
-
-* The `Interactive Data Cleaning section `_ of the Data Management Guide.
-* `Preparing and Cleaning FRED data in GAUSS `_
-* `Getting to Know Your Data with GAUSS 22 `_
-
-Selection of data
-+++++++++++++++++++
-Stata allows you to select, drop, or rename columns using command line keywords:
-
-.. code-block:: Stata
-
- keep sex total_bill tip
-
- drop sex
-
- rename total_bill total_bill_2
-
-In GAUSS, the same can be done using the **Data Management** pane.
-
-.. figure:: ../_static/images/data-cleaning-open-symbol-editor-filter.jpg
-
-To open the **Data Management** pane:
-
-1. Double-click the name of the dataframe in the **Symbols** window on the **Data** page.
-2. Click the **Manage** button with the cog icon on the top right of the open **Symbol Editor** window.
-
-Select columns from a dataframe
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Columns can be selected or removed from the dataframe using the **Variables** list.
-
-* If a variable has a check box next to the name of the variables it is included in the dataframe.
-* To clear the variable from the dataframe clear the check box next to the variable name.
-
-These changes will not be made until you click **Apply**.
-
-Changing variable names
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Variable names can also be changes from the **Variables** list.
-
-.. figure:: ../_static/images/data-organization-rename-variable.jpg
- :scale: 50%
-
-1. Double-click the dataframe you want to modify in the **Symbols** pane of the **Data** page.
-2. Click the **Manage** button at the top right of the open **Symbol Editor**.
-3. Click downward pointing triangle button to the right of the name of the variable name you want to change and select **Rename**.
-4. Enter the new name in the **Name** text box.
-
-These changes will not be made until you click **Apply**.
-
-GAUSS also offers programmatic options for selecting data and changing variable names:
-
-::
-
- // Keep only 'total_bill' 'tip' and 'sex'
- tips2 = tips2[., "total_bill" "tip" "sex"];
-
- // Drop sex variable
- tips2 = delcols(tips2, "sex");
-
- // Rename variable 'total_bill' to 'total_bill_2'
- tips2 = dfname(tips2, "total_bill_2", "total_bill");
-
-Sorting
-++++++++++++++++
-In Stata the ``sort`` command is used for sorting data:
-
-.. code-block:: Stata
-
- sort sex total_bill
-
-In GAUSS, this is done using :func:`sortc`.
-
-We can accomplish the same sorting as the Stata line above using:
-
-::
-
- // Sort the 'tips2' dataframe based
- // on 'sex' and 'total_bill' variables
- tips2 = sortc(tips2, "sex" $| "total_bill");
-
-Date Functionality
---------------------
-GAUSS dataframes include a date data type which makes it convenient to read, format, and use dates in analysis.
-
-Date variables can be loaded interactively using the **Data Import** window or programmatically using :func:`loadd` and the ``date`` keyword.
-
-Creating usable dates from raw data
-++++++++++++++++++++++++++++++++++++++
-In Stata, dates are most often imported as strings from raw data. They must then be converted to usable date types using the ``date()`` function and a readable format is set using ``format``.
-
-For example, when the ``yellowstone.csv`` dataset is imported into Stata, the variable ``date`` is a string variable
-The ``date`` variable must be converted to a date type:
-
-.. code-block:: Stata
-
- generate date_var = date(date, "YMD");
-
-and the viewing format should be set
-
-.. code-block:: Stata
-
- format date_var %d.
-
-In GAUSS, dates can be directly read in as date variables using the :func:`loadd` procedure and the ``date`` keyword. The :func:`loadd` procedure automatically detects common date formats and doesn’t require a format specification unless a custom format is being used in the raw data:
-
-::
-
- // Create filename
- fname = getGAUSSHome $+ "examples/yellowstone.csv";
-
- // Load the variable Visits, LowtTep, HighTemp and Date
- // from the file 'yellowstone.csv'
- yellowstone = loadd(fname, "Visits + LowtTemp + HighTemp + date($Date)");
-
-.. figure:: ../_static/images/yellowstone-dates.jpg
- :width: 80%
-
-Creating dates from existing strings
-++++++++++++++++++++++++++++++++++++++
-The GAUSS :func:`asDate` procedure works similarly to the Stata ``date()`` function and can be used to convert strings to dataframe dates.
-
-For example, suppose we want to convert the string ``"2002-10-01"`` to a date in Stata:
-
-.. code-block:: Stata
-
- generate date_var = date("2002-10-01", "YMD")
-
-When we do this in Stata the data is displayed in the date numeric format and we have to use the ``format`` command to change the display format:
-
-.. code-block:: Stata
-
- format date_var %d
-
-In GAUSS, this is done using the :func:`asDate` procedure:
-
-::
-
- // Convert string date '2002-10-01'
- // to a date variable
- date_var = asDate("2002-10-01");
-
-The :func:`asDate` procedure automatically recognizes dates in the format ``"YYYY-MM-DD HH:MM:SS"``. However, if the date is in a different format, a format string can be used:
-
-::
-
- // Convert string date '10/01/2002'
- // to a date variable
- date_var = asDate("10/01/2002", "%d/%m/%Y");
-
-
-Changing the display format
-++++++++++++++++++++++++++++++++++++++
-Once a date variable has been imported or created, the display format can be specified interactively using the GAUSS **Data Management Tool**.
-
-The **Specify Date Format** dialog is accessed by selecting **Properties** from the variable's dropdown:
-
-.. figure:: ../_static/images/interactive-data-cleaning-variable-properties.jpg
- :width: 60%
-
-If the variable is a date variable, the **Specify Date Format** window will open:
-
-.. figure:: ../_static/images/select-date-format.jpg
- :width: 60%
-
-Dates can be managed programmatically using :func:`asDate`:
-
-::
-
- // Convert 'Date' variable from string variable
- // to date variable
- yellowstone = asdate(yellowstone, "%b-%d-%Y", "Date");
-
-String Processing
--------------------
-
-Finding the length of a string
-+++++++++++++++++++++++++++++++
-The ``strlen()`` and ``ustrlen()`` functions are used in Stata to find the length of strings:
-
-.. code-block:: Stata
-
- generate strlen_time = strlen(time)
- generate ustrlen_time = ustrlen(time)
-
-GAUSS also uses a :func:`strlen()` procedure to find string lengths:
-
-::
-
- // Find length of all observations
- // of the variable 'time' in
- // the 'tips2' dataframe
- strlen_time = strlen(tips2[., "time"]);
-
-Finding the position of a substring
-+++++++++++++++++++++++++++++++++++++++
-
-Finding the position of strings can be useful for data searching and cleaning. In Stata, the ``strpos()`` function allows you to find the location of a specified substring within another string:
-
-.. code-block:: Stata
-
- generate str_position = strpos(sex, "ale")
-
-In GAUSS, this is done using the :func:`strindx()` or :func:`strrindx()` procedures. The :func:`strindx()` procedure searches from the beginning of the string and the :func:`strrindx()` procedure searches from the end of the string.
-
-The functions require two inputs:
-
-* *where* (string or scalar) – the data to be searched.
-* *what* (string or scalar) – the substring to be searched for in *where*.
-
-For example consider the ``sex`` variable in the ``tips2`` dataframe. The first ten observations are:
-
-::
-
- tips2[1:10, "sex"];
-
- sex
- Female
- Male
- Male
- Male
- Female
- Male
- Male
- Male
- Male
- Male
-
-::
-
- // Find the location of the substring 'ale'
- // in the variable 'sex' in the 'tips2' dataframe
- str_pos = strindx(tips2[., "sex"], "ale");
-
- // Display the first 10 observations of
- // all variables in 'str_pos'
- str_pos[1:10, .];
-
-The printed result is:
-
-::
-
- 4.0000000
- 2.0000000
- 2.0000000
- 2.0000000
- 4.0000000
- 2.0000000
- 2.0000000
- 2.0000000
- 2.0000000
- 2.0000000
-
-Extracting a substring by position
-++++++++++++++++++++++++++++++++++++
-In Stata, the ``substr()`` function is used to extract substrings from a string. The ``substr()`` function uses position and string length to specify which substring to extract:
-
-.. code-block:: Stata
-
- generate short_sex = substr(sex, 1, 1)
-
-The same thing can be done in GAUSS using the :func:`strsect()`:
-
-::
-
- // Extract first letter from
- // the variable 'sex' in the
- // 'tips2' dataframe
- short_sex = strsect(tips2[., "sex"], 1, 1);
- short_sex[1:5, .];
-
-The printed result is:
-
-::
-
- sex
- F
- M
- M
- M
- F
-
-Extracting words
-++++++++++++++++++
-Stata allows you to extract the nth word from a string using the :func:`word()` function. For example, to consider if we wish to separate the first and last names from a name into two variables.
-
-.. code-block:: Stata
-
- clear
- input str20 name
- "John Smith"
- "Jane Cook"
- end
-
- generate first_name = word(name, 1)
- generate last_name = word(name, -1)
-
-
-While GAUSS doesn’t have an exactly analogous function, this can be done fairly easily using the :func:`strsplit` procedure.
-
-The :func:`strsplit` procedure splits the string using an optional specified separator. If no separator is provided, :func:`strsplit` separates strings based on spaces.
-
-For example:
-
-::
-
- // Generate string array of names
- string name = { "John Smith", "Jane Cook" };
-
- // Split into two strings
- // and name variables 'first_name' and 'last_name'
- name_split = asDF(strsplit(name), "first_name", "last_name");
-
-This creates the ``name_split`` dataframe:
-
-::
-
- first_name last_name
- John Smith
- Jane Cook
-
-If the original name data has first, middle, and last names, all separated by spaces, then :func:`strsplit` will split the strings into three columns:
-
-::
-
- // Generate string array of names
- string full_name = { "John Robert Smith", "Jane Elizabeth Cook" };
-
- // Split into three strings
- // and name variables 'first_name', 'middle_name', and 'last_name'
- name_split = asDF(strsplit(full_name), "first_name", "middle_name", "last_name");
-
-Now the ``name_split`` variable contains three variables:
-
-::
-
- first_name middle_name last_name
- John Robert Smith
- Jane Elizabeth Cook
-
-Finally, suppose our names are separated by a comma and a space, instead of a space:
-
-::
-
- // Generate string array of names
- string name = { "Smith,John", "Cook,Jane" };
-
- // Split into two strings using ', ' as a separator
- // and name variables 'last_name' and 'first_name'
- name_split = asDF(strsplit(name, ", "), "last_name", "first_name");
-
-Now our ``name_split`` variable is:
-
-::
-
- last_name first_name
- Smith John
- Cook Jane
-
-Changing case
-++++++++++++++++++++
-GAUSS uses the :func:`upper` and :func:`lower` procedures to change all letters in strings to uppercase and lowercase, respectively.
-
-For example:
-
-::
-
- // Change time variable in 'tips2' to all uppercase
- tips2[., "time"] = upper(tips2[., "time"]);
-
- // Change sex variable in 'tips2' to all lowercase
- tips2[., "sex"] = lower(tips2[., "sex"]);
-
-This compares to the ``strupper()`` and ``strlower()`` functions in Stata, which change all letters in a string to uppercase and lowercase, respectively.
-
-.. code-block:: Stata
-
- generate upper_time = strupper(time)
- generate lower_sex = strlower(sex)
-
-Missing values
--------------------
-Missing values are represented by the same dot notation, ``.``, in both Stata and GAUSS.
-
-This notation can be used for filtering data Stata:
-
-.. code-block:: Stata
-
- * Keep missing values
- list if value_x == .
-
- * Keep non-missing values
- list if value_x != .
-
-In GAUSS missing values can be created with a statement or using the :func:`error` function:
-
-::
-
- // Keep missing values
- mss = { . };
- data = selif(data, data[., "x"] .== mss));
-
- // Keep non-missing values
- data = selif(data, data[., "x"] .!= error(0));
-
-
-Counting missing values
-++++++++++++++++++++++++++
-In Stata, missing values in individual variables can be counted using the ``count`` command. This command works with a logical statement specifying what condition is to be counted:
-
-.. code-block:: Stata
-
- count if rep78 == .
-
-In GAUSS, missing values can be counted using the :func:`counts` function and ``error(0)``:
-
-::
-
- counts(auto2[., "rep78"], error(0));
-
-This finds how many missing values there are in the ``rep78`` variable, found in the ``auto2`` dataframe:
-
-::
-
- 5.0000000
-
-Alternatively, missing values are counted as part of the descriptive statistics using :func:`dstatmt`:
-
-::
-
- // Get descriptive statistics
- call dstatmt(auto2);
-
-This returns
-
-::
-
- ---------------------------------------------------------------------------------------------
- Variable Mean Std Dev Variance Minimum Maximum Valid Missing
- ---------------------------------------------------------------------------------------------
- make ----- ----- ----- ----- ----- 74 0
- price 6165 2949 8.7e+06 3291 1.591e+04 74 0
- mpg 21.3 5.786 33.47 12 41 74 0
- rep78 ----- ----- ----- Poor Excellent 69 5
- headroom 2.993 0.846 0.7157 1.5 5 74 0
- trunk 13.76 4.277 18.3 5 23 74 0
- weight 3019 777.2 6.04e+05 1760 4840 74 0
- length 187.9 22.27 495.8 142 233 74 0
- turn 39.65 4.399 19.35 31 51 74 0
- displacement 197.3 91.84 8434 79 425 74 0
- gear_ratio 3.015 0.4563 0.2082 2.19 3.89 74 0
- foreign ----- ----- ----- Domestic Foreign 74 0
-
-Removing missing values
-++++++++++++++++++++++++
-GAUSS provides two options for removing missing values from a matrix:
-
-* The :func:`packr()` procedure removes all rows from a matrix that contain any missing values.
-* The :func:`delif()` procedure removes all rows which meet a particular condition.
-
-::
-
- // Create matrix
- a = { 1 .,
- . 4,
- 5 6 };
-
- // Remove all rows with a missing value
- print packr(a);
-
-will return
-
-::
-
- 5 6
-
-Conversely
-
-::
-
- // Create matrix
- a = { 1 .,
- . 4,
- 5 6 };
-
- // Remove all rows with a missing value
- // in the second column
- print delif(a, a[., 2] .== error(0));
-
-will only delete rows with a missing value in the second column
-
-::
-
- . 4
- 5 6
-
-Replacing missing values
-++++++++++++++++++++++++++
-GAUSS also provides two functions for replacing missing values:
-
-* The :func:`missrv` function.
-* The :func:`impute` function.
-
-The :func:`missrv` function replaces all missing values in a matrix with a user-specified value
-
-::
-
- // Create matrix
- a = { 1 .,
- . 4,
- 5 6 };
-
- // Replace all missing values with -999
- print missrv(a, -999);
-
-returns
-
-::
-
- 1 -999
- -999 4
- 5 6
-
-This is similar to using the replace variable in Stata
-
-.. code-block:: Stata
-
- replace a = -999 if a >= .
-
-The :func:`impute()` procedure replaces missing values in the columns of a matrix using a specified imputation method.
-The procedure offers six potential methods for imputation:
-
-* ``"mean"`` - replaces missing values with the mean of the column.
-* ``"median"`` - replaces missing values with the median of the column.
-* ``"mode"`` - replace missing values with the mode of the column.
-* ``"pmm"`` - replaces missing values using predictive mean matching.
-* ``"lrd"`` - replaces missing values using local residual draws.
-* ``"predict"`` - replaces missing values using linear regression prediction.
-
-More details about dealing with missing values are available in:
-
-* `The Introduction to Handling Missing Values blog. `_
-* `The Data Cleaning section `_ of the GAUSS Data Management Guide.
-
-Merging
-----------------
-In Stata merging:
-
-* Is performed using the ``merge`` command.
-* Is done using a dataset in memory and a data file on disk.
-* Keeps all data from the data in memory and the `using` data.
-* Creates a ``_merge`` variable indicating if the data point from the original data, the ``using`` data, or the intersection of the two.
-* Allows for one-to-one, one-to-many, many-to-one, and many-to-many joining operations.
-
-In GAUSS merging:
-
-* Is done using the :func:`outerJoin` or :func:`innerJoin` procedures.
-* Is done completely with data in memory.
-* The :func:`innerJoin` function only keeps matching observations.
-* The :func:`outerJoin` function keeps observations either from both data sources or the left-hand data source.
-* Allows for one-to-one, one-to-many, many-to-one, and many-to-many joining operations.
-
-As a first example, let’s consider two dataframes. The first contains ``ID`` and ``Age``:
-
-::
-
- ID Age
- John 22
- Mary 18
- Susan 34
- Connie 45
-
-The second contains ``ID`` and ``Occupation``:
-
-::
-
- ID Occupation
- John Teacher
- Mary Surgeon
- Susan Developer
- Tyler Nurse
-
-In Stata, we merge these using ``merge()``:
-
-.. code-block:: Stata
-
- * Create and save the age dataset
- clear
- input str10 ID
- John Doe
- Mary Jane
- Susan Smith
- Connie Lee
- end
-
- input age
- 22
- 18
- 34
- 45
- end
- save df1.dta
-
- * Now create occupation data
- * and keep in memory
- clear
- input str10 ID
- John
- Mary
- Susan
- Tyler
- end
-
- input str10 occupation
- Teacher
- Surgeon
- Developer
- Nurse
- end
-
- merge 1:1 ID using df1
-
-We can do the same in GAUSS using :func:`outerJoin`:
-
-::
-
- // Create ID strings
- string ID1 = { "John", "Mary", "Susan", "Connie" };
- string ID2 = { "John", "Mary", "Susan", "Tyler" };
-
- // Create age vector
- age = { 22, 18, 34, 45 };
-
- // Create occupation string
- string Occupation = { "Teacher", "Surgeon", "Developer", "Nurse" };
-
- // Create first df
- df1 = asDF(ID1, "ID") ~ asDF(age, "Age");
-
- // Create second df
- df2 = asDF(ID2, "ID") ~ asDF(Occupation, "Occupation");
-
- // Merge dataframes
- df3 = outerJoin(df2, "ID", df1, "ID", "full");
-
-The ``df3`` dataframe contains:
-
-::
-
- ID Occupation Age
- John Teacher 22.000000
- Mary Surgeon 18.000000
- Susan Developer 34.000000
- Tyler Nurse .
- Connie . 45.000000
-
-The ``df3`` dataframe contains all observations from both the ``df1`` and ``df2`` dataframes, even if they aren't matched, because we included the ``"full"`` option.
-
-If we just wanted to keep the matches to the keys from the ``df2`` dataframe we would exclude the ``"full"`` option:
-
-::
-
- // Merge dataframes
- df3 = outerJoin(df2, "ID", df1, "ID");
-
-Now ``df3`` includes:
-
-::
-
- ID Occupation Age
- John Teacher 22.000000
- Mary Surgeon 18.000000
- Susan Developer 34.000000
- Tyler Nurse .
diff --git a/docs/comlog.rst b/docs/comlog.rst
index 0d055567..4d9f0b06 100644
--- a/docs/comlog.rst
+++ b/docs/comlog.rst
@@ -90,3 +90,4 @@ Remarks
* Interactive commands to run a file, i.e. ``run ols.e;`` will not be logged by `comlog`.
+.. seealso:: Functions :func:`screen`, :func:`output`
diff --git a/docs/compile.rst b/docs/compile.rst
index 766ec892..d3f2e32b 100644
--- a/docs/compile.rst
+++ b/docs/compile.rst
@@ -32,20 +32,20 @@ Examples
compile qxy.e;
-In this example, the `source path` would be searched for qxy.e, which
+In this example, the ``source path`` would be searched for qxy.e, which
would be compiled to a file called :file:`qxy.gcg` on the same subdirectory *qxy.e* was found.
::
compile qxy.e xy;
-In this example, the `source path` would be searched for *qxy.e* which
+In this example, the ``source path`` would be searched for *qxy.e* which
would be compiled to a file called :file:`xy.gcg` on the current subdirectory.
Remarks
-------
-- The source file will be searched for in the `source path` if the full path
+- The source file will be searched for in the ``source path`` if the full path
is not specified and it is not present in the current directory.
- The source file is a regular text file containing a GAUSS program.
@@ -66,7 +66,7 @@ Remarks
- The program saved in the compiled file can be run with the `run`
command. If no extension is given, the `run` command will look for a
file with the correct extension for the version of GAUSS. The
- `source path` will be used to locate the file if the full path name is not
+ ``source path`` will be used to locate the file if the full path name is not
given and it is not located on the current directory.
- When the compiled file is run, all previous symbols and procedures
@@ -74,10 +74,10 @@ Remarks
to execute a `new` before running a compiled file.
- If you want line number records in the compiled file you can put a
- `#lineson` statement in the source file or turn line tracking on from
+ ``#lineson`` statement in the source file or turn line tracking on from
the main GAUSS menu, :menuselection:`Tools --> Preferences --> Advanced`.
-- Don't try to include compiled files with `#include`.
+- Don't try to include compiled files with ``#include``.
- GAUSS compiled files are platform and bit-size specific. For example,
a file compiled with GAUSS for Windows 64-bit will not run under
diff --git a/docs/conf.py b/docs/conf.py
index 6f0b175b..5c4b2329 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -20,7 +20,7 @@
# -- Project information -----------------------------------------------------
project = 'GAUSS'
-copyright = '2025, Aptech Systems, Inc'
+copyright = '2026, Aptech Systems, Inc'
author = 'Aptech Systems, Inc'
# The short X.Y version
diff --git a/docs/conj.rst b/docs/conj.rst
index 0e16f9c5..35c678d2 100644
--- a/docs/conj.rst
+++ b/docs/conj.rst
@@ -39,3 +39,4 @@ Remarks
Compare :func:`conj` with the transpose (``'``) operator.
+.. seealso:: Functions :func:`complex`, :func:`real`, :func:`imag`, :func:`hasimag`
diff --git a/docs/contingency.rst b/docs/contingency.rst
index a501090d..b91150bc 100644
--- a/docs/contingency.rst
+++ b/docs/contingency.rst
@@ -205,5 +205,5 @@ Agresti, Alan. 2002. *Categorical Data Analysis*. 2nd ed. New York: John Wiley a
Bishop, Yvonne, Stephen Fienberg and Paul Holland. 1975. *Discrete Multivariate Analysis: Theory and Practice*. Cambridge, Mass.: MIT Press.
-.. seealso:: Functions :func:`tabulate`, :func:`frequency`, :func:`crossprod`
+.. seealso:: Functions :func:`tabulate`, :func:`frequency`, :func:`crossprod`, :func:`ttest`
diff --git a/docs/contour.rst b/docs/contour.rst
index f52a5785..124b0c2a 100644
--- a/docs/contour.rst
+++ b/docs/contour.rst
@@ -52,6 +52,18 @@ To specify a vector of your own unequal contour levels, set the vector
To specify your own evenly spaced contour levels, see :func:`ztics`.
+Example
+-------
+
+::
+
+ // Create a contour plot of z = x^2 + y^2
+ x = seqa(-3, 0.5, 13);
+ y = seqa(-3, 0.5, 13);
+ z = x' .*. ones(13, 1);
+ z = z .* z + (ones(1, 13) .*. y) .* (ones(1, 13) .*. y);
+ contour(x', y, z);
+
Source
------
diff --git a/docs/convertsatostr.rst b/docs/convertsatostr.rst
index 4ef09c85..8c57c6dc 100644
--- a/docs/convertsatostr.rst
+++ b/docs/convertsatostr.rst
@@ -18,4 +18,22 @@ Format
:rtype str: string
+Examples
+----------------
+
+::
+
+ // Create a 1x1 string array
+ string sa = { "hello" };
+
+ // Convert to a string type
+ s = convertsatostr(sa);
+ print s;
+
+The code above produces the following output:
+
+::
+
+ hello
+
.. seealso:: :func:`convertstrtosa`
diff --git a/docs/csvreadm.rst b/docs/csvreadm.rst
index 2af4bff9..7d50aca5 100644
--- a/docs/csvreadm.rst
+++ b/docs/csvreadm.rst
@@ -203,7 +203,7 @@ Remarks
------------
The standard input stream (stdin) can be read with :func:`csvReadM` by passing
-in `__STDIN` as the filename input. Note that `__STDIN` should not be
+in ``__STDIN`` as the filename input. Note that ``__STDIN`` should not be
passed as a string, surrounded by quotes. Correct usage is shown below:
::
diff --git a/docs/csvreadsa.rst b/docs/csvreadsa.rst
index 3ac493a6..c3ecc226 100644
--- a/docs/csvreadsa.rst
+++ b/docs/csvreadsa.rst
@@ -113,7 +113,7 @@ Remarks
-------
The standard input stream (stdin) can be read with :func:`csvReadSA` by passing
-in `__STDIN` as the filename input. Note that `__STDIN` should not be
+in ``__STDIN`` as the filename input. Note that ``__STDIN`` should not be
passed as a string, surrounded by quotes. Correct usage is shown below:
::
diff --git a/docs/csvwritem.rst b/docs/csvwritem.rst
index c726a899..dcb37d83 100644
--- a/docs/csvwritem.rst
+++ b/docs/csvwritem.rst
@@ -146,8 +146,8 @@ Remarks
- Use :func:`saved` to create a CSV dataset.
- The standard output and standard error streams (stdout, stderr) can be
- written to with :func:`csvWriteM` by passing in the variable `__STDOUT`, or
- `__STDERR` as the filename input. Note that `__STDOUT`, or `__STDERR`
+ written to with :func:`csvWriteM` by passing in the variable ``__STDOUT``, or
+ ``__STDERR`` as the filename input. Note that ``__STDOUT``, or ``__STDERR``
should not be passed in as a string. The following example shows correct
usage:
diff --git a/docs/d.rst b/docs/d.rst
index 97a99e4e..7274f0a3 100644
--- a/docs/d.rst
+++ b/docs/d.rst
@@ -43,6 +43,7 @@ D
dbisopenerror
dbisopen
dbisvalid
+ dbnomics_search
dbnomics_series
dbnomics_set
dbopen
@@ -101,14 +102,17 @@ D
design
detl
det
+ dfaddcol
dfappend
dflonger
dfwider
dffti
dfft
+ dfcontrolcreate
dfname
dftype
diag
+ diagmat
diagrv
digamma
dlibrary
diff --git a/docs/data-management/data-exploration.rst b/docs/data-management/data-exploration.rst
index ec864bcb..075bb4ed 100644
--- a/docs/data-management/data-exploration.rst
+++ b/docs/data-management/data-exploration.rst
@@ -355,7 +355,7 @@ In this example, the optional argument, *sort*, is used to specify that the bars
:scale: 50%
Plotting frequencies percentages
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In this example, the optional argument, *pct_axis*, is used to specify frequency percentages should be plotted. Note the optional argument, *sort*, must still be specified because optional arguments must be specified in order.
diff --git a/docs/data-management/data-sampling.rst b/docs/data-management/data-sampling.rst
index b6c21c23..589c38ce 100644
--- a/docs/data-management/data-sampling.rst
+++ b/docs/data-management/data-sampling.rst
@@ -1,38 +1,61 @@
Data Sampling
=============================
-Sampling with replacement from a matrix or dataframe
---------------------------------------------------------
-There are two ways to sample with replacement from a matrix or dataframe:
+Sampling draws a subset of observations from a dataset. Common uses
+include bootstrapping, Monte Carlo simulation, creating holdout sets
+for validation, and working with datasets too large to fit in memory.
-* The :func:`sampleData` procedure.
-* The :func:`rndi` procedure.
++---------------------------+---------------------------------------------------------------------+
+| Function | Description |
++===========================+=====================================================================+
+| :func:`sampleData` | Sample rows from a matrix or dataframe, with or without |
+| | replacement. |
++---------------------------+---------------------------------------------------------------------+
+| :func:`rndi` | Generate random integers for custom index-based sampling. |
++---------------------------+---------------------------------------------------------------------+
-The :func:`sampleData` procedure directly returns a sample from a matrix or dataframe. The final argument is an indicator for replacement and should be set to 1 to indicate sampling with replacement.
-Example: Sampling with replacement from a matrix
-++++++++++++++++++++++++++++++++++++++++++++++++++
+Sampling with Replacement
+--------------------------------------------
+
+Sampling **with replacement** means the same row can appear more than
+once in the sample. This is the basis of bootstrap methods.
+
+Using sampleData
++++++++++++++++++++++++++++++++++
+
+:func:`sampleData` is the simplest way to draw a sample.
+By default, it samples **without** replacement. Set the third argument
+to ``1`` for sampling with replacement:
::
- // Set seed for repeatable random draws
- rndseed 23423;
+ sample = sampleData(x, n_rows, 1);
+
+- *x* — matrix or dataframe to sample from.
+- *n_rows* — number of rows to draw.
+- The third argument: ``1`` = with replacement, ``0`` = without (default).
- // Create a 7x2 vector
- x = { 1.2 1.8,
- 2.7 2.1,
- 3.0 3.3,
- 4.8 4.1,
- 5.1 5.4,
- 6.0 2.8,
- 7.2 3.9 };
+Example: Bootstrap sample
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
- replace = 1;
+::
- // Take a sample of 5 rows of 'x' with replacement
- sample = sampleData(x, 5, replace);
+ rndseed 23423;
-After the code above, *sample* is equal to:
+ x = { 1.2 1.8,
+ 2.7 2.1,
+ 3.0 3.3,
+ 4.8 4.1,
+ 5.1 5.4,
+ 6.0 2.8,
+ 7.2 3.9 };
+
+ // Draw 5 rows with replacement
+ sample = sampleData(x, 5, 1);
+ print sample;
+
+This prints:
::
@@ -42,19 +65,33 @@ After the code above, *sample* is equal to:
4.8 4.1
3.0 3.3
-Repeated observations of ``3.0`` and ``3.3`` occur because the sampling takes place with replacement.
+Row ``3.0 3.3`` appears twice because sampling with replacement can
+select the same row more than once.
+
+
+Using rndi for index-based sampling
+++++++++++++++++++++++++++++++++++++
+
+The :func:`rndi` function generates random integers in a specified
+range. Using these as row indices lets you generate one index vector
+and apply it to any number of variables — useful when you need to
+keep *X*, *y*, and other variables aligned:
-The :func:`rndi` function returns random integers from a uniform distribution with the option to specify a range. These can be used as indices for sampling, enabling you to easily draw corresponding rows from two or more variables.
+::
+
+ // 1|rows(x) creates the 2x1 vector { 1, rows(x) }
+ // using the vertical concatenation operator |
+ idx = rndi(n_rows, 1, 1|rows(x));
-.. note:: Sampling with random indices maintains the metadata from the original dataframe and will contain variable names, types, etc.
+- The third argument is a 2x1 vector giving the range:
+ ``min_value | max_value``.
-Example: Sampling with replacement from multiple matrices
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Example: Sampling aligned X and y
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- // Set seed for repeatable random draws
- rndseed 73725;
+ rndseed 73725;
y = { 9.1,
2.3,
@@ -68,91 +105,147 @@ Example: Sampling with replacement from multiple matrices
3.9 4.2,
8.2 9.1 };
-
- // Create a random sample of
- // integers from 1 to 5
+ // Random integers from 1 to 5
idx = rndi(5, 1, 1|5);
- // Use 'idx' to draw corresponding rows from 'y' and 'X'
+ // Index into both variables with the same indices
y_s = y[idx];
- X_s = X[idx,.];
+ X_s = X[idx, .];
-After the code above:
+ print idx ~ y_s ~ X_s;
+
+This prints:
::
- idx = 5 y_s = 5.1 X_s = 8.2 9.1
- 4 4.4 3.9 4.2
- 2 2.3 8.8 7.9
- 3 6.7 2.4 1.9
- 5 5.1 8.2 9.1
+ 5.0000000 5.1000000 8.2000000 9.1000000
+ 4.0000000 4.4000000 3.9000000 4.2000000
+ 2.0000000 2.3000000 8.8000000 7.9000000
+ 3.0000000 6.7000000 2.4000000 1.9000000
+ 5.0000000 5.1000000 8.2000000 9.1000000
+
+Each row is consistent across all variables because the same ``idx``
+was used for both ``y`` and ``X``.
+
+.. note::
-Example: Generating indices to sample from a matrix
-++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ When sampling from a dataframe, the result preserves column names,
+ types, and other metadata from the original.
+
+
+Example: Sampling from a real dataset
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- // Load data from the 'fueleconomy' dataset
- // in the GAUSS examples directory
- file_name = getGAUSSHome("examples/fueleconomy.dat");
- fueleconomy = loadd(file_name);
-
- // Create a 100x1 vector of random
- // integers between 1 and 100
- range_start = 1;
- range_end = rows(fueleconomy);
- idx = rndi(100, 1, range_start | range_end);
-
- // Draw a 100 observation sample from 'fueleconomy'
- fuel_sample = fueleconomy[idx, .];
-
-Sampling without replacement from a matrix
+ // Load data
+ fname = getGAUSSHome("examples/fueleconomy.dat");
+ fueleconomy = loadd(fname);
+
+ // Draw 100 rows with replacement
+ idx = rndi(100, 1, 1|rows(fueleconomy));
+ fuel_sample = fueleconomy[idx, .];
+
+ print "Original rows:" rows(fueleconomy);
+ print "Sample rows: " rows(fuel_sample);
+
+
+Sampling without Replacement
--------------------------------------------
-The :func:`sampleData` procedure can also be used to sample from a matrix or dataframe without replaced. In this case, the final argument should be set to 0 to indicate sampling without replacement.
-Example: Sampling without replacement
-+++++++++++++++++++++++++++++++++++++++++
+Sampling **without replacement** means each row can appear at most once.
+This is the default behavior of :func:`sampleData` — when you omit the
+third argument (or set it to ``0``), sampling is without replacement:
::
- // Set seed for repeatable random draws
- rndseed 23423;
+ sample = sampleData(x, n_rows);
+
+The sample size must be less than or equal to the number of rows
+in *x*.
- // Create a 7x1 vector
- x = { 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7 };
+Example: Draw a unique subset
++++++++++++++++++++++++++++++++++
- // Take a sample of 3 elements without replacement
- s = sampleData(x, 3);
+::
-.. note:: Setting the :func:`rndseed` before using :func:`sampleData` should be done if you want to replicate the same sample each draw.
+ rndseed 23423;
-Drawing a random sample from a dataset
-------------------------------------------
-The :func:`exctSmpl` procedure draws a sample with replacement from an existing data file and saves the result as a new data file. Neither the data file drawn from nor the new sample created are saved in the GAUSS workspace.
+ x = { 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7 };
-The :func:`exctSmpl` procedure returns the number of rows in the new data file OR an error code. Specific error code details are available in Command Reference listing for :func:`exctSmpl`.
+ // Draw 3 elements without replacement
+ s = sampleData(x, 3);
+ print s;
-Example: Sample from data file
-+++++++++++++++++++++++++++++++++++++++++++
+This prints:
::
- // Create file name with full path
- fname = getGAUSSHome("examples/credit.dat");
+ 5.0000000
+ 3.0000000
+ 7.0000000
+
+Every value appears exactly once.
+
+.. tip::
+
+ To **shuffle** the rows of a matrix, sample all rows without
+ replacement::
- // Randomly sample 30% of the rows from 'credit.dat'
- // and write them to a new dataset in the
- // GAUSS working directory, named 'sample.dat'
- n_rows = exctsmpl(fname, "sample.dat", 30);
+ shuffled = sampleData(x, rows(x));
-After the code above,
+
+Setting Seeds for Reproducibility
+--------------------------------------------
+
+Sampling functions use the GAUSS random number generator. To get the
+same sample every time, set the seed with :func:`rndseed` before
+sampling:
::
- n_rows = 120
+ rndseed 12345;
+ s1 = sampleData(x, 5, 1);
+
+ rndseed 12345;
+ s2 = sampleData(x, 5, 1);
+
+ // s1 and s2 are identical
+ print (s1 .== s2);
+
+Every element prints ``1``, confirming the two samples match.
+
+
+Choosing a Method
+--------------------------------------------
+
+.. list-table::
+ :widths: 25 40 35
+ :header-rows: 1
+
+ * - Method
+ - Best for
+ - Notes
+
+ * - :func:`sampleData`
+ - General-purpose sampling from a matrix or dataframe
+ - Simplest option; supports with and without replacement
+
+ * - :func:`rndi`
+ - Sampling aligned rows from multiple variables
+ - Generate one index, apply to any number of variables
+
+.. note::
+
+ The GAUSS Machine Learning (GML) add-on provides additional
+ functions for model evaluation workflows: :func:`trainTestSplit`
+ for train/test splits, :func:`cvSplit` for k-fold cross-validation,
+ and :func:`splitData` for splitting a single matrix.
+
+.. seealso:: Functions :func:`sampleData`, :func:`rndi`, :func:`rndseed`
diff --git a/docs/data-management/data-smoothing.rst b/docs/data-management/data-smoothing.rst
index 4cf1aeb1..175ee80e 100644
--- a/docs/data-management/data-smoothing.rst
+++ b/docs/data-management/data-smoothing.rst
@@ -1,13 +1,19 @@
Data Smoothing
=============================
+
+Data smoothing reduces noise in a series so that underlying trends and
+patterns become easier to see. GAUSS provides several approaches, from
+simple moving averages to nonparametric regression and spline
+interpolation.
+
+------------------------+-----------------------------------------------------------------------------+
| Function | Description |
-+========================+================================+============================================+
++========================+=============================================================================+
|:func:`movingave` | Computes moving average of a series. |
+------------------------+-----------------------------------------------------------------------------+
-|:func:`movingaveExpWgt` | Computes exponentially weighted moving average of a series. |
+|:func:`movingaveExpwgt` | Computes exponentially weighted moving average of a series. |
+------------------------+-----------------------------------------------------------------------------+
-|:func:`movingaveWgt` | Computes weighted moving average of a series |
+|:func:`movingaveWgt` | Computes weighted moving average of a series. |
+------------------------+-----------------------------------------------------------------------------+
| :func:`loessmt` | Computes coefficients of locally weighted regression. |
+------------------------+-----------------------------------------------------------------------------+
@@ -16,47 +22,377 @@ Data Smoothing
| :func:`spline` | Computes a two-dimensional interpolatory spline. |
+------------------------+-----------------------------------------------------------------------------+
-Finding moving averages
+
+Moving Averages
+----------------------------------------------
+
+A moving average replaces each observation with the mean of its
+neighboring values within a sliding window. This is the simplest form
+of smoothing and is especially common in time-series work (e.g.,
+3-month or 12-month moving averages).
+
+Three variants are available:
+
+- :func:`movingave` — equal-weight (simple) moving average.
+- :func:`movingaveWgt` — weighted moving average with user-supplied weights.
+- :func:`movingaveExpwgt` — exponentially weighted moving average,
+ where recent observations receive more weight.
+
+All three return a vector the same size as the input. The first
+*d* − 1 rows are set to missing because a full window is not yet
+available.
+
+Simple moving average
++++++++++++++++++++++++++++++++++
+
+::
+
+ y_smooth = movingave(x, d);
+
+- *x* — NxK matrix of data.
+- *d* — scalar, window size (order of the moving average).
+
+Example: 3-month moving average of Treasury bill rates
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ // Load monthly 3-month T-bill rates
+ fname = getGAUSSHome("examples/tbill_3mo.xlsx");
+ y = loadd(fname, "date($obs_date, '%m/%d/%Y %T.%L') + tbill_3m");
+
+ // Compute 3-month simple moving average
+ ma3 = movingave(y[., "tbill_3m"], 3);
+
+ // First two rows are missing (window not full yet)
+ print y[1:6, "tbill_3m"] ~ ma3[1:6];
+
+This prints:
+
+::
+
+ tbill_3m tbill_3m
+ 12.920000 .
+ 14.280000 .
+ 13.310000 13.503333
+ 13.340000 13.643333
+ 12.710000 13.120000
+ 13.080000 13.043333
+
+Weighted moving average
++++++++++++++++++++++++++++++++++
+
+::
+
+ y_smooth = movingaveWgt(x, d, w);
+
+- *x* — NxK matrix of data.
+- *d* — scalar, window size.
+- *w* — dx1 vector of weights. The weights are applied directly (not
+ normalized), so they should sum to 1 if you want a weighted average.
+
+Example: Emphasize recent observations
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ // Load data
+ fname = getGAUSSHome("examples/tbill_3mo.xlsx");
+ y = loadd(fname, "tbill_3m");
+
+ // Weights: most recent observation gets the most weight
+ w = { 0.2, 0.3, 0.5 };
+ wma = movingaveWgt(y, 3, w);
+
+ print y[1:6] ~ wma[1:6];
+
+This prints:
+
+::
+
+ tbill_3m tbill_3m
+ 12.920000 .
+ 14.280000 .
+ 13.310000 13.523000
+ 13.340000 13.519000
+ 12.710000 13.019000
+ 13.080000 13.021000
+
+
+Exponentially weighted moving average
++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ y_smooth = movingaveExpwgt(x, d, p);
+
+- *x* — NxK matrix of data.
+- *d* — scalar, window size.
+- *p* — scalar, smoothing coefficient (0 < *p* < 1). Lower values
+ make the average track recent observations more closely; higher
+ values produce a smoother, more slowly responding series.
+
+Example: Smoothing with different coefficients
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ // Load data
+ fname = getGAUSSHome("examples/tbill_3mo.xlsx");
+ y = loadd(fname, "tbill_3m");
+
+ // Smooth: p = 0.3 (tracks recent values closely)
+ ema_close = movingaveExpwgt(y, 3, 0.3);
+
+ // Smooth: p = 0.8 (heavier smoothing)
+ ema_smooth = movingaveExpwgt(y, 3, 0.8);
+
+ print y[3:8] ~ ema_close[3:8] ~ ema_smooth[3:8];
+
+This prints:
+
+::
+
+ tbill_3m tbill_3m tbill_3m
+ 13.310000 13.236980 11.179810
+ 13.340000 13.139167 11.221951
+ 12.710000 12.639308 10.806369
+ 13.080000 12.768948 10.767480
+ 11.860000 11.946295 10.317886
+ 9.000000 9.693155 9.098645
+
+The first smoothed column (p = 0.3) stays close to the original data,
+while the second (p = 0.8) responds more slowly to changes.
+
+
+Locally Weighted Regression (LOESS)
----------------------------------------------
-Three procedures are available for computing moving averages.
-* The :func:`movingave` procedure computes the moving average given a specified order of moving average.
-* The :func:`movingaveWgt` procedure computes the weighted moving average given a specified order and weights.
-* The :func:`movingaveExpWgt` procedure computes exponentially weighted moving average of a series given a specified order of moving average and a smoothing coefficient.
+The :func:`loessmt` procedure fits a smooth curve through scattered data
+using locally weighted polynomial regression. Unlike a moving average,
+LOESS adapts to the local density of the data and can handle
+non-uniformly spaced observations. It is based on the method described
+in Cleveland (1979).
-Example: Smoothing a random walk series
-++++++++++++++++++++++++++++++++++++++++++
+::
+
+ { yhat, ys, xs } = loessmt(depvar, indvars);
+ { yhat, ys, xs } = loessmt(depvar, indvars, l_ctl);
+
+- *depvar* — Nx1 vector, dependent variable (the values to smooth).
+- *indvars* — NxK matrix, independent variables.
+- *l_ctl* — optional :class:`loessmtControl` structure.
+
+Returns:
+
+- *yhat* — Nx1 fitted values at the original data points. Use this for
+ residuals (``depvar - yhat``) or when you need predictions at the
+ observed locations.
+- *ys* — Mx1 fitted values at *M* equally spaced evaluation points.
+ Use *ys* and *xs* together to plot a smooth curve.
+- *xs* — Mx1 the evaluation points themselves.
+
+Controlling the fit
++++++++++++++++++++++++++++++++++
+
+Create a :class:`loessmtControl` structure to adjust the smoothing
+behavior:
+
+::
+
+ struct loessmtControl l_ctl;
+ l_ctl = loessmtControlCreate();
+
+Key members and their defaults:
+
+.. list-table::
+ :widths: 20 15 65
+ :header-rows: 1
+
+ * - Member
+ - Default
+ - Description
+
+ * - ``Span``
+ - 0.6667
+ - Fraction of data used in each local fit. Larger values produce
+ smoother curves; smaller values follow the data more closely.
+ Must be > 2/N.
+
+ * - ``Degree``
+ - 1
+ - Polynomial degree: 1 = locally linear, 2 = locally quadratic.
+
+ * - ``WgtType``
+ - 2
+ - Weight function: 1 = Gaussian, 2 = robust symmetric (bisquare).
+ Use bisquare (default) when your data may contain outliers.
+
+ * - ``NumEval``
+ - 50
+ - Number of equally spaced evaluation points for *ys* and *xs*.
+
+ * - ``output``
+ - 1
+ - Set to 0 to suppress the printed table.
+
+
+Example: LOESS with custom settings
++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Load dataset
+ fname = getGAUSSHome("examples/lowess1.dta");
+ data = loadd(fname, "h1 + depth");
+
+ depvar = data[., "h1"];
+ indvars = data[., "depth"];
+
+ // Configure: tighter span, suppress printed output
+ struct loessmtControl l_ctl;
+ l_ctl = loessmtControlCreate();
+ l_ctl.Span = 0.4;
+ l_ctl.output = 0;
+
+ { yhat, ys, xs } = loessmt(depvar, indvars, l_ctl);
+
+ // yhat contains fitted values at the original data points
+ // ys/xs contain the smooth curve at 50 equally spaced points
+ print "Evaluation points:" rows(xs);
+ print "First 5 fitted values:";
+ print yhat[1:5];
+
+
+Curve Smoothing
+----------------------------------------------
+
+The :func:`curve` function fits a smooth curve through one-dimensional
+data using a **tension spline** — a curve that resists bending between
+data points. The tension parameter controls how stiff the curve is:
+low tension produces soft, cubic-like curves; high tension pulls the
+curve toward straight-line segments between points.
::
- // Load data
- fname = getGAUSSHome("examples/tbill_3mo.xlsx");
- y = loadd(fname, "date($obs_date, '%m/%d/%Y %T.%L') + tbill_3m");
+ { u, v } = curve(x, y, d, s, sigma, G);
+
+- *x* — Kx1 vector of x-coordinates (must be strictly increasing).
+- *y* — Kx1 vector of y-coordinates.
+- *d* — Kx1 vector or scalar, observation weights (standard deviations
+ or 1 for equal weighting).
+- *s* — scalar, smoothing parameter. Set to 0 for exact interpolation.
+ A reasonable value when *d* contains standard deviations is K (the
+ number of data points).
+- *sigma* — scalar, tension factor. Values near 1 give a standard
+ smooth curve; values near 0 produce cubic-like curves; large values
+ (e.g. 50) produce nearly straight-line segments.
+- *G* — scalar, grid refinement factor. The output will contain
+ K × G points.
+
+Returns:
- // Find 3 month moving average
- twentyMA = movingave(y[., "tbill_3m"], 3);
+- *u* — (K × G) x 1 vector of regularly spaced x-values.
+- *v* — (K × G) x 1 vector of smoothed y-values.
+
+Example: Smoothing noisy data
++++++++++++++++++++++++++++++++++
+
+::
- // Find 3 month exponenetial moving average
- twentyExpWgtMA = movingaveExpwgt(y[., "tbill_3m"], 3, 0.8);
+ rndseed 42;
+ // Generate noisy sine wave
+ x = seqa(1, 1, 20);
+ y = sin(x / 3) + rndn(20, 1) * 0.3;
-Locally weighted linear regression smoothing
+ // Smooth with moderate tension, grid factor of 5
+ { u, v } = curve(x, y, 1, 20, 1, 5);
+
+ // u and v contain 100 points (20 * 5)
+ print "Output points:" rows(u);
+
+
+Two-Dimensional Spline Interpolation
----------------------------------------------
-The :func:`loessmt` procedure smooths data using locally weighted linear regression. Because it relies on linear regression, the function requires both a dependent variable to be smoothed and a matrix of independent variables to be used in the weighted regression.
-Example: Lowess smoother
+The :func:`spline` function computes a smooth surface through data on
+a two-dimensional grid using a tension spline.
+
+::
+
+ { u, v, w } = spline(x, y, z, sigma, g);
+
+- *x* — Kx1 vector of x-coordinates.
+- *y* — Nx1 vector of y-coordinates.
+- *z* — KxN matrix of z-values (the surface heights).
+- *sigma* — scalar, tension factor (same behavior as :func:`curve`).
+- *g* — scalar, grid refinement factor.
+
+Returns:
+
+- *u* — (K × g) x 1 vector of refined x-coordinates.
+- *v* — (N × g) x 1 vector of refined y-coordinates.
+- *w* — (K × g) x (N × g) matrix of interpolated surface values.
+
+Example: Interpolating a surface
+++++++++++++++++++++++++++++++++
::
- // Load dataset
- fname = getGAUSSHome("examples/lowess1.dta");
- data = loadd(fname, "h1 + depth");
+ rndseed 42;
+
+ // Create a small 5x4 grid
+ x = seqa(0, 1, 5);
+ y = seqa(0, 1, 4);
+ z = rndn(5, 4);
+
+ // Interpolate with grid factor 3 (produces 15x12 output)
+ { u, v, w } = spline(x, y, z, 1, 3);
+
+ print "Output grid:" rows(u) "x" cols(w);
+
+
+Choosing a Method
+----------------------------------------------
+
+.. list-table::
+ :widths: 20 35 25 20
+ :header-rows: 1
+
+ * - Method
+ - Best for
+ - Data requirement
+ - Key parameter
+
+ * - :func:`movingave`
+ - Quick smoothing of evenly spaced time series
+ - Evenly spaced
+ - Window size *d*
+
+ * - :func:`movingaveWgt`
+ - When certain observations in the window matter more
+ - Evenly spaced
+ - Weight vector *w*
+
+ * - :func:`movingaveExpwgt`
+ - Tracking trends with exponential decay
+ - Evenly spaced
+ - Smoothing coefficient *p*
+
+ * - :func:`loessmt`
+ - Nonparametric regression; unevenly spaced data
+ - Any spacing
+ - Span (bandwidth)
- // Define independent variable
- depvar = data[., "h1"];
+ * - :func:`curve`
+ - Smooth interpolation of 1-D scattered data
+ - Strictly increasing *x*
+ - Smoothing *s*, tension *sigma*
- // Defined dependent variable
- indvars = data[., "depth"];
+ * - :func:`spline`
+ - Smooth interpolation of 2-D gridded data
+ - Regular grid
+ - Tension *sigma*
- { yhat, ys, xs } = loessmt(depvar, indvars);
+.. seealso:: Functions :func:`movingave`, :func:`movingaveWgt`, :func:`movingaveExpwgt`, :func:`loessmt`, :func:`curve`, :func:`spline`
diff --git a/docs/data-management/data-transformations.rst b/docs/data-management/data-transformations.rst
index ef2d27f0..93ea0a49 100644
--- a/docs/data-management/data-transformations.rst
+++ b/docs/data-management/data-transformations.rst
@@ -858,7 +858,7 @@ Our preview shows that the first element of the *PPI_lag* vector is a missing va
1913-04-01 12.000000
Computing a different lags of each column of a matrix with ``lagn``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To compute different lags of each column of data at the same time, a vector input of lags specifying a separate lag for each column of data can be used. Note that the lag vector must have the same number of elements as the number of columns in the matrix being lagged:
::
diff --git a/docs/dataopen.rst b/docs/dataopen.rst
index 0bfecbd4..6a0446fa 100644
--- a/docs/dataopen.rst
+++ b/docs/dataopen.rst
@@ -140,7 +140,7 @@ dataset name must be provided, e.g.
::
- glm("h5://C:/gauss/examples/testdata.h5/mydata").
+ dataopen("h5://C:/gauss/examples/testdata.h5/mydata", "read");
Source
------
diff --git a/docs/dayofweek.rst b/docs/dayofweek.rst
index c2a36972..05f493b4 100644
--- a/docs/dayofweek.rst
+++ b/docs/dayofweek.rst
@@ -49,6 +49,25 @@ After running above code, *d* is 4 which means Wednesday.
+Examples
+--------
+
+::
+
+ // April 15, 2015, 18:32:07
+ a = 20150415183207;
+
+ d = dayofweek(a);
+ print d;
+
+The code above produces the following output:
+
+::
+
+ 4.0000000
+
+The return value of 4 indicates Wednesday.
+
Source
------
diff --git a/docs/dbclose.rst b/docs/dbclose.rst
index 4051b8ca..7d3817a7 100644
--- a/docs/dbclose.rst
+++ b/docs/dbclose.rst
@@ -14,6 +14,24 @@ Format
:param db_id: database connection index number.
:type db_id: scalar
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Configure and open the connection
+ dbSetDatabaseName(db_id, "mydb");
+ dbOpen(db_id);
+
+ // Perform database operations...
+ qid = dbExecQuery(db_id, "SELECT * FROM customers");
+
+ // Close the connection when done
+ dbClose(db_id);
+
Remarks
-------
diff --git a/docs/dbgetconnectoptions.rst b/docs/dbgetconnectoptions.rst
index 6fb627fc..46e9c492 100644
--- a/docs/dbgetconnectoptions.rst
+++ b/docs/dbgetconnectoptions.rst
@@ -25,4 +25,18 @@ If you have not set any connection options with :func:`dbSetConnectOptions`,
then this function will return an empty string. For a full list of
options see :func:`dbSetConnectOptions`.
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Retrieve the current connection options
+ opts = dbGetConnectOptions(db_id);
+
+ // Print the options string
+ print opts;
+
.. seealso:: :func:`dbSetConnectOptions`
diff --git a/docs/dbgetdatabasename.rst b/docs/dbgetdatabasename.rst
index d092ab56..fb168e1e 100644
--- a/docs/dbgetdatabasename.rst
+++ b/docs/dbgetdatabasename.rst
@@ -18,3 +18,18 @@ Format
:rtype db_name: string
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Set the database name
+ dbSetDatabaseName(db_id, "inventory");
+
+ // Retrieve and print the database name
+ db_name = dbGetDatabaseName(db_id);
+ print db_name;
+
diff --git a/docs/dbgethostname.rst b/docs/dbgethostname.rst
index 249c2131..121b6669 100644
--- a/docs/dbgethostname.rst
+++ b/docs/dbgethostname.rst
@@ -18,3 +18,18 @@ Format
:rtype host_name: string
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Set the host name
+ dbSetHostName(db_id, "db.example.com");
+
+ // Retrieve and print the host name
+ host_name = dbGetHostName(db_id);
+ print host_name;
+
diff --git a/docs/dbgetlasterrornum.rst b/docs/dbgetlasterrornum.rst
index 8b21fa3f..ef759738 100644
--- a/docs/dbgetlasterrornum.rst
+++ b/docs/dbgetlasterrornum.rst
@@ -18,3 +18,21 @@ Format
:rtype last_error: scalar
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+ dbSetDatabaseName(db_id, "mydb");
+
+ // Attempt to open the connection
+ ret = dbOpen(db_id);
+
+ // Check for errors if the open failed
+ if ret == 0;
+ err = dbGetLastErrorNum(db_id);
+ print (err);
+ endif;
+
diff --git a/docs/dbgetlasterrortext.rst b/docs/dbgetlasterrortext.rst
index 0b9559d0..71fead59 100644
--- a/docs/dbgetlasterrortext.rst
+++ b/docs/dbgetlasterrortext.rst
@@ -18,3 +18,21 @@ Format
:rtype last_error: string
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+ dbSetDatabaseName(db_id, "mydb");
+
+ // Attempt to open the connection
+ ret = dbOpen(db_id);
+
+ // Check for errors if the open failed
+ if ret == 0;
+ err_text = dbGetLastErrorText(db_id);
+ print err_text;
+ endif;
+
diff --git a/docs/dbgetnumericalprecpolicy.rst b/docs/dbgetnumericalprecpolicy.rst
index 6eca6e34..b78d7b1f 100644
--- a/docs/dbgetnumericalprecpolicy.rst
+++ b/docs/dbgetnumericalprecpolicy.rst
@@ -26,3 +26,17 @@ Format
:rtype prec_policy: scalar
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+ dbSetDatabaseName(db_id, "mydb");
+ dbOpen(db_id);
+
+ // Retrieve the current precision policy
+ prec_policy = dbGetNumericalPrecPolicy(db_id);
+ print (prec_policy);
+
diff --git a/docs/dbgetpassword.rst b/docs/dbgetpassword.rst
index 16eb0f9f..b8e2ec6d 100644
--- a/docs/dbgetpassword.rst
+++ b/docs/dbgetpassword.rst
@@ -22,3 +22,18 @@ Remarks
-------
:func:`dbGetPassword` will only return passwords set with :func:`dbSetPassword`.
+
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Set the password before opening
+ dbSetPassword(db_id, "secretpass");
+
+ // Retrieve the password
+ pw = dbGetPassword(db_id);
+ print pw;
diff --git a/docs/dbgetport.rst b/docs/dbgetport.rst
index 0bd89807..b6bae01b 100644
--- a/docs/dbgetport.rst
+++ b/docs/dbgetport.rst
@@ -23,3 +23,18 @@ Remarks
:func:`dbGetPort` will only return the port number if it was previously set
with :func:`dbSetPort`.
+
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Set the port number
+ dbSetPort(db_id, 3306);
+
+ // Retrieve and verify the port
+ port = dbGetPort(db_id);
+ print (port);
diff --git a/docs/dbgetprimaryindex.rst b/docs/dbgetprimaryindex.rst
index 6333bcbb..90755347 100644
--- a/docs/dbgetprimaryindex.rst
+++ b/docs/dbgetprimaryindex.rst
@@ -21,3 +21,17 @@ Format
:rtype primary_index: 2x1 string array
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+ dbSetDatabaseName(db_id, "mydb");
+ dbOpen(db_id);
+
+ // Get the primary index for the 'orders' table
+ idx = dbGetPrimaryIndex(db_id, "orders");
+ print idx;
+
diff --git a/docs/dbgettableheaders.rst b/docs/dbgettableheaders.rst
index 794ca571..da20ce3f 100644
--- a/docs/dbgettableheaders.rst
+++ b/docs/dbgettableheaders.rst
@@ -25,3 +25,17 @@ Remarks
-------
The order in which the fields appear in the record is undefined.
+
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+ dbSetDatabaseName(db_id, "mydb");
+ dbOpen(db_id);
+
+ // Get the column names for the 'customers' table
+ headers = dbGetTableHeaders(db_id, "customers");
+ print headers;
diff --git a/docs/dbgettables.rst b/docs/dbgettables.rst
index 4ab9ad5e..5c2c355b 100644
--- a/docs/dbgettables.rst
+++ b/docs/dbgettables.rst
@@ -30,3 +30,21 @@ Format
:rtype tables: Nx1 string array
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+ dbSetDatabaseName(db_id, "mydb");
+ dbOpen(db_id);
+
+ // Get all user tables
+ tables = dbGetTables(db_id);
+ print tables;
+
+ // Get all views
+ views = dbGetTables(db_id, "Views");
+ print views;
+
diff --git a/docs/dbgetusername.rst b/docs/dbgetusername.rst
index 331c66dd..04f68644 100644
--- a/docs/dbgetusername.rst
+++ b/docs/dbgetusername.rst
@@ -18,4 +18,19 @@ Format
:rtype user_name: string
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Set the user name
+ dbSetUserName(db_id, "admin");
+
+ // Retrieve the user name
+ user_name = dbGetUserName(db_id);
+ print user_name;
+
.. seealso:: Functions :func:`dbSetUserName`
diff --git a/docs/dbisdriveravailable.rst b/docs/dbisdriveravailable.rst
index 6450baf3..fce400d0 100644
--- a/docs/dbisdriveravailable.rst
+++ b/docs/dbisdriveravailable.rst
@@ -18,3 +18,17 @@ Format
:rtype ret: scalar
+Examples
+----------------
+
+::
+
+ // Check if the MySQL driver is available
+ ret = dbIsDriverAvailable("MYSQL");
+
+ if ret;
+ print "MySQL driver is available";
+ else;
+ print "MySQL driver is not available";
+ endif;
+
diff --git a/docs/dbisopen.rst b/docs/dbisopen.rst
index 6f75bdb2..79a6f013 100644
--- a/docs/dbisopen.rst
+++ b/docs/dbisopen.rst
@@ -18,3 +18,20 @@ Format
:rtype ret: scalar
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+ dbSetDatabaseName(db_id, "mydb");
+
+ // Open the connection
+ dbOpen(db_id);
+
+ // Check if the connection is open
+ if dbIsOpen(db_id);
+ print "Connection is open";
+ endif;
+
diff --git a/docs/dbisopenerror.rst b/docs/dbisopenerror.rst
index 5598a557..291d3c52 100644
--- a/docs/dbisopenerror.rst
+++ b/docs/dbisopenerror.rst
@@ -18,3 +18,20 @@ Format
:rtype ret: scalar
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+ dbSetDatabaseName(db_id, "mydb");
+
+ // Attempt to open the connection
+ dbOpen(db_id);
+
+ // Check if an error occurred during open
+ if dbIsOpenError(db_id);
+ print "Error opening database connection";
+ endif;
+
diff --git a/docs/dbqueryclear.rst b/docs/dbqueryclear.rst
index af20cda5..3676485f 100644
--- a/docs/dbqueryclear.rst
+++ b/docs/dbqueryclear.rst
@@ -14,6 +14,19 @@ Format
:param qid: query number.
:type qid: scalar
+Examples
+----------------
+
+::
+
+ // Execute a query
+ qid = dbExecQuery(db_id, "SELECT * FROM orders");
+
+ // Process results...
+
+ // Clear the result set and release resources
+ dbQueryClear(qid);
+
Remarks
-------
diff --git a/docs/dbquerycols.rst b/docs/dbquerycols.rst
index bd22af24..eec7a74d 100644
--- a/docs/dbquerycols.rst
+++ b/docs/dbquerycols.rst
@@ -18,3 +18,17 @@ Format
:rtype num_fields: scalar
+Examples
+----------------
+
+::
+
+ // Execute a query
+ qid = dbExecQuery(db_id, "SELECT id, name, price FROM products");
+
+ // Get the number of fields in the result set
+ num_fields = dbQueryCols(qid);
+
+ // Should print 3
+ print (num_fields);
+
diff --git a/docs/dbqueryfinish.rst b/docs/dbqueryfinish.rst
index ee598d0f..04e73d8d 100644
--- a/docs/dbqueryfinish.rst
+++ b/docs/dbqueryfinish.rst
@@ -23,3 +23,18 @@ re-use the query at a later time.
Sets the query to inactive. Bound values retain their values.
+Examples
+----------------
+
+::
+
+ // Execute a query
+ qid = dbExecQuery(db_id, "SELECT * FROM orders");
+
+ // Process some results...
+ dbQuerySeekNext(qid);
+ val = dbQueryGetField(qid, 1);
+
+ // Signal that no more data will be fetched for now
+ dbQueryFinish(qid);
+
diff --git a/docs/dbquerygetfield.rst b/docs/dbquerygetfield.rst
index 01b30d46..c3ccb97d 100644
--- a/docs/dbquerygetfield.rst
+++ b/docs/dbquerygetfield.rst
@@ -21,6 +21,21 @@ Format
.. WARNING:: Specifying a string name may result in much slower performance than a numeric index. Use with caution.
+Examples
+----------------
+
+::
+
+ // Execute a query
+ qid = dbExecQuery(db_id, "SELECT forename, surname FROM people");
+
+ // Loop through results and retrieve fields by index
+ do while dbQuerySeekNext(qid);
+ forename = dbQueryGetField(qid, 1);
+ surname = dbQueryGetField(qid, 2);
+ print forename surname;
+ endo;
+
Remarks
-------
diff --git a/docs/dbquerygetlasterrornum.rst b/docs/dbquerygetlasterrornum.rst
index 337a8302..539368ed 100644
--- a/docs/dbquerygetlasterrornum.rst
+++ b/docs/dbquerygetlasterrornum.rst
@@ -21,4 +21,19 @@ Remarks
Because a failed query will not have a valid handle (*id*), this function
retrieves stored error information about the last executed query.
+Examples
+----------------
+
+::
+
+ // Execute a query
+ qid = dbExecQuery(db_id, "SELECT * FROM nonexistent_table");
+
+ // Check for a query error
+ err_num = dbQueryGetLastErrorNum();
+
+ if err_num != 0;
+ print (err_num);
+ endif;
+
.. seealso:: :func:`dbQueryGetLastErrorText`
diff --git a/docs/dbquerygetlasterrortext.rst b/docs/dbquerygetlasterrortext.rst
index 0ade1011..523438a1 100644
--- a/docs/dbquerygetlasterrortext.rst
+++ b/docs/dbquerygetlasterrortext.rst
@@ -21,4 +21,16 @@ Remarks
Because a failed query will not have a valid handle (*id*), this function
retrieves stored error information about the last executed query.
+Examples
+----------------
+
+::
+
+ // Execute a query
+ qid = dbExecQuery(db_id, "SELECT * FROM nonexistent_table");
+
+ // Get the error text for the last failed query
+ err_txt = dbQueryGetLastErrorText();
+ print err_txt;
+
.. seealso:: :func:`dbQueryGetLastErrorNum`
diff --git a/docs/dbquerygetlastquery.rst b/docs/dbquerygetlastquery.rst
index c1297b30..d92af60d 100644
--- a/docs/dbquerygetlastquery.rst
+++ b/docs/dbquerygetlastquery.rst
@@ -18,3 +18,17 @@ Format
:rtype query_string: string
+Examples
+----------------
+
+::
+
+ // Execute a query
+ qid = dbExecQuery(db_id, "SELECT name, price FROM products");
+
+ // Retrieve the SQL text of the current query
+ sql = dbQueryGetLastQuery(qid);
+
+ // Prints: SELECT name, price FROM products
+ print sql;
+
diff --git a/docs/dbqueryisforwardonly.rst b/docs/dbqueryisforwardonly.rst
index cf0c2ceb..3d1e9e25 100644
--- a/docs/dbqueryisforwardonly.rst
+++ b/docs/dbqueryisforwardonly.rst
@@ -24,4 +24,19 @@ Remarks
Setting a query to "forward only" will usually improve performance. By
default, queries are created with "forward only" on.
+Examples
+----------------
+
+::
+
+ // Execute a query
+ qid = dbExecQuery(db_id, "SELECT * FROM products");
+
+ // Check if the result set is forward-only
+ if dbQueryIsForwardOnly(qid);
+ print "Forward-only mode is enabled";
+ else;
+ print "Bidirectional scrolling is allowed";
+ endif;
+
.. seealso:: Functions :func:`dbQuerySetForwardOnly`, :func:`dbQuerySeekNext`
diff --git a/docs/dbqueryisnull.rst b/docs/dbqueryisnull.rst
index 09f9db34..41c0da14 100644
--- a/docs/dbqueryisnull.rst
+++ b/docs/dbqueryisnull.rst
@@ -31,4 +31,20 @@ Remarks
Note that for some drivers, :func:`dbQueryIsNull` will not return accurate
information until after an attempt is made to retrieve data.
+Examples
+----------------
+
+::
+
+ // Execute a query
+ qid = dbExecQuery(db_id, "SELECT name, email FROM customers");
+
+ // Move to the first record
+ dbQuerySeekNext(qid);
+
+ // Check if the second field (email) is NULL
+ if dbQueryIsNull(qid, 2);
+ print "Email field is NULL";
+ endif;
+
.. seealso:: Functions :func:`dbQueryIsActive`, :func:`dbQueryIsValid`
diff --git a/docs/dbqueryseek.rst b/docs/dbqueryseek.rst
index b6aa49ce..4374305c 100644
--- a/docs/dbqueryseek.rst
+++ b/docs/dbqueryseek.rst
@@ -62,4 +62,23 @@ positioned after the last record if :math:`idx >= 0`, (or before the first
record if *idx* is negative), and 0 is returned. If the record is
successfully retrieved, 1 is returned.
+Examples
+----------------
+
+::
+
+ // Execute a query
+ qid = dbExecQuery(db_id, "SELECT * FROM products");
+
+ // Seek to the 5th record (absolute positioning)
+ ret = dbQuerySeek(qid, 5);
+
+ if ret;
+ val = dbQueryGetField(qid, 1);
+ print val;
+ endif;
+
+ // Seek 2 records forward from current position (relative)
+ ret = dbQuerySeek(qid, 2, 1);
+
.. seealso:: Functions :func:`dbQuerySeekFirst`, :func:`dbQuerySeekLast`, :func:`dbQuerySeekNext`, :func:`dbQuerySeekPrevious`
diff --git a/docs/dbqueryseekprevious.rst b/docs/dbqueryseekprevious.rst
index 4cf35257..d1c021f0 100644
--- a/docs/dbqueryseekprevious.rst
+++ b/docs/dbqueryseekprevious.rst
@@ -36,4 +36,26 @@ The following rules apply:
the previous record.
+Examples
+----------------
+
+::
+
+ // Execute a query with bidirectional scrolling
+ qid = dbExecQuery(db_id, "SELECT name, price FROM products");
+
+ // Move to the first record
+ dbQuerySeekNext(qid);
+
+ // Move to the second record
+ dbQuerySeekNext(qid);
+
+ // Go back to the first record
+ ret = dbQuerySeekPrevious(qid);
+
+ if ret;
+ name = dbQueryGetField(qid, 1);
+ print name;
+ endif;
+
.. seealso:: Functions :func:`dbQuerySeekFirst`, :func:`dbQuerySeekLast`, :func:`dbQuerySeekNext`, :func:`dbQuerySeek`, :func:`dbQueryGetPosition`
diff --git a/docs/dbquerysetforwardonly.rst b/docs/dbquerysetforwardonly.rst
index 7cb40389..6d93efd8 100644
--- a/docs/dbquerysetforwardonly.rst
+++ b/docs/dbquerysetforwardonly.rst
@@ -35,5 +35,20 @@ scrollable.
:func:`dbQueryIsForwardOnly` will always return the correct status of the
result set.
+Examples
+----------------
+
+::
+
+ // Create a query
+ qid = dbCreateQuery(db_id);
+
+ // Disable forward-only mode to allow bidirectional scrolling
+ dbQuerySetForwardOnly(qid, 0);
+
+ // Now prepare and execute the query
+ dbQueryPrepare(qid, "SELECT * FROM products");
+ dbQueryExecPrepared(qid);
+
.. seealso:: Function :func:`dbQueryIsForwardOnly`
diff --git a/docs/dbremovedatabase.rst b/docs/dbremovedatabase.rst
index ff3341e4..5a1c68b9 100644
--- a/docs/dbremovedatabase.rst
+++ b/docs/dbremovedatabase.rst
@@ -14,3 +14,19 @@ Format
:param db_id: database connection index number.
:type db_id: scalar
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+ dbSetDatabaseName(db_id, "mydb");
+ dbOpen(db_id);
+
+ // Perform database operations...
+
+ // Close and remove the connection entirely
+ dbClose(db_id);
+ dbRemoveDatabase(db_id);
+
diff --git a/docs/dbrollback.rst b/docs/dbrollback.rst
index c6a1c647..5665e51a 100644
--- a/docs/dbrollback.rst
+++ b/docs/dbrollback.rst
@@ -27,3 +27,21 @@ a :func:`dbTransaction` has been started.
.. Note:: For some databases, the rollback will fail and return 0 if there is an active query using the database for a ``SELECT``. Make the query inactive before doing the rollback.
Call :func:`dbGetLastError` to get information about errors.
+
+Examples
+----------------
+
+::
+
+ // Begin a transaction
+ dbTransaction(db_id);
+
+ // Execute an update query
+ qid = dbExecQuery(db_id, "UPDATE accounts SET balance = balance - 100 WHERE id = 1");
+
+ // Rollback if something went wrong
+ ret = dbRollback(db_id);
+
+ if ret == 0;
+ print "Rollback failed";
+ endif;
diff --git a/docs/dbsetdatabasename.rst b/docs/dbsetdatabasename.rst
index 3fe483b8..20d10f92 100644
--- a/docs/dbsetdatabasename.rst
+++ b/docs/dbsetdatabasename.rst
@@ -43,4 +43,18 @@ entry in the ODBC manager:
dbOpen(db_id);
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Set the database name before opening
+ dbSetDatabaseName(db_id, "sales_data");
+
+ // Open the connection
+ dbOpen(db_id);
+
.. seealso:: :func:`dbGetDatabaseName`
diff --git a/docs/dbsethostname.rst b/docs/dbsethostname.rst
index ea6284e9..ceba42cd 100644
--- a/docs/dbsethostname.rst
+++ b/docs/dbsethostname.rst
@@ -22,3 +22,18 @@ Remarks
For this function to have an effect, it must be called before the
database connection is opened with :func:`dbOpen`.
+
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Set the host name before opening
+ dbSetHostName(db_id, "db.example.com");
+
+ // Configure remaining settings and open
+ dbSetDatabaseName(db_id, "mydb");
+ dbOpen(db_id);
diff --git a/docs/dbsetnumericalprecpolicy.rst b/docs/dbsetnumericalprecpolicy.rst
index 49cece95..d75121aa 100644
--- a/docs/dbsetnumericalprecpolicy.rst
+++ b/docs/dbsetnumericalprecpolicy.rst
@@ -26,3 +26,20 @@ Format
:type prec_policy: scalar
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+ dbSetDatabaseName(db_id, "mydb");
+ dbOpen(db_id);
+
+ // Set precision policy to use strings for high precision
+ dbSetNumericalPrecPolicy(db_id, 0);
+
+ // Verify the policy was set
+ prec = dbGetNumericalPrecPolicy(db_id);
+ print (prec);
+
diff --git a/docs/dbsetpassword.rst b/docs/dbsetpassword.rst
index f77cf8a4..6a83dc9b 100644
--- a/docs/dbsetpassword.rst
+++ b/docs/dbsetpassword.rst
@@ -23,5 +23,21 @@ Remarks
This function must be called before the connection is opened with
:func:`dbOpen` to have an effect.
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Set connection credentials before opening
+ dbSetUserName(db_id, "admin");
+ dbSetPassword(db_id, "secretpass");
+
+ // Open the connection
+ dbSetDatabaseName(db_id, "mydb");
+ dbOpen(db_id);
+
.. seealso:: :func:`dbGetPassword`
diff --git a/docs/dbsetport.rst b/docs/dbsetport.rst
index e1628ee7..b12ab882 100644
--- a/docs/dbsetport.rst
+++ b/docs/dbsetport.rst
@@ -23,5 +23,21 @@ Remarks
This function must be called before the connection is opened with
:func:`dbOpen` to have an effect.
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Set the port number before opening
+ dbSetPort(db_id, 3306);
+
+ // Configure remaining settings and open
+ dbSetHostName(db_id, "localhost");
+ dbSetDatabaseName(db_id, "mydb");
+ dbOpen(db_id);
+
.. seealso:: :func:`dbGetPort`
diff --git a/docs/dbsetusername.rst b/docs/dbsetusername.rst
index 4f122098..7c2db03c 100644
--- a/docs/dbsetusername.rst
+++ b/docs/dbsetusername.rst
@@ -23,5 +23,21 @@ Remarks
This function must be called before the connection is opened with
:func:`dbOpen` to have an effect.
+Examples
+----------------
+
+::
+
+ // Add MySQL to the list of database connections
+ db_id = dbAddDatabase("MYSQL");
+
+ // Set the user name before opening
+ dbSetUserName(db_id, "db_user");
+
+ // Configure remaining settings and open
+ dbSetDatabaseName(db_id, "mydb");
+ dbSetPassword(db_id, "password");
+ dbOpen(db_id);
+
.. seealso:: :func:`dbGetUserName`
diff --git a/docs/debug.rst b/docs/debug.rst
index e18e9f4e..7f6a0eb6 100644
--- a/docs/debug.rst
+++ b/docs/debug.rst
@@ -25,3 +25,12 @@ Remarks
See the `Debugging chapter `_ for more details.
+Example
+-------
+
+::
+
+ // Launch the debugger on a program file
+ debug myprogram.gss;
+
+.. seealso:: Functions :func:`trace`
diff --git a/docs/deletedataloop.rst b/docs/deletedataloop.rst
index 0d68df75..4f4084da 100644
--- a/docs/deletedataloop.rst
+++ b/docs/deletedataloop.rst
@@ -23,7 +23,7 @@ Remarks
Deletes only those rows for which logical_expression is ``TRUE``. Any
variables referenced must already exist, either as elements of the
-source dataset, as `extern`'s, or as the result of a previous make,
+source dataset, as ``extern``'s, or as the result of a previous make,
vector, or code statement.
GAUSS expects *logical_expression* to return a row vector of 1's and 0's.
diff --git a/docs/dentozero.rst b/docs/dentozero.rst
index 28fbce77..1b1c30c5 100644
--- a/docs/dentozero.rst
+++ b/docs/dentozero.rst
@@ -45,3 +45,5 @@ At the end of the example, *y* is equal to:
1.000e+000
0.000e+000
3.000e+000
+
+.. seealso:: Functions :func:`zerosmiss`, :func:`miss`, :func:`missrv`
diff --git a/docs/dfaddcol.rst b/docs/dfaddcol.rst
new file mode 100644
index 00000000..c842377d
--- /dev/null
+++ b/docs/dfaddcol.rst
@@ -0,0 +1,81 @@
+
+dfaddcol
+==============================================
+
+Purpose
+----------------
+
+Adds a new named column to a dataframe.
+
+Format
+----------------
+.. function:: df_new = dfaddcol(df, name, data)
+
+ :param df: The dataframe to add a column to.
+ :type df: NxK Dataframe
+
+ :param name: The name for the new column.
+ :type name: String
+
+ :param data: The data for the new column.
+ :type data: Nx1 vector, string array, or dataframe
+
+ :return df_new: The original dataframe with the new column appended on the right.
+
+ :rtype df_new: Nx(K+1) Dataframe
+
+Examples
+----------------
+
+Add a computed column
+++++++++++++++++++++++++
+
+::
+
+ // Load dataset
+ fname = getGAUSSHome("examples/auto2.dta");
+ auto2 = loadd(fname);
+
+ // Add a new column computed from an existing column
+ auto2 = dfaddcol(auto2, "price_k", auto2[., "price"] ./ 1000);
+
+ // Preview first 5 rows of selected columns
+ head(auto2[., "make" "price" "price_k"]);
+
+::
+
+ make price price_k
+ AMC Concord 4099.000 4.099000
+ AMC Pacer 4749.000 4.749000
+ AMC Spirit 3799.000 3.799000
+ Buick Century 4816.000 4.816000
+ Buick Electra 7827.000 7.827000
+
+Add a string column
+++++++++++++++++++++++++
+
+::
+
+ // Create a small numeric dataframe
+ x = asdf(100 | 200 | 300, "value");
+
+ // Add a string column
+ x = dfaddcol(x, "label", "low" $| "mid" $| "high");
+
+::
+
+ x = value label
+ 100.00000 low
+ 200.00000 mid
+ 300.00000 high
+
+Remarks
+----------------
+
+* :func:`dfaddcol` always appends the new column to the right side of the dataframe. To insert a column at a specific position, use :func:`insertcols`.
+
+* The *data* argument must have the same number of rows as *df*.
+
+* This function is equivalent to ``df ~ asDF(data, name)`` but reads more clearly when adding computed columns.
+
+.. seealso:: Functions :func:`asdf`, :func:`delcols`, :func:`dfappend`, :func:`dfname`, :func:`insertcols`
diff --git a/docs/dfappend.rst b/docs/dfappend.rst
index 128f8c1b..665b62df 100644
--- a/docs/dfappend.rst
+++ b/docs/dfappend.rst
@@ -109,3 +109,5 @@ Remarks
* :func:`dfappend` should be used instead of the vertical concatenation operator for dataframes with categorical or string columns, because :func:`dfappend` will merge the metadata in cases where the keys and labels are not identical.
* Both inputs must be dataframes.
+
+.. seealso:: Functions :func:`dfaddcol`, :func:`insertcols`
diff --git a/docs/dflonger.rst b/docs/dflonger.rst
index c3f24d1e..56e182b3 100644
--- a/docs/dflonger.rst
+++ b/docs/dflonger.rst
@@ -414,4 +414,4 @@ Now we can call :func:`dflonger` with the inputs we have created.
-.. seealso:: Functions :func:`dfwider`
+.. seealso:: Functions :func:`dfwider`, :func:`pdBalance`
diff --git a/docs/diag.rst b/docs/diag.rst
index 1924af32..fbe38f56 100644
--- a/docs/diag.rst
+++ b/docs/diag.rst
@@ -115,4 +115,4 @@ containing the diagonals of each of the 10 4x4 arrays contained in *x*.
matrix.
-.. seealso:: Functions :func:`diagrv`
+.. seealso:: Functions :func:`diagrv`, :func:`diagmat`
diff --git a/docs/diagmat.rst b/docs/diagmat.rst
new file mode 100644
index 00000000..af04e35f
--- /dev/null
+++ b/docs/diagmat.rst
@@ -0,0 +1,108 @@
+
+diagmat
+==============================================
+
+Purpose
+----------------
+Creates a diagonal or off-diagonal matrix from a vector.
+
+Format
+----------------
+.. function:: D = diagmat(v[, k])
+
+ :param v: the diagonal elements.
+ :type v: Nx1 or 1xN vector
+
+ :param k: Optional, the diagonal offset. ``k > 0`` places *v* on the *k*-th superdiagonal, ``k < 0`` places *v* on the \|\ *k*\ \|-th subdiagonal. Default = 0.
+ :type k: scalar
+
+ :return D: with *v* on the specified diagonal and zeros elsewhere. When *k* = 0, the result is NxN. When *k* ≠ 0, the result is (N + \|\ *k*\ \|) x (N + \|\ *k*\ \|).
+
+ :rtype D: matrix
+
+Examples
+----------------
+
+Basic diagonal matrix
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ v = { 1, 2, 3 };
+
+ D = diagmat(v);
+
+After the above code, ``D`` will equal:
+
+::
+
+ 1 0 0
+ 0 2 0
+ 0 0 3
+
+Superdiagonal (k = 1)
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ v = { 1, 2, 3 };
+
+ D = diagmat(v, 1);
+
+After the above code, ``D`` will equal:
+
+::
+
+ 0 1 0 0
+ 0 0 2 0
+ 0 0 0 3
+ 0 0 0 0
+
+Subdiagonal (k = -1)
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ v = { 4, 5, 6 };
+
+ D = diagmat(v, -1);
+
+After the above code, ``D`` will equal:
+
+::
+
+ 0 0 0 0
+ 4 0 0 0
+ 0 5 0 0
+ 0 0 6 0
+
+Round-trip with diag
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ v = { 5, 10, 15 };
+
+ // Create diagonal matrix, then extract diagonal
+ D = diagmat(v);
+ v2 = diag(D);
+
+After the above code, ``v2`` will equal ``v``.
+
+Remarks
+-------
+
+.. versionadded:: 26.0.1
+
+:func:`diagmat` creates a new diagonal matrix. To extract the diagonal of an existing matrix, use :func:`diag`. To replace the diagonal of an existing matrix, use :func:`diagrv`.
+
+Off-diagonal matrices are useful for building companion matrices, shift operators, and tridiagonal systems::
+
+ // Build a tridiagonal matrix
+ main = { 2, 2, 2 };
+ upper = { -1, -1 };
+ lower = { -1, -1 };
+
+ T = diagmat(main) + diagmat(upper, 1) + diagmat(lower, -1);
+
+.. seealso:: Functions :func:`diag`, :func:`diagrv`, :func:`bandrv`, :func:`eye`
diff --git a/docs/diagrv.rst b/docs/diagrv.rst
index 8de12020..27b94bf1 100644
--- a/docs/diagrv.rst
+++ b/docs/diagrv.rst
@@ -53,4 +53,4 @@ Remarks
Use :func:`bandrv` to create a diagonal matrix from a vector.
-.. seealso:: Functions :func:`diag`
+.. seealso:: Functions :func:`diag`, :func:`diagmat`
diff --git a/docs/digamma.rst b/docs/digamma.rst
index 21cb0f82..e2502c7b 100644
--- a/docs/digamma.rst
+++ b/docs/digamma.rst
@@ -44,3 +44,5 @@ Remarks
The :func:`digamma` function is the first derivative of the log of the :func:`gamma`
function with respect to its argument.
+
+.. seealso:: Functions :func:`trigamma`, :func:`gamma`, :func:`lnfact`
diff --git a/docs/dllcall.rst b/docs/dllcall.rst
index 3665011c..550e1750 100644
--- a/docs/dllcall.rst
+++ b/docs/dllcall.rst
@@ -113,4 +113,18 @@ Example usage::
// Combined with return check
dllcall -ro processData(inputMatrix, rows, cols);
+Example
+-------
+
+::
+
+ // Link a shared library and call a function
+ dlibrary mylib;
+ x = rndn(100, 1);
+ dllcall -r computeStats(x);
+
+ // Read-only call for better performance with large data
+ bigmat = rndn(10000, 50);
+ dllcall -ro analyzeData(bigmat);
+
.. seealso:: `dlibrary`, :func:`sysstate`
diff --git a/docs/doswin.rst b/docs/doswin.rst
index bfda0ef3..9c2516e2 100644
--- a/docs/doswin.rst
+++ b/docs/doswin.rst
@@ -22,7 +22,18 @@ Calling :func:`doswin` is equivalent to:
call DOSWinOpen("", error(0));
+Example
+-------
+
+::
+
+ // Open DOS compatibility window (legacy, no longer supported)
+ // In modern GAUSS, this call can usually be removed
+ doswin;
+
Source
------
gauss.src
+
+.. seealso:: Functions :func:`DOSWinCloseall`
diff --git a/docs/doswincloseall.rst b/docs/doswincloseall.rst
index efbffb53..3de346f1 100644
--- a/docs/doswincloseall.rst
+++ b/docs/doswincloseall.rst
@@ -33,3 +33,4 @@ Calling :func:`DOSWinCloseall` closes the DOS window immediately, without asking
for confirmation. If a program is running, its I/O reverts to the
Command window.
+.. seealso:: Functions :func:`doswin`
diff --git a/docs/dropdataloop.rst b/docs/dropdataloop.rst
index 2c05fc5d..cd2f34ff 100644
--- a/docs/dropdataloop.rst
+++ b/docs/dropdataloop.rst
@@ -25,7 +25,7 @@ Commas are optional in *variable_list*.
Deletes the specified variables from the output dataset. Any variables
referenced must already exist, either as elements of the source data
-set, or as the result of a previous `make`, `vector`, or `code` statement.
+set, or as the result of a previous `make`, ``vector``, or `code` statement.
If neither :func:`keep` nor :func:`drop` is used, the output dataset will contain all
variables from the source dataset, as well as any defined variables.
diff --git a/docs/dscreate.rst b/docs/dscreate.rst
index fa98a514..4bd81c95 100644
--- a/docs/dscreate.rst
+++ b/docs/dscreate.rst
@@ -30,3 +30,5 @@ Source
------
ds.src
+
+.. seealso:: Functions :func:`datacreate`, :func:`saved`
diff --git a/docs/dstat.rst b/docs/dstat.rst
index f76f4b71..09452192 100644
--- a/docs/dstat.rst
+++ b/docs/dstat.rst
@@ -23,7 +23,7 @@ Format
* A Kx1 character vector containing the names of variables.
* A Kx1 numeric vector containing indices of variables.
- * A `formula string`. e.g. :code:`"PAY + WT"` or :code:`". - sex"`.
+ * A ``formula string``. e.g. :code:`"PAY + WT"` or :code:`". - sex"`.
These can be any size subset of the variables in the dataset and can be in any order. If a scalar 0 is passed, all columns of the dataset will be used.
@@ -283,12 +283,12 @@ values for the valid data. The means and standard deviations will be
computed using the correct number of valid observations for each
variable.
-2. The supported dataset types are `CSV`, `XLS`, `XLSX`, `HDF5`, `FMT`, `DAT`, `DTA`.
+2. The supported dataset types are ``CSV``, ``XLS``, ``XLSX``, ``HDF5``, ``FMT``, ``DAT``, ``DTA``.
-For HDF5 file, the dataset must include `file schema` and both file name and dataset name must be provided, e.g.
+For HDF5 file, the dataset must include ``file schema`` and both file name and dataset name must be provided, e.g.
:code:`dstat("h5://C:/gauss/examples/testdata.h5/mydata", formula)`
-.. seealso:: `Formula String`
+.. seealso:: ``Formula String``
Source
------
diff --git a/docs/dstatmt.rst b/docs/dstatmt.rst
index 24d01a79..d88658cf 100644
--- a/docs/dstatmt.rst
+++ b/docs/dstatmt.rst
@@ -20,7 +20,7 @@ Format
* A Kx1 character vector containing the names of variables.
* A Kx1 numeric vector containing indices of variables.
- * A `formula string`.
+ * A ``formula string``.
e.g. :code:`"PAY + WT"` or :code:`". - sex"`
e.g :code:`"X1 + by(X2)", "by(X2)"` specifies that the data should be separated into different tables based on the groups defined by ``X2``.
@@ -346,5 +346,5 @@ Source
dstatmt.src
-.. seealso:: Functions :func:`dstatmtControlCreate`, `formula string`
+.. seealso:: Functions :func:`dstatmtControlCreate`, ``formula string``
diff --git a/docs/dtdayofweek.rst b/docs/dtdayofweek.rst
index 25260028..a3d94386 100644
--- a/docs/dtdayofweek.rst
+++ b/docs/dtdayofweek.rst
@@ -35,7 +35,7 @@ First find the day of the week components using a Sunday start.
fname = getGAUSSHome("examples/yellowstone.csv");
data = loadd(fname);
- // Get quarters for date column
+ // Get day of the week for date column
dow = dtDayofWeek(data, "Date");
// Print first and last five dates
diff --git a/docs/dtdayofyear.rst b/docs/dtdayofyear.rst
index fcfce616..4f03e42c 100644
--- a/docs/dtdayofyear.rst
+++ b/docs/dtdayofyear.rst
@@ -37,7 +37,7 @@ Examples
head(data[., "Date"]);
tail(data[., "Date"]);
- // Print corresponding years
+ // Print corresponding day of year
"Day of Year:"
head(doy);
tail(doy);
diff --git a/docs/dttoutc.rst b/docs/dttoutc.rst
index d1d717c3..1b1d7942 100644
--- a/docs/dttoutc.rst
+++ b/docs/dttoutc.rst
@@ -36,7 +36,7 @@ The above code produces the following output:
Remarks
-------
-In DT scalar format, 10:50:31 on July 15, 2010 is 20100703105031. A UTC
+In DT scalar format, 10:50:31 on July 3, 2010 is 20100703105031. A UTC
scalar gives the number of seconds since or before January 1, 1970
Greenwich Mean Time.
diff --git a/docs/dwstat.rst b/docs/dwstat.rst
index be6c9973..5d4a8b40 100644
--- a/docs/dwstat.rst
+++ b/docs/dwstat.rst
@@ -39,3 +39,5 @@ Source
------
fgls.src
+
+.. seealso:: Functions :func:`ols`, :func:`olsmt`
diff --git a/docs/e.rst b/docs/e.rst
index 007e815d..e669ab4f 100644
--- a/docs/e.rst
+++ b/docs/e.rst
@@ -11,6 +11,9 @@ E
eighv
eig
eigv
+ element-by-element-division
+ element-by-element-multiplication
+ element-by-element-power
elapsedtradingdays
endp
end
@@ -22,6 +25,8 @@ E
eqsolvemt
eqsolve
eqsolveset
+ equal
+ equality
erfcplxerfccplx
erferfc
erfinverfcinv
@@ -44,6 +49,12 @@ E
europeanbsput_impvol
europeanbsput
exctsmpl
+ exe-equal
+ exe-greater-than
+ exe-greater-than-equal
+ exe-less-than
+ exe-less-than-equal
+ exe-not-equal
execbg
exec
exp
diff --git a/docs/ed.rst b/docs/ed.rst
index c69bacb9..3f3ccb2e 100644
--- a/docs/ed.rst
+++ b/docs/ed.rst
@@ -70,3 +70,5 @@ Set the alternate editor to TextEdit.
* See the `edit` command to open a file in the GAUSS editor from the command
line.
+
+.. seealso:: Functions :func:`edit`, :func:`run`
diff --git a/docs/eigh.rst b/docs/eigh.rst
index 3ab71725..d8f44e50 100644
--- a/docs/eigh.rst
+++ b/docs/eigh.rst
@@ -52,4 +52,24 @@ The eigenvalues are in ascending order.
The eigenvalues of a complex hermitian or real symmetric matrix are
always real.
+Examples
+----------------
+
+::
+
+ // Symmetric matrix
+ x = { 4 1, 1 3 };
+
+ va = eigh(x);
+ print va;
+
+The code above produces the following output:
+
+::
+
+ 2.3819660
+ 4.6180340
+
+The eigenvalues are returned in ascending order.
+
.. seealso:: Functions :func:`eig`, :func:`eighv`, :func:`eigv`
diff --git a/docs/eighv.rst b/docs/eighv.rst
index af39e581..291791ff 100644
--- a/docs/eighv.rst
+++ b/docs/eighv.rst
@@ -59,4 +59,28 @@ are orthonormal.
The eigenvalues of a complex hermitian or real symmetric matrix are
always real.
+Examples
+----------------
+
+::
+
+ // Symmetric matrix
+ x = { 4 1, 1 3 };
+
+ { va, ve } = eighv(x);
+ print va;
+ print ve;
+
+The code above produces the following output:
+
+::
+
+ 2.3819660
+ 4.6180340
+
+ 0.52573111 -0.85065081
+ -0.85065081 -0.52573111
+
+The columns of *ve* are the eigenvectors corresponding to each eigenvalue.
+
.. seealso:: Functions :func:`eig`, :func:`eigh`, :func:`eigv`
diff --git a/docs/equal.rst b/docs/equal.rst
index 4e618181..d4abbb1a 100644
--- a/docs/equal.rst
+++ b/docs/equal.rst
@@ -63,7 +63,7 @@ Example 2: Matrix and scalar comparison
flag = A == B; // flag will be 1 (true)
Example 3: Row vector and matrix comparison
-++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++
::
@@ -78,7 +78,7 @@ Example 3: Row vector and matrix comparison
flag = A == B; // flag will be 1 (true)
Example 4: Matrix inequality due to different elements
-++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
::
@@ -93,7 +93,7 @@ Example 4: Matrix inequality due to different elements
flag = A == B; // flag will be 0 (false)
Example 5: Scalar and matrix comparison where elements differ
-++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
::
@@ -107,7 +107,7 @@ Example 5: Scalar and matrix comparison where elements differ
flag = A == B; // flag will be 0 (false)
Example 6: Row vector and matrix comparison with differing elements
-++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
::
diff --git a/docs/exctsmpl.rst b/docs/exctsmpl.rst
index eea723ab..4690e07a 100644
--- a/docs/exctsmpl.rst
+++ b/docs/exctsmpl.rst
@@ -64,3 +64,5 @@ Source
------
exctsmpl.src
+
+.. seealso:: Functions :func:`sampleData`, :func:`rndi`
diff --git a/docs/externdataloop.rst b/docs/externdataloop.rst
index a4f306a9..7fad6dbf 100644
--- a/docs/externdataloop.rst
+++ b/docs/externdataloop.rst
@@ -43,11 +43,11 @@ Remarks
Commas in *variable_list* are optional.
-The `extern` statement tells the translator not to generate local code for the listed
+The ``extern`` statement tells the translator not to generate local code for the listed
variables, and not to assume that they are elements of the input data
set.
-All `extern` statements should be placed before any reference to the symbols
+All ``extern`` statements should be placed before any reference to the symbols
listed. The specified names should not exist in the input dataset, or
be used in a `make` statement.
diff --git a/docs/f.rst b/docs/f.rst
index e450d623..5b87c70c 100644
--- a/docs/f.rst
+++ b/docs/f.rst
@@ -5,6 +5,7 @@ F
:maxdepth: 1
:caption: Functions:
+ factorial
fcheckerr
fclearerr
feqfgefgtflefltfne
@@ -20,6 +21,8 @@ F
fgets
fgetst
fgls
+ fglscontrolcreate
+ findidx
fileinfo
filesa
fix
diff --git a/docs/fclearerr.rst b/docs/fclearerr.rst
index ffebfb39..b51b741a 100644
--- a/docs/fclearerr.rst
+++ b/docs/fclearerr.rst
@@ -32,3 +32,19 @@ error.
The flag accessed by :func:`fclearerr` is not the same as that accessed by
:func:`fstrerror`.
+
+Example
+-------
+
+::
+
+ // Open a file and check its error status
+ fname = tempname("/tmp", "ex", ".txt");
+ fh = fopen(fname, "w");
+ call fputs(fh, "test data");
+ call close(fh);
+
+ fh = fopen(fname, "r");
+ err = fclearerr(fh);
+ print "Error status (0=none):" err;
+ call close(fh);
diff --git a/docs/fflush.rst b/docs/fflush.rst
index 18d5fc84..77ced909 100644
--- a/docs/fflush.rst
+++ b/docs/fflush.rst
@@ -25,3 +25,16 @@ If :func:`fflush` fails, you can call :func:`fstrerror` to find out why.
If you pass :func:`fflush` the handle of a file opened with `open` (i.e., a data
set or matrix file), your program will terminate with a fatal error.
+
+Example
+-------
+
+::
+
+ // Write to a file and flush the buffer
+ fname = tempname("/tmp", "ex", ".txt");
+ fh = fopen(fname, "w");
+ call fputs(fh, "buffered data");
+ ret = fflush(fh);
+ print "Flush result (0=success):" ret;
+ call close(fh);
diff --git a/docs/fftn.rst b/docs/fftn.rst
index f251bc19..52174c1a 100644
--- a/docs/fftn.rst
+++ b/docs/fftn.rst
@@ -43,13 +43,38 @@ because 33600 is a highly composite number,
:math:`2^15`.
For this reason, you may want to hand-pad matrices to
-optimum dimensions before passing them to :func:`fftn`. The `Run-Time Library`
+optimum dimensions before passing them to :func:`fftn`. The ``Run-Time Library``
includes a routine, :func:`optn`, for determining optimum dimensions.
-The `Run-Time Library` also includes the :func:`nextn` routine, for
+The ``Run-Time Library`` also includes the :func:`nextn` routine, for
determining allowable dimensions for a matrix. (You can use this to see
the dimensions to which :func:`fftn` would pad a matrix.)
:func:`fftn` scales the computed FFT by :math:`1/(L*M)`.
+Examples
+--------
+
+::
+
+ // Create a simple 4-element signal
+ x = { 1, 2, 3, 4 };
+
+ // Compute the complex FFT (scaled by 1/(L*M))
+ y = fftn(x);
+
+ print "FFT of x:";
+ print y;
+
+The above code produces the following output:
+
+::
+
+ FFT of x:
+
+ 2.5000000
+ -0.50000000 + 0.50000000i
+ -0.50000000
+ -0.50000000 - 0.50000000i
+
.. seealso:: Functions :func:`fft`, :func:`ffti`, :func:`fftm`, :func:`fftmi`, :func:`rfft`, :func:`rffti`, :func:`rfftip`, :func:`rfftn`, :func:`rfftnp`, :func:`rfftp`
diff --git a/docs/fgls.rst b/docs/fgls.rst
index 83f3a08d..7f653306 100644
--- a/docs/fgls.rst
+++ b/docs/fgls.rst
@@ -171,7 +171,7 @@ The output for data matrices includes default variable names:
X3 -0.0228 0.129 -0.177 0.860 -0.275 0.229
Basic usage with a dataframe and a formula string
-++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++
::
diff --git a/docs/fglscontrolcreate.rst b/docs/fglscontrolcreate.rst
index 9f175f2f..eb8c5cf8 100644
--- a/docs/fglscontrolcreate.rst
+++ b/docs/fglscontrolcreate.rst
@@ -5,7 +5,7 @@ fglsControlCreate
Purpose
----------------
-Creates default olsmtControl structure.
+Creates default fglsControl structure.
Format
----------------
diff --git a/docs/findidx.rst b/docs/findidx.rst
new file mode 100644
index 00000000..0bf16987
--- /dev/null
+++ b/docs/findidx.rst
@@ -0,0 +1,73 @@
+
+findIdx
+==============================================
+
+Purpose
+----------------
+Returns the indices of elements where a condition is true.
+
+Format
+----------------
+.. function:: idx = findIdx(cond)
+
+ :param cond: boolean vector of 0s and 1s, typically the result of an element-wise comparison such as ``x .> 0``. Both column vectors and row vectors are accepted.
+ :type cond: Nx1 or 1xN vector
+
+ :return idx: the row indices where *cond* is nonzero. If no elements are nonzero, a scalar missing value is returned.
+
+ :rtype idx: Mx1 vector
+
+Examples
+----------------
+
+Find indices of positive elements
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ x = { 3, -1, 5, -2, 7 };
+
+ idx = findIdx(x .> 0);
+
+After the above code, ``idx`` will equal:
+
+::
+
+ 1
+ 3
+ 5
+
+Use indices to extract matching elements
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ x = { 3, -1, 5, -2, 7 };
+
+ // Get indices where x is negative
+ idx = findIdx(x .< 0);
+
+ // Extract those elements
+ neg_vals = x[idx];
+
+After the above code, ``neg_vals`` will equal:
+
+::
+
+ -1
+ -2
+
+Remarks
+-------
+
+.. versionadded:: 26.0.1
+
+:func:`findIdx` is equivalent to::
+
+ idx = selif(seqa(1, 1, rows(cond)), cond);
+
+If you only need the matching *values* (not their indices), use :func:`selif` directly::
+
+ pos_vals = selif(x, x .> 0);
+
+.. seealso:: Functions :func:`selif`, :func:`delif`, :func:`indexcat`, :func:`ismiss`
diff --git a/docs/fopen.rst b/docs/fopen.rst
index f93580dc..3fec5222 100644
--- a/docs/fopen.rst
+++ b/docs/fopen.rst
@@ -75,4 +75,21 @@ If :func:`fopen` fails, it returns a 0.
Use :func:`close` and `closeall` to close files opened with :func:`fopen`.
+Example
+-------
+
+::
+
+ // Write a string to a temp file, then read it back
+ fname = tempname("/tmp", "ex", ".txt");
+ fh = fopen(fname, "w");
+ call fputs(fh, "Hello from GAUSS\n");
+ call close(fh);
+
+ // Open the file for reading
+ fh = fopen(fname, "r");
+ s = fgets(fh, 256);
+ print s;
+ call close(fh);
+
.. seealso:: Functions :func:`fgets`, :func:`fputs`, :func:`fseek`, :func:`close`, `closeall`
diff --git a/docs/formatcv.rst b/docs/formatcv.rst
index 16d7b9f3..e9cd8beb 100644
--- a/docs/formatcv.rst
+++ b/docs/formatcv.rst
@@ -65,6 +65,6 @@ gauss.src
Globals
-------
-`\__fmtcv`
+``__fmtcv``
.. seealso:: Functions :func:`formatnv`, :func:`printfm`, :func:`printfmt`
diff --git a/docs/formatnv.rst b/docs/formatnv.rst
index 811d8b40..bfe5a423 100644
--- a/docs/formatnv.rst
+++ b/docs/formatnv.rst
@@ -61,6 +61,6 @@ gauss.src
Globals
------------
-`\__fmtnv`
+``__fmtnv``
.. seealso:: Functions :func:`formatcv`, :func:`printfm`, :func:`printfmt`
diff --git a/docs/fputs.rst b/docs/fputs.rst
index 6f79966e..39ac8757 100644
--- a/docs/fputs.rst
+++ b/docs/fputs.rst
@@ -97,7 +97,7 @@ Remarks
-------
- To write to the standard output stream or the standard error stream,
- pass in `\__STDOUT` or `\__STDERR` as the file handle argument.
+ pass in ``__STDOUT`` or ``__STDERR`` as the file handle argument.
::
diff --git a/docs/fputst.rst b/docs/fputst.rst
index fa303efd..94303cb2 100644
--- a/docs/fputst.rst
+++ b/docs/fputst.rst
@@ -96,7 +96,7 @@ Remarks
-------
- To write to the standard output stream or the standard error stream,
- pass in `\__STDOUT` or `\__STDERR` as the file handle argument.
+ pass in ``__STDOUT`` or ``__STDERR`` as the file handle argument.
::
diff --git a/docs/fseek.rst b/docs/fseek.rst
index 7631dca4..22564be0 100644
--- a/docs/fseek.rst
+++ b/docs/fseek.rst
@@ -70,4 +70,21 @@ location, as in
If you pass :func:`fseek` the handle of a file opened with `open` (i.e., a data
set or matrix file), your program will terminate with a fatal error.
+Example
+-------
+
+::
+
+ // Write data, then seek to a specific position and read
+ fname = tempname("/tmp", "ex", ".txt");
+ fh = fopen(fname, "wb");
+ call fputs(fh, "ABCDEFGHIJ");
+ call close(fh);
+
+ fh = fopen(fname, "rb");
+ call fseek(fh, 5, 0); // Seek to byte 5 from beginning
+ pos = ftell(fh);
+ print "Current position:" pos;
+ call close(fh);
+
.. seealso:: Functions :func:`fopen`
diff --git a/docs/fstrerror.rst b/docs/fstrerror.rst
index c0768682..f1f05ffa 100644
--- a/docs/fstrerror.rst
+++ b/docs/fstrerror.rst
@@ -34,5 +34,18 @@ The Windows system command called by :func:`ftell` does not set the internal
error flag accessed by :func:`fstrerror`. Therefore, calling :func:`fstrerror` after
:func:`ftell` on Windows will not produce any error information.
+Example
+-------
+
+::
+
+ // Check for file I/O errors
+ s = fstrerror;
+ if s $== "";
+ print "No file I/O errors.";
+ else;
+ print "Error:" s;
+ endif;
+
.. seealso:: Functions :func:`fopen`, :func:`ftell`
diff --git a/docs/ftell.rst b/docs/ftell.rst
index ac2bbe32..53c8361d 100644
--- a/docs/ftell.rst
+++ b/docs/ftell.rst
@@ -31,4 +31,24 @@ what the error was.
If you pass :func:`ftell` the handle of a file opened with `open` (i.e., a data
set or matrix file), your program will terminate with a fatal error.
+Example
+-------
+
+::
+
+ // Open a file and track the file pointer position
+ fname = tempname("/tmp", "ex", ".txt");
+ fh = fopen(fname, "wb");
+ call fputs(fh, "ABCDEFGHIJ");
+ call close(fh);
+
+ fh = fopen(fname, "rb");
+ pos = ftell(fh);
+ print "Initial position:" pos;
+
+ call fseek(fh, 5, 0);
+ pos = ftell(fh);
+ print "After seeking to byte 5:" pos;
+ call close(fh);
+
.. seealso:: Functions :func:`fopen`, :func:`fseek`
diff --git a/docs/g.rst b/docs/g.rst
index aa909b0b..db831231 100644
--- a/docs/g.rst
+++ b/docs/g.rst
@@ -81,3 +81,5 @@ G
gradpgradcplx
graphprt
graphset
+ greater-or-equal
+ greater-than
diff --git a/docs/gausset.rst b/docs/gausset.rst
index 6bc58e67..98869535 100644
--- a/docs/gausset.rst
+++ b/docs/gausset.rst
@@ -14,9 +14,20 @@ Format
Globals
-------
-`__altnam`, `__con`, `__ff`, `__fmtcv`, `__fmtnv`, `__header`, `__miss`,
-`__output`, `__row`, `__rowfac`, `__sort`, `__title`, `__tol`, `__vpad`,
-`__vtype`, `__weight`
+``__altnam``, ``__con``, ``__ff``, ``__fmtcv``, ``__fmtnv``, ``__header``, ``__miss``,
+``__output``, ``__row``, ``__rowfac``, ``__sort``, ``__title``, ``__tol``, ``__vpad``,
+``__vtype``, ``__weight``
+
+Example
+-------
+
+::
+
+ // Reset all global control variables to defaults
+ __output = 0;
+ __con = 1;
+ gausset;
+ // __output and __con are now back to their default values
Source
------
diff --git a/docs/ge/api-overview.rst b/docs/ge/api-overview.rst
new file mode 100644
index 00000000..25a64536
--- /dev/null
+++ b/docs/ge/api-overview.rst
@@ -0,0 +1,265 @@
+C API: Overview
+===============
+
+Functions
+---------------
+
+Pre-initialization setup
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These are the first functions called. Use these to setup logging, I/O, error handling and the home directory location.
+
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_GetHome | Gets the **GAUSS Engine** home path. |
++====================================+=====================================================================+
+| GAUSS_GetHomeVar | Gets the name of the environment variable containing the home path. |
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_HookProgramErrorOutput | Sets the callback function for program error output. |
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_HookProgramInputChar | Sets callback function for **key** function. |
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_HookProgramInputCharBlocking | Sets callback function for **keyw** and **show** functions. |
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_HookProgramInputCheck | Sets callback function for **keyav** function. |
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_HookProgramInputString | Sets callback function for **con** and **cons** functions. |
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_HookProgramOutput | Sets the callback function for normal program output. |
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_SetHome | Sets the **GAUSS Engine** home path directly. |
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_SetHomeVar | Sets the name of an environment variable containing the home path. |
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_SetLogFile | Sets the file name and path for logging system errors. |
++------------------------------------+---------------------------------------------------------------------+
+| GAUSS_SetLogStream | Sets the file pointer for logging system errors. |
++------------------------------------+---------------------------------------------------------------------+
+
+Initialization and Shutdown
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++-----------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_Initialize | Initializes the **GAUSS Engine**. Call at the beginning of your application, after setup functions. |
++=============================+=====================================================================================================+
+| GAUSS_Shutdown | Shuts the **GAUSS Engine** down. Call prior to ending your application. |
++-----------------------------+-----------------------------------------------------------------------------------------------------+
+
+
+Compiling and Executing GAUSS programs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_CompileExpression | Compiles a right-hand side expression. |
++================================+==================================================================+
+| GAUSS_CompileFile | Compiles a file containing **GAUSS** code. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_CompileString | Compiles a character string containing **GAUSS** code. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_CompileStringAsFile | Compiles a character string containing **GAUSS** code as a file. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_CreateWorkspace | Creates a workspace handle. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_Execute | Executes a program. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_ExecuteExpression | Executes a right-hand side expression. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_FreeProgram | Frees a program handle created in a compile. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_FreeWorkspace | Frees a workspace handle. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_LoadCompiledBuffer | Loads a compiled program from a buffer. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_LoadCompiledFile | Loads a compiled program from a file. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_LoadWorkspace | Loads workspace information saved in a file. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_SaveProgram | Saves a compiled program as a file. |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_SaveWorkspace | Saves workspace information in a file |
++--------------------------------+------------------------------------------------------------------+
+| GAUSS_TranslateDataloopFile | Translates a dataloop file. |
++--------------------------------+------------------------------------------------------------------+
+
+
+Calling Procedures
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CallProc | Calls a procedure |
++================================+======================================================================================+
+| GAUSS_CallProcFreeArgs | Calls a procedure and frees its arguments. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CopyArgToArg | Copies an argument from one argument list to another. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CopyArgToArray | Copies an array from an argument list descriptor to an array descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CopyArgToMatrix | Copies a matrix from an argument list descriptor to a matrix descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CopyArgToString | Copies a string from an argument list descriptor to a string descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CopyArgToStringArray | Copies a string array from an argument list descriptor to a string array descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CopyArrayToArg | Copies an array to an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CopyMatrixToArg | Copies a matrix to an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CopyStringArrayToArg | Copies a string array to an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CopyStringToArg | Copies a string to an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CreateArgList | Creates an empty argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_CreateProgram | Creates a program handle to use when calling a procedure. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_DeleteArg | Deletes an argument from an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_FreeArgList | Frees an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_GetArgType | Gets the type of an argument in an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_InsertArg | Inserts an argument in an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_MoveArgToArg | Moves an argument from one argument list to another. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_MoveArgToArray | Moves an array from an argument list descriptor to an array descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_MoveArgToMatrix | Moves a matrix from an argument list descriptor to a matrix descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_MoveArgToString | Moves a string from an argument list descriptor to a string descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_MoveArgToStringArray | Moves a string array from an argument list descriptor to a string array descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_MoveArrayToArg | Moves an array to an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_MoveMatrixToArg | Moves a matrix to an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_MoveStringArrayToArg | Moves a string array to an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+| GAUSS_MoveStringToArg | Moves a string to an argument list descriptor. |
++--------------------------------+--------------------------------------------------------------------------------------+
+
+Creating and Freeing GAUSS Format Data
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_ComplexArray | Creates an array descriptor for a complex array and copies the array. |
++===============================+=====================================================================================================+
+| GAUSS_ComplexArrayAlias | Creates an array descriptor for a complex array. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_ComplexMatrix | Creates a matrix descriptor for a complex matrix and copies the matrix. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_ComplexMatrixAlias | Creates a matrix descriptor for a complex matrix. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_FreeArray | Frees an array descriptor. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_FreeMatrix | Frees a matrix descriptor. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_FreeString | Frees a string descriptor. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_FreeStringArray | Frees a string array descriptor. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_Array | Creates an array descriptor and copies array. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_ArrayAlias | Creates an array descriptor. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_Matrix | Creates a matrix descriptor and copies matrix. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_MatrixAlias | Creates a matrix descriptor. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_String | Creates a string descriptor and copies the string. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_StringAlias | Creates a string descriptor. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_StringAliasL | Creates a string descriptor for a string of user-specified length. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_StringArray | Creates a string array descriptor and copies the string array. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_StringArrayL | Creates a string array descriptor for strings of user-specified length and copies the string array. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+| GAUSS_StringL | Creates a string descriptor for string of user-specified length and copies the string. |
++-------------------------------+-----------------------------------------------------------------------------------------------------+
+
+Moving Data Between GAUSS and Your Application
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_AssignFreeableArray | Assigns **malloc**\ ’d data to a global array. |
++=================================+==============================================================+
+| GAUSS_AssignFreeableMatrix | Assigns **malloc**\ ’d data to a global matrix. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_CopyGlobal | Copies a symbol from one workspace to another. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_CopyArrayToGlobal | Copies an array to **GAUSS**. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_CopyMatrixToGlobal | Copies a matrix to **GAUSS**. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_CopyStringToGlobal | Copies a string to **GAUSS**. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_CopyStringArrayToGlobal | Copies a string array to **GAUSS**. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_GetDouble | Gets a double from a **GAUSS** global. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_GetArray | Gets an array from a **GAUSS** global. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_GetArrayAndClear | Gets an array from a **GAUSS** global and clears the global. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_GetMatrix | Gets a matrix from a **GAUSS** global. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_GetMatrixAndClear | Gets a matrix from a **GAUSS** global and clears the global. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_GetMatrixInfo | Gets information for a matrix in a **GAUSS** global. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_GetString | Gets a string from a **GAUSS** global. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_GetStringArray | Gets a string array from a **GAUSS** global. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_GetSymbolType | Gets the type of a symbol in a **GAUSS** global. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_MoveArrayToGlobal | Moves an array to **GAUSS** and frees the descriptor. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_MoveMatrixToGlobal | Moves a matrix to **GAUSS** and frees the descriptor. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_MoveStringToGlobal | Moves a string to **GAUSS** and frees the descriptor. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_MoveStringArrayToGlobal | Moves a string array to **GAUSS** and frees the descriptor. |
++---------------------------------+--------------------------------------------------------------+
+| GAUSS_PutDouble | Puts a double into **GAUSS**. |
++---------------------------------+--------------------------------------------------------------+
+
+GAUSS Engine Error Handling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++---------------------------------+-------------------------------------------------+
+| GAUSS_CheckInterrupt | Checks for a thread-specific interrupt request. |
++=================================+=================================================+
+| GAUSS_ClearGlobalInterrupt | Clears a global interrupt request. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_ClearInterrupt | Clears a thread-specific interrupt request. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_ClearProgramInterrupt | Clears a program interrupt request. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_ClearWorkspaceInterrupt | Clears a workspace interrupt request. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_ErrorText | Gets the text for an error number. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_GetError | Gets the stored error number. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_GetLogFile | Gets the current error log file. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_GetLogStream | Gets the current error log stream. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_SetError | Sets the stored error number. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_SetGlobalInterrupt | Sets a global interrupt request. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_SetInterrupt | Sets a thread specific interrupt request. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_SetProgramInterrupt | Sets a program interrupt request. |
++---------------------------------+-------------------------------------------------+
+| GAUSS_SetWorkspaceInterrupt | Sets a workspace interrupt request. |
++---------------------------------+-------------------------------------------------+
+
+Include Files
+-------------------
+
+**mteng.h** contains all the function declarations, structure definitions, etc. for the C API. Include it in any C file that references the **GAUSS Engine**.
diff --git a/docs/ge/api-reference.rst b/docs/ge/api-reference.rst
new file mode 100644
index 00000000..9f29713c
--- /dev/null
+++ b/docs/ge/api-reference.rst
@@ -0,0 +1,8962 @@
+C API: Reference
+================
+
+GAUSS_Array
+------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Creates an **Array_t** for a real array and copies the array data. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Array_t *GAUSS_Array( size_t** *dims*, **double ***\ *orders*, **double ***\ *addr* **);** |
+| | |
+| | *arr* = **GAUSS_Array(** *dims, orders, addr* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *dims* number of dimensions. |
+| | |
+| | *orders* vector of orders. |
+| | |
+| | *addr* pointer to array. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *mat* pointer to an array descriptor. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_Array malloc**\ ’s an **Array_t** and fills it in with your input information. It makes a copy of the array and sets the *adata* member of the **Array_t** to point to the copy. **GAUSS_Array** should only be used for real arrays. To create an **Array_t** for a complex array, use **GAUSS_ComplexArray**. To create an **Array_t** for a real array without making a copy of the array, use **GAUSS_ArrayAlias**. |
+| | |
+| | Set *orders* to NULL if the vector of orders of the array is located at the beginning of the block of memory that contains the array data. In this case, *addr* should point to the vector of orders, followed by the array data. Otherwise, set *orders* to point to the block of memory that contains vector of orders. The vector of orders should contain *dims* doubles. |
+| | |
+| | To create an **Array_t** for an empty array, set *dims* to 0 and *addr* to NULL. |
+| | |
+| | If *arr* is NULL, there was insufficient memory to **malloc** space for the array and its descriptor. |
+| | |
+| | Use this function to create an array descriptor that you can use in the following functions: |
+| | |
+| | GAUSS_CopyArrayToArg |
+| | |
+| | GAUSS_CopyArrayToGlobal |
+| | |
+| | GAUSS_MoveArrayToArg |
+| | |
+| | GAUSS_MoveArrayToGlobal |
+| | |
+| | Free the **Array_t** with **GAUSS_FreeArray**. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | int ret; |
+| | |
+| | double orders[3] = { 2.0, 2.0, 3.0 }; |
+| | |
+| | double a[2][2][3] = { { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 } } |
+| | |
+| | { { 7.0, 8.0, 9.0 }, { 10.0, 11.0, 12.0 } } |
+| | |
+| | }; |
+| | |
+| | if ( ret = GAUSS_MoveArrayToGlobal( |
+| | |
+| | wh, |
+| | |
+| | GAUSS_Array(3, orders, a ), |
+| | |
+| | "a" |
+| | |
+| | )) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GAUSS_MoveArrayToGlobal failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The above example uses **GAUSS_Array** to copy a local array into an **Array_t** structure, and moves the array into a **GAUSS** workspace. It assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_ComplexArray, GAUSS_ArrayAlias, GAUSS_CopyArrayToGlobal, |
+| | |
+| | GAUSS_CopyArrayToArg, GAUSS_MoveArrayToGlobal, |
+| | |
+| | GAUSS_MoveArrayToArg, GAUSS_FreeArray |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_ArrayAlias
+-----------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Creates an **Array_t** for a real array. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Array_t *GAUSS_ArrayAlias( size_t** *dims*, **double** *****\ *addr* **);** |
+| | |
+| | *arr* = **GAUSS_ArrayAlias(** *dims, addr* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *dims* number of dimensions. |
+| | |
+| | *addr* pointer to matrix. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *arr* pointer to an array descriptor. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_ArrayAlias** is similar to **GAUSS_Array**; however, it sets the *adata* member of the **Array_t** to point to the array indicated by *addr* instead of making a copy of the array. **GAUSS_ArrayAlias** should only be used for real arrays. For complex arrays, use **GAUSS_ComplexArrayAlias**. |
+| | |
+| | The argument *addr* should point to a **malloc**\ ’d block containing two sections. The first section, which is the vector of orders for the array, contains *dims* doubles. The second section contains the array data. The number of doubles in the section that contains the array data is the product of the elements in the vector of orders. These two sections are laid out contiguously in memory. |
+| | |
+| | If *arr* is NULL, there was insufficient memory to **malloc** space for the array descriptor. |
+| | |
+| | Use this function to create an array descriptor that you can use in the following functions: |
+| | |
+| | GAUSS_CopyArrayToArg |
+| | |
+| | GAUSS_CopyArrayToGlobal |
+| | |
+| | GAUSS_MoveArrayToArg |
+| | |
+| | GAUSS_MoveArrayToGlobal |
+| | |
+| | Free the **Array_t** with **GAUSS_FreeArray**. It will not free the array data. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | Array_t *arr; |
+| | |
+| | double *a; |
+| | |
+| | int ret; |
+| | |
+| | size_t dims; |
+| | |
+| | dims = 3; |
+| | |
+| | a = ( double *)malloc( ( 12+dims )*sizeof(double) ); |
+| | |
+| | *a = 2.0; |
+| | |
+| | *(a+1 ) = 3.0; |
+| | |
+| | *(a+2 ) = 2.0; |
+| | |
+| | memset( a+dims, 0, 12*sizeof( double ) ); |
+| | |
+| | if ( ( arr = GAUSS_ArrayAlias( dims, a ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "ArrayAlias failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_MoveArrayToGlobal( wh, arr, "c" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "CopyArrayToGlobal failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeArray( arr ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example **malloc**\ ’s an array of zeros and then creates an **Array_t** for the array. It moves the array to *wh*, which it assumes to be a pointer to a valid workspace. The array data is freed by **GAUSS** when necessary. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_Array, GAUSS_ComplexArrayAlias, GAUSS_CopyArrayToGlobal, |
+| | |
+| | GAUSS_CopyArrayToArg, GAUSS_MoveArrayToGlobal, |
+| | |
+| | GAUSS_MoveArrayToArg, GAUSS_FreeArray |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_AssignFreeableArray
+--------------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Assigns a **malloc**\ ’d N-dimensional array to a **GAUSS** workspace. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int** **GAUSS_AssignFreeableArray( WorkspaceHandle_t ***\ *wh*\ **, size_t** |
+| | |
+| | *dims*, **int** *complex*, **double ***\ *address*, **char ***\ *name* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *ret* = **GAUSS_AssignFreeableArray(** *wh, dims, complex, address, name* **);** |
+| | |
+| | *wh* pointer to a workspace handle. |
+| | |
+| | *dims* number of dimensions. |
+| | |
+| | *complex* 0 if array is real, 1 if complex. |
+| | |
+| | *address* pointer to array. |
+| | |
+| | *name* pointer to name of array to assign to. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **26** Too many symbols. |
+| | |
+| | **91** Symbol name too long. |
+| | |
+| | **481** **GAUSS** assignment failed. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_AssignFreeableArray** assigns an array that is created using **malloc** to a **GAUSS** workspace. **GAUSS** takes ownership of the array and frees it when necessary. The data are not moved or reallocated, making this the most efficient way to move a large array to a **GAUSS** workspace. Do not attempt to free an array that has been assigned to **GAUSS** with **USS_AssignFreeableArray**. |
+| | |
+| | The argument *address* should point to a **malloc**\ ’d block containing two sections in the case of a real array or three sections in the case of a complex array. The first section, which is the vector of orders for the array, contains *dims* doubles. The second section contains the real part of the array. The optional third section contains the imaginary part. The number of doubles in the real section is the product of the vector of orders. The number of doubles in the imaginary section is the same as the real section. These three sections are laid out contiguously in memory. |
+| | |
+| | Call **GAUSS_AssignFreeableArray** with a **WorkspaceHandle_t** returned from **GAUSS_CreateWorkspace**. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | int zmat( |
+| | |
+| | WorkspaceHandle_t *wh, |
+| | |
+| | Char *name, |
+| | |
+| | size_t dims, |
+| | |
+| | double *orders |
+| | |
+| | ) |
+| | |
+| | { |
+| | |
+| | double *fm, *tmp; |
+| | |
+| | size_t i, nelems; |
+| | |
+| | int err; |
+| | |
+| | nelems = 1; |
+| | |
+| | tmp = orders; |
+| | |
+| | for ( i=0; irows != 20 \|\| sa->cols != 1 ) |
+| | |
+| | { |
+| | |
+| | printf( "String array corrupt\n" ); |
+| | |
+| | GAUSS_FreeStringArray( sa ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | GAUSS_FreeStringArray( sa ); |
+| | |
+| | This example assumes that *wh* is a pointer to a valid workspace and that the 20*1 string array *names* is already resident in that workspace. It gets *names* from *wh*, and puts it into a string array descriptor, *sa*. It checks the rows and columns of the string array and then frees *sa*. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_StringArray, GAUSS_StringArrayL, GAUSS_GetStringArray |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_FreeWorkspace
+--------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Frees a workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_FreeWorkspace( WorkspaceHandle_t ***\ *wh* **);** |
+| | |
+| | **GAUSS_FreeWorkspace(** *wh* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_FreeWorkspace** frees a workspace handle that was created with **GAUSS_CreateWorkspace**. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | WorkspaceHandle_t *wh; |
+| | |
+| | ProgramHandle_t *ph; |
+| | |
+| | wh = GAUSS_CreateWorkspace( "main" ); |
+| | |
+| | if ( ( ph = GAUSS_CompileFile( wh, "examples/qnewton1.e", 0, 0 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "CompileFile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeWorkspace( wh ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeWorkspace( wh ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeWorkspace( wh ); |
+| | |
+| | This example creates the workspace handle, *wh*, and runs the example file **qnewton1.e** in that workspace. At the end, it frees the program handle used to run the file as well as the workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CreateWorkspace, GAUSS_SaveWorkspace, GAUSS_LoadWorkspace |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetArgType
+-----------------
+
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the type of a symbol in an **ArgList_t**. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_GetArgType( ArgList_t ***\ *args*, **int** *argnum* **);** |
+| | |
+| | *typ* **= GAUSS_GetArgType(** *args, argnum* **);** |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list descriptor. |
+| | |
+| | *argnum* argument number. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *typ* type of symbol: |
+| | |
+| | GAUSS_ARRAY |
+| | |
+| | GAUSS_MATRIX |
+| | |
+| | GAUSS_STRING |
+| | |
+| | GAUSS_STRING_ARRAY |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | Use **GAUSS_GetArgType** to find the type of a symbol in an **ArgList_t**, so you can use the following functions to move the symbols to type-specific structures: |
+| | |
+| | GAUSS_CopyArgToArray |
+| | |
+| | GAUSS_CopyArgToMatrix |
+| | |
+| | GAUSS_CopyArgToString |
+| | |
+| | GAUSS_CopyArgToStringArray |
+| | |
+| | GAUSS_MoveArgToArray |
+| | |
+| | GAUSS_MoveArgToMatrix |
+| | |
+| | GAUSS_MoveArgToString |
+| | |
+| | GAUSS_MoveArgToStringArray |
+| | |
+| | If **GAUSS_GetArgType** fails, *typ* will be -1. It will fail only if the argument is out of range. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | ArgList_t *ret; |
+| | |
+| | Matrix_t *mat; |
+| | |
+| | if ( ( ph = GAUSS_CompileExpression( |
+| | |
+| | wh, |
+| | |
+| | "prodc( seqa( 1, .01, 25 ) );", |
+| | |
+| | 1, |
+| | |
+| | 1 |
+| | |
+| | ))==NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( ret |
+| | |
+| | = GAUSS_ExecuteExpression( ph ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( GAUSS_GetArgType( ret, 1 ) ) != GAUSS_MATRIX ) |
+| | |
+| | { |
+| | |
+| | printf( "Argument corrupt\n" ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_MoveArgToMatrix( args, 1 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MoveArgToMatrix failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example assumes that *wh* is a pointer to a valid workspace handle. It executes an expression, which places its return in an **ArgList_t.** The example checks to make sure that the return is of type **GAUSS_MATRIX** before moving it to a matrix descriptor. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CallProc, GAUSS_CallProcFreeArgs, GAUSS_ExecuteExpression |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetArray
+---------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global array from a **GAUSS** workspace. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Array_t *GAUSS_GetArray( WorkspaceHandle_t ***\ *wh*, **char** *****\ *name* **);** |
+| | |
+| | *arr* **= GAUSS_GetArray(** *wh, name* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of array. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *arr* pointer to an array descriptor. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetArray** finds an array in a **GAUSS** workspace and **malloc**\ ’s an array descriptor, filling it in with the information for the array. It makes a copy of the array and sets the *adata* member of the array descriptor to point to the copy. This gives you a safe copy of the array that you can work with without affecting the contents of the **GAUSS** symbol table. This copy of the array then belongs to you. Free it with **GAUSS_FreeArray**. |
+| | |
+| | If the array is complex, its copy will be stored in memory with the entire real part first, followed by the imaginary part. |
+| | |
+| | If the array is empty, the *dims* and *nelems* members of the **Array_t** will be set to 0, and the *adata* member will be NULL. |
+| | |
+| | Call **GAUSS_GetArray** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetArray** fails, *arr* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetArray** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | Array_t *arr; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( wh, "orders = { 3,4,5,6,7 }; |
+| | |
+| | a = areshape(seqa(1,1,prodc(orders)),orders); |
+| | |
+| | b = atranspose(a,2|4|3|5|1);", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( arr = GAUSS_GetArray( wh, "b" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetArray failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetArrayAndClear, GAUSS_CopyArrayToGlobal, GAUSS_MoveArrayToGlobal |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetArrayAndClear
+-----------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global array from a **GAUSS** workspace and clears the array in that workspace. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Array_t *GAUSS_GetArrayAndClear( WorkspaceHandle_t ***\ *wh*, **char** *****\ *name* **);** |
+| | |
+| | *arr* **= GAUSS_GetArrayAndClear(** *wh, name* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of array. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *arr* pointer to a array descriptor. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetArrayAndClear** finds an array in a **GAUSS** workspace and **malloc**\ ’s an array descriptor, filling it in with the information for the array. It sets the *adata* member of the **Array_t** to point to the array and sets the array to a 1-dimensional array of 1 element with a value of 0 in the **GAUSS** symbol table. This allows you to get large arrays from a **GAUSS** workspace without using the time and memory space needed to copy the array. The array then belongs to you. Free it with **GAUSS_FreeArray**. |
+| | |
+| | If the array is complex, its copy will be stored in memory with the entire real part first, followed by the imaginary part. |
+| | |
+| | If the array is empty, the *dims* and *nelems* members of the **Array_t** will be set to **0**, and the *adata* member will be NULL. |
+| | |
+| | Call **GAUSS_GetArrayAndClear** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetArrayAndClear** fails, *arr* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetArrayAndClear** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | Array_t *arr; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "a = dimensioninit(100|100|20|10|5,1);", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_GetArrayAndClear( wh, "a" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetArrayAndClear failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. It gets a 5-dimensional array of ones, *a*, and resets *a* in *wh* to a 1-dimensional array of 1 element that is set to zero. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetArray, GAUSS_CopyArrayToGlobal, GAUSS_MoveArrayToGlobal, |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetDouble
+---------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global double from a **GAUSS** workspace. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_GetDouble( WorkspaceHandle_t ***\ *wh*, **double ***\ *d*, **char** *****\ *name* **);** |
+| | |
+| | *ret* **= GAUSS_GetDouble(** *wh, d, name* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *d* pointer to be set to double. |
+| | |
+| | *name* pointer to name of symbol. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **41** Argument must be scalar. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetDouble** finds a scalar in a **GAUSS** workspace and assigns the value of it to *d*. This gives you a safe copy of the data that you can work with without affecting the contents of the symbol table. |
+| | |
+| | **GAUSS_GetDouble** must be called with a **WorkspaceHandle_t** returned from **GAUSS_CreateWorkspace**. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph |
+| | |
+| | double d; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( wh, "{ a, rs } = rndKMn( 1, 1, 31 );", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_GetDouble( wh, &d, "a" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetDouble failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The above example assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_PutDouble, GAUSS_GetMatrix |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetError
+---------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Returns the stored error number. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | int GAUSS_GetError( void ); |
+| | |
+| | *errnum* **= GAUSS_GetError();** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *errnum* error number. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The **GAUSS Engine** stores the error number of the most recently encountered error in a system variable. If a **GAUSS Engine** command fails, it automatically resets this variable with the number of the error. However, the command does not clear the variable if it succeeds. |
+| | |
+| | Many **GAUSS Engine** commands also return a success code. It is set to **0** if the command succeeds or to a specific error number if it fails. Most of the commands that do not return a success code will return a NULL pointer if they fail. Use **GAUSS_GetError** to check the errors from these commands. Since the variable does not get cleared, only call **GAUSS_GetError** if a function fails. |
+| | |
+| | The system variable is global to the current thread. |
+| | |
+| | Follow **GAUSS_GetError** with a call to **GAUSS_ErrorText** to get the error message that corresponds to *errnum*. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | String_t *str; |
+| | |
+| | if ( ( str = GAUSS_GetString( wh, "s" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetString =failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example prints the error message if **GAUSS_GetString** fails. It assumes that *wh* is a pointer to a valid workspace handle and that *s* is already resident in *wh*. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetError, GAUSS_ErrorText |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetHome
+--------------
+
++--------------+-------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the current **GAUSS Engine** home path. |
++--------------+-------------------------------------------------------------------------------------------------+
+| **FORMAT** | **char *GAUSS_GetHome( char ***\ *buff* **);** |
+| | |
+| | *path = GAUSS_GetHome( buff* **);** |
++--------------+-------------------------------------------------------------------------------------------------+
+| **INPUT** | *buff* pointer to 1024 byte buffer to put path. |
++--------------+-------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *path* pointer to buffer. |
++--------------+-------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetHome** fills *buff* with the current home path and returns a pointer to that buffer. |
++--------------+-------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | char buff[1024]; |
+| | |
+| | printf( "%s\n", GAUSS_GetHome( buff ) ); |
++--------------+-------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetHome |
++--------------+-------------------------------------------------------------------------------------------------+
+
+GAUSS_GetHomeVar
+-----------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the name of the current home environment variable for the **GAUSS Engine**. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **char *GAUSS_GetHomeVar( char ***\ *buff* **);** |
+| | |
+| | *hvar* **= GAUSS_GetHomeVar(** *buff* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *buff* pointer to buffer to put name of home environment variable. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *hvar* pointer to buffer. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetHomeVar** fills *buff* with the name of the current home environment variable and returns a pointer to that buffer. |
+| | |
+| | The default home environment variable is **MTENGHOME26**. Use the C library function *getenv* to get the value of the environment variable. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | char buff[100]; |
+| | |
+| | printf( "%s\n", GAUSS_GetHomeVar( buff ) ); |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetHome, GAUSS_SetHomeVar, GAUSS_SetHome, GAUSS_Initialize |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetLogFile
+-----------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the name of the current log file. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **char *GAUSS_GetLogFile( char ***\ *buff* **);** |
+| | |
+| | *logfn* **= GAUSS_GetLogFile(** *buff* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *buff* pointer to buffer for log file name to be put in. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *logfn* pointer to name of log file. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The **GAUSS Engine** logs certain system level errors in 2 places: a file and an open file pointer. The default file is **/tmp/mteng.###.log** where **###** is the process ID number. The default file pointer is *stderr*. |
+| | |
+| | **GAUSS_GetLogFile** fills *buff* with the name of the current log file and returns a pointer to that buffer. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | char buff[40]; |
+| | |
+| | printf( "%s\n", GAUSS_GetLogFile( buff ) ); |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetLogFile, GAUSS_GetLogStream, GAUSS_SetLogStream |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetLogStream
+------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the current log file pointer. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | FILE *GAUSS_GetLogStream( void ); |
+| | |
+| | *logfp* = GAUSS_GetLogStream(); |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *logfp* pointer to log file handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The **GAUSS Engine** logs certain system level errors in 2 places: a file and an open file pointer. The default file is **/tmp/mteng.###.log** where **###** is the process ID number. The default file pointer is *stderr*. |
+| | |
+| | **GAUSS_GetLogStream** returns the current log file pointer. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetLogStream, GAUSS_GetLogFile, GAUSS_SetLogFile |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetMatrix
+----------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global matrix from a **GAUSS** workspace. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Matrix_t *GAUSS_GetMatrix( WorkspaceHandle_t ***\ *wh*, **char** *****\ *name* **);** |
+| | |
+| | *mat* **= GAUSS_GetMatrix(** *wh, name* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of matrix. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *mat* pointer to a matrix descriptor. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetMatrix** finds a matrix in a **GAUSS** workspace and **malloc**\ ’s a matrix descriptor, filling it in with the information for the matrix. It makes a copy of the matrix and sets the *mdata* member of the matrix descriptor to point to the copy. This gives you a safe copy of the matrix that you can work with without affecting the contents of the **GAUSS** symbol table. This copy of the matrix then belongs to you. Free it with **GAUSS_FreeMatrix**. |
+| | |
+| | If the matrix is complex, its copy will be stored in memory with the entire real part first, followed by the imaginary part. |
+| | |
+| | If the matrix is empty, the *rows* and *cols* members of the **Matrix_t** will be set to 0, and the *mdata* member will be NULL. |
+| | |
+| | Call **GAUSS_GetMatrix** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetMatrix** fails, *mat* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetMatrix** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | Matrix_t *mat; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "{a,rs } =rndKMn( 4, 4,31); b=inv(a);", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_GetMatrix( wh, "b" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetMatrix failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetMatrixAndClear, GAUSS_GetMatrixInfo, GAUSS_CopyMatrixToGlobal, GAUSS_MoveMatrixToGlobal, GAUSS_GetDouble |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetMatrixAndClear
+------------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global matrix from a **GAUSS** workspace and clears the matrix in that workspace. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Matrix_t *GAUSS_GetMatrixAndClear( WorkspaceHandle_t ***\ *wh*, **char** *****\ *name* **);** |
+| | |
+| | *mat* **= GAUSS_GetMatrixAndClear(** *wh, name* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of matrix. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *mat* pointer to a matrix descriptor. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetMatrixAndClear** finds a matrix in a **GAUSS** workspace and **malloc**\ ’s a matrix descriptor, filling it in with the information for the matrix. It sets the *mdata* member of the **Matrix_t** to point to the matrix and sets the matrix to a scalar 0 in the **GAUSS** symbol table. This allows you to get large matrices from a **GAUSS** workspace without using the time and memory space |
+| | |
+| | needed to copy the matrix. The matrix then belongs to you. Free it with **GAUSS_FreeMatrix**. |
+| | |
+| | If the matrix is complex, its copy will be stored in memory with the entire real part first, followed by the imaginary part. |
+| | |
+| | If the matrix is empty, the *rows* and *cols* members of the **Matrix_t** will be set to 0, and the *mdata* member will be NULL. |
+| | |
+| | Call **GAUSS_GetMatrixAndClear** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetMatrixAndClear** fails, *mat* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetMatrixAndClear** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | Matrix_t *mat; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "{ a, rs } = rndKMu( 10000, 1000, 31 );", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_GetMatrixAndClear( wh, "a" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetMatrixAndClear failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. It gets a matrix of random numbers, *a*, and resets *a* in *wh* to a scalar 0. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetMatrix, GAUSS_GetMatrixInfo, GAUSS_CopyMatrixToGlobal, GAUSS_MoveMatrixToGlobal, GAUSS_GetDouble |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetMatrixInfo
+--------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets information for a matrix in a **GAUSS** workspace. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | int GAUSS_GetMatrixInfo( WorkspaceHandle_t *\ *wh*, GAUSS_MatrixInfo_t *\ *matinfo*, char *\ *name* ); |
+| | |
+| | *ret* = GAUSS_GetMatrixInfo( *wh, matinfo, name* ); |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *matinfo* pointer to a matrix info descriptor. |
+| | |
+| | *name* pointer to name of matrix. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetMatrixInfo** finds a matrix in a **GAUSS** workspace and fills in the matrix info descriptor with the information for the matrix. It sets the *maddr* member of the descriptor to point to the matrix. If the matrix is complex, it will be stored in memory with the entire real part first, followed by the imaginary part. Since **GAUSS_GetMatrixInfo** gives you a pointer to the data of the matrix contained in a **GAUSS** workspace, any changes you make to the data after getting it will be reflected in the symbol table. The matrix still belongs to **GAUSS**, and **GAUSS** will free it when necessary. You should not attempt to free a matrix that you get with **GAUSS_GetMatrixInfo**. |
+| | |
+| | Call **GAUSS_GetMatrixInfo** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | GAUSS_MatrixInfo_t matinfo; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "a = reshape( seqm( 2, .4, 25 ), 5, 5 );", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_GetMatrixInfo( wh, &matinfo, "a" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetMatrixInfo failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetMatrix, GAUSS_GetMatrixAndClear, GAUSS_CopyMatrixToGlobal, GAUSS_MoveMatrixToGlobal, GAUSS_AssignFreeableMatrix, GAUSS_GetDouble |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetString
+----------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global string from a **GAUSS** workspace. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **String_t *GAUSS_GetString( WorkspaceHandle_t ***\ *wh,* **char ***\ *name* **);** |
+| | |
+| | *str* **= GAUSS_GetString(** *wh, name* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of string. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *str* pointer to a string descriptor. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetString** finds a string in a **GAUSS** workspace and **malloc**\ ’s a string descriptor, filling it in with the information for the string. It makes a copy of the string’s data and sets the *stdata* member of the string descriptor to point to the copy. This gives you a safe copy of the data that you can work with without affecting the contents of the **GAUSS** symbol table. This copy of the data then |
+| | |
+| | belongs to you. Free it with **GAUSS_FreeString**. |
+| | |
+| | Call **GAUSS_GetString** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetString** fails, *str* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetString** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | String_t *str; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "s = \\"birds\\";", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( str = GAUSS_GetString( wh, "s" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetString failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_FreeString, GAUSS_GetError, GAUSS_CopyStringToGlobal, GAUSS_MoveStringToGlobal, GAUSS_GetStringArray |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetStringArray
+---------------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global string array from a **GAUSS** workspace. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **StringArray_t *GAUSS_GetStringArray( WorkspaceHandle_t ***\ *wh*, **char** *****\ *name* **);** |
+| | |
+| | *sa* **= GAUSS_GetStringArray(** *wh, name* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of string array. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *sa* pointer to a string array descriptor. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetStringArray** finds a string array in a **GAUSS** workspace and **malloc**\ ’s a string array descriptor, filling it in with the information for the string array. It fills the *table* member of the descriptor with the address of an array of *rows*cols* string element descriptors. **GAUSS_GetStringArray** makes copies of each string in the array and places the copies directly after the string element descriptors in memory. This gives you a safe copy of the string array that you can work with without affecting the contents of the **GAUSS** symbol table. This copy of the string array belongs to you. Free it with **GAUSS_FreeStringArray**. |
+| | |
+| | Call **GAUSS_GetStringArray** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetStringArray** fails, *sa* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetStringArray** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | StringArray_t *stra; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "string sa = { \\"cats\\" \\"dogs\\", \\"fish\\" \\"birds\\" };", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( stra = GAUSS_GetStringArray( wh, "sa" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetStringArray failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_FreeStringArray, GAUSS_GetError, GAUSS_CopyStringArrayToGlobal, GAUSS_MoveStringArrayToGlobal, GAUSS_GetString |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_createworkspace-1:
+
+GAUSS_CreateWorkspace
+----------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Initializes a workspace. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **WorkspaceHandle_t *GAUSS_CreateWorkspace( char ***\ *name* **);** |
+| | |
+| | *wh* **= GAUSS_CreateWorkspace(** *name* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *name* pointer to name of workspace. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *wh* pointer to a workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The workspace contains all of the global symbols. You can create as many workspaces as you want. Each workspace is isolated from all other workspaces. |
+| | |
+| | If **GAUSS_CreateWorkspace** fails, *wh* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_CreateWorkspace** may fail with any of the following errors: |
+| | |
+| | **28** Can’t open configuration file. |
+| | |
+| | **29** Missing left parenthesis. |
+| | |
+| | **497** Missing right parenthesis. |
+| | |
+| | **498** Environment variable not found. |
+| | |
+| | **499** Recursive definition of **GAUSSDIR**. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | WorkspaceHandle_t *wh; |
+| | |
+| | if ( ( wh = GAUSS_CreateWorkspace( "wksp1" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "CreateWorkspace failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SaveWorkspace, GAUSS_LoadWorkspace, GAUSS_FreeWorkspace, GAUSS_GetError |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_deletearg-1:
+
+GAUSS_DeleteArg
+----------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Deletes an argument from an **ArgList_t**. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_DeleteArg( ArgList_t ***\ *args*, **int** *argnum* **);** |
+| | |
+| | *ret* **= GAUSS_DeleteArg(** *args, argnum* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list descriptor. |
+| | |
+| | *argnum* argument number. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* 0 if successful, otherwise 494 if the argument is out of range. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | Use **GAUSS_DeleteArg** to delete an argument from an **ArgList_t** so that you can reuse the **ArgList_t** for a different procedure call. To simply replace an argument in an **ArgList_t**, use one of the following functions: |
+| | |
+| | GAUSS_CopyMatrixToArg |
+| | |
+| | GAUSS_CopyStringArrayToArg |
+| | |
+| | GAUSS_CopyStringToArg |
+| | |
+| | GAUSS_MoveMatrixToArg |
+| | |
+| | GAUSS_MoveStringArrayToArg |
+| | |
+| | GAUSS_MoveStringToArg |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; ArgList_t *args; |
+| | |
+| | if ( ( ph = GAUSS_CompileExpression( |
+| | |
+| | wh, |
+| | |
+| | "rndKMi(200,4,31);", |
+| | |
+| | 1, |
+| | |
+| | 1 |
+| | |
+| | ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( args = GAUSS_ExecuteExpression( ph ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( GAUSS_DeleteArg( args, 2 ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "DeleteArg failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgs( args ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The above example assumes that *wh* is a pointer to a valid workspace handle. It executes an expression, which gives its returns in the **ArgList_t**, *args*. The example deletes the second argument from *args* so that the first argument may be used as the input for a later procedure call. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyArgToArg, GAUSS_CreateArgList, GAUSS_FreeArgList, GAUSS_InsertArg, GAUSS_CallProc, GAUSS_CallProcFreeArgs |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_errortext-1:
+
+GAUSS_ErrorText
+----------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Returns the error message that corresponds to a given error number. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **char *GAUSS_ErrorText( char ***\ *buff*, **int** *errnum* **);** |
+| | |
+| | *cp* **= GAUSS_ErrorText(** *buff, errnum* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *buff* pointer to a character buffer. |
+| | |
+| | *errnum* error number. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *cp* pointer to the character buffer containing the error message. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_ErrorText** fills in the character buffer *buff* with the error message corresponding to *errnum*. It returns a pointer to that character buffer. This command allows you to get the error messages that correspond to error numbers returned from failed function calls or from **GAUSS_GetError**. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | Matrix_t *mat; |
+| | |
+| | if ( ( mat = GAUSS_GetMatrix( wh, "a" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GAUSS_GetMatrix failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example prints the error message if **GAUSS_GetMatrix** fails. It assumes that *wh* is a pointer to a valid workspace handle and that a is already resident in *wh*. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetError |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_execute-1:
+
+GAUSS_Execute
+--------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Executes a program handle. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_Execute( ProgramHandle_t ***\ *ph* **);** |
+| | |
+| | *ret* **= GAUSS_Execute(** *ph* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *ph* pointer to a program handle. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success code, 0 if successful, otherwise: |
+| | |
+| | **493** Program execute failed. |
+| | |
+| | **495** Workspace inactive or corrupt. |
+| | |
+| | **496** Program inactive or corrupt. |
+| | |
+| | **530** User interrupt. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_Execute** is called with a program handle pointer that was returned from one of the following commands: |
+| | |
+| | GAUSS_CompileFile |
+| | |
+| | GAUSS_CompileString |
+| | |
+| | GAUSS_CompileStringAsFile |
+| | |
+| | GAUSS_LoadCompiledBuffer |
+| | |
+| | GAUSS_LoadCompiledFile |
++--------------+----------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileFile( wh, "examples/ols.e", 0, 0 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example code above runs the **GAUSS** example file **ols.e.** It assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CompileFile, GAUSS_CompileString, GAUSS_CompileStringAsFile, GAUSS_LoadCompiledBuffer, GAUSS_LoadCompiledFile |
++--------------+----------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_executeexpression-1:
+
+GAUSS_ExecuteExpression
+------------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Executes an expression compiled into a program handle. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **ArgList_t *GAUSS_ExecuteExpression( ProgramHandle_t ***\ *ph* **);** |
+| | |
+| | *rets* **= GAUSS_ExecuteExpression(** *ph* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *ph* pointer to a program handle. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *rets* pointer to argument list descriptor containing the returns of the expression. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_ExecuteExpression** is called with a program handle pointer that was returned from **GAUSS_CompileExpression**. |
+| | |
+| | **GAUSS_ExecuteExpression** creates an **ArgList_t** structure in which it puts the returns of the expression. Use the following functions to move the returns of an expression from an **ArgList_t** into descriptors for each respective data type: |
+| | |
+| | GAUSS_CopyArgToMatrix |
+| | |
+| | GAUSS_CopyArgToString |
+| | |
+| | GAUSS_CopyArgToStringArray |
+| | |
+| | GAUSS_MoveArgToMatrix |
+| | |
+| | GAUSS_MoveArgToString |
+| | |
+| | GAUSS_MoveArgToStringArray |
+| | |
+| | Use **GAUSS_GetArgType** to get the type of an argument in an **ArgList_t**. |
+| | |
+| | It is your responsibility to free the **ArgList_t** returned from **GAUSS_CompileExpression**. It may be freed with **GAUSS_FreeArgList**. |
+| | |
+| | If **GAUSS_ExecuteExpression** fails, *rets* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_ExecuteExpression** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **493** Program execute failed. |
+| | |
+| | **495** Workspace inactive or corrupt. |
+| | |
+| | **496** Program inactive or corrupt. |
+| | |
+| | **530** User interrupt. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | ArgList_t *ret; |
+| | |
+| | Matrix_t *mat; |
+| | |
+| | if ( |
+| | |
+| | ( ph = GAUSS_CompileExpression( wh, "inv( x ) * x", 1, 1 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( ret = GAUSS_ExecuteExpression( ph ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_MoveArgToMatrix( ret, 1 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MoveArgToMatrix: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example code above assumes that *x* is already resident in the workspace *wh*. |
+| | |
+| | **GAUSS_ExecuteExpression** creates the **ArgList_t**, *ret*, which contains the return from the executed expression. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_Execute, GAUSS_CompileExpression, GAUSS_GetError, GAUSS_FreeArgList |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_freearglist-1:
+
+GAUSS_FreeArgList
+------------------
+
++--------------+----------------------------------------------------------------------------------------------+
+| **PURPOSE** | Frees an argument list. |
++--------------+----------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_FreeArgList( ArgList_t ***\ *args* **);** |
+| | |
+| | **GAUSS_FreeArgList(** *args* **);** |
++--------------+----------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
++--------------+----------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_FreeArgList** frees an **ArgList_t** structure and all of the arguments it contains. |
++--------------+----------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | ArgList_t *ret; |
+| | |
+| | Matrix_t *mat; |
+| | |
+| | ph = GAUSS_CompileExpression( wh, "sumc(seqm(.2,1,50))", 1, 1 ); |
+| | |
+| | if ( ph == NULL ); |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff,GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( ret = GAUSS_ExecuteExpression( ph ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_MoveArgToMatrix( ret, 1 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MoveArgToMatrix failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+----------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CreateArgList, GAUSS_CallProc, GAUSS_CallProcFreeArgs |
++--------------+----------------------------------------------------------------------------------------------+
+
+.. _gauss_freearray-1:
+
+GAUSS_FreeArray
+----------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Frees an array descriptor and the data it contains. |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_FreeArray( Array_t ***\ *arr* **);** |
+| | |
+| | **GAUSS_FreeArray(** *arr* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *arr* pointer to an array descriptor. |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_FreeArray** frees an array descriptor and the array it points to. |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | Array_t *arr; |
+| | |
+| | ArgList_t *args; |
+| | |
+| | double orders[3] = { 2.0, 4.0, 2.0 }; |
+| | |
+| | double x[2][4][2] = { |
+| | |
+| | { { 3.0, -4.0 }, { 6.0, 9.0 }, {-5.0, 0.0 }, { -1.0, -8.0 } } |
+| | |
+| | { { 9.0, -2.0 }, { 0.0, -3.0 }, { 1.0, 4.0 }, { 7.0, 5.0 } } |
+| | |
+| | }; |
+| | |
+| | args = GAUSS_CreateArgList(); |
+| | |
+| | if ( ( arr = GAUSS_Array( 3, orders, x ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Array failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( GAUSS_CopyArrayToArg( args, arr, 0 ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "CopyArrayToArg failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeArray( arr ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | GAUSS_FreeArray( arr ); |
+| | |
+| | The above example creates an array descriptor, *arr*, and copies it to *args* as its first argument. It then frees *arr*. |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_Array, GAUSS_ArrayAlias, GAUSS_ComplexArray, GAUSS_ComplexArrayAlias, GAUSS_GetArray |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_freematrix-1:
+
+GAUSS_FreeMatrix
+-----------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Frees a matrix descriptor and the data it contains. |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_FreeMatrix( Matrix_t ***\ *mat* **);** |
+| | |
+| | **GAUSS_FreeMatrix(** *mat* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *mat* pointer to a matrix descriptor. |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_FreeMatrix** frees a matrix descriptor and the matrix it points to. |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | Matrix_t *mat; |
+| | |
+| | ArgList_t *args; |
+| | |
+| | double x[4][2] = { {3,-4}, {6,9}, {-5,0}, {-1,-8} }; |
+| | |
+| | args = GAUSS_CreateArgList(); |
+| | |
+| | if ( ( mat = GAUSS_Matrix( 4, 2, &x[0][0] ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Matrix failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( GAUSS_CopyMatrixToArg( args, mat, 0 ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "CopyMatrixToArg failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeMatrix( mat ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | GAUSS_FreeMatrix( mat ); |
+| | |
+| | The above example creates a matrix descriptor, *mat*, and copies it to *args* as its first argument. It then frees *mat*. |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_Matrix, GAUSS_MatrixAlias, GAUSS_ComplexMatrix, GAUSS_ComplexMatrixAlias, GAUSS_GetMatrix |
++--------------+---------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_freeprogram-1:
+
+GAUSS_FreeProgram
+------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Frees a program handle. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_FreeProgram( ProgramHandle_t ***\ *ph* **);** |
+| | |
+| | **GAUSS_FreeProgram(** *ph* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *ph* pointer to a program handle. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_FreeProgram** frees a program handle that was created from one of the following commands: |
+| | |
+| | GAUSS_CompileExpression |
+| | |
+| | GAUSS_CompileFile |
+| | |
+| | GAUSS_CompileString |
+| | |
+| | GAUSS_CompileStringAsFile |
+| | |
+| | GAUSS_CreateProgram |
+| | |
+| | GAUSS_LoadCompiledBuffer |
+| | |
+| | GAUSS_LoadCompiledFile |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileFile( wh, "examples/ols.e", 0, 0 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | The example code above runs the **GAUSS** example file **ols.e**. It assumes that *wh* is a valid workspace handle. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CreateProgram, GAUSS_CompileExpression, GAUSS_CompileFile, GAUSS_CompileString, GAUSS_CompileStringAsFile, GAUSS_LoadCompiledBuffer, GAUSS_LoadCompiledFile |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_freestring-1:
+
+GAUSS_FreeString
+-----------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Frees a string descriptor and the data it contains. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_FreeString( String_t ***\ *str* **);** |
+| | |
+| | **GAUSS_FreeString(** *str* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *str* pointer to a string descriptor. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_FreeString** frees a string descriptor and the string it points to. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | String_t *str; |
+| | |
+| | char s[] = "tmp.out"; |
+| | |
+| | if ( ( str = GAUSS_String( s ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "String failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( GAUSS_CopyStringToGlobal( wh, str, "fname" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "CopyStringToGlobal failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeString( str ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | GAUSS_FreeString( str ); |
+| | |
+| | This example assumes that *wh* is a pointer to a valid workspace. It frees *str* after copying the string it contains to *wh*. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_String, GAUSS_StringAlias, GAUSS_StringL, GAUSS_StringAliasL, GAUSS_GetString |
++--------------+--------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_freestringarray-1:
+
+GAUSS_FreeStringArray
+----------------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Frees a string array descriptor and the data it contains. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_FreeStringArray( StringArray_t ***\ *sa* **);** |
+| | |
+| | **GAUSS_FreeStringArray(** *sa* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *sa* pointer to a string array descriptor. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_FreeStringArray** frees a string array descriptor and the string array it points to. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | StringArray_t *sa; |
+| | |
+| | if ( ( sa = GAUSS_GetStringArray( wh, "names" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetStringArray failed: %s\n", |
+| | |
+| | GAUSS_ErrorText(buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( sa->rows != 20 \|\| sa->cols != 1 ) |
+| | |
+| | { |
+| | |
+| | printf( "String array corrupt\n" ); |
+| | |
+| | GAUSS_FreeStringArray( sa ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | GAUSS_FreeStringArray( sa ); |
+| | |
+| | This example assumes that *wh* is a pointer to a valid workspace and that the 20*1 string array *names* is already resident in that workspace. It gets *names* from *wh*, and puts it into a string array descriptor, *sa*. It checks the *rows* and *columns* of the string array and then frees *sa*. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_StringArray, GAUSS_StringArrayL, GAUSS_GetStringArray |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_freeworkspace-1:
+
+GAUSS_FreeWorkspace
+--------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Frees a workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_FreeWorkspace( WorkspaceHandle_t ***\ *wh* **);** |
+| | |
+| | **GAUSS_FreeWorkspace(** *wh* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_FreeWorkspace** frees a workspace handle that was created with **GAUSS_CreateWorkspace**. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | WorkspaceHandle_t *wh; |
+| | |
+| | ProgramHandle_t *ph; |
+| | |
+| | wh = GAUSS_CreateWorkspace( "main" ); |
+| | |
+| | if ( ( ph = GAUSS_CompileFile( wh, "examples/qnewton1.e", 0, 0 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "CompileFile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeWorkspace( wh ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeWorkspace( wh ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeWorkspace( wh ); |
+| | |
+| | This example creates the workspace handle, *wh*, and runs the example file **qnewton1.e** in that workspace. At the end, it frees the program handle used to run the file as well as the workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CreateWorkspace, GAUSS_SaveWorkspace, GAUSS_LoadWorkspace |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getargtype-1:
+
+GAUSS_GetArgType
+-----------------
+
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the type of a symbol in an **ArgList_t**. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_GetArgType( ArgList_t ***\ *args*, **int** *argnum* **);** |
+| | |
+| | *typ* **= GAUSS_GetArgType(** *args, argnum* **);** |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list descriptor. |
+| | |
+| | *argnum* argument number. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *typ* type of symbol: |
+| | |
+| | GAUSS_ARRAY |
+| | |
+| | GAUSS_MATRIX |
+| | |
+| | GAUSS_STRING |
+| | |
+| | GAUSS_STRING_ARRAY |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | Use **GAUSS_GetArgType** to find the type of a symbol in an **ArgList_t**, so you can use the following functions to move the symbols to type-specific structures: |
+| | |
+| | GAUSS_CopyArgToArray |
+| | |
+| | GAUSS_CopyArgToMatrix |
+| | |
+| | GAUSS_CopyArgToString |
+| | |
+| | GAUSS_CopyArgToStringArray |
+| | |
+| | GAUSS_MoveArgToArray |
+| | |
+| | GAUSS_MoveArgToMatrix |
+| | |
+| | GAUSS_MoveArgToString |
+| | |
+| | GAUSS_MoveArgToStringArray |
+| | |
+| | If **GAUSS_GetArgType** fails, *typ* will be -1. It will fail only if the argument is out of range. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | ArgList_t *ret; |
+| | |
+| | Matrix_t *mat; |
+| | |
+| | if ( ( ph = GAUSS_CompileExpression( |
+| | |
+| | wh, |
+| | |
+| | "prodc( seqa( 1, .01, 25 ) );", |
+| | |
+| | 1, |
+| | |
+| | 1 |
+| | |
+| | ))==NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( ret |
+| | |
+| | = GAUSS_ExecuteExpression( ph ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( GAUSS_GetArgType( ret, 1 ) ) != GAUSS_MATRIX ) |
+| | |
+| | { |
+| | |
+| | printf( "Argument corrupt\n" ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_MoveArgToMatrix( args, 1 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MoveArgToMatrix failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example assumes that *wh* is a pointer to a valid workspace handle. It executes an expression, which places its return in an **ArgList_t.** The example checks to make sure that the return is of type **GAUSS_MATRIX** before moving it to a matrix descriptor. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CallProc, GAUSS_CallProcFreeArgs, GAUSS_ExecuteExpression |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getarray-1:
+
+GAUSS_GetArray
+---------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global array from a **GAUSS** workspace. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Array_t *GAUSS_GetArray( WorkspaceHandle_t ***\ *wh*, **char ***\ *name* **);** |
+| | |
+| | *arr* **= GAUSS_GetArray(** *wh, name* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of array. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *arr* pointer to an array descriptor. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetArray** finds an array in a **GAUSS** workspace and **malloc**\ ’s an array descriptor, filling it in with the information for the array. It makes a copy of the array and sets the *adata* member of the array descriptor to point to the copy. This gives you a safe copy of the array that you can work with without affecting the contents of the **GAUSS** symbol table. This copy of the array then belongs to you. Free it with **GAUSS_FreeArray**. |
+| | |
+| | If the array is complex, its copy will be stored in memory with the entire real part first, followed by the imaginary part. |
+| | |
+| | If the array is empty, the *dims* and *nelems* members of the **Array_t** will be set to 0, and the *adata* member will be NULL. |
+| | |
+| | Call **GAUSS_GetArray** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetArray** fails, *arr* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetArray** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | Array_t *arr; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "orders = { 3,4,5,6,7 }; |
+| | |
+| | a = areshape(seqa(1,1,prodc(orders)),orders); |
+| | |
+| | b = atranspose(a,2|4|3|5|1);", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( arr = GAUSS_GetArray( wh, "b" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetArray failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetArrayAndClear, GAUSS_CopyArrayToGlobal, GAUSS_MoveArrayToGlobal |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getarrayandclear-1:
+
+GAUSS_GetArrayAndClear
+-----------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global array from a **GAUSS** workspace and clears the array in that workspace. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Array_t *GAUSS_GetArrayAndClear( WorkspaceHandle_t ***\ *wh*, **char ***\ *name* **);** |
+| | |
+| | *arr* **= GAUSS_GetArrayAndClear(** *wh, name* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of array. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *arr* pointer to a array descriptor. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetArrayAndClear** finds an array in a **GAUSS** workspace and **malloc**\ ’s an array descriptor, filling it in with the information for the array. It sets the *adata* member of the **Array_t** to point to the array and sets the array to a 1-dimensional array of 1 element with a value of 0 in the **GAUSS** symbol table. This allows you to get large arrays from a **GAUSS** workspace without using the time and memory space needed to copy the array. The array then belongs to you. Free it with **GAUSS_FreeArray**. |
+| | |
+| | If the array is complex, its copy will be stored in memory with the entire real part first, followed by the imaginary part. |
+| | |
+| | If the array is empty, the *dims* and *nelems* members of the **Array_t** will be set to 0, and the *adata* member will be NULL. |
+| | |
+| | Call **GAUSS_GetArrayAndClear** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetArrayAndClear** fails, *arr* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetArrayAndClear** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | Array_t *arr; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "a = dimensioninit(100|100|20|10|5,1);", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_GetArrayAndClear( wh, "a" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetArrayAndClear failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. It gets a 5-dimensional array of ones, *a*, and resets *a* in *wh* to a 1-dimensional array of 1 element that is set to zero. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetArray, GAUSS_CopyArrayToGlobal, GAUSS_MoveArrayToGlobal, |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getdouble-1:
+
+GAUSS_GetDouble
+---------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global double from a **GAUSS** workspace. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_GetDouble( WorkspaceHandle_t ***\ *wh*, **double ***\ *d*, **char ***\ *name* **);** |
+| | |
+| | *ret* = **GAUSS_GetDouble(** *wh, d, name* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *d* pointer to be set to double. |
+| | |
+| | *name* pointer to name of symbol. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **41** Argument must be scalar. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetDouble** finds a scalar in a **GAUSS** workspace and assigns the value of it to *d*. This gives you a safe copy of the data that you can work with without affecting the contents of the symbol table. |
+| | |
+| | **GAUSS_GetDouble** must be called with a **WorkspaceHandle_t** returned from **GAUSS_CreateWorkspace**. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph |
+| | |
+| | double d; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, "{ a, rs } = rndKMn( 1, 1, 31 );", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_GetDouble( wh, &d, "a" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetDouble failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The above example assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_PutDouble, GAUSS_GetMatrix |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_geterror-1:
+
+GAUSS_GetError
+---------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Returns the stored error number. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | int GAUSS_GetError( void ); |
+| | |
+| | *errnum* **= GAUSS_GetError();** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *errnum* error number. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The **GAUSS Engine** stores the error number of the most recently encountered error in a system variable. If a **GAUSS Engine** command fails, it automatically resets this variable with the number of the error. However, the command does not clear the variable if it succeeds. |
+| | |
+| | Many **GAUSS Engine** commands also return a success code. It is set to 0 if the command succeeds or to a specific error number if it fails. Most of the commands that do not return a success code will return a NULL pointer if they fail. Use **GAUSS_GetError** to check the errors from these commands. Since the variable does not get cleared, only call **GAUSS_GetError** if a function fails. |
+| | |
+| | The system variable is global to the current thread. |
+| | |
+| | Follow **GAUSS_GetError** with a call to **GAUSS_ErrorText** to get the error message that corresponds to *errnum*. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | String_t *str; |
+| | |
+| | if ( ( str = GAUSS_GetString( wh, "s" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetString =failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example prints the error message if **GAUSS_GetString** fails. It assumes that *wh* is a pointer to a valid workspace handle and that *s* is already resident in *wh*. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetError, GAUSS_ErrorText |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_gethome-1:
+
+GAUSS_GetHome
+--------------
+
++--------------+-------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the current **GAUSS Engine** home path. |
++--------------+-------------------------------------------------------------------------------------------------+
+| **FORMAT** | **char *GAUSS_GetHome( char ***\ *buff* **);** |
+| | |
+| | *path* **= GAUSS_GetHome(** *buff* **);** |
++--------------+-------------------------------------------------------------------------------------------------+
+| **INPUT** | *buff* pointer to 1024 byte buffer to put path. |
++--------------+-------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *path* pointer to buffer. |
++--------------+-------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetHome** fills *buff* with the current home path and returns a pointer to that buffer. |
++--------------+-------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | char buff[1024]; |
+| | |
+| | printf( "%s\n", GAUSS_GetHome( buff ) ); |
++--------------+-------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetHome |
++--------------+-------------------------------------------------------------------------------------------------+
+
+.. _gauss_gethomevar-1:
+
+GAUSS_GetHomeVar
+-----------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the name of the current home environment variable for the **GAUSS Engine**. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **char *GAUSS_GetHomeVar( char ***\ *buff* **);** |
+| | |
+| | *hvar* **= GAUSS_GetHomeVar(** *buff* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *buff* pointer to buffer to put name of home environment variable. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *hvar* pointer to buffer. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetHomeVar** fills *buff* with the name of the current home environment variable and returns a pointer to that buffer. |
+| | |
+| | The default home environment variable is **MTENGHOME26**. Use the C library function *getenv* to get the value of the environment variable. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | char buff[100]; |
+| | |
+| | printf( "%s\n", GAUSS_GetHomeVar( buff ) ); |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetHome, GAUSS_SetHomeVar, GAUSS_SetHome, GAUSS_Initialize |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getlogfile-1:
+
+GAUSS_GetLogFile
+-----------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the name of the current log file. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **char *GAUSS_GetLogFile( char ***\ *buff* **);** |
+| | |
+| | *logfn* **= GAUSS_GetLogFile(**\ *buff*\ **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *buff* pointer to buffer for log file name to be put in. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *logfn* pointer to name of log file. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The **GAUSS Engine** logs certain system level errors in 2 places: a file and an open file pointer. The default file is **/tmp/mteng.###.log** where **###** is the process ID number. The default file pointer is *stderr*. |
+| | |
+| | **GAUSS_GetLogFile** fills *buff* with the name of the current log file and returns a pointer to that buffer. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | char buff[40]; |
+| | |
+| | printf( "%s\n", GAUSS_GetLogFile( buff ) ); |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetLogFile, GAUSS_GetLogStream, GAUSS_SetLogStream |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getlogstream-1:
+
+GAUSS_GetLogStream
+------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the current log file pointer. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | FILE *GAUSS_GetLogStream( void ); |
+| | |
+| | *logfp* **= GAUSS_GetLogStream();** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *logfp* pointer to log file handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The **GAUSS Engine** logs certain system level errors in 2 places: a file and an open file pointer. The default file is **/tmp/mteng.###.log** where **###** is the process ID number. The default file pointer is *stderr*. |
+| | |
+| | **GAUSS_GetLogStream** returns the current log file pointer. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetLogStream, GAUSS_GetLogFile, GAUSS_SetLogFile |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getmatrix-1:
+
+GAUSS_GetMatrix
+----------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global matrix from a **GAUSS** workspace. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Matrix_t *GAUSS_GetMatrix( WorkspaceHandle_t** *****\ *wh*, **char ***\ *name* **);** |
+| | |
+| | **mat** = **GAUSS_GetMatrix(** **wh, name** **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of matrix. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *mat* pointer to a matrix descriptor. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetMatrix** finds a matrix in a **GAUSS** workspace and **malloc**\ ’s a matrix descriptor, filling it in with the information for the matrix. It makes a copy of the matrix and sets the *mdata* member of the matrix descriptor to point to the copy. This gives you a safe copy of the matrix that you can work with without affecting the contents of the **GAUSS** symbol table. This copy of the matrix then belongs to you. Free it with **GAUSS_FreeMatrix**. |
+| | |
+| | If the matrix is complex, its copy will be stored in memory with the entire real part first, followed by the imaginary part. |
+| | |
+| | If the matrix is empty, the *rows* and *cols* members of the **Matrix_t** will be set to **0**, and the *mdata* member will be NULL. |
+| | |
+| | Call **GAUSS_GetMatrix** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetMatrix** fails, *mat* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetMatrix** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | Matrix_t *mat; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "{a,rs } =rndKMn( 4, 4,31); b=inv(a);", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_GetMatrix( wh, "b" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetMatrix failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetMatrixAndClear, GAUSS_GetMatrixInfo, GAUSS_CopyMatrixToGlobal, GAUSS_MoveMatrixToGlobal, GAUSS_GetDouble |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getmatrixandclear-1:
+
+GAUSS_GetMatrixAndClear
+------------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global matrix from a **GAUSS** workspace and clears the matrix in that workspace. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Matrix_t *GAUSS_GetMatrixAndClear( WorkspaceHandle_t ***\ *wh*\ **, char ***\ *name* ); |
+| | |
+| | *mat* = **GAUSS_GetMatrixAndClear(** *wh, name* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of matrix. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *mat* pointer to a matrix descriptor. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetMatrixAndClear** finds a matrix in a **GAUSS** workspace and **malloc**\ ’s a matrix descriptor, filling it in with the information for the matrix. It sets the *mdata* member of the **Matrix_t** to point to the matrix and sets the matrix to a scalar 0 in the **GAUSS** symbol table. This allows you to get large matrices from a **GAUSS** workspace without using the time and memory space |
+| | |
+| | needed to copy the matrix. The matrix then belongs to you. Free it with **GAUSS_FreeMatrix**. |
+| | |
+| | If the matrix is complex, its copy will be stored in memory with the entire real part first, followed by the imaginary part. |
+| | |
+| | If the matrix is empty, the *rows* and *cols* members of the **Matrix_t** will be set to 0, and the *mdata* member will be NULL. |
+| | |
+| | Call **GAUSS_GetMatrixAndClear** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetMatrixAndClear** fails, *mat* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetMatrixAndClear** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | Matrix_t *mat; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "{ a, rs } = rndKMu( 10000, 1000, 31 );", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_GetMatrixAndClear( wh, "a" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetMatrixAndClear failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. It gets a matrix of random numbers, *a*, and resets *a* in *wh* to a scalar 0. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetMatrix, GAUSS_GetMatrixInfo, GAUSS_CopyMatrixToGlobal, GAUSS_MoveMatrixToGlobal, GAUSS_GetDouble |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getmatrixinfo-1:
+
+GAUSS_GetMatrixInfo
+--------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets information for a matrix in a **GAUSS** workspace. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_GetMatrixInfo( WorkspaceHandle_t ***\ *wh*, **GAUSS_MatrixInfo_t ***\ *matinfo*, **char ***\ *name* **);** |
+| | |
+| | *ret* **= GAUSS_GetMatrixInfo(** *wh, matinfo, name* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *matinfo* pointer to a matrix info descriptor. |
+| | |
+| | *name* pointer to name of matrix. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetMatrixInfo** finds a matrix in a **GAUSS** workspace and fills in the matrix info descriptor with the information for the matrix. It sets the *maddr* member of the descriptor to point to the matrix. If the matrix is complex, it will be stored in memory with the entire real part first, followed by the imaginary part. Since **GAUSS_GetMatrixInfo** gives you a pointer to the data of the matrix contained in a **GAUSS** workspace, any changes you make to the data after getting it will be reflected in the symbol table. The matrix still belongs to **GAUSS**, and **GAUSS** will free it when necessary. You should not attempt to free a matrix that you get with **GAUSS_GetMatrixInfo**. |
+| | |
+| | Call **GAUSS_GetMatrixInfo** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | GAUSS_MatrixInfo_t matinfo; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "a = reshape( seqm( 2, .4, 25 ), 5, 5 );", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_GetMatrixInfo( wh, &matinfo, "a" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetMatrixInfo failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetMatrix, GAUSS_GetMatrixAndClear, GAUSS_CopyMatrixToGlobal, GAUSS_MoveMatrixToGlobal, GAUSS_AssignFreeableMatrix, GAUSS_GetDouble |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getstring-1:
+
+GAUSS_GetString
+----------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global string from a **GAUSS** workspace. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **String_t *GAUSS_GetString( WorkspaceHandle_t ***\ *wh*, **char ***\ *name* **);** |
+| | |
+| | *str* = **GAUSS_GetString(** *wh, name* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of string. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *str* pointer to a string descriptor. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetString** finds a string in a **GAUSS** workspace and **malloc**\ ’s a string descriptor, filling it in with the information for the string. It makes a copy of the string’s data and sets the *stdata* member of the string descriptor to point to the copy. This gives you a safe copy of the data that you can work with without affecting the contents of the **GAUSS** symbol table. This copy of the data then |
+| | |
+| | belongs to you. Free it with **GAUSS_FreeString**. |
+| | |
+| | Call **GAUSS_GetString** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetString** fails, *str* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetString** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | String_t *str; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "s = \\"birds\\";", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( str = GAUSS_GetString( wh, "s" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetString failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_FreeString, GAUSS_GetError, GAUSS_CopyStringToGlobal, GAUSS_MoveStringToGlobal, GAUSS_GetStringArray |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _gauss_getstringarray-1:
+
+GAUSS_GetStringArray
+---------------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets a global string array from a **GAUSS** workspace. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **StringArray_t *GAUSS_GetStringArray( WorkspaceHandle_t ***\ *wh*\ **, char ***\ *name* **);** |
+| | |
+| | *sa* = **GAUSS_GetStringArray(** *wh, name* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of string array. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *sa* pointer to a string array descriptor. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetStringArray** finds a string array in a **GAUSS** workspace and **malloc**\ ’s a string array descriptor, filling it in with the information for the string array. It fills the *table* member of the descriptor with the address of an array of *rows*cols* string element descriptors. **GAUSS_GetStringArray** makes copies of each string in the array and places the copies directly after the string element descriptors in memory. This gives you a safe copy of the string array that you can work with without affecting the contents of the **GAUSS** symbol table. This copy of the string array belongs to you. Free it with **GAUSS_FreeStringArray**. |
+| | |
+| | Call **GAUSS_GetStringArray** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetStringArray** fails, *sa* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetStringArray** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **470** Symbol not found. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | StringArray_t *stra; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "string sa = { \\"cats\\" \\"dogs\\", \\"fish\\" \\"birds\\" };", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, |
+| | |
+| | GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( stra = GAUSS_GetStringArray( wh, "sa" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetStringArray failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_FreeStringArray, GAUSS_GetError, GAUSS_CopyStringArrayToGlobal, GAUSS_MoveStringArrayToGlobal, GAUSS_GetString |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetSymbolType
+-------------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the type of a symbol in a **GAUSS** workspace. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_GetSymbolType( WorkspaceHandle_t ***\ *wh*, **char ***\ *name* **);** |
+| | |
+| | *typ* = **GAUSS_GetSymbolType(** *wh, name* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to name of symbol. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *typ* type of symbol: |
+| | |
+| | GAUSS_ARRAY |
+| | |
+| | GAUSS_MATRIX |
+| | |
+| | GAUSS_STRING |
+| | |
+| | GAUSS_STRING_ARRAY |
+| | |
+| | GAUSS_PROC |
+| | |
+| | GAUSS_OTHER |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetSymbolType** returns the type of a symbol in a **GAUSS** workspace or 0 if it cannot find the symbol. |
+| | |
+| | Call **GAUSS_GetSymbolType** with a **WorkspaceHandle_t** returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_GetSymbolType** fails, *typ* will be -1. Use **GAUSS_GetError** to get the number of the error. **GAUSS_GetSymbolType** may fail with either of the following errors: |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | Matrix_t *mat; |
+| | |
+| | int ret, typ; |
+| | |
+| | if ( ( ph = GAUSS_CompileString( |
+| | |
+| | wh, |
+| | |
+| | "b = { \\"apple\\" \\"orange\\" \\"pear\\" };", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( typ = GAUSS_GetSymbolType( wh, "b" ) ) != GAUSS_MATRIX ) |
+| | |
+| | { |
+| | |
+| | printf( "Wrong symbol type\n" ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_GetMatrix( wh, "b" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GAUSS_GetMatrixfailed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The example above sets a character matrix, *b*, in a **GAUSS** workspace. It gets the type of *b* to ensure that it is a matrix, and gets the matrix from the workspace. The example assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetArray, GAUSS_GetMatrix, GAUSS_GetString, GAUSS_GetStringArray |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_GetWorkspaceName
+-----------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Gets the name of a **GAUSS** workspace. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **char *GAUSS_GetWorkspaceName( WorkspaceHandle_t ***\ *wh*, **char ***\ *buff* **);** |
+| | |
+| | *bp* **= GAUSS_GetWorkspaceName(** *wh, buff* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *buff* pointer to character buffer at least 64 bytes in length. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *bp* pointer, same as buff. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_GetWorkspaceName** fills in the character buffer, *buff*, with the name of a **GAUSS** workspace indicated by a **WorkspaceHandle_t**. If the buffer is shorter than 64 bytes, this can core dump. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CreateWorkspace, GAUSS_SetWorkspaceName |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_HookFlushProgramOutput
+----------------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Specifies the function **GAUSS** calls to flush buffered output. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_HookFlushProgramOutput( void ( ***\ *flush_output_fn* **)( void ) );** |
+| | |
+| | **GAUSS_HookFlushProgramOutput(** *flush_output_fn* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *flush_output_fn* pointer to function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_HookFlushProgramOutput** specifies the function called to flush buffered output by the following **GAUSS** functions: **con, cons, keyw, lshow, print, printfm, show**, and **sleep**. |
+| | |
+| | Many **GAUSS** programs perform I/O, but the **GAUSS Engine** has no connections of its own to the outside world. Instead, it relies on you to supply it with functions it can call for both normal and critical I/O. **The GAUSS_Hook*** commands are used to specify those functions. See section 3.1.3. |
+| | |
+| | The callbacks are thread specific. This function must be called by every thread that will use the callback function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | **GAUSS_HookProgramOutput** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_HookGetCursorPosition
+----------------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Specifies the function **GAUSS** calls to get the position of the cursor. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_HookGetCursorPosition( int ( ***\ *get_cursor_fn* **)( void ) );** |
+| | |
+| | **GAUSS_HookGetCursorPosition(** *get_cursor_fn* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *get_cursor_fn* pointer to function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_HookGetCursorPosition** specifies the function called by the **GAUSS** **csrcol** and **csrlin** commands to get the position of the cursor. Your get cursor postion function must take nothing and return an **int**, the position of the cursor. |
+| | |
+| | Many **GAUSS** programs perform I/O, but the **GAUSS Engine** has no connections of its own to the outside world. Instead, it relies on you to supply it with functions it can call for both normal and critical I/O. The **GAUSS_Hook*** commands are used to specify those functions. See section 3.1.3. |
+| | |
+| | The callbacks are thread-specific. This function must be called by every thread that will use the callback function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_HookProgramOutput |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_HookProgramErrorOutput
+----------------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Specifies the function **GAUSS** calls to display error messages. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_HookProgramErrorOutput( void ( ***\ *dpy_err_str_fn* **)( char * ) );** |
+| | |
+| | **GAUSS_HookProgramErrorOutput(** *dpy_err_str_fn* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *dpy_err_str_fn* pointer to function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_HookProgramErrorOutput** specifies the function that **GAUSS** calls to display its error messages. Your display error string function must takea **char *** (a pointer to the error string to print), and return nothing. |
+| | |
+| | Many **GAUSS** programs perform I/O, but the **GAUSS Engine** has no connections of its own to the outside world. Instead, it relies on you to supply it with functions it can call for both normal and critical I/O. The **GAUSS_Hook*** commands are used to specify those functions. See section 3.1.3. |
+| | |
+| | The callbacks are thread-specific. This function must be called by every thread that will use the callback function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | void program_error( char *str ) |
+| | |
+| | { |
+| | |
+| | FILE *fp; |
+| | |
+| | fp = fopen("test.log", "a"); |
+| | |
+| | fputs(str, fp); |
+| | |
+| | fclose(fp); |
+| | |
+| | } |
+| | |
+| | This function will write the **GAUSS** program error output to a file called **test.log**. It should be hooked at the beginning of a thread as follows: |
+| | |
+| | GAUSS_HookProgramErrorOutput( program_error ); |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_HookProgramOutput |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_HookProgramInputChar
+--------------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Specifies the function **GAUSS** calls to get a character of input. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_HookProgramInputChar( int ( ***\ *input_char_function* **)( void ) );** |
+| | |
+| | **GAUSS_HookProgramInputChar(** *input_char_function* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *input_char_function* pointer to function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_HookProgramInputChar** specifies the function called by the **GAUSS** **key** command to get a character of input if available. Your input character function must take no arguments and return an *int*, the value of the character of input. |
+| | |
+| | Many **GAUSS** programs perform I/O, but the **GAUSS Engine** has no connections of its own to the outside world. Instead, it relies on you to supply it with functions it can call for both normal and critical I/O. The **GAUSS_Hook*** commands are used to specify those functions. See section 3.1.3. |
+| | |
+| | The callbacks are thread-specific. This function must be called by every thread that will use the callback function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_HookProgramInputCharBlocking, GAUSS_HookProgramInputCheck, GAUSS_HookProgramInputString |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_HookProgramInputCharBlocking
+-----------------------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Specifies the function **GAUSS** calls to wait for a character of input. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_HookProgramInputCharBlocking( ***\ *inp_char blking_fn* **) ( void ) );** |
+| | |
+| | **( GAUSS_HookProgramInputCharBlocking(** *inp_char_blking_fn* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *inp_char_blking_fn* function pointer. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_HookProgramInputCharBlocking** specifies the function called by the **GAUSS** **keyw** and **show** commands to get ( blocking ) character input from your application. Your input character blocking function must take no arguments and return an **int**, the value of the character of input. |
+| | |
+| | Many **GAUSS** programs perform I/O, but the **GAUSS Engine** has no connections of its own to the outside world. Instead, it relies on you to supply it with functions that it can call for both normal and critical I/O. The **GAUSS_Hook*** commands are used to specify those functions. See section 3.1.3. |
+| | |
+| | The callbacks are thread-specific. This function must be called by every thread that will use the callback function. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_HookProgramInputChar, GAUSS_HookProgramInputCheck, GAUSS_HookProgramInputString |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_HookProgramInputCheck
+---------------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Specifies the function **GAUSS** calls to check for pending input. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_HookProgramInputCheck( int ( ***\ *input_check_fn* **)( void ) );** |
+| | |
+| | **GAUSS_HookProgramInputCheck(** *input_check_fn* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *input_check_fn* pointer to function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_HookProgramInputCheck** specifies the function called by the **GAUSS** **keyav** command calls to check if input is pending. Your input check function must take no arguments and return an **int**, 1 if input is available, 0 otherwise. |
+| | |
+| | Many **GAUSS** programs perform I/O, but the **GAUSS Engine** has no connections of its own to the outside world. Instead, it relies on you to supply it with functions it can call for both normal and critical I/O. The **GAUSS_Hook*** commands are used to specify those functions. See section 3.1.3. |
+| | |
+| | The callbacks are thread-specific. This function must be called by every thread that will use the callback function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_HookProgramInputChar, GAUSS_HookProgramInputCharBlocking, GAUSS_HookProgramInputString |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_HookProgramInputString
+-----------------------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Specifies the function **GAUSS** calls to wait for a string of input. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_HookProgramInputString( int ( ***\ *input_string_fn* **)( char *, int ) );** |
+| | |
+| | **GAUSS_HookProgramInputString(** *input_string_fn* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *input_string_fn* pointer to function. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_HookProgramInputString** specifies the function called by the **GAUSS** **con** and **cons** commands to get ( blocking ) string input from your application. Your input string function must takea character pointer (the buffer in which to place the string) and an integer specifying the length of the buffer. Your function must return an int which gives the length of the string, not including the null terminating byte. |
+| | |
+| | Many **GAUSS** programs perform I/O,but the **GAUSS Engine** has no connections of its own to the outside world. Instead, it relies on you to supply it with functions it can call for both normal and critical I/O. The **GAUSS_Hook*** commands are used to specify those functions. See section 3.1.3. |
+| | |
+| | The callbacks are thread-specific. This function must be called by every thread that will use the callback function. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_HookProgramInputChar, GAUSS_HookProgramInputCharBlocking, GAUSS_HookProgramInputCheck |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_HookProgramOutput
+------------------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Specifies the function **GAUSS** calls to display program output. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_HookProgramOutput( void ( ***\ *display_string_fn* **)( char * ) );** |
+| | |
+| | **GAUSS_HookProgramOutput(** *display_string_fn* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *display_string_fn* pointer to function. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_HookProgramOutput** specifies the function **GAUSS** calls to display its program output. Your display string function must take a **char *** (a pointer to the string to print) and return nothing. |
+| | |
+| | Many **GAUSS** programs perform I/O, but the **GAUSS** Engine has no connections of its own to the outside world. Instead, it relies on you to supply it with functions it can call for both normal and critical I/O. The **GAUSS_Hook**\ * commands are used to specify those functions. See section 3.1.3. |
+| | |
+| | The callbacks are thread-specific. This function must be called by every thread that will use the callback function. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | void program_output( char *str ) |
+| | |
+| | { |
+| | |
+| | FILE *fp; |
+| | |
+| | fp = fopen("progout.log", "a"); |
+| | |
+| | fputs(str, fp); |
+| | |
+| | fclose(fp); |
+| | |
+| | } |
+| | |
+| | This function will write the normal **GAUSS** program output to a file called **progout.log**. It should be hooked at the beginning of a thread as follows: |
+| | |
+| | GAUSS_HookProgramOutput( program_output ); |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_HookProgramErrorOutput |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_Initialize
+-----------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Initializes the **GAUSS Engine**. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | int GAUSS_Initialize( void ); |
+| | |
+| | *ret* = **GAUSS_Initialize();** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **85** Invalid file type. |
+| | |
+| | **482** **GAUSS Engine** already initialized. |
+| | |
+| | **483** Cannot determine home directory. |
+| | |
+| | **487** License expired. |
+| | |
+| | **488** Cannot stat file. |
+| | |
+| | **489** File has no execute permissions. |
+| | |
+| | **490** License manager initialization error. |
+| | |
+| | **491** License manager error. |
+| | |
+| | **492** Licensingfailure. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_Initialize** reads the configuration file.You need to call it once at the beginning of your application. If **GAUSS_Initialize** fails, you should terminate your application. |
+| | |
+| | Call **GAUSS_SetHome** or **GAUSS_SetHomeVar** before calling **GAUSS_Initialize**. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetHome, GAUSS_SetHomeVar, GAUSS_Shutdown |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_InsertArg
+----------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Inserts an empty argument into an **ArgList_t**. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_InsertArg( ArgList_t ***\ *args*, **int** *argnum* **);** |
+| | |
+| | *newargnum* = **GAUSS_InsertArg(** *args, argnum* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
+| | |
+| | *argnum* number of argument. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *newargnum* number of inserted argument. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_InsertArg** inserts an empty argument descriptor into an **ArgList_t** before the *argnum* argument. Fill in the argument descriptor with the following commands: |
+| | |
+| | GAUSS_CopyMatrixToArg |
+| | |
+| | GAUSS_CopyStringArrayToArg |
+| | |
+| | GAUSS_CopyStringToArg |
+| | |
+| | GAUSS_MoveMatrixToArg |
+| | |
+| | GAUSS_MoveStringArrayToArg |
+| | |
+| | GAUSS_MoveStringToArg |
+| | |
+| | If **GAUSS_InsertArg** fails, *newargnum* will be -1. Use **GAUSS_GetError** to get the number of the error. **GAUSS_InsertArg** may fail with either of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **494** Invalid argument number. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CreateArgList, GAUSS_FreeArgList, GAUSS_CallProc, GAUSS_CallProcFreeArgs, GAUSS_DeleteArg, GAUSS_GetError |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_IsMissingValue
+---------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Checks a double to see if it contains a **GAUSS** missing value. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_IsMissingValue( double ***\ *d* **);** |
+| | |
+| | *ret* = **GAUSS_IsMissingValue(** *d* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *d* data. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* 1 if d contains a **GAUSS** missing value, 0 if not. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | double d; |
+| | |
+| | if ( ret = GAUSS_GetDouble( wh, &d, "a" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GetDouble failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ! GAUSS_IsMissingValue( &d ) ) |
+| | |
+| | printf( "a = %lf", d ); |
+| | |
+| | This example assumes that *a* is a global 1x1 matrix in the **GAUSS** workspace indicated by *wh*. It finds *a* in the **GAUSS** workspace and sets *d* to its value. The example then checks to see if *d* contains a **GAUSS** missing value and prints its value if it does not. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_MissingValue |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_LoadCompiledBuffer
+-------------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Loads a compiled program stored in a character buffer. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **ProgramHandle_t *GAUSS_LoadCompiledBuffer( WorkspaceHandle_t ***\ *wh*, **char** *****\ *buff* **);** |
+| | |
+| | *ph* = **GAUSS_LoadCompiledBuffer(** *wh, buff* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *buff* pointer to a buffer containing the program. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ph* pointer to a program handle. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The buffer can be created with the **mkcb** utility and then compiled into your application using a C compiler. Execute **mkcb** with no arguments to get the syntax. **mkcb** converts a **.gcg** file to a C character string definition that can be compiled into your application. |
+| | |
+| | **GAUSS_LoadCompiledBuffer** returns a program handle pointer you can use in **GAUSS_Execute** to execute the program. |
+| | |
+| | Call **GAUSS_LoadCompiledBuffer** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_LoadCompiledBuffer** fails, *ph* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_LoadCompiledBuffer** may fail with either of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_Execute, GAUSS_LoadCompiledFile, GAUSS_CompileFile, |
+| | |
+| | GAUSS_CompileStringAsFile, GAUSS_GetError |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_LoadCompiledFile
+-----------------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Loads a compiled file into a program handle. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **ProgramHandle_t *GAUSS_LoadCompiledFile( WorkspaceHandle_t ***\ *wh*, **char ***\ *gcgfile* **);** |
+| | |
+| | *ph* **= GAUSS_LoadCompiledFile(** *wh, gcgfile* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *gcgfile* pointer to name of a compiled file. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ph* pointer to a program handle. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_LoadCompiledFile** takes a compiled file and loads it into a workspace. It returns a program handle pointer you can use in **GAUSS_Execute** to execute the program. |
+| | |
+| | Call **GAUSS_LoadCompiledFile** with a **WorkspaceHandle_t** pointer returned from **GAUSS_CreateWorkspace**. |
+| | |
+| | If **GAUSS_LoadCompiledFile** fails, *ph* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_LoadCompiledFile** may fail with either of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **494** Invalid argument number. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph1, *ph2; |
+| | |
+| | int ret; |
+| | |
+| | if ( ( ph1 = GAUSS_CompileString( |
+| | |
+| | wh1, |
+| | |
+| | "{ a, rs } = rndKMn( 4,4,31 ); b = det( a );", |
+| | |
+| | 0, |
+| | |
+| | 0 |
+| | |
+| | ) ) == NULL) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf("Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_SaveProgram( ph1, "det.gcg" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GAUSS_SaveProgram failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph1 ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( ph2 = GAUSS_LoadCompiledFile( wh2, "det.gcg" ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GAUSS_LoadCompiledFile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph1 ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The above example compiles a string into one workspace, saves the program information into a file, and then loads the program information into another workspace. It assumes that *wh1* and *wh2* are pointers to valid workspace handles. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_Execute, GAUSS_CompileFile, GAUSS_CompileStringAsFile, GAUSS_SaveProgram |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_LoadWorkspace
+--------------------
+
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Loads workspace information stored in a file. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **WorkspaceHandle_t *GAUSS_LoadWorkspace( char ***\ *file* **);** |
+| | |
+| | *wh* **= GAUSS_LoadWorkspace(** *file* **);** |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *file* pointer to name of a compiled file |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *wh* pointer to a workspace handle. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_LoadWorkspace** gets the workspace information saved in a file and returns it in a workspace handle. |
+| | |
+| | If **GAUSS_LoadWorkspace** fails, *wh* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_LoadWorkspace** may fail with either of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CreateWorkspace, GAUSS_SaveWorkspace, GAUSS_FreeWorkspace |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MakePathAbsolute
+-----------------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Takes a partial path and makes it absolute. |
++--------------+--------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_MakePathAbsolute( char ***\ *path* **);** |
+| | |
+| | **GAUSS_MakePathAbsolute(** *path* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *path* pointer to buffer containing partial path. |
++--------------+--------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MakePathAbsolute** overwrites the input buffer containing the partial path with the corresponding absolute path. |
++--------------+--------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetHome |
++--------------+--------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_Matrix
+-------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Creates a **Matrix_t** for a real matrix and copies the matrix data. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Matrix_t *GAUSS_Matrix( size_t** *rows*, **size_t** *cols*\ **, double ***\ *addr* **);** |
+| | |
+| | *mat* = **GAUSS_Matrix(** *rows, cols, addr* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *rows* number of rows. |
+| | |
+| | *cols* number of columns. |
+| | |
+| | *addr* pointer to matrix. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *mat* pointer to a matrix descriptor. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_Matrix malloc’**\ s a **Matrix_t** and fills it in with your input information. It makes a copy of the matrix and sets the *mdata* member of the **Matrix_t** to point to the copy. **GAUSS_Matrix** should only be used for real matrices. To create a **Matrix_t** for a complex matrix, use **GAUSS_ComplexMatrix**. To create a **Matrix_t** for a real matrix without making a copy of the matrix, use **GAUSS_MatrixAlias**. |
+| | |
+| | To create a **Matrix_t** for an empty matrix, set *rows* and *cols* to 0 and *addr* to NULL. |
+| | |
+| | If *mat* is NULL, there was insufficient memory to **malloc** space for the matrix and its descriptor. |
+| | |
+| | Use this function to create a matrix descriptor that you can use in the following functions: |
+| | |
+| | GAUSS_CopyMatrixToArg |
+| | |
+| | GAUSS_CopyMatrixToGlobal |
+| | |
+| | GAUSS_MoveMatrixToArg |
+| | |
+| | GAUSS_MoveMatrixToGlobal |
+| | |
+| | Free the **Matrix_t** with **GAUSS_FreeMatrix**. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | double m[2][3]={ { 1, 2, 3},{4, 5, 6 } }; |
+| | |
+| | int ret; |
+| | |
+| | if ( ret = GAUSS_MoveMatrixToGlobal( |
+| | |
+| | wh, |
+| | |
+| | GAUSS_Matrix( 2, 3, &m[0][0] ), |
+| | |
+| | "a" |
+| | |
+| | ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "GAUSS_MoveMatrixToGlobal failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The above example uses **GAUSS_Matrix** to copy a local matrix into a **Matrix_t** structure, and moves the matrix into a **GAUSS** workspace. It assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_ComplexMatrix, GAUSS_MatrixAlias, GAUSS_CopyMatrixToGlobal, GAUSS_CopyMatrixToArg, GAUSS_MoveMatrixToGlobal, GAUSS_MoveMatrixToArg, GAUSS_FreeMatrix |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MatrixAlias
+------------------
+
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Creates a **Matrix_t** for a real matrix. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Matrix_t *GAUSS_MatrixAlias( size_t** *rows*, **size_t** *cols*, **double ***\ *addr* **);** |
+| | |
+| | *mat* = **GAUSS_MatrixAlias(** *rows, cols, addr* **);** |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *rows* number of rows. |
+| | |
+| | *cols* number of columns. |
+| | |
+| | *addr* pointer to matrix. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *mat* pointer to a matrix descriptor. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MatrixAlias** is similar to **GAUSS_Matrix**; however, it sets the *mdata* member of the **Matrix_t** to point to the matrix indicated by *addr* instead of making a copy of the matrix. **GAUSS_MatrixAlias** should only be used for real matrices. For complex matrices, use **GAUSS_ComplexMatrixAlias**. |
+| | |
+| | If *mat* is NULL, there was insufficient memory to **malloc** space for the matrix descriptor. |
+| | |
+| | Use this function to create a matrix descriptor that you can use in the following functions: |
+| | |
+| | GAUSS_CopyMatrixToArg |
+| | |
+| | GAUSS_CopyMatrixToGlobal |
+| | |
+| | GAUSS_MoveMatrixToArg |
+| | |
+| | GAUSS_MoveMatrixToGlobal |
+| | |
+| | Free the **Matrix_t** with **GAUSS_FreeMatrix**. The matrix data will not be freed or overwritten by **GAUSS_FreeMatrix** or any other **GAUSS** **Engine** commands. You are responsible for freeing the data pointed to by *addr*. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | Matrix_t *mat; |
+| | |
+| | double *a; |
+| | |
+| | int ret; |
+| | |
+| | a = (double *)malloc( 9*sizeof(double) ); |
+| | |
+| | memset( a, 0, 9*sizeof(double) ); |
+| | |
+| | if ( ( mat = GAUSS_MatrixAlias( 3, 3, a ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MatrixAlias failed: %s\n", GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | free(a); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_CopyMatrixToGlobal( wh, mat, "c" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "CopyMatrixToGlobal failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeMatrix( mat ); |
+| | |
+| | free(a); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | free(a); |
+| | |
+| | This example **malloc**\ ’s a matrix of zeroes and then creates a **Matrix_t** for the matrix. It copies the matrix to *wh*, which it assumes to be a pointer to a valid workspace. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_Matrix, GAUSS_ComplexMatrixAlias, GAUSS_CopyMatrixToGlobal, GAUSS_CopyMatrixToArg, GAUSS_MoveMatrixToGlobal, GAUSS_MoveMatrixToArg, GAUSS_FreeMatrix |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MissingValue
+-------------------
+
++--------------+-----------------------------------------------------+
+| **PURPOSE** | Returns a **GAUSS** missing value. |
++--------------+-----------------------------------------------------+
+| **FORMAT** | double GAUSS_MissingValue( void ); |
+| | |
+| | *miss* = **GAUSS_MissingValue();** |
++--------------+-----------------------------------------------------+
+| **OUTPUT** | *miss* **GAUSS** missing value. |
++--------------+-----------------------------------------------------+
+| **SEE ALSO** | GAUSS_IsMissingValue |
++--------------+-----------------------------------------------------+
+
+GAUSS_MoveArgToArg
+------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves an argument from one **ArgList_t** to another. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_MoveArgToArg( ArgList_t ***\ *targs*, **int** *targnum*, **ArgList_t ***\ *sargs*, **int** *sargnum* **);** |
+| | |
+| | *ret* = **GAUSS_MoveArgToArg(** *targs, targnum, sargs, sargnum* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *targs* pointer to target argument list structure. |
+| | |
+| | *targnum* number of argument in target argument list. |
+| | |
+| | *sargs* pointer to source argument list structure. |
+| | |
+| | *sargnum* number of argument in source argument list. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **94** Argument out of range. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveArgToArg** moves the *sargnum* argument in *sargs* to *targs*. It clears the *sargnum* argument descriptor after moving the argument indicated by it. However, it does not change the number of arguments in *sargs*. Therefore, you can overwrite the *sargnum* argument of *sargs* by copying or moving another argument into it. |
+| | |
+| | To add an argument to the end of an argument list or to an empty argument list, set *targnum* to 0. To replace an argument, set *targnum* to the number of the argument you want to replace. It will overwrite that argument’s information and free its data. To insert an argument, call **GAUSS_InsertArg** and then set *targnum* to the number of the inserted argument. Arguments are numbered starting with 1. |
+| | |
+| | The argument’s data will be freed when you call **GAUSS_CallProcFreeArgs** or **GAUSS_FreeArgList** later. |
+| | |
+| | If you want to retain the argument in *sargs*, use **GAUSS_CopyMatrixToArg** instead. However, **GAUSS_MoveMatrixToArg** saves time and memory space. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ArgList_t *marg( WorkspaceHandle_t *wh, ArgList_t *args ) |
+| | |
+| | { |
+| | |
+| | ProgramHandle_t *ph; |
+| | |
+| | ArgList_t *ret; |
+| | |
+| | if ( ( ph = GAUSS_CompileExpression( |
+| | |
+| | wh, |
+| | |
+| | "rndKMi(100,4);", |
+| | |
+| | 1, |
+| | |
+| | 1 |
+| | |
+| | ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return NULL; |
+| | |
+| | } |
+| | |
+| | if ( ( ret = GAUSS_ExecuteExpression( ph ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return NULL; |
+| | |
+| | } |
+| | |
+| | if ( GAUSS_MoveArgToArg( args, 2, ret, 2 ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MoveArgToArg failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | return NULL; |
+| | |
+| | } |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | return args; |
+| | |
+| | } |
+| | |
+| | The above example compiles an expression in *wh*, which gives its return in an **ArgList_t**. It moves the second argument contained in *ret* into *args* as its second argument. It assumes that *args* has at least two arguments, and it overwrites the second argument of *args*. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyArgToArg, GAUSS_CreateArgList, GAUSS_InsertArg, GAUSS_FreeArgList, GAUSS_CallProc, GAUSS_CallProcFreeArgs |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveArgToArray
+---------------------
+
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves an array from an **ArgList_t** to an **Array_t** structure. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Array_t *GAUSS_MoveArgToArray( ArgList_t ***\ *args*, **int** *argnum* **);** |
+| | |
+| | *arr* **= GAUSS_MoveArgToArray(** *args, argnum* **);** |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
+| | |
+| | *argnum* number of argument in the argument list. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *arr* pointer to an array descriptor. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveArgToArray** creates an array descriptor, *arr*, and moves an array contained in *args* into it. *arr* belongs to you. Free it with **GAUSS_FreeArray**. |
+| | |
+| | **GAUSS_MoveArgToArray** clears the *argnum* argument descriptor after moving the array indicated by it. However, it does not change the number of arguments in *args*. Therefore, you can overwrite the *argnum* argument of *args* by copying or moving another argument into it. Arguments are numbered starting with 1. |
+| | |
+| | If you want to retain the array in the **ArgList_t**, use **GAUSS_CopyArgToArray** instead. However, **GAUSS_MoveArgToArray** saves time and memory space. |
+| | |
+| | If **GAUSS_MoveArgToArray** fails, *arr* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_MoveArgToArray** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **94** Argument out of range. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | ArgumentList_t *ret; |
+| | |
+| | Array_t *arr; |
+| | |
+| | if ( ( ph = GAUSS_CompileExpression( |
+| | |
+| | wh, |
+| | |
+| | "asum(areshape(seqa(1,1,120),2|3|4|5),3);", |
+| | |
+| | 1, |
+| | |
+| | 1 |
+| | |
+| | ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( ret = GAUSS_ExecuteExpression( ph ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( arr = GAUSS_MoveArgToArray( ret, 1 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MoveArgToArray failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyArgToArray, GAUSS_CallProc, GAUSS_CallProcFreeArgs, GAUSS_ExecuteExpression, GAUSS_FreeArray, GAUSS_GetArgType, GAUSS_GetError |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+*args* pointer to an argument list structure.
+
+*argnum* number of argument in the argument list.
+
+GAUSS_MoveArgToMatrix
+----------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves a matrix from an **ArgList_t** to a **Matrix_t** structure. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **Matrix_t *GAUSS_MoveArgToMatrix( ArgList_t ***\ *args,* **int** *argnum* **);** |
+| | |
+| | *mat* = **GAUSS_MoveArgToMatrix(** *args, argnum* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
+| | |
+| | *argnum* number of argument in the argument list. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *mat* pointer to a matrix descriptor. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveArgToMatrix** creates a matrix descriptor, *mat*, and moves a matrix contained in **args** into it. *mat* belongs to you. Free it with **GAUSS_FreeMatrix**. |
+| | |
+| | **GAUSS_MoveArgToMatrix** clears the *argnum* argument descriptor after moving the matrix indicated by it. However, it does not change the number of arguments in *args*. Therefore, you can overwrite the *argnum* argument of *args* by copying or moving another argument into it. Arguments are numbered starting with 1. |
+| | |
+| | If you want to retain the matrix in the **ArgList_t**, use **GAUSS_CopyArgToMatrix** instead. However, **GAUSS_MoveArgToMatrix** saves time and memory space. |
+| | |
+| | If **GAUSS_MoveArgToMatrix** fails, *mat* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_MoveArgToMatrix** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **94** Argument out of range. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | ArgumentList_t *ret; |
+| | |
+| | Matrix_t *mat; |
+| | |
+| | if ( ( ph = GAUSS_CompileExpression( |
+| | |
+| | wh, |
+| | |
+| | "band( reshape( seqa( 1,2,20 ),5,4 ),2 );", |
+| | |
+| | 1, |
+| | |
+| | 1 |
+| | |
+| | ))==NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( ret = GAUSS_ExecuteExpression( ph ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( mat = GAUSS_MoveArgToMatrix( ret, 1 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MoveArgToMatrix failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyArgToMatrix, GAUSS_CallProc, GAUSS_CallProcFreeArgs, GAUSS_ExecuteExpression, GAUSS_FreeMatrix, GAUSS_GetArgType, GAUSS_GetError |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveArgToString
+----------------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves a string from an **ArgList_t** to a **String_t** structure. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **String_t *GAUSS_MoveArgToString( ArgList_t ***\ *args*, **int** *argnum* **);** |
+| | |
+| | *str* = **GAUSS_MoveArgToString(** *args, argnum* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
+| | |
+| | *argnum* number of argument in the argument list. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *str* pointer to a string descriptor. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveArgToString** creates a **String_t,** *str*, and moves a string contained in *args* into it. *str* belongs to you. Free it with **GAUSS_FreeString**. |
+| | |
+| | **GAUSS_MoveArgToString** clears the *argnum* argument descriptor after moving the string indicated by it. However, it does not change the number of arguments in *args*. Therefore, you can overwrite the *argnum* argument of *args* by copying or moving another argument into it. |
+| | |
+| | Arguments are numbered starting with **1**. |
+| | |
+| | If you want to retain the string in the **ArgList_t**, use **GAUSS_CopyArgToString** instead. However, **GAUSS_MoveArgToString** saves time and memory space. |
+| | |
+| | If **GAUSS_MoveArgToString** fails, *str* will be NULL. Use **GAUSS_GetError** to get the number of the error. **GAUSS_MoveArgToString** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **94** Argument out of range. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | ArgList_t *ret; |
+| | |
+| | String_t *str; |
+| | |
+| | if ( ( ph = GAUSS_CompileExpression( |
+| | |
+| | wh, |
+| | |
+| | "\\"output\\"$+\\".log\\";", |
+| | |
+| | 1, |
+| | |
+| | 1 |
+| | |
+| | ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf ( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( ret = GAUSS_ExecuteExpression( ph ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( str = MoveArgToString( args, 1 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MoveArgToString failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( ret ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyArgToString, GAUSS_CallProc, GAUSS_CallProcFreeArgs, GAUSS_ExecuteExpression, GAUSS_FreeString, GAUSS_GetArgType, GAUSS_GetError |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveArgToStringArray
+---------------------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves a string array from an **ArgList_t** to a **StringArray_t** structure. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **StringArray_t *GAUSS_MoveArgToStringArray( ArgList_t ***\ *args*, **int** *argnum* **);** |
+| | |
+| | *sa* **= GAUSS_MoveArgToStringArray(** *args, argnum* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
+| | |
+| | *argnum* number of argument in the argument list. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *sa* pointer to a string array descriptor. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveArgToStringArray** creates a **StringArray_t**, *sa*, and moves a string array contained in *args* into it. *sa* belongs to you. Free it with **GAUSS_FreeStringArray**. |
+| | |
+| | **GAUSS_MoveArgToStringArray** clears the *argnum* argument descriptor after moving the string array indicated by it. However, it does not change the number of arguments in *args*. Therefore, you can overwrite the *argnum* argument of *args* by copying or moving another argument into it. |
+| | |
+| | Arguments are numbered starting with **1**. |
+| | |
+| | If you want to retain the string array in the **ArgList_t**, use **GAUSS_CopyArgToStringArray** instead. However, **GAUSS_MoveArgToStringArray** saves time and memory space. |
+| | |
+| | If **GAUSS_MoveArgToStringArray** fails, *sa* will be NULL. Use **GAUSS_GetError** to get the number of the error. |
+| | |
+| | **GAUSS_MoveArgToStringArray** may fail with any of the following errors: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **71** Type mismatch. |
+| | |
+| | **94** Argument out of range. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | ProgramHandle_t *ph; |
+| | |
+| | ArgList_t *ret; |
+| | |
+| | StringArray_t *sa; |
+| | |
+| | if ( ( ph = GAUSS_CompileExpression( |
+| | |
+| | wh, |
+| | |
+| | "\\"one\\" $\| \\"two\\" $\| \\"three\\";", |
+| | |
+| | 1, |
+| | |
+| | 1 |
+| | |
+| | ))==NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( ret = GAUSS_ExecuteExpression( ph ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ( sa = GAUSS_MoveArgToStringArray( args, 1 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MoveArgToStringArray failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | GAUSS_FreeArgList( sa ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example assumes that *wh* is a pointer to a valid workspace handle. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyArgToStringArray, GAUSS_CallProc, GAUSS_CallProcFreeArgs, GAUSS_ExecuteExpression, GAUSS_FreeStringArray, GAUSS_GetArgType, GAUSS_GetError |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveArrayToArg
+---------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves an array contained in an **Array_t** to an **ArgList_t** and frees the **Array_t**. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_MoveArrayToArg( ArgList_t ***\ *args*, **Array_t ***\ *arr*, **int** *argnum* **);** |
+| | |
+| | *ret* = **GAUSS_MoveArrayToArg(** *args, arr, argnum* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
+| | |
+| | *arr* pointer to an array descriptor. |
+| | |
+| | *argnum* number of argument. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **494** Invalid argument number. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveArrayToArg** moves the array contained in *arr* into *args* and frees *arr*. |
+| | |
+| | To add an argument to the end of an argument list or to an empty argument list, set *argnum* to 0. To replace an argument, set *argnum* to the number of the argument you want to replace. It will overwrite that argument’s information and free its data. To insert an argument, call **GAUSS_InsertArg** and then set *argnum* to the number of the inserted argument. Arguments are numbered starting with 1. |
+| | |
+| | The array will be freed when you call **GAUSS_CallProcFreeArgs** or **GAUSS_FreeArgList** later. |
+| | |
+| | If you want to retain *arr*, use **GAUSS_CopyArrayToArg** instead. However, **GAUSS_MoveArrayToArg** saves time and memory space. |
+| | |
+| | Call **GAUSS_MoveArrayToArg** with an **Array_t** returned from **GAUSS_Array**, **GAUSS_ComplexArray**, or **GAUSS_GetArray**. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyArrayToArg, GAUSS_Array, GAUSS_ComplexArray GAUSS_CreateArgList, GAUSS_FreeArgList, GAUSS_InsertArg, GAUSS_CallProc, GAUSS_CallProcFreeArgs |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveArrayToGlobal
+------------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves an array contained in an **Array_t** into a **GAUSS** workspace and frees the **Array_t**. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_MoveArrayToGlobal( WorkspaceHandle_t ***\ *wh*\ **, Array_t ***\ *arr*, **char ***\ *name* ); |
+| | |
+| | *ret* = **GAUSS_MoveArrayToGlobal(** *wh, arr, name* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *arr* pointer to an array descriptor. |
+| | |
+| | *name* pointer to name of array. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **26** Too many symbols. |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **471** Null pointer. |
+| | |
+| | **481** **GAUSS** assignment failed. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveArrayToGlobal** moves the matrix contained in *arr* into a **GAUSS** workspace and frees *arr*. **GAUSS** takes ownership of the matrix and frees it when necessary. |
+| | |
+| | If you want to retain *arr*, use **GAUSS_CopyArrayToGlobal** instead. However, **GAUSS_MoveArrayToGlobal** saves time and memory space. |
+| | |
+| | Call **GAUSS_MoveArrayToGlobal** with an **Array_t** returned from one of the following functions: |
+| | |
+| | GAUSS_ComplexArray |
+| | |
+| | GAUSS_ComplexArrayAlias |
+| | |
+| | GAUSS_GetArray |
+| | |
+| | GAUSS_Array |
+| | |
+| | GAUSS_ArrayAlias |
+| | |
+| | Input a **WorkspaceHandle_t** returned from **GAUSS_CreateWorkspace**. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | Array_t *arr; |
+| | |
+| | int ret; |
+| | |
+| | double orders[3] = { 2.0, 2.0, 3.0 }; |
+| | |
+| | double ad[2][2][3] = { |
+| | |
+| | { { 3.0, 4.0, 2.0 }, { 7.0, 9.0, 5.0 } } |
+| | |
+| | { { 6.0, 9.0, 3.0 }, { 8.0, 5.0, 1.0 } } |
+| | |
+| | }; |
+| | |
+| | arr = GAUSS_Array( 3, orders, ad ); |
+| | |
+| | if ( ret = GAUSS_MoveArrayToGlobal( wh, arr, "a" ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "MoveArrayToGlobal failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | The above example moves the array **ad** into the **GAUSS** workspace indicated by *wh*. It assumes that *wh* is a pointer to a valid workspace handle. It frees *arr*. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyArrayToGlobal, GAUSS_Array, GAUSS_ComplexArray, GAUSS_AssignFreeableArray, GAUSS_GetArray |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveMatrixToArg
+----------------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves a matrix contained in a **Matrix_t** to an **ArgList_t** and frees the **Matrix_t**. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_MoveMatrixToArg( ArgList_t ***\ *args*, **Matrix_t ***\ *mat*, **int** *argnum* **);** |
+| | |
+| | *ret* = **GAUSS_MoveMatrixToArg(** *args, mat, argnum* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
+| | |
+| | *mat* pointer to a matrix descriptor. |
+| | |
+| | *argnum* number of argument. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **494** Invalid argument number. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveMatrixToArg** moves the matrix contained in *mat* into *args* and frees *mat*. |
+| | |
+| | To add an argument to the end of an argument list or to an empty argument list, set *argnum* to 0. To replace an argument, set *argnum* to the number of the argument you want to replace. It will overwrite that argument’s information and free its data. To insert an argument, call **GAUSS_InsertArg** and then set **argnum** to the number of the inserted argument. Arguments are numbered starting with 1. |
+| | |
+| | The matrix will be freed when you call **GAUSS_CallProcFreeArgs** or **GAUSS_FreeArgList** later. |
+| | |
+| | If you want to retain *mat*, use **GAUSS_CopyMatrixToArg** instead. However, **GAUSS_MoveMatrixToArg** saves time and memory space. |
+| | |
+| | Call **GAUSS_MoveMatrixToArg** with a **Matrix_t** returned from **GAUSS_Matrix**, **GAUSS_ComplexMatrix**, or **GAUSS_GetMatrix**. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyMatrixToArg, GAUSS_Matrix, GAUSS_ComplexMatrix GAUSS_CreateArgList, GAUSS_FreeArgList, GAUSS_InsertArg, GAUSS_CallProc, GAUSS_CallProcFreeArgs |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveMatrixToGlobal
+-------------------------
+
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves a matrix contained in a **Matrix_t** into a **GAUSS** workspace and frees the **Matrix_t**. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_MoveMatrixToGlobal( WorkspaceHandle_t ***\ *wh*, **Matrix_t ***\ *mat*, **char** *****\ *name* **);** |
+| | |
+| | *ret* = **GAUSS_MoveMatrixToGlobal(** *wh, mat, name* **);** |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *mat* pointer to a matrix descriptor. |
+| | |
+| | *name* name of matrix. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **26** Too many symbols. |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **481** **GAUSS** assignment failed. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveMatrixToGlobal** moves the matrix contained in *mat* into a **GAUSS** workspace and frees *mat*. **GAUSS** takes ownership of the matrix and frees it when necessary. |
+| | |
+| | If you want to retain *mat*, use **GAUSS_CopyMatrixToGlobal** instead. However, **GAUSS_MoveMatrixToGlobal** saves time and memory space. |
+| | |
+| | Call **GAUSS_MoveMatrixToGlobal** with a **Matrix_t** returned from **GAUSS_Matrix**, **GAUSS_ComplexMatrix**, or **GAUSS_GetMatrix**. |
+| | |
+| | Input a **WorkspaceHandle_t** returned from **GAUSS_CreateWorkspace**. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyMatrixToGlobal, GAUSS_Matrix, GAUSS_ComplexMatrix, GAUSS_AssignFreeableMatrix, GAUSS_GetMatrix, GAUSS_PutDouble |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveStringArrayToArg
+---------------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves a string array contained in a **StringArray_t** to an **ArgList_t** and frees the **StringArray_t**. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_MoveStringArrayToArg( ArgList_t ***\ *args*, **StringArray_t ***\ *sa*, **int** *argnum* **);** |
+| | |
+| | *ret* = **GAUSS_MoveStringArrayToArg(** *args, sa, argnum* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
+| | |
+| | *sa* pointer to a string array descriptor. |
+| | |
+| | *argnum* number of argument. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **494** Invalid argument number. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveStringArrayToArg** moves the string array contained in *sa* into *args* and frees *sa*. |
+| | |
+| | To add an argument to the end of an argument list or to an empty argument list, set *argnum* to 0. To replace an argument, set *argnum* to the number of the argument you want to replace. It will overwrite that argument’s information and free its data. To insert an argument, call **GAUSS_InsertArg** and then set *argnum* to the number of the inserted argument. Arguments are numbered starting with 1. |
+| | |
+| | The string array will be freed when you call **GAUSS_CallProcFreeArgs** or **GAUSS_FreeArgList** later. |
+| | |
+| | If you want to retain *sa*, use **GAUSS_CopyStringArrayToArg** instead. However, **GAUSS_MoveStringArrayToArg** saves time and memory space. |
+| | |
+| | Create a **StringArray_t** with **GAUSS_StringArray** or **GAUSS_StringArrayL**, or use a **StringArray_t** returned from **GAUSS_GetStringArray**. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyStringArrayToArg, GAUSS_StringArray, GAUSS_StringArrayL, GAUSS_CreateArgList, GAUSS_FreeArgList, GAUSS_InsertArg, GAUSS_CallProc, GAUSS_CallProcFreeArgs |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveStringArrayToGlobal
+------------------------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves a string array contained in a **StringArray_t** into a **GAUSS** workspace and frees the **StringArray_t.** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_MoveStringArrayToGlobal( WorkspaceHandle_t ***\ *wh*, **StringArray_t ***\ *sa*, **char** *****\ *name* **);** |
+| | |
+| | *ret* = **GAUSS_MoveStringArrayToGlobal(** *wh, sa, name* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *sa* pointer to string array descriptor. |
+| | |
+| | *name* pointer to name of string array. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **26** Too many symbols. |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **481** **GAUSS** assignment failed. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveStringArrayToGlobal** moves the string array contained in *sa* into a **GAUSS** workspace and frees *sa*. **GAUSS** takes ownership of the string array and frees it when necessary. |
+| | |
+| | If you want to retain *sa*, use **GAUSS_CopyStringArrayToGlobal** instead. However, **GAUSS_MoveStringArrayToGlobal** saves time and memory space. |
+| | |
+| | Create a StringArray_t with **GAUSS_StringArray** or **GAUSS_StringArrayL**, and call **GAUSS_MoveStringArrayToGlobal** with a **WorkspaceHandle_t** returned from **GAUSS_CreateWorkspace**. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyStringArrayToGlobal, GAUSS_StringArray, GAUSS_StringArrayL, GAUSS_GetStringArray |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveStringToArg
+----------------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves a string contained in a **String_t** to an **ArgList_t** and frees the **String_t**. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_MoveStringToArg( ArgList_t ***\ *args*, **String_t ***\ *str*, **int** *argnum* **);** |
+| | |
+| | *ret* **= GAUSS_MoveStringToArg(** *args, str, argnum* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
+| | |
+| | *str* pointer to a string descriptor. |
+| | |
+| | *argnum* number of argument. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **494** Invalid argument number. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveStringToArg** moves the string contained in *str* into *args* and free\ **s** *str.* |
+| | |
+| | To add an argument to the end of an argument list or to an empty argument list, set **argnum** to 0. To replace an argument, set *argnum* to the number of the argument you want to replace. It will overwrite that argument’s information and free its data. To insert an argument, call **GAUSS_InsertArg** and then set *argnum* to the number of the inserted argument. Arguments are numbered starting with 1. |
+| | |
+| | The string will be freed when you call **GAUSS_CallProcFreeArgs** or **GAUSS_FreeArgList** later. |
+| | |
+| | If you want to retain *str*, use **GAUSS_CopyStringToArg** instead. However, **GAUSS_MoveStringToArg** saves time and memory space. |
+| | |
+| | Call **GAUSS_MoveStringToArg** with a **String_t** returned from **GAUSS_String**, **GAUSS_StringL**, or **GAUSS_GetString**. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyStringToArg, GAUSS_String, GAUSS_StringL, GAUSS_CreateArgList, GAUSS_FreeArgList, GAUSS_InsertArg, GAUSS_CallProc, GAUSS_CallProcFreeArgs |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MoveStringToGlobal
+-------------------------
+
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Moves a string contained in a **String_t** into a **GAUSS** workspace and frees the **String_t**. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_MoveStringToGlobal( WorkspaceHandle_t ***\ *wh*, **String_t ***\ *str*, **char ***\ *name* **);** |
+| | |
+| | *ret* = **GAUSS_MoveStringToGlobal(** *wh, str, name* **);** |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *str* pointer to string descriptor. |
+| | |
+| | *name* pointer to name of string. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **26** Too many symbols. |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **481** **GAUSS** assignment failed. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MoveStringToGlobal** moves the string contained in *str* into a **GAUSS** workspace and frees *str*. **GAUSS** takes ownership of the string and frees it when necessary. |
+| | |
+| | If you want to retain *str,* use **GAUSS_CopyStringToGlobal** instead. However, **GAUSS_MoveStringToGlobal** saves time and memory space. |
+| | |
+| | Call **GAUSS_MoveStringToGlobal** with a **String_t** returned from **GAUSS_String**, **GAUSS_StringL**, or **GAUSS_GetString**. |
+| | |
+| | Input a **WorkspaceHandle_t** returned from **GAUSS_CreateWorkspace**. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyStringToGlobal, GAUSS_String, GAUSS_StringL, GAUSS_GetString |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_ProgramErrorOutput
+-------------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Passes a string to the program error callback function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_ProgramErrorOutput( char ***\ *str* **);** |
+| | |
+| | **GAUSS_ProgramErrorOutput(** *str* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *str* pointer to a string. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_ProgramErrorOutput** passes a string to the program error callback function hooked with **GAUSS_HookProgramErrorOutput**. |
+| | |
+| | The callbacks are thread-specific. **GAUSS_ProgramErrorOutput** will call the callback function that was hooked in that particular thread. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | char strbuff[50]; |
+| | |
+| | strcpy( strbuff, "Test 1 error output:" ); |
+| | |
+| | GAUSS_ProgramErrorOutput( strbuff ); |
+| | |
+| | This example assumes that a program error output callback function has already been hooked with **GAUSS_HookProgramErrorOutput** in this thread. This call to **GAUSS_ProgramErrorOutput** will pass *strbuff* to that callback function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_HookProgramErrorOutput, GAUSS_ProgramOutput |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_ProgramInputString
+-------------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Calls for user input using the program input string function. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_ProgramInputString( char ***\ *buff*, **int** *bufflen* **);** |
+| | |
+| | *len* **= GAUSS_ProgramInputString(** *buff, bufflen* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *buff* pointer to buffer in which to place input. |
+| | |
+| | *bufflen* length of buffer. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_ProgramInputString** calls the program input string function hooked with **GAUSS_HookProgramInputString**. It passes the pointer to a character buffer in which the input is to be placed to the input string function, as well as the length of the buffer. **GAUSS_ProgramInputString** returns the length of the string inputted into the buffer. |
+| | |
+| | The callbacks are thread-specific. **GAUSS_ProgramInputString** will call the input string function that was hooked in that particular thread. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | char strbuff[1024]; |
+| | |
+| | int len; |
+| | |
+| | printf("Enter name of GAUSS program file to run:\n"); |
+| | |
+| | len = GAUSS_ProgramInputString( strbuff, 1024 ); |
+| | |
+| | if ( ( ph = GAUSS_CompileFile( wh, strbuff, 0, 0 ) ) == NULL ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Compile failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, GAUSS_GetError() ) ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | if ( ret = GAUSS_Execute( ph ) ) |
+| | |
+| | { |
+| | |
+| | char buff[100]; |
+| | |
+| | printf( "Execute failed: %s\n", |
+| | |
+| | GAUSS_ErrorText( buff, ret ) ); |
+| | |
+| | GAUSS_FreeProgram( ph ); |
+| | |
+| | return -1; |
+| | |
+| | } |
+| | |
+| | This example assumes that a program input string function has already been hooked with **GAUSS_HookProgramInputString** in this thread. This call to **GAUSS_ProgramInputString** will get user input using that input string function and place it in *strbuff*. This example assumes that the input string will contain the name of a **GAUSS** program file, which it then attempts to run in **GAUSS**. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_HookProgramInputString |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_ProgramOutput
+--------------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Passes a string to the program output callback function. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_ProgramOutput( char ***\ *str* **);** |
+| | |
+| | **GAUSS_ProgramOutput(** *str* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *str* pointer to a string. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_ProgramOutput** passes a string to the program output callback function hooked with **GAUSS_HookProgramOutput**. |
+| | |
+| | The callbacks are thread-specific. **GAUSS_ProgramOutput** will call the callback function that was hooked in that particular thread. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **EXAMPLE** | char strbuff[50]; |
+| | |
+| | strcpy( strbuff, "Test 1 output:" ); |
+| | |
+| | GAUSS_ProgramOutput( strbuff ); |
+| | |
+| | This example assumes that a program output callback function has already been hooked with **GAUSS_HookProgramOutput** in this thread. This call to **GAUSS_ProgramOutput** will pass *strbuff* to that callback function. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_HookProgramOutput, GAUSS_ProgramErrorOutput |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_PutDouble
+----------------
+
++--------------+-----------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Puts a **double** into a **GAUSS** workspace. |
++--------------+-----------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_PutDouble( WorkspaceHandle_t ***\ *wh*, **double** *d*, **char** *****\ *name* **);** |
+| | |
+| | *ret* = **GAUSS_PutDouble(** *wh, d, name* **);** |
++--------------+-----------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *d* data. |
+| | |
+| | *name* pointer to name of symbol. |
++--------------+-----------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **26** Too manysymbols. |
+| | |
+| | **91** Symbol too long. |
+| | |
+| | **481** **GAUSS** assignment failed. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+-----------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_PutDouble** puts a double into a **GAUSS** workspace. |
+| | |
+| | Call **GAUSS_PutDouble** with a **WorkspaceHandle_t** returned from **GAUSS_CreateWorkspace**. |
++--------------+-----------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetDouble, GAUSS_CopyMatrixToGlobal, GAUSS_MoveMatrixToGlobal |
++--------------+-----------------------------------------------------------------------------------------------------+
+
+GAUSS_PutDoubleInArg
+---------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Puts a double into an **ArgList_t.** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_PutDoubleInArg( ArgList_t ***\ *args*, **double** *d*, **int** *argnum* **);** |
+| | |
+| | *ret* = **GAUSS_PutDoubleInArg(** *args, d, argnum* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *args* pointer to an argument list structure. |
+| | |
+| | *d* data. |
+| | |
+| | *argnum* number of argument. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **494** Invalid argument number. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_PutDouble** puts the double *d* into *args*. |
+| | |
+| | To add an argument to the end of an argument list or to an empty argument list, set *argnum* to 0. To replace an argument, set *argnum* to the number of the argument you want to replace. It will overwrite that argument’s information and free its data. To insert an argument, call **GAUSS_InsertArg** and then set *argnum* to the number of the inserted argument. Arguments are numbered starting with 1. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CopyMatrixToArg, GAUSS_MoveMatrixToArg, GAUSS_CreateArgList, GAUSS_FreeArgList, GAUSS_InsertArg, GAUSS_CallProc, GAUSS_CallProcFreeArgs |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SaveProgram
+------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Saves a compiled program as a file. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_SaveProgram( ProgramHandle_t** *****\ *ph*, **char** *****\ *fn* **);** |
+| | |
+| | *ret* = **GAUSS_SaveProgram(** *ph, fn* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *ph* pointer to a program handle. |
+| | |
+| | *fn* pointer to name of file. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success code, 0 if successful, otherwise: |
+| | |
+| | **10** Can’t open output file. |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **132** Can’t write, disk probably full. |
+| | |
+| | **495** Workspace inactive or corrupt. |
+| | |
+| | **496** Program inactive or corrupt. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_SaveProgram** saves a compiled program given by a program handle into a file. It saves all of the workspace information, which is contained in the program handle. The file will have the name given by *fn*. Load the program with **GAUSS_LoadCompiledFile**. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CompileString, GAUSS_CompileFile, GAUSS_CompileStringAsFile, GAUSS_LoadCompiledFile, GAUSS_FreeProgram |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SaveWorkspace
+--------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Saves workspace information in a file. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_SaveWorkspace( WorkspaceHandle_t ***\ *wh*, **char** *****\ *fn* **);** |
+| | |
+| | *ret* = **GAUSS_SaveWorkspace(** *wh, fn* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *fn* pointer to name of file. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success code, 0 if successful, otherwise: |
+| | |
+| | **10** Can’t open output file. |
+| | |
+| | **30** Insufficient memory. |
+| | |
+| | **132** Can’t write, disk probably full. |
+| | |
+| | **495** Workspace inactive or corrupt. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_SaveWorkspace** saves workspace information contained in a workspace handle into a file. The file will have the name given by *fn*. Load the workspace information with **GAUSS_LoadWorkspace**. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CreateWorkspace, GAUSS_LoadWorkspace, GAUSS_FreeWorkspace |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SetError
+---------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Sets the stored error number and returns the previous error number. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_SetError( int** *newerrnum* **);** |
+| | |
+| | *olderrnum* = **GAUSS_SetError(** *newerrnum* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *newerrnum* new error number. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *olderrnum* previous error number. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The **GAUSS Engine** stores the error number of the most recently encountered error in a system variable. If a **GAUSS Engine** command fails, it automatically resets this variable with the number of the error. However, the command does not clear the variable if it succeeds. |
+| | |
+| | Use **GAUSS_SetError** to manually reset the variable. It returns the error number that was previously stored in the variable. |
+| | |
+| | The system variable is global to the current thread. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetError, GAUSS_ErrorText |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SetGlobalInterrupt
+-------------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Sets a global interrupt request. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_SetGlobalInterrupt(** void **);** |
+| | |
+| | GAUSS_SetGlobalInterrupt(); GAUSS_SetHome |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | This affects all threads in all programs in all workspaces, including child threads spawned by a **GAUSS** program. This interrupt must be explicitly cleared using **GAUSS_ClearGlobalInterrupt**. |
+| | |
+| | Interrupts are checked after assignments and in certain I/O statements, not every instruction. The **GAUSS** language command **CheckInterrupt** can be used in a **GAUSS** program to check for interrupts and terminate if one is pending. |
+| | |
+| | CheckInterrupt; |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetProgramInterrupt, GAUSS_SetWorkspaceInterrupt, GAUSS_ClearGlobalInterrupt |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SetHome
+--------------
+
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Sets the home path for the **GAUSS Engine**. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_SetHome( char ***\ *path* **);** |
+| | |
+| | *ret* = **GAUSS_SetHome(** *path* **);** |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *path* pointer to path to be set. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success code, 0 if successful, otherwise 486 if character argument too long. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_SetHome** specifies the home directory used to locate the Run-Time Library, source files, library files, etc. in a normal **GAUSS Engine** installation. It overrides any environment variable. Call **GAUSS_SetHome** before calling **GAUSS_Initialize**. |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetHomeVar, GAUSS_GetHome, GAUSS_GetHomeVar, GAUSS_Initialize |
+| | |
+| | GAUSS_SetInterrupt |
++--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SetHomeVar
+----------------
+
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Sets the name of the home environment variable for the **GAUSS Engine**. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_SetHomeVar( char ***\ *newname* **);** |
+| | |
+| | *ret* = **GAUSS_SetHomeVar(** *newname* **);** |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *newname* pointer to new name to be set. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success code, 0 if successful, otherwise 486 if character argument too long. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The default value is **MTENGHOME26**. Use the C library function *getenv* to get the value of the environment variable. |
+| | |
+| | It is better to use **GAUSS_SetHome** which sets the home directory, overriding the environment variable. Call **GAUSS_SetHomeVar** or **GAUSS_SetHome** before calling **GAUSS_Initialize**. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetHome, GAUSS_GetHomeVar, GAUSS_GetHome, GAUSS_Initialize |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SetInterrupt
+-------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Sets an interrupt request on a thread. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_SetInterrupt( pthread_t** *tid* **);** |
+| | |
+| | *ret* **= GAUSS_SetInterrupt(** *tid* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *tid* thread id of thread to interrupt. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success code, ≥ 0 if successful. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | This affects only the thread specified. If the **GAUSS** program spawns threads the main program will wait until all the child threads have finished. Use **GAUSS_SetProgramInterrupt()** or **GAUSS_SetWorkspaceInterrupt()** instead. |
+| | |
+| | **In general, this command should be considered obsolete.** |
+| | |
+| | If *ret* is 0, the interrupt request is successful. The program or compile may not stop immediately. If the program is executing an intrinsic function on a large matrix, such an an inverse or matrix multiply, the operation will continue until it is finished and the program will stop at the next instruction. |
+| | |
+| | If *ret* is greater than 0, the interrupt is already requested and *ret* is the UTC time of the original request. |
+| | |
+| | If *ret* is -1, the system is out of memory. |
+| | |
+| | If *ret* is -2, the Engine is shutdown and the interrupt request has been ignored. |
+| | |
+| | Interrupts are checked during certainI/Ostatements, not every instruction. The **GAUSS** language command *CheckInterrupt* can be used in a **GAUSS** program to check for interrupts and terminate if one is pending. |
+| | |
+| | CheckInterrupt; |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetGlobalInterrupt, GAUSS_SetProgramInterrupt, GAUSS_SetWorkspaceInterrupt, GAUSS_CheckInterrupt, GAUSS_ClearInterrupt |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SetProgramInterrupt
+-----------------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Sets an interrupt request for all programs using a specified program handle. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_SetProgramInterrupt( ProgramHandle_t ***\ *ph* **);** |
+| | |
+| | **GAUSS_SetProgramInterrupt(** *ph* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *ph* pointer to a program handle. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | This affects all threads in all programs in the specified program handle, including child threads spawned by a **GAUSS** program. This interrupt must be explicitly cleared using **GAUSS_ClearProgramInterrupt**. |
+| | |
+| | Interrupts are checked after assignments and in certain I/O statements, not every instruction. The **GAUSS** language command **CheckInterrupt** can be used in a **GAUSS** program to check for interrupts and terminate if one is pending. |
+| | |
+| | CheckInterrupt; |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetGlobalInterrupt, GAUSS_SetWorkspaceInterrupt, GAUSS_ClearProgramInterrupt |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SetWorkspaceInterrupt
+----------------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Sets an interrupt request for all programs using a specified workspace handle. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **void GAUSS_SetWorkspaceInterrupt( WorkspaceHandle_t ***\ *wh* **);** |
+| | |
+| | **GAUSS_SetWorkspaceInterrupt(** *wh* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | This affects all threads in all programs using the specified workspace handle, including child threads spawned by a **GAUSS** program. This interrupt must be explicitly cleared using **GAUSS_ClearWorkspaceInterrupt**. |
+| | |
+| | Interrupts are checked after assignments and in certain I/O statements, not every instruction. The **GAUSS** language command **CheckInterrupt** can be used in a **GAUSS** program to check for interrupts and terminate if one is pending. |
+| | |
+| | CheckInterrupt; |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_SetGlobalInterrupt, GAUSS_SetProgramInterrupt, GAUSS_ClearWorkspaceInterrupt |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SetLogFile
+-----------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Sets the file for logged errors. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **int GAUSS_SetLogFile( char ***\ *logfn*, **char** *****\ *mode* **);** |
+| | |
+| | *ret* = **GAUSS_SetLogFile(** *logfn, mode* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *logfn* name of log file. |
+| | |
+| | *mode* **{w}**\ to overwrite the contents of the file. |
+| | |
+| | **{a}**\ to append to the contents of the file. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *ret* success flag, 0 if successful, otherwise: |
+| | |
+| | **484** Cannot open log file. |
+| | |
+| | **485** Cannot write to log file. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The **GAUSS Engine** logs certain system level errors in 2 places: a file and an open file pointer. The default file is **/tmp/mteng.###.log** where **###** is the process ID number. The default file pointer is *stderr*. |
+| | |
+| | **GAUSS_SetLogFile** allows you to set the file that the errors will be logged in. You can turn off the error logging to file by inputting a NULL pointer for *logfn*. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetLogFile, GAUSS_SetLogStream, GAUSS_GetLogStream |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SetLogStream
+-------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Sets the file pointer for logged errors. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *logfp* file pointer of an open file. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | **void GAUSS_SetLogStream( FILE ***\ *logfp* **);** |
+| | |
+| | **GAUSS_SetLogStream(** *logfp* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | The **GAUSS Engine** logs certain system level errors in 2 places :a file and an open file pointer. The default file is **/tmp/mteng.###.log** where **###** is the process ID number. The default file pointer is *stderr*. |
+| | |
+| | **GAUSS_SetLogStream** allows you to set the file pointer that the errors will be logged to. You can turn off the error logging to file pointer by inputting a NULL pointer for *logfp*. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetLogStream, GAUSS_SetLogFile, GAUSS_GetLogFile |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_SetWorkspaceName
+-----------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Sets the name of a **GAUSS** workspace. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **char *GAUSS_SetWorkspaceName( WorkspaceHandle_t ***\ *wh*, **char** *****\ *name* **);** |
+| | |
+| | *newname* = **GAUSS_SetWorkspaceName(** *wh, name* **);** |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *wh* pointer to a workspace handle. |
+| | |
+| | *name* pointer to the new workspace name. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *newname* pointer to new name, should be considered read only. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_SetWorkspaceName** sets the name of a **GAUSS** workspace indicated by a **WorkspaceHandle_t**. The maximum length is 63 characters. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetWorkspaceName, GAUSS_CreateWorkspace |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_Shutdown
+---------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Shuts down the **GAUSS Engine**, preparatory to ending the application. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | void GAUSS_Shutdown( void ); |
+| | |
+| | GAUSS_Shutdown(); |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_Shutdown** cleans up any temporary files generated by the **GAUSS Engine.** It also closes any dynamic libraries used by the foreign language interface. You should call it once at the close of your application after freeing any open pointers. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_Initialize |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_String
+-------------
+
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Creates a **String_t** and copies the string data. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **String_t *GAUSS_String( char ***\ *str* **);** |
+| | |
+| | *strdesc* = **GAUSS_String(** *str* **);** |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *str* pointer to string. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *strdesc* pointer to a string descriptor. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_String malloc**\ ’s a **String_t** and fills it in with your input information. It makes a copy of the string and sets the *stdata* member of the **String_t** to point to the copy. To create a **String_t** for your string without making a copy of it, use **GAUSS_StringAlias**. |
+| | |
+| | This function uses *strlen* to determine the length of the string. Since *strlen* only computes the length of a string to the first null byte, your string may not contain embedded 0’s. To create a **String_t** with a string that contains embedded 0’s, use **GAUSS_StringL**. |
+| | |
+| | If *strdesc* is NULL, there was insufficient memory to **malloc** space for the string and its descriptor. |
+| | |
+| | Use this function to create a string descriptor that you can use in the following |
+| | |
+| | functions: |
+| | |
+| | GAUSS_CopyStringToArg |
+| | |
+| | GAUSS_CopyStringToGlobal |
+| | |
+| | GAUSS_MoveStringToArg |
+| | |
+| | GAUSS_MoveStringToGlobal |
+| | |
+| | Free the **String_t** with **GAUSS_FreeString**. |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_StringL, GAUSS_StringAlias, GAUSS_StringAliasL, GAUSS_FreeString |
++--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_StringAlias
+------------------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Creates a **String_t**. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **String_t *GAUSS_StringAlias( char ***\ *str* **);** |
+| | |
+| | *strdesc* = **GAUSS_StringAlias(** *str* **);** |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *str* pointer to string. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *strdesc* pointer to a string descriptor. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_StringAlias** is similar to **GAUSS_String**; however, it sets the *stdata* member of the **String_t** to point to *str* instead of making a copy of the string. This function uses *strlen* to determine the length of the string. Since *strlen* only computes the length of a string to the first null byte, your string may not contain embedded 0’s. To create a **String_t** with a string that contains embedded 0’s, use **GAUSS_StringAliasL**. |
+| | |
+| | If *strdesc* is NULL, there was insufficient memory to **malloc** space for the string descriptor. |
+| | |
+| | Use this function to create a string descriptor that you can use in **GAUSS_CopyStringToArg** and **GAUSS_CopyStringToGlobal**. |
+| | |
+| | Free the **String_t** with **GAUSS_FreeString**. It will not free the string data. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_String, GAUSS_StringAliasL, GAUSS_StringL, GAUSS_FreeString |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_StringAliasL
+-------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Creates a **String_t** with string of user-specified length. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **String_t *GAUSS_StringAliasL( char ***\ *str*, **int** *len* **);** |
+| | |
+| | *strdesc* = **GAUSS_StringAliasL(** *str, len* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *str* pointer to string. |
+| | |
+| | *len* length of string, including null terminator. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *strdesc* pointer to a string descriptor. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_StringAliasL** is similar to **GAUSS_StringL**; however, it sets the *stdata* member of the **String_t** to point to *str* instead of making a copy of the string. |
+| | |
+| | This function takes the length of the string from the *len* argument rather than calling *strlen,* which computes the length of a string only to the first null byte. This allows your string to contain embedded 0’s. If your string does not contain embedded 0’s, you can use **GAUSS_StringAlias** to create your **String_t**. |
+| | |
+| | If *strdesc* is NULL, there was insufficient memory to **malloc** space for the string descriptor. |
+| | |
+| | Use this function to create a string descriptor that you can use in **GAUSS_CopyStringToArg** and **GAUSS_CopyStringToGlobal**. |
+| | |
+| | You can free the **String_t** with **GAUSS_FreeString**. It will not free the string data. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_String, GAUSS_StringAlias, GAUSS_StringL, GAUSS_FreeString |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_StringArray
+------------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Creates a **StringArray_t** and copies the string array data. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **StringArray_t *GAUSS_StringArray(size_t** *rows*, **size_t** *cols\ *\ **,** **char ****\ *strs* **);** |
+| | |
+| | *sa* = **GAUSS_StringArray(** *rows, cols, strs* **);** |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *rows* number of rows. |
+| | |
+| | *cols* number of columns. |
+| | |
+| | *strs* pointer to an array of character pointers containing the strings of the array. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *sa* pointer to a string array descriptor. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_StringArray malloc**\ ’s a **StringArray_t** and fills it in with your input information. It makes a copy of all the strings in the array and creates an array of *rows*cols* **StringElement_t’**\ s. The table member of the **StringArray_t** is set to the address of the array of **StringElement_t**\ ’s. |
+| | |
+| | This function uses *strlen* to determine the lengths of the strings. Since *strlen* only computes the length of a string to the first null byte, your strings may not contain embedded 0’s. To create a **StringArray_t** with strings that contain embedded 0’s, use **GAUSS_StringArrayL**. |
+| | |
+| | If *sa* is NULL, there was insufficient memory to **malloc** space for the string array and its descriptor. |
+| | |
+| | Use this function to create a string array descriptor that you can use in the following functions: |
+| | |
+| | GAUSS_CopyStringArrayToArg |
+| | |
+| | GAUSS_CopyStringArrayToGlobal |
+| | |
+| | GAUSS_MoveStringArrayToArg |
+| | |
+| | GAUSS_MoveStringArrayToGlobal |
+| | |
+| | Free the **StringArray_t** with **GAUSS_FreeStringArray**. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_StringArrayL, GAUSS_FreeStringArray |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_StringArrayL
+-------------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Creates a StringArray_t with strings of user-specified length and copies the string array data. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **StringArray_t *GAUSS_StringArrayL( size_t** *rows*\ **,** **size_t** *cols*, **char ****\ *strs\ *\ **,** **size_t ***\ *lens* **);** |
+| | |
+| | *sa* = **GAUSS_StringArrayL(** *rows, cols, strs, lens* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *rows* number of rows. |
+| | |
+| | *cols* number of columns. |
+| | |
+| | *strs* pointer to an array of character pointers containing the strings of the array. |
+| | |
+| | *lens* pointer to an array of **size_t**\ ’s containing the length of each string, including null terminator. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *sa* pointer to a string array descriptor. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_StringArrayL malloc**\ ’s a **StringArray_t** and fills it in with your input information. It makes a copy of all the strings in the array and creates an array of *rows*cols* **StringElement_t**\ ’s. The *table* member of the **StringArray_t** is set to the address of the array of **StringElement_t**\ ’s. |
+| | |
+| | This function takes the length of the strings from the *lens* argument rather than calling *strlen,* which computes the length of a string only to the first null byte. This allows your strings to contain embedded 0’s. If your strings do not contain embedded 0’s, you can use **GAUSS_StringArray** to create your **StringArray_t**. |
+| | |
+| | If *sa* is NULL, there was insufficient memory to **malloc** space for the string array and its descriptor. |
+| | |
+| | Use this function to create a string array descriptor that you can use in the following functions: |
+| | |
+| | GAUSS_CopyStringArrayToArg |
+| | |
+| | GAUSS_CopyStringArrayToGlobal |
+| | |
+| | GAUSS_MoveStringArrayToArg |
+| | |
+| | GAUSS_MoveStringArrayToGlobal |
+| | |
+| | You can free the **StringArray_t** with **GAUSS_FreeStringArray**. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_StringArray, GAUSS_FreeStringArray |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_StringL
+--------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Creates a **String_t** with string of user-specified length and copies the string data. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | **String_t *GAUSS_StringL(** **char ***\ *str*, **int** *len* **);** |
+| | |
+| | *strdesc* **= GAUSS_StringL(** *str, len* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *str* pointer to string. |
+| | |
+| | *len* length of string, including null terminator. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *strdesc* pointer to a string descriptor. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_StringL malloc**\ ’s a **String_t** and fills it in with your input information. It makes a copy of the string and sets the *sdata* member of the **String_t** to point to the copy. To create a **String_t** for your string without making a copy of it, use **GAUSS_StringAliasL**. |
+| | |
+| | This function takes the length of the string from the *len* argument rather than calling *strlen*, which computes the length of a string only to the first null byte. This allows your string to contain embedded 0’s. If your string does not contain embedded 0’s, you can use **GAUSS_String** to create your **String_t**. |
+| | |
+| | If **strdesc** is NULL, there was insufficient memory to **malloc** space for the string and its descriptor. |
+| | |
+| | Use this function to create a string descriptor that you can use in the following functions: |
+| | |
+| | GAUSS_CopyStringToArg |
+| | |
+| | GAUSS_CopyStringToGlobal |
+| | |
+| | GAUSS_MoveStringToArg |
+| | |
+| | GAUSS_MoveStringToGlobal |
+| | |
+| | Free the **String_t** with **GAUSS_FreeString**. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_String, GAUSS_StringAliasL, GAUSS_StringAlias, GAUSS_FreeString |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_TranslateDataloopFile
+----------------------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | Translates a dataloop file. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | int GAUSS_TranslateDataloopFile( char *transfile, char *\ *srcfile* ); |
+| | |
+| | *errs* = **GAUSS_TranslateDataloopFile(** *transfile, srcfile* **);** |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **INPUT** | *transfile* pointer to name of translated file. |
+| | |
+| | *srcfile* pointer to name of source file. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **OUTPUT** | *errs* number of errors. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_TranslateDataloopFile** translates a file that contains a dataloop, so it can be read by the compiler. After translating a file, you can compile it with **GAUSS_CompileFile** and then run it with **GAUSS_Execute**. |
+| | |
+| | If you want to see any errors that **GAUSS_TranslateDataloopFile** encounters, then you must call **GAUSS_HookProgramErrorOutput** before calling **GAUSS_TranslateDataloopFile**. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_CompileFile, GAUSS_Execute |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
diff --git a/docs/ge/command-line.rst b/docs/ge/command-line.rst
new file mode 100644
index 00000000..4555e989
--- /dev/null
+++ b/docs/ge/command-line.rst
@@ -0,0 +1,260 @@
+Using the Command Line Interface
+================================
+
+**ENGAUSS** is the command line version of **GAUSS**, which comes with the **GAUSS Engine**. The executable file, **engauss**, is located in the **GAUSS Engine** installation directory.
+
+The format for using **ENGAUSS** is:
+
+**engauss** *flag(s) program program...*
+
++-----------------+------------------------------------------------------------------------------------------------------------------------------------+
+| -b | Execute file in batch mode and then exit. You can execute multiple files by separating file names with spaces. |
++=================+====================================================================================================================================+
+| -l *logfile* | Set the name of batch mode log file when using the *-b* argument. The default is **wksp/gauss.log.###,** where **###** is the pid. |
++-----------------+------------------------------------------------------------------------------------------------------------------------------------+
+| -e *expression* | Executes a **GAUSS** expression. This command is not logged when **GAUSS** is in batch mode. |
++-----------------+------------------------------------------------------------------------------------------------------------------------------------+
+| -o | Suppresses the sign-on banner (output only). |
++-----------------+------------------------------------------------------------------------------------------------------------------------------------+
+| -T | Turns the dataloop translator on. |
++-----------------+------------------------------------------------------------------------------------------------------------------------------------+
+| -t | Turns the dataloop translator off. |
++-----------------+------------------------------------------------------------------------------------------------------------------------------------+
+
+Viewing Graphics
+---------------------
+
+**GAUSS** generates **.tkf** files for graphical output. The default output for graphics is **graphic.tkf**. Two functions are available to convert **.tkf** files to PostScript for printing and viewing with external viewers: the **tkf2ps** function will convert .\ **tkf** files to PostScript\ **(.ps)** files, and the **tkf2eps** function will convert .\ **tkf** files to encapsulated PostScript(**.eps**) files. For example, to convert the file **graphic.tkf** to a postscript file named **graphic.ps** use:
+
+ret = tkf2ps *(“filename.*\ **tkf**\ *”, “filename.*\ **ps**\ *”)*
+
+If the function is successful it returns **0**.
+
+Interactive Commands
+-------------------------
+
+quit
+~~~~~~~~~~~
+
+The **quit** command will exit **ENGAUSS**.
+
+The format for **quit** is:
+
+quit
+
+You can also use the **system** command to exit **ENGAUSS** from either the command line or a program (see **system** in the **GAUSS** Language Reference). The format for **system** is:
+
+system
+
+ed
+~~~~~~~~~
+
+The **ed** command will open an input file in an external text editor, see **ed** in the **GAUSS** Language Reference.
+
+The format for **ed** is:
+
+ed *filename*
+
+compile
+~~~~~~~~~~~~~~
+
+The **compile** command will compile a **GAUSS** program file to a compiled code file.
+
+The format for **compile** is:
+
+**compile** *source_file*
+
+**compile** *source_file output_file*
+
+If you do not specify an *output_file*, **GAUSS** will append a .\ **gcg** extension to your *source_file* to create an *output_file*. Unlike the **gc** compiler, the **compile** command will not automatically replace a **.gau** extension with a **.gcg** extension. It will append a **.gcg** extension to .\ **gau** files.
+
+run
+~~~~~~~~~~
+
+The **run** command will run a **GAUSS** program file or compiled code file.
+
+The format for **run**:
+
+**run** *filename*
+
+browse
+~~~~~~~~~~~~~
+
+The **browse** command allows you to search for specific symbols in a file and open the file in the default editor. You can use wildcards to extend search capabilities of the **browse** command.
+
+The format for **browse** is:
+
+browse *symbol*
+
+config
+~~~~~~~~~~~~~
+
+The **config** command gives you access to the configuration menu allowing you to change the way **GAUSS** runs and compiles files.
+
+The format for **config** is:
+
+config
+
+Run Menu
+^^^^^^^^^
+
++---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| Translator | Toggles on/off the translation of a file using **dataloop**. The translator is not necessary for **GAUSS** program files not using **dataloop**. |
++=================================+==================================================================================================================================================+
+| Line number tracking | Toggles on/off execution time line number tracking of the original file before translation. |
++---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| Translator line number tracking | Toggles on/off the execution time line number tracking. If the translator is on, the line numbers refer to the translated file. |
++---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+
+Compile Menu
+^^^^^^^^^^^^^
+
++---------------------+------------------------------------------------------------------------------------------+
+| Autoload | Toggles on/off the autoloader. |
++=====================+==========================================================================================+
+| GAUSS_Library | Toggles on/off the **GAUSS** library functions. |
++---------------------+------------------------------------------------------------------------------------------+
+| Autodelete | Toggles on/off autodelete. |
++---------------------+------------------------------------------------------------------------------------------+
+| User Library | Toggles on/off the user library functions. |
++---------------------+------------------------------------------------------------------------------------------+
+| Declare Warnings | Toggles on/off the **declare** warning messages during compiling. |
++---------------------+------------------------------------------------------------------------------------------+
+| Compiler Trace | |
++---------------------+------------------------------------------------------------------------------------------+
+| | **Off** Turns off the compiler trace function. |
++---------------------+------------------------------------------------------------------------------------------+
+| | **On** Turns on the compiler trace function. |
++---------------------+------------------------------------------------------------------------------------------+
+| | **Line** Traces compilation by line. |
++---------------------+------------------------------------------------------------------------------------------+
+| | **File** Creates a report of procedures and the local and global symbols they reference. |
++---------------------+------------------------------------------------------------------------------------------+
+
+Debugging
+--------------
+
+The **debug** command runs a program under the source level debugger.
+
+The format for **debug** is:
+
+debug *filename*
+
+General Functions
+^^^^^^^^^^^^^^^^^^
+
++-------------------+---------------------------------------------------------------+
+| ? | Displays a list of available commands. |
++===================+===============================================================+
+| q/Esc | Exits the debugger and returns to the **GAUSS** command line. |
++-------------------+---------------------------------------------------------------+
+| +/- | Enables/disables the last command repeat function. |
++-------------------+---------------------------------------------------------------+
+
+Listing Functions
+^^^^^^^^^^^^^^^^^^
+
++--------------------+------------------------------------------------------------------------------+
+| **l** *number* | Displays a specified number of lines of source code in the current file. |
++====================+==============================================================================+
+| lc | Displays source code in the current file starting with the current line. |
++--------------------+------------------------------------------------------------------------------+
+| **ll** *file line* | Displays source code in the named file starting with the specified line. |
++--------------------+------------------------------------------------------------------------------+
+| **ll** *file* | Displays source code in the named file starting with the first line. |
++--------------------+------------------------------------------------------------------------------+
+| **ll** *line* | Displays source code starting with the specified line. File does not change. |
++--------------------+------------------------------------------------------------------------------+
+| ll | Displays the next page of source code. |
++--------------------+------------------------------------------------------------------------------+
+
+Execution Functions
+^^^^^^^^^^^^^^^^^^^^
+
++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| s *number* | Executes the specified number of lines, stepping over procedures. |
++=================+==================================================================================+===============================================================================================+
+| i *number* | Executes the specified number of lines, stepping into procedures. |
++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| X *number* | Executes code from the beginning of the program to the specified line count, or until a breakpoint is hit. |
++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| G [[*args*]] | Executes from the current line to the end of the program, stopping at breakpoints. The optional arguments specify other stopping points. |
+| | |
+| | The syntax for each optional argument is: |
++-----------------+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
+| | *filename line cycle* | The debugger will stop every *cycle* times it reaches the specified *line* in the named file. |
++-----------------+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
+| | *filename line* | The debugger will stop when it reaches the specified *line* in the named file. |
++-----------------+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
+| | *filename , cycle* | The debugger will stop every *cycle* times it reaches any *line* in the current file. |
++-----------------+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
+| | *line cycle* | The debugger will stop every *cycle* times it reaches the specified line in the current file. |
++-----------------+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
+| | *filename* | The debugger will stop at every *line* in the named file. |
++-----------------+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
+| | *line* | The debugger will stop when it reaches the specified *line* in the current file. |
++-----------------+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
+| | *procedure cycle* | The debugger will stop every *cycle* times it reaches the first *line* in a called procedure. |
++-----------------+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
+| | *procedure* | The debugger will stop every time it reaches the first *line* in a called procedure. |
++-----------------+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
+| j [[*args*]] | Executes code to a specified line, procedure, or cycle in the file without stopping at breakpoints. The optional arguments are the same as **g,** listed above. |
++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| jx *number* | Executes code to the execution count specified (*number*) without stopping at breakpoints. |
++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| o | Executes the remainder of the current procedure (or to a breakpoint) and stops at the next line in the calling procedure. |
++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+ View Commands
+^^^^^^^^^^^^^^^
+
++---------------------------+---------------------------------------------------------------------------------------------------------+
+| **v [[**\ *vars*\ **]]** | Searches for (a local variable, then a global variable) and displays the value of a specified variable. |
++===========================+=========================================================================================================+
+| **v$ [[**\ *vars*\ **]]** | Searches for (a local variable, then a global variable) and displays the specified character matrix. |
++---------------------------+---------------------------------------------------------------------------------------------------------+
+
+The display properties of matrices can be set using the following commands:
+
++------------------+-----------------------------------------------------------------------------+
+| r | Specifies the number of rows to be shown. |
++==================+=============================================================================+
+| c | Specifies the number of columns to be shown. |
++------------------+-----------------------------------------------------------------------------+
+| *number, number* | Specifies the indices of the upper left corner of the block to be shown. |
++------------------+-----------------------------------------------------------------------------+
+| w | Specifies the width of the columns to be shown. |
++------------------+-----------------------------------------------------------------------------+
+| p | Specifies the precision shown. |
++------------------+-----------------------------------------------------------------------------+
+| f | Specifies the format of the numbers as decimal, scientific, or auto format. |
++------------------+-----------------------------------------------------------------------------+
+| q | Quits the matrix viewer. |
++------------------+-----------------------------------------------------------------------------+
+
+Breakpoint Commands
+^^^^^^^^^^^^^^^^^^^^
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| lb | Shows all the breakpoints currently defined. |
++==============+==========================================================+=================================================================================================+
+| b [[*args*]] | Sets a breakpoint in the code. The syntax for each optional argument is: |
++--------------+----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
+| | *filename line cycle* | The debugger will stop every *cycle* times it reaches the specified *line* in the named file. |
++--------------+----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
+| | *filename line* | The debugger will stop when it reaches the specified *line* in the named file. |
++--------------+----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
+| | *filename , cycle* | The debugger will stop every *cycle* times it reaches any *line* in the current file. |
++--------------+----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
+| | *line cycle* | The debugger will stop every *cycle* times it reaches the specified *line* in the current file. |
++--------------+----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
+| | *filename* | The debugger will stop at every *line* in the named file. |
++--------------+----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
+| | *line* | The debugger will stop when it reaches the specified *line* in the current file. |
++--------------+----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
+| | *procedure cycle* | The debugger will stop every *cycle* times it reaches the first *line* in a called procedure. |
++--------------+----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
+| | *procedure* | The debugger will stop every time it reaches the first *line* in a called procedure. |
++--------------+----------------------------------------------------------+-------------------------------------------------------------------------------------------------+
+| d [[*args*]] | Removes a previously specified breakpoint. The optional arguments are the same arguments as **b**, listed above. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
diff --git a/docs/ge/gc-compiler.rst b/docs/ge/gc-compiler.rst
new file mode 100644
index 00000000..ff982303
--- /dev/null
+++ b/docs/ge/gc-compiler.rst
@@ -0,0 +1,14 @@
+The GC Compiler
+===============
+
+The **GC** compiler can be used in Makefiles or at a system command line to compile **GAUSS** programs. The syntax is as follows:
+
+**gc [-**\ *flags*\ **]-o** *output_file source\_ file*
+
+**gc [-**\ *flags*\ **][-d** *output directory*\ **]**\ *source_file source_file*\ **...**
+
+The **-o** flag allows you to specify the name of the compiled file. If your *source_file* has a **.gau** extension, the default is to replace the **.gau** extension with **.gcg**. Otherwise, the default is to append **.gcg** to the name of your *source_file*. **GAUSS** will run compiled files only if they have a **.gcg** extension. Therefore, if you use the **-o** flag to specify an *output_file* name, you should give it a name with a **.gcg** extension.
+
+The **-d** flag allows you to specify the directory in which the compiled files will reside. If you set the **-d** flag, all of the *source_files* you compile in that execution of **gc** will be placed in the specified directory. The default *output_directory* is the current working directory.
+
+To specify a read only compile or execute, use **-roc** or **-roe**, respectively.
diff --git a/docs/ge/grte.rst b/docs/ge/grte.rst
new file mode 100644
index 00000000..d21e28dc
--- /dev/null
+++ b/docs/ge/grte.rst
@@ -0,0 +1,338 @@
+Using the GAUSS Run-Time Engine (GRTE)
+======================================
+
+The **GAUSS Run-Time Engine (GRTE)** allows you to create distributable applications that take advantage of the computational speed and power of **GAUSS**.
+
+Creating a Distributable Application
+-----------------------------------------
+
+To use the **GAUSS Engine** in an application on Windows, you must link the application with **mteng.lib**, and your application directory must contain **mteng.dll**. On Linux, link the application with **-lmteng** and make sure that **libmteng.so** is in your application directory. On both platforms, your application will run only if a valid license file with the **MTENG** feature can
+
+be found in your application directory. This license is linked to a particular **hostid**, so it will run only on your development machine.
+
+To create a distributable application, you must use the **GRTE**:
+
+- **Windows:** Link your application with **mtengrt.lib** (instead of **mteng.lib**) and distribute **mtengrt.dll** with your application.
+
+- **Linux:** Link your application with **-lmtengrt** (instead of **-lmteng**), and distribute **libmtengrt.so** with your application.
+
+- **macOS:** Link your application with **-lmtengrt** (instead of **-lmteng**), and distribute **libmtengrt.dylib** with your application.
+
+For the application to run, you must also distribute a license file with the **MTGRTE** feature, named **g.gkf** in your application directory.
+
+Applications that use the **GRTE** will not be able to create globals in a **GAUSS** workspace. Therefore, any global variables or procedures that are needed by the application must be compiled with the **GAUSS Engine** into a **.gcg** file that is distributed with the application. You may use either the compile command from the command line interface, **engauss**, or the **GC** compiler to compile a **GAUSS** program containing global declarations.
+
+Deployment Overview
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following table summarizes the GRTE deployment bundle for a headless (no GUI) application. Qt is **not required** for headless deployments -- stub libraries are provided that eliminate all Qt dependencies.
+
++-------------------------------+----------+----------------------------------------------+
+| Component | Bundled? | Notes |
++===============================+==========+==============================================+
+| ``mtengrt`` shared library | Yes | Primary engine (GRTE variant) |
++-------------------------------+----------+----------------------------------------------+
+| ``libgauss`` | Yes | Core mathematical functions |
++-------------------------------+----------+----------------------------------------------+
+| ``libgla`` | Yes | BLAS/LAPACK (self-contained, no system |
+| | | BLAS/LAPACK/MKL dependency) |
++-------------------------------+----------+----------------------------------------------+
+| Graphics/database stubs | Yes | ``libgsgraphics_stubs`` + ``libcql_stubs`` |
+| | | replace Qt with no-ops for headless use |
++-------------------------------+----------+----------------------------------------------+
+| ``libreadstat`` | Yes | Statistical file format support |
++-------------------------------+----------+----------------------------------------------+
+| ``libcityhash`` | Yes | Internal hashing |
++-------------------------------+----------+----------------------------------------------+
+| ``libhdf5`` | Yes | HDF5 data format support |
++-------------------------------+----------+----------------------------------------------+
+| ``libxl`` | Yes | Excel file support |
++-------------------------------+----------+----------------------------------------------+
+| ``libtbb``, ``libtbbmalloc`` | Yes | Threading (Intel TBB) |
++-------------------------------+----------+----------------------------------------------+
+| ``gauss.cfg`` | Yes | Runtime configuration (text file) |
++-------------------------------+----------+----------------------------------------------+
+| ``g.gkf`` | Required | Authorization token for GRTE |
++-------------------------------+----------+----------------------------------------------+
+| ``.gcg`` compiled files | Required | Pre-compiled GAUSS programs |
++-------------------------------+----------+----------------------------------------------+
+| Qt frameworks | **No** | Not needed for headless deployment |
++-------------------------------+----------+----------------------------------------------+
+| System BLAS/LAPACK/MKL | **No** | Fully bundled in ``libgla`` |
++-------------------------------+----------+----------------------------------------------+
+
+All dependencies can be collected automatically using the provided **deploy.py** script.
+
+.. note::
+
+ On macOS arm64, the engine uses Apple's Accelerate framework for optimized linear algebra. Accelerate is a system framework present on all macOS installations -- no additional distribution is required.
+
+List of Files To Distribute
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There are several files which must be distributed with your application in order for the application to be able to use the **GRTE**. The list of files differs between platforms.
+
+
+Windows
+^^^^^^^^
+
+On Windows, the necessary files are (located in GAUSS installation directory):
+
+1. The **.gcg** file containing compiled declarations of all global variables and procedures needed by the application.
+
+2. Steps 3-6 can be skipped with this method. Use the provided ‘\ **deploy.py**\ ’ Python script to copy the dependencies to a different directory. This script will run with Python 2 or Python 3. GAUSS user code dependencies are not copied automatically.
+
+..
+
+ usage: deploy.py [-h] [--with-graphics] [--with-database] [--with-qt]
+
+ [--dest DEST]
+
+ file
+
+ positional arguments:
+
+ file Binary to distribute
+
+ optional arguments:
+
+ -h, --help show this help message and exit
+
+ --with-graphics Enable graphics functionality. Adds additional dependencies
+
+ --with-database Enable database functionality. Adds additional dependencies
+
+ --with-qt Enables graphics and database functionality. Identical to
+
+ --with-graphics and --with-database. Adds additional
+
+ dependencies
+
+ --dest DEST Output directory to deploy to
+
+An example after building the provided ‘mtcall’ example would be:
+
+C:\\Python34\\python.exe deploy.py mtcall.exe
+
+The files required to run mtcall.exe would now be located in the default deployment directory (‘dist’ in the current working directory).
+
+3. The shared library files: **gauss.dll, readstat.dll, iconv.dll, gla.dll, cityhash.dll, hdf5.dll, zlib.dll, szip.dll, tbb.dll, tbbmalloc.dll, TecIO.dll, libiomp5md.dll, libxl.dll, mtengrt.dll, pthreadVC2.dll,** and **xls.dll.**
+
+4. Database functionality
+
+ a. If your program uses the **GAUSS** database functionality, then you will also need to distribute: **cql.dll**, **Qt5Core.dll** and **Qt5Sql.dll**.
+
+ b. If your program does NOT use the **GAUSS** database functionality, then you can rename **cql_stubs.dll** to **cql.dll** and add this file to your project.
+
+5. The **GAUSS** configuration file, **gauss.cfg**. The distributed copy of **gauss.cfg** must have both the *user_lib* and *gauss_lib* options set to **off**. By default, they are both set to **on**.
+
+6. A license file with the **MTGRTE** feature, which must have a **g.gkf** file name and be located in the directory containing the shared library and configuration files.
+
+7. The target machine will also need the Microsoft Visual C++ 2015 Redistributable Package for your target architecture (32-bit or 64-bit). This can be freely obtained from the Microsoft Download Center.
+
+
+Linux
+^^^^^^
+
+On Linux, the necessary files are (located in GAUSS installation directory as well as ‘bin’ directory):
+
+1. The **.gcg** file containing compiled declarations of all global variables and procedures needed by the application.
+
+2. Steps 3-6 can be skipped with this method. Use the provided ‘\ **deploy.py**\ ’ Python script to copy the dependencies to a different directory. This script will run with Python 2 or Python 3. GAUSS user code dependencies are not copied automatically.
+
+..
+
+ usage: deploy.py [-h] [--with-graphics] [--with-database] [--with-qt]
+
+ [--dest DEST]
+
+ file
+
+ positional arguments:
+
+ file Binary to distribute
+
+ optional arguments:
+
+ -h, --help show this help message and exit
+
+ --with-graphics Enable graphics functionality. Adds additional dependencies
+
+ --with-database Enable database functionality. Adds additional dependencies
+
+ --with-qt Enables graphics and database functionality. Identical to
+
+ --with-graphics and --with-database. Adds additional
+
+ dependencies
+
+ --dest DEST Output directory to deploy to
+
+An example after building the provided ‘mtcall’ example would be:
+
+python deploy.py mtcall
+
+The files required to run mtcall would now be located in the default deployment directory (‘dist’ in the current working directory).
+
+3. The shared library files **libgauss.so, libreadstat.so, libiconv.so, libgla.so, libcityhash.so, libhdf5.so, libszip.so, libtbb.so, libtbbmalloc.so, libiomp5.so, libmtengrt.so** and **libxl.so.**
+
+4. Database functionality
+
+a. If your program uses the **GAUSS** database functionality, then you will also need to distribute: **libcql.so**, **libQtCore.so.5** and **libQtSql.so.5**.
+
+b. If your program does NOT use the **GAUSS** database functionality, then you can rename **libcql_stubs.so** to **libcql.so** and add this file to your project.
+
+5. The **GAUSS** configuration file, **gauss.cfg**. The distributed copy of **gauss.cfg** must have both the *user_lib* and *gauss_lib* options set to **off**. By default, they are both set to **on**.
+
+6. A license file with the **MTGRTE** feature, which must have a **g.gkf** file name and be located in the directory containing the shared library and configuration files.
+
+
+macOS
+^^^^^^
+
+On macOS, the necessary files are (Located in GAUSS installation directory as well as ‘redist’ directory):
+
+1. The **.gcg** file containing compiled declarations of all global variables and procedures needed by the application.
+
+2. Steps 3-6 can be skipped with this method. Use the provided ‘\ **deploy.py**\ ’ Python script to copy the dependencies to a different directory. This script will run with Python 2 or Python 3. GAUSS user code dependencies are not copied automatically.
+
+..
+
+ usage: deploy.py [-h] [--with-graphics] [--with-database] [--with-qt]
+
+ [--dest DEST]
+
+ file
+
+ positional arguments:
+
+ file Binary to distribute
+
+ optional arguments:
+
+ -h, --help show this help message and exit
+
+ --with-graphics Enable graphics functionality. Adds additional dependencies
+
+ --with-database Enable database functionality. Adds additional dependencies
+
+ --with-qt Enables graphics and database functionality. Identical to
+
+ --with-graphics and --with-database. Adds additional
+
+ dependencies
+
+ --dest DEST Output directory to deploy to
+
+An example after building the provided ‘mtcall’ example would be:
+
+python deploy.py mtcall
+
+The files required to run mtcall would now be located in the default deployment directory (‘dist’ in the current working directory).
+
+3. The shared library files **libgauss.dylib, libreadstat.dylib, libiconv.dylib, libgla.dylib, libcityhash.dylib, libhdf5.dylib, libszip.dylib, libtbb.dylib, libtbbmalloc.dylib, libiomp5.dylib, libmtengrt.dylib** and **libxl.dylib.**
+
+4. Database functionality
+
+a. If your program uses the **GAUSS** database functionality, then you will also need to distribute: **libcql.dylib**, **QtCore** and **QtSql**.
+
+b. If your program does NOT use the **GAUSS** database functionality, then you can rename **libcql_stubs.dylib** to **libcql.dylib** and add this file to your project.
+
+5. The **GAUSS** configuration file, **gauss.cfg**. The distributed copy of **gauss.cfg** must have both the *user_lib* and *gauss_lib* options set to **off**. By default, they are both set to **on**.
+
+6. A license file with the **MTGRTE** feature, which must have a **g.gkf** file name and be located in the directory containing the shared library and configuration files.
+
+Setting the Home Directory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Before the end user is able to run the application, the home path for the **GAUSS Run-Time Engine** must be set, so it can find the shared library, configuration, and license files. There are three ways to do this:
+
+1. The end user can set the environment variable **MTENGHOME26** to the path of the directory containing the shared library and configuration files.
+
+2. You can specify the name of a new home environment variable in your application with **GAUSS_SetHomeVar**. The end user would then need to set that environment variable to the path of the directory containing the shared library and configuration files.
+
+3. You can include code in your application that will find the correct path and set it using **GAUSS_SetHome**.
+
+..
+
+ On **Linux**, the following environment variables must be set:
+
+1. The path of the directory containing the shared library files must also be included in the environment variable **LD_LIBRARY_PATH**, or the shared library files must be placed in the canonical system location. To reference shared library files that exist in MTENGHOME26, the following two paths must be added to LD_LIBRARY_PATH:
+
+export LD_LIBRARY_PATH=$MTENGHOME26:$MTENGHOME26/bin
+
+2. If using database functionality (linking against libcql.so) or graphics (libsgsgraphics.so), then the following environment setup is required:
+
+..
+
+ export QT_QPA_PLATFORM=offscreen
+
+ export QT_PLUGIN_PATH=$MTENGHOME26/plugins
+
+unset QT_QPA_PLATFORMTHEME
+
+The grte01 and grte02 Executables
+--------------------------------------
+
+The **GAUSS Run-Time Engine** is shipped with two complete examples demonstrating how you may create and distribute an application that uses the functionality of **GAUSS**. These examples can be found in the main directory of your **GAUSS Engine**
+
+installation directory. The main directory contains a **README** file, which gives instructions on building and running the examples.
+
+Building the Executable
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The **grte01** and **grte02** examples are made up of five files:
+
+1. **grte01.c** -the example application code for **grte01**.
+
+2. **grte02.c** -the example application code for **grte02**.
+
+3. **grte01.gau** -the **GAUSS** program file containing declarations of all of the global variables and procedures that are used in **grte01**.
+
+4. **grte02.gau** -the **GAUSS** program file containing declarations of all of the global variables and procedures that are used in **grte02**.
+
+5. Makefile - the Makefile needed to build the **grte01** and **grte02** executables.
+
+To build the application, you must make the **grte01** and **grte02** executables and compile **grte01.gau** and **grte02.gau** into **grte01.gcg** and **grte02.gcg** respectively. You may use either the compile command from the command line interface, **engauss**, or the GUI version, gauss, or the **GC** compiler to compile the **.gau** file.
+
+Including the Necessary Files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After building the example applications, you should create a directory named **distribute** and copy all of the files needed to run the application into **distribute** as follows:
+
+
+Windows
+^^^^^^^^
+
+1. Copy or move **grte01.exe, grte02.exe, grte02.gcg,** and **grte01.gcg** into **distribute**.
+
+2. Copy the shared library files **gauss.dll, readstat.dll, iconv.dll, gla.dll, cityhash.dll, hdf5.dll, zlib.dll, szip.dll, tbb.dll, tbbmalloc.dll, TecIO.dll, libiomp5md.dll, libxl.dll, mtengrt.dll, pthreadVC2.dll,** and **xls.dll,** as well as the **GAUSS** configuration file, **gauss.cfg**, from your **GAUSS Engine** installation directory into **distribute**. Then set both the *user_lib* and *gauss_lib* options in the **distribute** copy of **gauss.cfg** to **off**.
+
+3. Copy your **GAUSS Run-Time Engine** license file (which should be called **g.gkf**) into the **distribute** directory.
+
+
+Linux
+^^^^^^
+
+1. Copy or move **grte01, grte02, grte02.gcg,** and **grte01.gcg** into **distribute**.
+
+2. Copy the shared library files **libgauss.so, libreadstat.so, libiconv.so, libgla.so, libcityhash.so, libhdf5.so, libszip.so, libtbb.so, libtbbmalloc.so, libiomp5.so, libmtengrt.so** and **libxl.so**, as well as the **GAUSS** configuration file, **gauss.cfg**, from your **GAUSS Engine** installation directory into **distribute**. Then set both the *user\_ lib* and *gauss\_ lib* options in the distribute copy of **gauss.cfg** to **off**.
+
+3. Copy your **GAUSS Run-Time Engine** license file (which should be called **g.gkf**) into the **distribute** directory.
+
+
+macOS
+^^^^^
+
+1. Copy or move **grte01, grte02, grte02.gcg,** and **grte01.gcg** into **distribute**.
+
+2. Copy the shared library files **libgauss.dylib, libreadstat.dylib, libiconv.dylib, libgla.dylib, libcityhash.dylib, libhdf5.dylib, libszip.dylib, libtbb.dylib, libtbbmalloc.dylib, libiomp5.dylib, libmtengrt.dylib** and **libxl.dylib**, as well as the **GAUSS** configuration file, **gauss.cfg**, from your **GAUSS Engine** installation directory into **distribute**. Then set both the *user\_ lib* and *gauss\_ lib* options in the distribute copy of **gauss.cfg** to **off**.
+
+3. Copy your **GAUSS Run-Time Engine** license file (which should be called **g.gkf**) into the **distribute** directory.
+
+Running the Executable
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After copying the files as specified above, the **distribute** directory should contain all of the files needed to run the **grte01**
+
+and **grte02** executables. This will allow the example to run if it is moved to another location.
diff --git a/docs/ge/index.rst b/docs/ge/index.rst
new file mode 100644
index 00000000..9984dc66
--- /dev/null
+++ b/docs/ge/index.rst
@@ -0,0 +1,20 @@
+GAUSS Engine v26
+================
+
+Programmer's Manual for the GAUSS Engine C API.
+
+.. toctree::
+ :maxdepth: 2
+
+ installation
+ sample-programs
+ using-the-engine
+ grte
+ multithreading
+ interrupts
+ command-line
+ utilities
+ gc-compiler
+ api-overview
+ api-reference
+ structures
diff --git a/docs/ge/installation.rst b/docs/ge/installation.rst
new file mode 100644
index 00000000..d3202c2e
--- /dev/null
+++ b/docs/ge/installation.rst
@@ -0,0 +1,236 @@
+Installation
+============
+
+Upgrading from a Previous Version
+----------------------------------
+
+All existing code, compiled **.gcg** files, and API calls are fully backward compatible with GAUSS Engine 26. To upgrade, replace the installation files and update your environment variable from **MTENGHOME25** to **MTENGHOME26**. No code changes are required.
+
+Linux
+----------
+
+Installing the Files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+From CD or download, copy the **.tar.gz** file to **/tmp**
+
+Choose a directory to install the **GAUSS Engine** to. We’ll assume the final path is going to be **/usr/local/mteng26**
+
+Go to that directory.
+
+cd /usr/local
+
+Extract the files:
+
+tar xvf /tmp/*tar_file_name*
+
+Change to the newly created mteng26 directory:
+
+cd mteng26
+
+The **GAUSS Engine** files are now in place.
+
+**NOTE**: If you choose to install **GAUSS Engine** in a directory which does not have write permissions for normal user accounts such as **/opt** or **/usr/local**, then you must choose the *Advanced Installation* and *Multi-User Installation* options during installation.
+
+Run the executable script:
+
+./**ginstall**
+
+1. This script will give you the option of a *default* or *advanced* install. The default option will install everything under the current directory. The advanced installation allows you to choose a single-user or multi-user installation and also allows you to place the shared libraries that the **GAUSS Engine** depends on in another location. If you choose a multi-user installation, the binaries and most of the rest of the installation will reside in the current directory. Each time a new user (a user that has never started **GAUSS Engine** on this machine ) starts **GAUSS Engine** on this machine, **GAUSS Engine** will create a local working directory for that user under the user's home directory. This local working directory will contain the files and folders that which may be customized by the user. This allows the admin to install **GAUSS Engine** in a location without universal write privileges. No files will be placed under the home directory of any user who does not start **GAUSS Engine**. Place the installation directory in the executable path.
+
+Licensing
+~~~~~~~~~~~~~~~~~
+
+The hostid of your machine is written to a text file during installation in your **GAUSS Engine** installation directory called **myhostid.txt** You will need your computer’s hostid to receive your license. To receive a license and license installation instructions, go to: **https://www.aptech.com/support/license**/ and provide the requested information:
+
+Configuring the Environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You need to set an environment variable called **MTENGHOME26** that points to the installation directory.
+
+**Cshell**
+^^^^^^^^^^^
+
+setenv MTENGHOME26 /usr/local/mteng26
+
+**Korn, Bourne shell**
+^^^^^^^^^^^^^^^^^^^^^^^
+
+export MTENGHOME26=/usr/local/mteng26
+
+The **GAUSS Engine** looks in **$MTENGHOME26** for its configuration file, **gauss.cfg**. Anyone who will be running the **GAUSS Engine** needs to have at least *read* access to this file. The name of the environment variable can be changed to something other than **MTENGHOME26** by calling **GAUSS_SetHomeVar**
+
+By default the **GAUSS Engine** creates temporary files in **/tmp**. You can change this by editing **gauss.cfg–look** for the **tmp_path** configuration variable. If you change it, anyone who uses the **GAUSS Engine** will need *read/write/execute* access to the directory you specify.
+
+Testing the Installation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After completing the above steps, you can build some of the sample programs to verify the correctness of the installation. See Chapter 2 for details.
+
+Swap Space
+~~~~~~~~~~~~~~~~~~
+
+The **GAUSS Engine** uses **malloc** and the normal system swap space. This system is dynamic and requires no workspace size setting. Make sure your system has enough swap space to handle the size and number of matrices you will be needing simultaneously. Each matrix takes 8 × rows × columns bytes.
+
+GAUSS Run-Time Engine
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you have purchased the **GAUSS Run-Time Engine (GRTE)**, you will see the shared library lib **mtengrt**. To use the GRTE, use **-lmtengrt** instead of **-lmteng** in your Makefile. The **GRTE** will not create globals. It is to be used with compiled **.gcg** files that have been compiled with the **GAUSS Engine**.
+
+To create compiled files, use the **compile** command from the command line interface, **engauss**, the graphical user interface, **gauss**, or the **gc** executable. Your application can call **GAUSS_LoadCompiledFile** to load the program contained in the .\ **gcg** file.
+
+Any global variables that are assigned within a **GAUSS** program or using the API assignment functions must be initialized in the **.gcg** file. **GAUSS_CompileString** can be used with the **GRTE** as long as it does not create new globals.
+
+macOS
+---------
+
+
+Installing the Files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+From CD or download:
+
+- Save the .\ **zip** file on your hard drive
+
+- Browse to the folder where you saved the .\ **zip** file
+
+- Extract the files
+
+- Double-click on the ***.pkg** file to launch the installer.
+
+The **GAUSS Engine** files are now in place.
+
+
+Licensing
+~~~~~~~~~~~~~~~~~
+
+The hostid of your machine is written to a text file during installation in your **GAUSS Engine** installation directory called **myhostid.txt** You will need your computer’s hostid to receive your license. To receive a license and license installation instructions, go to: **https://www.aptech.com/support/license**/ and provide the requested information:
+
+
+Configuring the Environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You need to set an environment variable called **MTENGHOME26** that points to the installation directory.
+
+
+**Korn, Bourne shell**
+^^^^^^^^^^^^^^^^^^^^^^^
+
+export MTENGHOME26=/Users/$USER/mteng26
+
+The **GAUSS Engine** looks in **$MTENGHOME26** for its configuration file, **gauss.cfg**. Anyone who will be running the **GAUSS Engine** needs to have at least *read* access to this file. The name of the environment variable can be changed to something other than **MTENGHOME26** by calling **GAUSS_SetHomeVar**
+
+By default the **GAUSS Engine** creates temporary files in **/tmp**. You can change this by editing **gauss.cfg**–look for the **tmp_path** configuration variable. If you change it, anyone who uses the **GAUSS Engine** will need *read/write/execute* access to the directory you specify.
+
+
+Testing the Installation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After completing the above steps, you can build some of the sample programs to verify the correctness of the installation. See Chapter 2 for details.
+
+
+Swap Space
+~~~~~~~~~~~~~~~~~~
+
+The **GAUSS Engine** uses **malloc** and the normal system swap space. This system is dynamic and requires no workspace size setting. Make sure your system has enough swap space to handle the size and number of matrices you will be needing simultaneously. Each matrix takes 8 × rows × columns bytes.
+
+
+GAUSS Run-Time Engine
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you have purchased the **GAUSS Run-Time Engine (GRTE)**, you will see the shared library lib **mtengrt**. To use the GRTE, use **-lmtengrt** instead of **-lmteng** in your Makefile. The **GRTE** will not create globals. It is to be used with compiled **.gcg** files that have been compiled with the **GAUSS Engine**.
+
+To create compiled files, use the **compile** command from the command line interface, **engauss**, the graphical user interface, **gauss**, or the **gc** executable. Your application can call **GAUSS_LoadCompiledFile** to load the program contained in the .\ **gcg** file.
+
+Any global variables that are assigned within a **GAUSS** program or using the API assignment functions must be initialized in the **.gcg** file. **GAUSS_CompileString** can be used with the **GRTE** as long as it does not create new globals.
+
+
+Windows
+------------
+
+
+Installing the Files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+From CD
+^^^^^^^^
+
+Insert the CD into a CD drive, and setup should start automatically. If setup does not start automatically:
+
+- Browse to the CD-ROM drive
+
+- Double-click on the ***.exe** file to launch the installer.
+
+- Follow the prompts to select a directory to install to and copy the **GAUSS Engine** files to your hard drive.
+
+From Download
+^^^^^^^^^^^^^^
+
+Download the **GAUSS Engine** from your Premier Support Download Account and do the following:
+
+- Save the .\ **zip** file on your hard drive
+
+- Browse to the folder where you saved the .\ **zip** file
+
+- Extract the files
+
+- Double-click on the ***.exe** file to launch the installer.
+
+- Follow the prompts to select a directory to install to and copy the **GAUSS Engine** files to your hard drive.
+
+
+Licensing
+~~~~~~~~~~~~~~~~
+
+To receive a license and license installation instructions, type this link in your internet browser and provide the content of **myhostid.txt** and other requested information: **https://www.aptech.com/support/license/**
+
+The hostid number of your machine is usually generated automatically and will be displayed during installation in a text file that is stored in your main **GAUSS Engine** directory called **myhostid.txt**
+
+
+Configuring the Environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The **GAUSS Engine** examples require an environment variable called **MTENGHOME26** that points to the installation directory.
+
+POSIX Threads
+~~~~~~~~~~~~~~~~~~~~
+
+The **GAUSS Engine** for Windows is implemented using POSIX threads forWin32. you can obtain the Pthreads library from:
+
+https://sources.redhat.com/pthreads-win32/
+
+The **GAUSS Engine** for Windows was linked using **pthreadVC2.dll** and **pthreadVC2.lib**. You need both the .dll and the .lib
+
+file to link with the **GAUSS Engine**.
+
+You will also need:
+
+pthread.h
+
+semaphore.h
+
+sched.h
+
+
+Testing the Installation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After completing the above steps, you can build some of the sample programs to verify the installation. See **Chapter 2** for details.
+
+
+Swap Space
+~~~~~~~~~~~~~~~~~
+
+The **GAUSS Engine** now uses **malloc** and the normal system swap space. This system is dynamic and requires no workspace size setting. Make sure your system has enough swap space to handle the size and number of matrices you will be needing simultaneously. Each matrix takes 8 × rows × columns bytes.
+
+
+GAUSS Run-Time Engine
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you have purchased the **GAUSS Run-Time Engine (GRTE)**, you will find **mtengrt.dll** and **mtengrt.lib**. To use it, link with these instead of **mteng.dll** and **mteng.lib** in your Makefile.
+
+The **GRTE** will not create GAUSS global variables. It is to be used with compiled GAUSS code (**.gcg)** files that have been compiled with the **GAUSS Engine.**
+
+To create compiled files, use the **compile** command from the command line interface, **engauss** or the **gc** executable. Your application can call **GAUSS_LoadCompiledFile** to load the program contained in the .\ **gcg** file.
+
+Any global variables that are assigned within a **GAUSS** program or using the API assignment functions must be initialized in the **.gcg** file. **GAUSS_CompileString** can be used with the **GRTE** as long as it does not create new globals.
diff --git a/docs/ge/interrupts.rst b/docs/ge/interrupts.rst
new file mode 100644
index 00000000..857ec321
--- /dev/null
+++ b/docs/ge/interrupts.rst
@@ -0,0 +1,26 @@
+Interrupts
+==========
+
+To interrupt **GAUSS** programs, there are the following functions:
+
++-------------------------------+------------------------------------------------------------+
+| GAUSS_SetGlobalInterrupt | Interrupt all programs. |
++===============================+============================================================+
+| GAUSS_SetProgramInterrupt | Interrupt all programs using a specified program handle. |
++-------------------------------+------------------------------------------------------------+
+| GAUSS_SetWorkspaceInterrupt | Interrupt all programs using a specified workspace handle. |
++-------------------------------+------------------------------------------------------------+
+
+To clear the interrupts use:
+
++--------------------------------+--------------------------------+
+| GAUSS_ClearGlobalInterrupt | |
++================================+================================+
+| GAUSS_ClearProgramInterrupt | |
++--------------------------------+--------------------------------+
+| GAUSS_ClearWorkspaceInterrupt | |
++--------------------------------+--------------------------------+
+
+A global interrupt must be explicitly cleared or no subsequent programs will run. If the program and workspace interrupts are not cleared, the associated handles will be disabled for subsequent programs. Also, all programs in all threads will run slightly slower when interrupts are pending. Clearing the interrupt requests will allow any simultaneously running threads to run at full speed,
+
+so it is good practice even if the associated handles will not be reused.
diff --git a/docs/ge/multithreading.rst b/docs/ge/multithreading.rst
new file mode 100644
index 00000000..21948053
--- /dev/null
+++ b/docs/ge/multithreading.rst
@@ -0,0 +1,68 @@
+Multi-threaded Applications
+===========================
+
+The **GAUSS Engine** can be used in multi-threaded applications. To achieve the maximum amount of concurrency, you need to structure your application correctly.
+
+The setup and initialization functions should be called from the main thread once at the beginning of the application. The functions that create the matrix, string and string array structures have no associated threading issues. The functions that compile, execute and move data between the application and the **GAUSS Engine** are discussed below.
+
+If each thread is using a different workspace, there are no associated concurrency issues. The **GAUSS Engine** API is thread-safe across different workspaces for all functions as long as each workspace has only one associated thread. **GAUSS_CopyGlobal**
+
+will read lock the source workspace and write lock the target workspace as it copies.
+
+There are rules that you can follow to achieve nearly 100% concurrency for multiple threads in a single workspace. Those rules are also discussed below.
+
+Locks
+----------
+
+A workspace can have multiple read locks or one write lock. If a thread has a write lock on a workspace, all other threads are blocked until the thread releases the write lock. If a workspace is read locked by one or more threads, any threads requesting write locks are blocked until all the read locks are released.
+
+Two flags are used with the compile functions to guarantee that the program compiled is thread-safe. These are **readonlyC** and **readonlyE** for “\ *read only* compile” and *“read only execute,”* respectively. They control workspace locking for compiling and execution of **GAUSS** code and are used during compiles to trap for code that is not thread-safe. The value of **readonlyE** is passed to the execute functions, via the program handle.
+
+Be aware that this information is not kept across multiple compiles in the same workspace. Only the values from the compile that created the program handle are passed to the executer. It is therefore possible to make multiple compiles in a workspace and do a *read only* compile that succeeds erroneously. The reason for this is that procedures that assign to globals may be resident in the workspace from a previous compile and will not get recompiled each time. If an already resident procedure that assigns to globals is called in a subsequent compile, the global assignment will not be detected.
+
+In practice, this does not usually matter. These arguments are to be used as an aid during development to verify that your code is or is not assigning to globals. They will not prevent you from creating code that is not thread-safe. When your compile fails it shows you the line of code that violated the rules you specified with the arguments.
+
+Compiling and Executing GAUSS Programs
+-------------------------------------------
+
+**GAUSS_CompileFile, GAUSS_CompileString** **and GAUSS_CompileExpression** read lock the workspace when the **readonlyC** argument is true (non-zero) and write lock the workspace when it is false. When **readonlyC** is true, the compile will fail if it tries to create or redefine any globals, including procedure definitions. When the **readonlyE** argument is true, the compile will fail if the program assigns to any globals. The value of **readonlyE** is passed to the executer, via the program handle.
+
+**GAUSS_Execute** and **GAUSS_ExecuteExpression** read lock the workspace if the program was compiled with the **readonlyE** argument set to true and write lock the workspace otherwise.
+
+Assuring Concurrency
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To assure concurrent compilation and execution of multiple threads in a single workspace, design your code so it can be compiled with **readonlyC** and **readonlyE** both true for any compiles and executes that you intend to run concurrently in the same workspace.
+
+In practice this usually means you have an initialization cycle (compile and execute) with both flags false to compile and execute the code necessary to define and initialize any global data for a workspace. You then have a second initialization cycle (compile only) with **readonlyE** true to compile the procedures you need. This data and these procedures can then be used in a thread-safe
+
+fashion (both flags true) in subsequent compiles and executes in the same workspace.
+
+Calling GAUSS Procedures
+-----------------------------
+
+The functions **GAUSS_CallProc** and **GAUSS_CallProcFreeArgs** provide a way to call **GAUSS** procedures with no globals used for either the arguments or the returns of the procedure. Arguments are passed directly from the application to the procedure via a C structure array and the returns are handled the same way. No globals are necessary in the workspace.
+
+The program handle used with these functions can be created with **GAUSS_CompileFile**, **GAUSS_CompileString** or **GAUSS_CreateProgram**. If the program handle is created with **readonlyE** true, then **GAUSS_CallProc** and **GAUSS_CallProcFreeArgs** *read lock* the workspace, otherwise they use a *write lock*.
+
+
+Assuring Concurrency
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To assure concurrent execution of multiple threads in a single workspace, design your procedures so they can be compiled with **readonlyE** true. Assuming a procedure that is listed in a library, the following code illustrates this:
+
+ProgramHandle_t *ph;
+
+char cmd[100];
+
+int readonlyC, readonlyE;
+
+strcpy( cmd, "library mylib; external proc proc1, proc2;" );
+
+readonlyC = 0;
+
+readonlyE = 1;
+
+ph = GAUSS_CompileString( wh, cmd, readonlyC, readonlyE );
+
+If this compile succeeds, you can call the procedures multiple times simultaneously in separate threads and they will execute concurrently. The compile will fail if the procedures contain code that assigns to global variables.
diff --git a/docs/ge/sample-programs.rst b/docs/ge/sample-programs.rst
new file mode 100644
index 00000000..87e4096b
--- /dev/null
+++ b/docs/ge/sample-programs.rst
@@ -0,0 +1,124 @@
+Sample Programs
+===============
+
+At least five sample programs are provided in the **GAUSS Engine** installation directory: **eng2d.c, mtexpr.c, mtcall.c, grte01.c,** and **grte02.c.**
+
+The examples that start with **grte** will run with the **GAUSS Engine**. The makefile is set to link these examples with the **GAUSS**
+
+**Run-Time Engine (GRTE)**. You will need to modify the makefile to link them with the **GAUSS Engine**. See the source code for these examples for further instructions.
+
+Linux/macOS
+----------------
+
+The **GAUSS Engine** is shipped with several sample C programs that incorporate the **GAUSS Engine**, and a Makefile for building them.
+
+For 32-bit compilation on a 64-bit machine, ensure the Makefile contains the **CCOPTIONS=-m32** line.
+
+Go to the directory you installed the **GAUSS Engine** to such as mteng26.
+
+cd /usr/local/mteng26
+
+Sample Program **eng2d**:
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Run make to build **eng2d**
+
+make eng2d
+
+**eng2d** sets some global variables, runs a program that uses them, then extracts the result from the workspace. Try running it.
+
+./eng2d
+
+You can see that the computation printed out by the **GAUSS** program and the data extracted by **GAUSS_GetMatrix**
+
+are the same.
+
+
+Windows
+------------
+
+The **GAUSS Engine** is shipped with several sample C programs that incorporate the **GAUSS Engine**, and a Makefile
+
+for building them. (Note: The Makefile is written for Microsoft Visual Studio 2019. If you are using a different compiler, you will have to manually compile the sample programs.)
+
+For 32-bit compilation on a 64-bit machine, ensure the Makefile contains the **CCOPTIONS=-m32** line.
+
+Open a Command window and go to the directory you installed the **GAUSS Engine** to. We’ll assume **c:\\mteng26**
+
+cd c:\\mteng26
+
+
+Sample Program **eng2d**:
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Run **nmake** to build **eng2d**.
+
+nmake eng2d
+
+**eng2d** sets some global variables, runs a program that uses them, then extracts the result from the workspace. Try running it.
+
+eng2d
+
+You can see that the computation printed out by the **GAUSS** program and the data extracted by **GAUSS_GetMatrix** are the same.
+
+Visual Studio Example **msvc_example**:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Change your current working directory to c:\\mteng26\\msvc_example and either open gauss_eng2d.sln with Visual Studio 2019 or build it from the command line:
+
+devenv.exe gauss_eng2d.sln /build “Release|x64”
+
+Note that if you are compiling for the 32-bit version of the GAUSS Engine you must change the ‘x64’ reference to ‘Win32’ (eg “Release|Win32”). After successfully compiling and linking, the new binary gauss_eng2d.exe should be located in your c:\\mteng26 directory.
+
+See the Makefile for other targets; there may have been additions after the manual was printed.
+
+Building With CMake
+-----------------------
+
+A **CMakeLists.txt** file is also available in the **GAUSS Engine** installation directory. To build the examples, CMake must be installed and able to be found in the PATH environment variable.
+
+1. Ensure the ‘rlm’ (rlm.exe on Windows) binary is running in the installation directory. This step is required for the grte01/grte02 programs to compile correctly. A temporary license is sufficient for the **mtcall**, **mtexpr** and **eng2d** examples but **grte01** and **grte02** require a full license with a **g.gkf** file present in the same directory to correctly run.
+
+2. Create the build directory: **mkdir build**
+
+3. Change to the build directory: **cd build**
+
+4. Run cmake with the appropriate values (Release can be substituted with ‘Debug’). The –G flag for CMake will specify the generator for creating the project. Command-line building is easiest with “NMake Makefiles” on Windows and “Unix Makefiles” on Linux/macOS. Omitting the –G flag will use the system default generator (ie Visual Studio Solution on Windows and Xcode project on macOS).
+
+ a. **cmake –G”NMake Makefiles” –DCMAKE_BUILD_TYPE=Release ..**
+
+..
+
+ OR
+
+b. **cmake –G”Visual Studio 14 Win64”**
+
+..
+
+ Or for a 32-bit build, specify the –m32 flag
+
+c. **cmake –G”NMake Makefiles” –DCMAKE_BUILD_TYPE=Release –DCMAKE_C_FLAGS=-m32 ..**
+
+..
+
+ OR
+
+d. **cmake –G”Visual Studio 14”**
+
+5. Build the examples
+
+ a. **make install** (Linux/macOS)
+
+..
+
+ OR
+
+b. **nmake install** (Windows)
+
+..
+
+ OR
+
+c. **cmake --build . --config Release --target install** (Either)
+
+Change back to the installation directory and execute the newly built binaries.
diff --git a/docs/ge/structures.rst b/docs/ge/structures.rst
new file mode 100644
index 00000000..00a1955c
--- /dev/null
+++ b/docs/ge/structures.rst
@@ -0,0 +1,228 @@
+Structure Reference
+===================
+
+Array_t
+--------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | N-dimensional array descriptor structure. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | An **Array_t** is a structure with the following members: |
+| | |
+| | **double *** *adata\ *\ **;** |
+| | |
+| | **size_t** *dims\ *\ **;** |
+| | |
+| | **size_t** *nelems\ *\ **;** |
+| | |
+| | **int** *complex\ *\ **;** |
+| | |
+| | *adata* pointer to array. |
+| | |
+| | *dims* number of dimensions. |
+| | |
+| | *nelems* number of elements in real part of array. |
+| | |
+| | *complex* 0 if array is real, 1 if complex. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | An **Array_t** is used to hold the information for an array. To create an **Array_t**, use one of the following functions: |
+| | |
+| | GAUSS_ComplexArray |
+| | |
+| | GAUSS_ComplexArrayAlias |
+| | |
+| | GAUSS_Array |
+| | |
+| | GAUSS_ArrayAlias |
+| | |
+| | The structure member *adata* points to a block of memory containing two sections in the case of a real array or three sections in the case of a complex array. The first section, which is the vector of orders for the array, contains *dims* doubles. The second section contains the real part of the array. The optional third section contains the imaginary part. The number of doubles in the real section is the product of the vector of orders and is contained in *nelems*. The number of doubles in the imaginary section is the same as the real section. These three sections are laid out contiguously in memory. |
+| | |
+| | Use **GAUSS_FreeArray** to free an **Array_t**. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_Array, GAUSS_ArrayAlias, GAUSS_ComplexArray, GAUSS_ComplexArrayAlias, GAUSS_FreeArray |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+GAUSS_MatrixInfo_t
+-------------------
+
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | 2-dimensional matrix info descriptor structure. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | A **GAUSS_MatrixInfo_t** is a structure with the following members: |
+| | |
+| | **size_t** *rows\ *\ **;** |
+| | |
+| | **size_t** *cols\ *\ **;** |
+| | |
+| | **int** *complex\ *\ **;** |
+| | |
+| | **double** * *maddr\ *\ **;** |
+| | |
+| | *rows* number of rows. |
+| | |
+| | *cols* number of columns. |
+| | |
+| | *complex* 0 if matrixis real, 1 if complex. |
+| | |
+| | *maddr* pointer to matrix. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | **GAUSS_MatrixInfo_t** structures are used only with **GAUSS_GetMatrixInfo**. A **GAUSS_MatrixInfo_t** gives you a pointer to the actual data of a matrix in a **GAUSS** workspace. Therefore, any changes you make to the matrix after getting it will be reflected in the **GAUSS** workspace. The matrix data of a **GAUSS_MatrixInfo_t** still belongs to **GAUSS**, and **GAUSS** will free it when necessary. You should not attempt to free a matrix indicated by a **GAUSS_MatrixInfo_t**. |
+| | |
+| | The matrix is always stored in row-major order in memory. If the matrix is complex, it will be stored in memory with the entire real part first, followed by the imaginary part. |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_GetMatrixInfo, Matrix_t |
++--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+Matrix_t
+---------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | 2-dimensional matrix descriptor structure. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | A **Matrix_t** is a structure with the following members: |
+| | |
+| | **double *** *mdata\ *\ **;** |
+| | |
+| | **size_t** *rows\ *\ **;** |
+| | |
+| | **size_t** *cols\ *\ **;** |
+| | |
+| | **int** *complex\ *\ **;** |
+| | |
+| | *mdata* pointer to matrix. |
+| | |
+| | *rows* number of rows. |
+| | |
+| | *cols* number of columns. |
+| | |
+| | *complex* 0 if matrix is real, 1 if complex. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | A **Matrix_t** is used to hold the information for a matrix. To create a **Matrix_t**, use one of the following functions: |
+| | |
+| | GAUSS_ComplexMatrix |
+| | |
+| | GAUSS_ComplexMatrixAlias |
+| | |
+| | GAUSS_Matrix |
+| | |
+| | GAUSS_MatrixAlias |
+| | |
+| | The matrix data of a **Matrix_t** are always stored in row-major order in memory. If the matrix is complex, it will be stored with the entire real part first, followed by the imaginary part. |
+| | |
+| | Use **GAUSS_FreeMatrix** to free a **Matrix_t**. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_Matrix, GAUSS_MatrixAlias, GAUSS_ComplexMatrix, GAUSS_ComplexMatrixAlias, GAUSS_FreeMatrix, GAUSS_MatrixInfo_t |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+String_t
+---------
+
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | String descriptor structure. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | A **String_t** is a structure with the following members: |
+| | |
+| | **char *** *stdata*; |
+| | |
+| | **size_t** *length*; |
+| | |
+| | *stdata* pointer to string. |
+| | |
+| | *length* length of string, including null terminator. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | A **String_t** is used to hold the information for a string. To create a **String_t**, use one of the following functions: |
+| | |
+| | GAUSS_String |
+| | |
+| | GAUSS_StringAlias |
+| | |
+| | GAUSS_StringAliasL |
+| | |
+| | GAUSS_StringL |
+| | |
+| | **GAUSS** strings are null-terminated, but they can also contain embedded 0’s. Therefore, you can’t rely on *strlen* to determine the length of a string; it must be explicitly stated. For this reason, the **GAUSS Engine** returns strings using a **String_t** structure rather than the simpler **char** pointer. |
+| | |
+| | Use **GAUSS_FreeString** to free a **String_t**. |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_String, GAUSS_StringAlias, GAUSS_StringL, GAUSS_StringAliasL, GAUSS_FreeString |
++--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+StringArray_t
+--------------
+
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | String array descriptor structure. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | A **StringArray_t** is a structure with the following members: |
+| | |
+| | **StringElement_t *** *table\ *\ **;** |
+| | |
+| | **size_t** *rows\ *\ **;** |
+| | |
+| | **size_t** *cols\ *\ **;** |
+| | |
+| | **size_t** *baseoffset\ *\ **;** |
+| | |
+| | *table* pointer to an array of string element descriptors. |
+| | |
+| | *rows* number of rows. |
+| | |
+| | *cols* number of columns. |
+| | |
+| | *baseoffset* offset of base of memory block containing strings. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | A **StringArray_t** is used to hold the information for a string array. To create a **StringArray_t**, use one of the following functions: |
+| | |
+| | GAUSS_StringAlias |
+| | |
+| | GAUSS_StringAliasL |
+| | |
+| | A **StringArray_t** contains a pointer to an array of **StringElement_t**\ ’s, one for each string in the array. |
+| | |
+| | The **GAUSS Engine** returns string arrays using **StringArray_t** and **StringElement_t** structures rather than the simpler **char *** array\ **.** The reason for this is that even though **GAUSS** strings are null-terminated, they can also contain embedded 0’s. Therefore, you cannot rely on *strlen* to determine the length of a string; it must be explicitly stated. |
+| | |
+| | Use **GAUSS_FreeStringArray** to free a **StringArray_t**. |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | GAUSS_StringArray, GAUSS_StringArrayL, GAUSS_FreeStringArray, StringElement_t |
++--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+StringElement t
+----------------
+
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **PURPOSE** | String descriptor structure used for strings in a string array. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **FORMAT** | A **StringElement_t** is a structure with the following members: |
+| | |
+| | **size_t** *offset*; |
+| | |
+| | **size_t** *length*; |
+| | |
+| | *offset* offset of string. |
+| | |
+| | *length* length of string. |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **REMARKS** | A **StringElement_t** is used to hold the information for a string in a string array. The *table* member of a **StringArray_t** points at an array of *rows*\ *****\ *cols* **StringElement_t’s**. The array of **StringElement_t’s** is followed in memory by the array of strings. The **baseoffset** member of a **StringArray_t** is the offset of the array of strings from *table*\ **.** |
+| | |
+| | baseoffset = rows*cols*sizeof( StringElement_t ) |
+| | |
+| | The address of the string **[**\ *r,c*\ **]** in a **StringArray_t** can be computed as follows, assuming *r* and *c* are base 1 indices as in **GAUSS**: |
+| | |
+| | StringArray_t *sa; |
+| | |
+| | StringElement_t *se; |
+| | |
+| | char *str; |
+| | |
+| | sa = GAUSS_GetStringArray( wh, "gsa" ); |
+| | |
+| | se = sa->table + ( r-1 )*sa->cols + c-1; |
+| | |
+| | str = ( char * )( sa->table ) + sa->baseoffset + se->offset; |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **SEE ALSO** | StringArray_t, GAUSS_StringArray, GAUSS_StringArrayL, GAUSS_FreeStringArray |
++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. |image1| image:: media/image1.jpeg
+ :width: 2.6in
+ :height: 0.59653in
diff --git a/docs/ge/using-the-engine.rst b/docs/ge/using-the-engine.rst
new file mode 100644
index 00000000..98185bc4
--- /dev/null
+++ b/docs/ge/using-the-engine.rst
@@ -0,0 +1,437 @@
+Using the GAUSS Engine
+======================
+
+This chapter covers the general guidelines for creating an application that uses the **GAUSS Engine**. Specific multi-threading issues are covered in Chapter 5.
+
+The use of the **GAUSS Engine** can be broken up into the following steps:
+
+- Setup and Initialization
+
+ - Set up logging
+
+ - Set home directory
+
+ - Hook I/O callback functions
+
+ - Initialize Engine
+
+- Computation
+
+ - Create workspaces
+
+ - Copy or move data
+
+ - Compile or load **GAUSS** code
+
+ - Execute **GAUSS** code
+
+ - Free workspaces
+
+- Shutdown
+
+Setup and Initialization
+----------------------------
+
+Logging
+~~~~~~~~~~~~~
+
+General **GAUSS Engine** system errors are sent to a file and/or a stream pointer. Default values are provided for each. You can change the default values or turnoff logging altogether with **GAUSS_SetLogFile** and **GAUSS_SetLogStream**. This should be done before calling any other **GAUSS Engine** functions.
+
+Home Directory
+~~~~~~~~~~~~~~~~~~~~~
+
+The **GAUSS Engine** home directory location is usually set to the same directory as the main executable of the calling application. It is used to locate the configuration file, Run-Time Library files, etc. used by the **GAUSS Engine**.
+
+Use **GAUSS_SetHome** to set the home directory, prior to calling **GAUSS_Initialize**. An alternate method is to use **GAUSS_SetHomeVar** to set the name of an environment variable that contains the home directory location.
+
+I/O CallbackFunctions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The **GAUSS Engine** calls user defined functions for program output from **print** statements and for error messages. Default functions are provided for the main thread in console applications.
+
++---------------------------------+------------------------------------+
+| Normal program output | **stdout** |
++---------------------------------+------------------------------------+
+| Program error output | **stderr** |
++---------------------------------+------------------------------------+
+| Program input | **stdin** |
++---------------------------------+------------------------------------+
+
+To change the default behavior, you can supply callback functions of your own and use the following functions to hook them:
+
++---------------------------------+------------------------------------+
+| Normal program output | **GAUSS_HookProgramOutput** |
++---------------------------------+------------------------------------+
+| Program error output | **GAUSS_HookProgramErrorOutput** |
++---------------------------------+------------------------------------+
+| Program input | **GAUSS_HookProgramInputString** |
++---------------------------------+------------------------------------+
+
+The functions **GAUSS_HookProgramInputChar, GAUSS_HookProgramInputCharBlocking** and **GAUSS_HookProgramInputCheck** are also supported, but no default behavior is defined.
+
+All I/O callback functions are thread specific and must be explicitly hooked in each thread that uses them, except for the three above that are hooked by default for the main thread.
+
+Use the hook functions to specify the input functions that the GAUSS Engine calls as follows:
+
++------------------------------------+------------------------------------+
+| **Functions Hooked By** | **Are Called By** |
++------------------------------------+------------------------------------+
+| GAUSS_HookProgramInputChar | key |
++------------------------------------+------------------------------------+
+| GAUSS_HookProgramInputCharBlocking | keyw, show |
++------------------------------------+------------------------------------+
+| GAUSS_HookProgramInputCheck | keyav |
++------------------------------------+------------------------------------+
+| GAUSS_HookProgramInputString | con, cons |
++------------------------------------+------------------------------------+
+
+There are two hook functions that are used to control output from **GAUSS** programs. Use **GAUSS_HookProgramOutput**
+
+to hook a function that **GAUSS** will call to display all normal program output. Use **GAUSS_HookProgramErrorOutput**
+
+to hook a function that **GAUSS** will call to display all program error output.
+
+Initialize Engine
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Call **GAUSS_Initialize** after the previous steps are completed. The **GAUSS Engine** ready for use.
+
+Computation
+----------------
+
+Workspaces
+~~~~~~~~~~~~~~~~~
+
+All computation in the **GAUSS Engine** is done in a *workspace*. Workspaces are independent from one another and each workspace contains its own global data and procedures. Workspaces are created with **GAUSS_CreateWorkspace**, which returns a *workspace handle*.
+
+Workspaces are freed with **GAUSS_FreeWorkspace**. The contents of a workspace can be saved to disk with **GAUSS_SaveWorkspace**.
+
+Programs
+~~~~~~~~~~~~~~~
+
+Two functions are provided in order to execute **GAUSS** program code. Each requires *a program handle.*
+
++---------------------------------+---------------------------------------+
+| **GAUSS_Execute** | Executes a **GAUSS** program |
++---------------------------------+---------------------------------------+
+| **GAUSS_ExecuteExpression** | Executes a right-hand side expression |
++---------------------------------+---------------------------------------+
+
+Six functions are provided to create program handles. A program handle contains compiled **GAUSS** program code.
+
++---------------------------------+---------------------------------------------------+
+| **GAUSS_CompileExpression** | Compiles a right-hand side expression |
++---------------------------------+---------------------------------------------------+
+| **GAUSS_CompileFile** | Compiles a **GAUSS** program file |
++---------------------------------+---------------------------------------------------+
+| **GAUSS_CompileString** | Compiles **GAUSS** commands in a character string |
++---------------------------------+---------------------------------------------------+
+| **GAUSS_CompileStringAsFile** | Compiles **GAUSS** commands in a character string |
++---------------------------------+---------------------------------------------------+
+| **GAUSS_LoadCompiledFile** | Loads a compiled program from disk |
++---------------------------------+---------------------------------------------------+
+| **GAUSS_LoadCompiledBuffer** | Loads a compiled program from disk |
++---------------------------------+---------------------------------------------------+
+
+The following code illustrates a simple program that creates a random matrix and computes its inverse.
+
+WorkspaceHandle_t *w1;
+
+ProgramHandle_t *ph;
+
+Int rv;
+
+w1 = GAUSS_CreateWorkspace("Workspace 1");
+
+ph = GAUSS_CompileString(w1,"x = rndu(10,10);xi = inv(x);",0,0);
+
+rv = GAUSS_Execute(ph);
+
+When this program is finished executing, the workspace will contain two global matrices. *x* is a 10×10 matrix of random numbers and *xi* is its inverse.
+
+The following code retrieves *xi* from the workspace to the calling application.
+
+Matrix_t *mat;
+
+mat = GAUSS_GetMatrix(w1,"xi");
+
+The following code copies the retrieved matrix to another workspace as *xinv*.
+
+WorkspaceHandle_t *w2;
+
+w2 = GAUSS_CreateWorkspace("Workspace 2");
+
+rv = GAUSS_CopyMatrixToGlobal(w2, mat,"xinv");
+
+The copy can also be done directly from one workspace to another.
+
+WorkspaceHandle_t *w2;
+
+w2 = GAUSS_CreateWorkspace("Workspace 2");
+
+rv = GAUSS_CopyGlobal(w2,"xinv",w1,"xi");
+
+GAUSS Engine Data Structures
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following data structures are used for moving data between the application and the **GAUSS Engine**. See **Chapter 12** for detailed information on the structures.
+
++--------------------------+-----------------------------------------+
+| Array\ **\_**\ t | N-dimensional array, real or complex |
++==========================+=========================================+
+| Matrix\ **\_**\ t | 2-dimensional matrix, real or complex |
++--------------------------+-----------------------------------------+
+| String\ **\_**\ t | character string |
++--------------------------+-----------------------------------------+
+| StringArray\ **\_**\ t | string array |
++--------------------------+-----------------------------------------+
+| StringElement\ **\_**\ t | string array element |
++--------------------------+-----------------------------------------+
+
+API calls to create and free this data. You can create copies of the data or aliases to the data.
+
+If you have a lot of data, you will want to minimize the amount of memory used and the number of times a block of data is copied from one location in memory to another.
+
+Use **GAUSS_Matrix** to create a **Matrix_t** structure. The following code creates a copy of the matrix *x*.
+
+WorkspaceHandle_t *w1;
+
+Matrix_t *mat;
+
+double x[100][20];
+
+w1 = GAUSS_CreateWorkspace("Workspace 1");
+
+mat = GAUSS_Matrix(w1, 100, 20, x);
+
+The call to **GAUSS_Matrix** calls **malloc** once for the **Matrix_t** structure and once for the matrix data. It then copies the matrix into the newly allocated block.
+
+The following code creates an alias for the matrix *x*.
+
+Matrix_t *matalias;
+
+Matalias = GAUSS_MatrixAlias(w1, 100, 20, x );
+
+The call to **GAUSS_MatrixAlias** calls **malloc** only once for the **Matrix_t** structure. It then sets the data pointer in the **Matrix_t** structure to the address of *x*. No copy is necessary.
+
+The following code frees both *mat* and *matalias*.
+
+GAUSS_FreeMatrix( mat );
+
+GAUSS_FreeMatrix( matalias );
+
+The first call above frees both the data block (which is a **malloc**\ ‘d copy of *x*) and the **Matrix_t** structure for *mat*. The second call frees only the **Matrix_t** structure for *matalias* because that **Matrix_t** structure contained only an alias to data that the user is left responsible for freeing if necessary.
+
+Memory Ownership Reference
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Every **Matrix_t** structure contains a ``freeable`` flag that determines whether the data block is freed when **GAUSS_FreeMatrix** is called. The following table summarizes who owns the data after each API call:
+
++------------------------------------------+--------------------+-----------------------+---------------------------------------+
+| Pattern | Data owned by | Shell struct owned by | Caller action after |
++==========================================+====================+=======================+=======================================+
+| ``GAUSS_Matrix`` + ``FreeMatrix`` | Engine (copy) | Engine | Call ``FreeMatrix`` when done |
++------------------------------------------+--------------------+-----------------------+---------------------------------------+
+| ``GAUSS_MatrixAlias`` + ``FreeMatrix`` | **Caller** (alias) | Engine | Call ``FreeMatrix`` (frees shell |
+| | | | only). Keep your data pointer alive. |
++------------------------------------------+--------------------+-----------------------+---------------------------------------+
+| ``GAUSS_Matrix`` + | Engine | Freed inside Move | **Do NOT call FreeMatrix** -- the |
+| ``MoveMatrixToGlobal`` | (transferred) | | shell is already freed by the move. |
++------------------------------------------+--------------------+-----------------------+---------------------------------------+
+| ``GAUSS_Matrix`` + | Caller (original) | Caller | Call ``FreeMatrix`` to free your copy |
+| ``CopyMatrixToGlobal`` | + Engine (copy) | | |
++------------------------------------------+--------------------+-----------------------+---------------------------------------+
+| ``GAUSS_GetMatrix`` | Caller (copy) | Caller | Call ``FreeMatrix`` when done |
++------------------------------------------+--------------------+-----------------------+---------------------------------------+
+| ``GAUSS_GetMatrixAndClear`` | Caller (zero-copy) | Caller | Call ``FreeMatrix`` when done. |
+| | | | Engine variable is reset to 1x1. |
++------------------------------------------+--------------------+-----------------------+---------------------------------------+
+| ``GAUSS_AssignFreeableMatrix`` | **Engine takes | N/A (no shell) | **Do NOT free the pointer** -- the |
+| | ownership** | | engine will free it. |
++------------------------------------------+--------------------+-----------------------+---------------------------------------+
+
+.. warning::
+
+ **Do not call GAUSS_FreeMatrix after GAUSS_MoveMatrixToGlobal.** The Move function frees the ``Matrix_t`` shell internally. Calling ``FreeMatrix`` afterward is a double-free that will crash your application.
+
+ **Do not free memory passed to GAUSS_AssignFreeableMatrix.** After this call, the engine owns the data block and will free it when the variable is reassigned or the workspace is destroyed.
+
+Copying and Moving Data to a Workspace
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use the **GAUSS Engine** API calls to pass the data between a **GAUSS Engine** workspace and your application. There are two versions of many of these API calls. One makes a copy of the data (**malloc**\ ’s a new data block) and the other moves the data (gives the data pointer away without any calls to **malloc** and frees the original structure). The functions are named accordingly.
+
+The following code uses **GAUSS_CopyMatrixToGlobal** to copy a matrix to the **GAUSS Engine**. The matrix will be called *xm* in the workspace.
+
+WorkspaceHandle_t *w1;
+
+Matrix_t *mat;
+
+double x[100][20];
+
+int rv;
+
+w1 = GAUSS_CreateWorkspace( "Workspace 1" );
+
+mat = GAUSS_Matrix( w1, 100, 20, x );
+
+rv = GAUSS_CopyMatrixToGlobal( w1, mat, "xm" );
+
+The following code uses **GAUSS_MoveMatrixToGlobal** to move a matrix to the **GAUSS Engine** and free the **Matrix_t**
+
+structure. The matrix will be called *xm* in the workspace. The original **malloc**\ ’d block held by the double pointer *x* is left intact.
+
+WorkspaceHandle_t *w1;
+
+Matrix_t *mat;
+
+double *x;
+
+int r, c;
+
+int rv;
+
+r = 1000;
+
+c = 10;
+
+x = (double *) malloc( r*c*sizeof(double) );
+
+memset( x, 0, r*c*sizeof(double) );
+
+w1 = GAUSS_CreateWorkspace( "Workspace 1" );
+
+mat = GAUSS_Matrix( w1, 100, 20, x );
+
+rv = GAUSS_MoveMatrixToGlobal( w1, mat, "xm" );
+
+This can also be accomplished with a nested call, eliminating the need for the intermediate structure. Again, the original **malloc**\ ’d block held by the double pointer *x* is left intact.
+
+WorkspaceHandle_t *w1;
+
+double *x;
+
+int r, c;
+
+int rv;
+
+r = 1000;
+
+c = 10;
+
+x = (double *) malloc( r*c*sizeof(double) );
+
+memset( x, 0, r*c*sizeof(double) );
+
+w1 = GAUSS_CreateWorkspace("Workspace 1");
+
+rv = GAUSS_MoveMatrixToGlobal( w1, GAUSS_Matrix( w1, r, c, x ), "xm" );
+
+A very large **malloc**\ ’d matrix can be given to a workspace without any additional **malloc**\ ’s or copying with **GAUSS_AssignFreeableMatrix**. In the code below, a 1000000×100 real matrix is created and placed in a workspace.
+
+WorkspaceHandle_t *w1;
+
+double *x;
+
+int r, c;
+
+int rv;
+
+r = 1000000;
+
+c = 100;
+
+x = (double *) malloc( r*c*sizeof(double) );
+
+memset( x, 0, r*c*sizeof(double) );
+
+w1 = GAUSS_CreateWorkspace( "Workspace 1" );
+
+rv = GAUSS_AssignFreeableMatrix( w1, r, c, 0, x, "largex" );
+
+After the call to **GAUSS_AssignFreeableMatrix**, the block of memory pointed to by the double pointer is owned by the **GAUSS Engine**. An attempt by the user to free it will cause a fatal error. The **GAUSS Engine** will free the block when necessary.
+
+Getting Data From a Workspace
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following code retrieves the matrix *xi* from the workspace to the calling application.
+
+Matrix_t *mat;
+
+mat = GAUSS_GetMatrix( w1, "xi" );
+
+The following code checks the type of the symbol *xi* and retrieves it from the workspace to the calling application.
+
+Array_t *arr;
+
+Matrix_t *mat;
+
+StringArray_t *sa;
+
+String_t *st;
+
+int type;
+
+arr = NULL;
+
+mat = NULL;
+
+sa = NULL;
+
+st = NULL;
+
+type = GAUSS_GetSymbolType( w1, "xi" );
+
+switch( type )
+
+{
+
+case GAUSS_ARRAY:
+
+ arr = GAUSS_GetArray( w1, "xi" );
+
+ break;
+
+case GAUSS_MATRIX:
+
+ mat = GAUSS_GetMatrix( w1, "xi" );
+
+ break;
+
+case GAUSS_STRING_ARRAY:
+
+ sa = GAUSS_GetStringArray( w1, "xi" );
+
+ break;
+
+case GAUSS_STRING:
+
+ st = GAUSS_GetString( w1, "xi" );
+
+ break;
+
+default:
+
+ fprintf( stderr, "Invalid type (%d)\n", type);
+
+ break;
+
+}
+
+Calling Procedures
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Two functions are provided to call **GAUSS** procedures, passing the arguments directly to the calling application and receiving the returns back directly, without the use of globals. Each requires an empty program handle. An empty program handle can be created with **GAUSS_CreateProgram**.
+
++---------------------------------+-----------------------------------------------------+
+| GAUSS\ **\_**\ CallProc | Calls a **GAUSS** procedure |
++=================================+=====================================================+
+| GAUSS\ **\_**\ CallProcFreeArgs | Calls a **GAUSS** procedure and frees the arguments |
++---------------------------------+-----------------------------------------------------+
+
+Shutdown
+------------
+
+When your application has completed using the **GAUSS Engine** you should call **GAUSS_Shutdown** before exiting the application.
+
+It is possible to restart the **GAUSS Engine** by calling **GAUSS_Initialize** again after calling **GAUSS_Shutdown**.
diff --git a/docs/ge/utilities.rst b/docs/ge/utilities.rst
new file mode 100644
index 00000000..1e373f98
--- /dev/null
+++ b/docs/ge/utilities.rst
@@ -0,0 +1,8 @@
+GAUSS Utilities
+===============
+
+There are several **GAUSS** utilities that are included with the **GAUSS Engine**. The **GAUSS** Profiler utilities include the collector tool, **encollect** (the **GAUSS Engine** equivalent to **tcollect**), and the **GAUSS** Profiler analysis tool, **gaussprof**. Also included are **ATOG**, a conversion utility that converts ASCII files into **GAUSS** data sets, and **vwr** or **vwrmp** depending upon your platform (Windows, Linux, etc.).
+
+The **GAUSS** User’s Guide and/or accompanying README files in the **GAUSS Engine** home directory provide details on how to use these tools. A short list of options and syntax is also often available by starting the utility without any options or by typing **utility -help** at a command prompt.
+
+Note: in all cases, these standalone utilities are not run from within the **GAUSS Engine** but rather from a command prompt window. You can easily go to a command prompt from a **GAUSS Engine** prompt by typing **dos**. This will take you to a command prompt in your current working directory.
diff --git a/docs/getheaders.rst b/docs/getheaders.rst
index a4c8dcd7..debfa8b5 100644
--- a/docs/getheaders.rst
+++ b/docs/getheaders.rst
@@ -90,8 +90,8 @@ After the above code, *headers* will contain:
gear_ratio
foreign
-SAS dataset
-+++++++++++
+Stata dataset
++++++++++++++
::
diff --git a/docs/getnr.rst b/docs/getnr.rst
index 88e1beb6..0b871017 100644
--- a/docs/getnr.rst
+++ b/docs/getnr.rst
@@ -27,13 +27,23 @@ Format
Remarks
-------
-If `__row` is greater than 0, *nr* will be set to `__row`.
+If ``__row`` is greater than 0, *nr* will be set to ``__row``.
-If an insufficient memory error is encountered, change `__rowfac` to a
+If an insufficient memory error is encountered, change ``__rowfac`` to a
number less than 1.0 (e.g. 0.75). The number of rows read will be
reduced in size by this factor.
+Example
+-------
+
+::
+
+ // Compute optimal rows to read for a file with 10 columns,
+ // assuming up to 3 copies of the data in memory
+ nr = getnr(3, 10);
+ print "Rows per iteration:" nr;
+
Source
------
@@ -42,4 +52,6 @@ gauss.src
Globals
-------
-`__row`, `__rowfac`, `__maxvec`
+``__row``, ``__rowfac``, ``__maxvec``
+
+.. seealso:: Functions :func:`getnrmt`, :func:`readr`
diff --git a/docs/getnrmt.rst b/docs/getnrmt.rst
index 1ecade84..63bc6350 100644
--- a/docs/getnrmt.rst
+++ b/docs/getnrmt.rst
@@ -36,7 +36,20 @@ Format
:rtype nr: scalar
+Example
+-------
+
+::
+
+ // Compute optimal rows per read iteration
+ // 3 copies, 10 columns, no fixed row count,
+ // full size factor, max 80000 elements
+ nr = getnrmt(3, 10, 0, 1.0, 80000);
+ print "Rows per iteration:" nr;
+
Source
------
gaussmt.src
+
+.. seealso:: Functions :func:`getnr`, :func:`readr`
diff --git a/docs/getorders.rst b/docs/getorders.rst
index ad459675..2d1d250c 100644
--- a/docs/getorders.rst
+++ b/docs/getorders.rst
@@ -6,7 +6,6 @@ Purpose
----------------
Returns a vector containing the size of the dimensions of an array, matrix, or other symbol.
-sss
Format
----------------
diff --git a/docs/getting-started/absolute-basics.rst b/docs/getting-started/absolute-basics.rst
new file mode 100644
index 00000000..778c808b
--- /dev/null
+++ b/docs/getting-started/absolute-basics.rst
@@ -0,0 +1,525 @@
+
+The Absolute Basics for Beginners
+=================================
+
+Never programmed before? This guide explains the fundamentals from scratch. By the end, you'll understand what programming is, how GAUSS works, and how to write simple programs.
+
+What is Programming?
+--------------------
+
+Programming is giving instructions to a computer. The computer follows your instructions exactly—no more, no less.
+
+Think of it like a recipe:
+
+1. Get 2 eggs
+2. Crack eggs into bowl
+3. Add 1 cup flour
+4. Mix for 2 minutes
+
+A computer program works the same way: step-by-step instructions that the computer executes in order.
+
+The difference: computers need **precise** instructions in a specific language. GAUSS is that language.
+
+The GAUSS Environment
+---------------------
+
+When you open GAUSS, you'll see several panels:
+
+.. figure:: ../_static/images/gauss26-ide-overview.png
+ :alt: GAUSS 26 IDE showing editor with sample program, project
+ folders on the left, and command output below. Four numbered
+ callouts mark key interface elements.
+
+ The GAUSS IDE workspace.
+
+① **Toolbar** — Shows your current working directory. The **Run button** (green arrow) is here — click it or press F5 to execute your program.
+
+② **Project Folders** — Browse and open files in your working directory. Double-click any ``.e`` file to open it in the editor.
+
+③ **Editor** — Write and edit programs here. Save as ``.e`` files.
+
+④ **Command Window** — Output appears here after you run code. You can also type single lines directly at the ``>>`` prompt.
+
+For this guide, we'll start in the **Command Window** ④. Look for the prompt — it might show ``>>`` or just a blinking cursor. That's where you type.
+
+Two Ways to Run Code
+--------------------
+
+**Way 1: Command Window (interactive)**
+
+1. Click in the Command Window
+2. Type a command
+3. Press Enter
+4. See the result immediately
+
+Good for: testing ideas, quick calculations, learning.
+
+**Way 2: Editor (programs)**
+
+1. Type multiple lines of code in the Editor
+2. Save the file (Ctrl+S or Cmd+S) with a ``.e`` extension
+3. Click Run (green arrow) or press F5
+4. See all results in the output area
+
+Good for: real work, saving your analysis, running multiple steps.
+
+For now, use the **Command Window**. We'll use the Editor later when programs get longer.
+
+Your First Program
+------------------
+
+Click in the Command Window and type this::
+
+ print "Hello, World!";
+
+Press Enter. You should see::
+
+ Hello, World!
+
+Congratulations—you just ran your first program.
+
+**What happened:**
+
+- ``print`` is a command that displays output
+- ``"Hello, World!"`` is the text to display (called a "string")
+- ``;`` marks the end of the instruction (required in GAUSS)
+
+Variables: Storing Information
+------------------------------
+
+A **variable** stores a value so you can use it later. Think of it as a labeled box.
+
+::
+
+ x = 5;
+ print x;
+
+Output::
+
+ 5.0000000
+
+**What happened:**
+
+- ``x = 5`` creates a variable named ``x`` and puts the value 5 in it
+- ``print x`` displays whatever is stored in ``x``
+
+You can change what's in a variable::
+
+ x = 5;
+ print x;
+
+ x = 10;
+ print x;
+
+Output::
+
+ 5.0000000
+ 10.000000
+
+And use variables in calculations::
+
+ x = 5;
+ y = 3;
+ z = x + y;
+ print z;
+
+Output::
+
+ 8.0000000
+
+Naming rules:
+
+- Start with a letter (not a number)
+- Use letters, numbers, and underscores
+- Case sensitive (``X`` and ``x`` are different)
+- Good: ``price``, ``total_sales``, ``gdp2020``
+- Bad: ``2price``, ``total-sales``, ``my variable``
+
+Basic Math
+----------
+
+GAUSS handles arithmetic like a calculator::
+
+ a = 2 + 3; // Addition
+ print a;
+
+ b = 10 - 4; // Subtraction
+ print b;
+
+ c = 5 * 6; // Multiplication
+ print c;
+
+ d = 20 / 4; // Division
+ print d;
+
+ e = 2^3; // Exponent (2 to the power of 3)
+ print e;
+
+Output::
+
+ 5.0000000
+ 6.0000000
+ 30.000000
+ 5.0000000
+ 8.0000000
+
+The ``//`` starts a **comment**—text the computer ignores. Comments explain your code to humans.
+
+Order of operations follows standard math rules (PEMDAS)::
+
+ y = 2 + 3 * 4; // 3*4 first, then +2 = 14
+ print y;
+
+ z = (2 + 3) * 4; // Parentheses first = 20
+ print z;
+
+Output::
+
+ 14.000000
+ 20.000000
+
+Matrices: GAUSS's Superpower
+----------------------------
+
+A **matrix** is a grid of numbers. GAUSS is built around matrices—they're the core data type.
+
+Create a matrix with braces ``{ }``::
+
+ // A 2x3 matrix (2 rows, 3 columns)
+ A = { 1 2 3,
+ 4 5 6 };
+ print A;
+
+Output::
+
+ 1.0000000 2.0000000 3.0000000
+ 4.0000000 5.0000000 6.0000000
+
+**Syntax:**
+
+- ``{ }`` encloses the matrix
+- Spaces separate columns
+- Commas separate rows
+- ``;`` ends the statement
+
+A single number is just a 1x1 matrix::
+
+ x = 5; // This is a 1x1 matrix
+ y = { 5 }; // Same thing
+
+A column of numbers (a "vector")::
+
+ prices = { 10.50,
+ 12.75,
+ 9.99,
+ 15.00 };
+ print prices;
+
+Matrix dimensions::
+
+ A = { 1 2 3, 4 5 6 };
+ print rows(A); // Number of rows
+ print cols(A); // Number of columns
+
+Output::
+
+ 2.0000000
+ 3.0000000
+
+Getting Specific Values
+-----------------------
+
+Access elements with square brackets ``[ ]``::
+
+ A = { 10 20 30,
+ 40 50 60 };
+
+ print A[1, 1]; // Row 1, Column 1
+ print A[2, 3]; // Row 2, Column 3
+ print A[1, .]; // Row 1, all columns
+ print A[., 2]; // All rows, Column 2
+
+Output::
+
+ 10.000000
+ 60.000000
+ 10.000000 20.000000 30.000000
+ 20.000000
+ 50.000000
+
+**Key points:**
+
+- Counting starts at 1 (not 0 like some languages)
+- Use ``.`` to mean "all" rows or columns
+- ``A[1, .]`` = first row
+- ``A[., 1]`` = first column
+
+Ranges with ``:``::
+
+ A = { 1 2 3 4 5,
+ 6 7 8 9 10 };
+
+ print A[1, 2:4]; // Row 1, columns 2 through 4
+ print A[1:2, 1:2]; // Rows 1-2, columns 1-2
+
+Output::
+
+ 2.0000000 3.0000000 4.0000000
+
+ 1.0000000 2.0000000
+ 6.0000000 7.0000000
+
+Math with Matrices
+------------------
+
+Add, subtract, multiply, divide—element by element::
+
+ A = { 1 2, 3 4 };
+ B = { 10 20, 30 40 };
+
+ C = A + B; // Add corresponding elements
+ print C;
+
+ D = A .* B; // Multiply corresponding elements
+ print D;
+
+Output::
+
+ 11.000000 22.000000
+ 33.000000 44.000000
+
+ 10.000000 40.000000
+ 90.000000 160.00000
+
+**Important:** The ``.`` before ``*`` means "element-wise." Without it, ``*`` does matrix multiplication (a different operation)::
+
+ A = { 1 2, 3 4 };
+ B = { 10 20, 30 40 };
+
+ C = A .* B; // Element-wise: 1*10, 2*20, 3*30, 4*40
+ print C;
+
+ D = A * B; // Matrix multiply: row-by-column
+ print D;
+
+Output::
+
+ 10.000000 40.000000
+ 90.000000 160.00000
+
+ 70.000000 100.00000
+ 150.00000 220.00000
+
+Scalar operations apply to every element::
+
+ A = { 1 2, 3 4 };
+
+ B = A + 10; // Add 10 to every element
+ print B;
+
+ C = A * 2; // Multiply every element by 2
+ print C;
+
+ D = A^2; // Square every element
+ print D;
+
+Output::
+
+ 11.000000 12.000000
+ 13.000000 14.000000
+
+ 2.0000000 4.0000000
+ 6.0000000 8.0000000
+
+ 1.0000000 4.0000000
+ 9.0000000 16.000000
+
+Useful Functions
+----------------
+
+GAUSS has hundreds of built-in functions. Here are the most common:
+
+**Statistics:**
+
+::
+
+ data = { 10, 20, 30, 40, 50 };
+
+ print meanc(data); // Average (mean)
+ print stdc(data); // Standard deviation
+ print sumc(data); // Sum
+ print minc(data); // Minimum
+ print maxc(data); // Maximum
+
+Output::
+
+ 30.000000
+ 15.811388
+ 150.00000
+ 10.000000
+ 50.000000
+
+The ``c`` in ``meanc``, ``sumc`` etc. means "column"—these work down columns.
+
+**Math functions:**
+
+::
+
+ print sqrt(16); // Square root
+ print ln(2.718); // Natural log
+ print exp(1); // e^1
+ print abs(-5); // Absolute value
+
+Output::
+
+ 4.0000000
+ 0.99989631
+ 2.7182818
+ 5.0000000
+
+Loading Data
+------------
+
+Real analysis uses data from files, not typed-in numbers::
+
+ // Load a CSV file
+ data = loadd("housing.csv");
+
+ // See what you loaded
+ print rows(data) "rows";
+ print cols(data) "columns";
+
+ // View first 5 rows
+ print data[1:5, .];
+
+**How** ``print`` **works:** ``print`` takes a space-separated list of items and displays them on one line. Here, ``rows(data)`` and ``"rows"`` are two separate items printed together.
+
+You can also print expressions directly::
+
+ a = 3;
+ b = 4;
+ print a + b; // Prints 7
+
+The ``loadd`` function reads CSV, Excel, and other formats automatically. It returns a **dataframe**—a matrix where columns have names. This lets you refer to columns by name (like ``data[., "price"]``) instead of by number.
+
+If the file isn't in your working directory, use the full path::
+
+ data = loadd("/Users/yourname/Documents/data/housing.csv");
+
+Or use GAUSS's example data::
+
+ data = loadd(getGAUSSHome("examples/housing.csv"));
+
+Writing a Simple Analysis
+-------------------------
+
+Now it's time to use the **Editor** instead of the Command Window. When you have multiple lines of code, the Editor is easier:
+
+1. Click in the Editor panel (the large area, usually on the right)
+2. Type or paste the code below
+3. Save the file: File → Save As, name it ``housing_analysis.e``
+4. Run it: Click the green Run button or press F5
+
+Let's put it together—load data, calculate statistics, show results::
+
+ // Load housing data
+ data = loadd(getGAUSSHome("examples/housing.csv"));
+
+ // Extract the price column (loadd creates a dataframe with named columns)
+ prices = data[., "price"];
+
+ // Calculate statistics
+ avg_price = meanc(prices);
+ std_price = stdc(prices);
+ min_price = minc(prices);
+ max_price = maxc(prices);
+
+ // Display results
+ print "Housing Price Summary";
+ print "=====================";
+ print "Average: $" avg_price "thousand";
+ print "Std Dev: $" std_price "thousand";
+ print "Minimum: $" min_price "thousand";
+ print "Maximum: $" max_price "thousand";
+
+Output::
+
+ Housing Price Summary
+ =====================
+ Average: $ 155.33100 thousand
+ Std Dev: $ 101.26221 thousand
+ Minimum: $ 21.000000 thousand
+ Maximum: $ 587.00000 thousand
+
+Common Errors (and How to Fix Them)
+-----------------------------------
+
+**Missing semicolon:**
+
+::
+
+ x = 5
+ print x;
+
+Error: ``G0008 : Syntax error 'print'``
+
+Fix: Add ``;`` after every statement::
+
+ x = 5;
+ print x;
+
+**Undefined variable:**
+
+::
+
+ print y;
+
+Error: ``G0025 : Undefined symbol: 'y'``
+
+Fix: Make sure you created the variable first::
+
+ y = 10;
+ print y;
+
+**File not found:**
+
+::
+
+ data = loadd("mydata.csv");
+
+Error: ``csvRead error: file 'mydata.csv' not found``
+
+Fix: Check the filename and use the full path if needed::
+
+ data = loadd("/full/path/to/mydata.csv");
+
+**Dimension mismatch:**
+
+::
+
+ A = { 1 2, 3 4 };
+ B = { 1, 2, 3 };
+ C = A * B;
+
+Error: ``G0036 : Matrix dimensions are incompatible``
+
+Fix: Make sure matrices have compatible dimensions for the operation. Here, ``A`` is 2x2 and ``B`` is 3x1—they can't be multiplied.
+
+Next Steps
+----------
+
+You now understand:
+
+- Variables and basic math
+- Matrices (creating, indexing, operations)
+- Loading data
+- Using functions
+- Common errors
+
+Ready for more?
+
+- :doc:`quickstart` — A faster-paced introduction with more features
+- :doc:`../data-management` — Working with real datasets
+- :doc:`running-existing-code` — If you have code to run
+
+Practice suggestion: Try modifying the housing analysis above to calculate statistics for a different column (like ``size`` or ``beds``).
diff --git a/docs/getting-started/images/quickstart-ide.png b/docs/getting-started/images/quickstart-ide.png
new file mode 100644
index 00000000..9c7f39ca
Binary files /dev/null and b/docs/getting-started/images/quickstart-ide.png differ
diff --git a/docs/getting-started/images/quickstart_histogram.png b/docs/getting-started/images/quickstart_histogram.png
new file mode 100644
index 00000000..ab604d2a
Binary files /dev/null and b/docs/getting-started/images/quickstart_histogram.png differ
diff --git a/docs/getting-started/images/quickstart_scatter.png b/docs/getting-started/images/quickstart_scatter.png
new file mode 100644
index 00000000..00076fba
Binary files /dev/null and b/docs/getting-started/images/quickstart_scatter.png differ
diff --git a/docs/getting-started/images/quickstart_timeseries.png b/docs/getting-started/images/quickstart_timeseries.png
new file mode 100644
index 00000000..8895292b
Binary files /dev/null and b/docs/getting-started/images/quickstart_timeseries.png differ
diff --git a/docs/getting-started/images/running-existing-code.png b/docs/getting-started/images/running-existing-code.png
new file mode 100644
index 00000000..4b000bf0
Binary files /dev/null and b/docs/getting-started/images/running-existing-code.png differ
diff --git a/docs/getting-started/index.rst b/docs/getting-started/index.rst
new file mode 100644
index 00000000..2036582c
--- /dev/null
+++ b/docs/getting-started/index.rst
@@ -0,0 +1,54 @@
+
+Getting Started
+===============
+
+New to GAUSS? Start here.
+
+.. grid:: 2
+
+ .. grid-item-card::
+ :shadow: none
+ :link: what-is-gauss
+ :link-type: doc
+
+ **What is GAUSS?**
+
+ Overview of GAUSS, who uses it, and why.
+
+ .. grid-item-card::
+ :shadow: none
+ :link: quickstart
+ :link-type: doc
+
+ **Quickstart**
+
+ Run your first GAUSS code in 10 minutes.
+
+.. grid:: 2
+
+ .. grid-item-card::
+ :shadow: none
+ :link: running-existing-code
+ :link-type: doc
+
+ **Running Existing Code**
+
+ Inherited GAUSS code? Get it running.
+
+ .. grid-item-card::
+ :shadow: none
+ :link: absolute-basics
+ :link-type: doc
+
+ **Absolute Basics**
+
+ New to programming? Start here.
+
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+
+ what-is-gauss
+ quickstart
+ running-existing-code
+ absolute-basics
diff --git a/docs/getting-started/quickstart.rst b/docs/getting-started/quickstart.rst
new file mode 100644
index 00000000..224aada0
--- /dev/null
+++ b/docs/getting-started/quickstart.rst
@@ -0,0 +1,281 @@
+
+GAUSS Quickstart
+================
+
+This 10-minute guide gets you writing and running GAUSS code. You'll learn to create matrices, load data, run a regression, and make a plot.
+
+Prerequisites
+-------------
+
+- GAUSS installed
+- Basic familiarity with any programming language (helpful but not required)
+
+**Where to type code:** Open GAUSS and create a new program file (File → New). Type or paste the examples below, then click the **Run** button to execute. You can also type single lines in the **Command Window** at the bottom.
+
+.. figure:: images/quickstart-ide.png
+ :width: 100%
+ :alt: The GAUSS application showing code in the Editor and output in the Command Window
+
+ Code goes in the **Editor** (top right). Output appears in the **Command Window** (bottom).
+
+Creating Matrices
+-----------------
+
+Everything in GAUSS is built on matrices. A **dataframe** is a matrix with named, typed columns -- you get one when you load data with :func:`loadd`. We'll start with plain matrices, then work with dataframes starting in `Loading Data`_ below.
+
+Every GAUSS statement ends with a semicolon (``;``). Lines starting with ``//`` are comments.
+
+Create a matrix by listing values in braces, with spaces separating columns and commas separating rows:
+
+::
+
+ // A 3x3 matrix
+ x = { 1 2 3,
+ 4 5 6,
+ 7 8 9 };
+ print x;
+
+Output::
+
+ 1.0000000 2.0000000 3.0000000
+ 4.0000000 5.0000000 6.0000000
+ 7.0000000 8.0000000 9.0000000
+
+Create sequences with :func:`seqa`:
+
+::
+
+ // Start at 1, increment by 1, 5 elements
+ x = seqa(1, 1, 5);
+ print x;
+
+Output::
+
+ 1.0000000
+ 2.0000000
+ 3.0000000
+ 4.0000000
+ 5.0000000
+
+Generate random data with :func:`rndn` (standard normal):
+
+::
+
+ // 3 rows, 4 columns of random normals
+ x = rndn(3, 4);
+ print x;
+
+Your output will differ since the values are random.
+
+Basic Operations
+----------------
+
+GAUSS uses ``*`` for matrix multiplication and ``.*`` for element-wise multiplication. The same dot-prefix pattern applies to division (``./``) and exponentiation (``.^``). Addition and subtraction (``+``, ``-``) always work element-wise:
+
+::
+
+ // A 5x1 column vector (commas separate rows)
+ x = { 1, 2, 3, 4, 5 };
+
+ // Element-wise square
+ y = x.^2;
+
+ // Horizontal concatenation with ~ (joins columns side by side)
+ print x~y;
+
+Output::
+
+ 1.0000000 1.0000000
+ 2.0000000 4.0000000
+ 3.0000000 9.0000000
+ 4.0000000 16.000000
+ 5.0000000 25.000000
+
+Common statistical functions:
+
+::
+
+ x = rndn(100, 3);
+
+ print "Column means:";
+ print meanc(x);
+
+ print "Column std devs:";
+ print stdc(x);
+
+ // sumc sums each column; nest it to get the grand total
+ print "Sum of all elements:";
+ print sumc(sumc(x));
+
+Loading Data
+------------
+
+Use :func:`loadd` to load CSV, Excel, SAS, Stata, or GAUSS datasets:
+
+::
+
+ // Get full path to a dataset included with GAUSS
+ fname = getGAUSSHome("examples/housing.csv");
+
+ // Load the data
+ data = loadd(fname);
+
+ print rows(data) "rows," cols(data) "columns";
+
+Output::
+
+ 100.00000 rows, 6.0000000 columns
+
+View column names:
+
+::
+
+ print getcolnames(data);
+
+Output::
+
+ taxes
+ beds
+ baths
+ new
+ price
+ size
+
+Preview the first few rows (the ``.`` means "all columns"):
+
+::
+
+ print data[1:5, .];
+
+Output::
+
+ taxes beds baths new price size
+ 3104.0000 4.0000000 2.0000000 0.0000000 279.90000 2048.0000
+ 1173.0000 2.0000000 1.0000000 0.0000000 146.50000 912.00000
+ 3076.0000 4.0000000 2.0000000 0.0000000 237.70000 1654.0000
+ 1608.0000 3.0000000 2.0000000 0.0000000 200.00000 2068.0000
+ 1454.0000 3.0000000 3.0000000 0.0000000 159.90000 1477.0000
+
+Running a Regression
+--------------------
+
+Use :func:`olsmt` for OLS regression with a formula string. Inside the formula, ``~`` separates the dependent variable from the independent variables, and ``+`` lists the predictors. (This ``~`` is unrelated to the concatenation operator — it only has this meaning inside a formula string.)
+
+``call`` discards the return value — use it when you just want the printed report:
+
+::
+
+ // Load the housing dataset
+ fname = getGAUSSHome("examples/housing.csv");
+ data = loadd(fname);
+
+ // Regress price on beds, baths, and size
+ call olsmt(data, "price ~ beds + baths + size");
+
+Output::
+
+ Ordinary Least Squares
+ ====================================================================================
+ Valid cases: 100 Dependent variable: price
+ Missing cases: 0 Deletion method: None
+ Total SS: 1.02e+06 Degrees of freedom: 96
+ R-squared: 0.701 Rbar-squared: 0.692
+ Residual SS: 3.03e+05 Std. err of est: 56.2
+ F(3,96): 75.1 Probability of F: 4.38e-25
+ ====================================================================================
+ Standard Prob Lower Upper
+ Variable Estimate Error t-value >|t| Bound Bound
+ ------------------------------------------------------------------------------------
+
+ CONSTANT -27.29 28.241 -0.96634 0.3363 -82.641 28.061
+ beds -14.466 10.583 -1.3668 0.17487 -35.209 6.2779
+ baths 6.8903 13.54 0.50888 0.612 -19.648 33.429
+ size 0.13043 0.011951 10.914 1.6423e-18 0.10701 0.15386
+ ====================================================================================
+
+The output shows coefficients, standard errors, t-values, p-values, and confidence intervals. House size is the only significant predictor (p < 0.001).
+
+Creating Plots
+--------------
+
+GAUSS has built-in plotting functions. Here's a scatter plot:
+
+::
+
+ // Generate sample data
+ x = seqa(1, 0.5, 20);
+ y = 2 + 0.5*x + rndn(20, 1)*0.3;
+
+ // Create a scatter plot
+ plotScatter(x, y);
+
+.. figure:: images/quickstart_scatter.png
+ :width: 600px
+ :alt: Sample scatter plot
+
+ A basic scatter plot
+
+Customize plots with a ``plotControl`` structure. Create one, set options on it with ``plotSet`` functions, then pass it to the plot call. The ``&`` before the structure name is required so the function can update the settings:
+
+::
+
+ struct plotControl myPlot;
+ myPlot = plotGetDefaults("scatter");
+
+ plotSetTitle(&myPlot, "Housing: Price vs Size");
+ plotSetXLabel(&myPlot, "Square Feet");
+ plotSetYLabel(&myPlot, "Price ($000s)");
+
+ fname = getGAUSSHome("examples/housing.csv");
+ data = loadd(fname);
+
+ // data[., "size"] selects all rows of the column named "size"
+ plotScatter(myPlot, data[., "size"], data[., "price"]);
+
+For histograms:
+
+::
+
+ fname = getGAUSSHome("examples/housing.csv");
+ data = loadd(fname);
+ plotHist(data[., "price"], 15);
+
+.. figure:: images/quickstart_histogram.png
+ :width: 600px
+ :alt: Histogram of housing prices
+
+ Distribution of housing prices
+
+Saving Your Work
+----------------
+
+Save the most recent plot to a file with :func:`plotSave`. The ``|`` operator stacks values into a column vector — here it creates a 2x1 width-by-height size:
+
+::
+
+ // Save the last plot as an 800x600 PNG
+ plotSave("my_scatter.png", 800|600, "px");
+
+Files are saved to your GAUSS working directory (shown at the top of the GAUSS window).
+
+Save data with :func:`saved`:
+
+::
+
+ // Save as CSV
+ saved(data, "mydata.csv");
+
+ // Save as GAUSS dataset (.gdat preserves column names and types)
+ saved(data, "mydata.gdat");
+
+What's Next?
+------------
+
+- :doc:`absolute-basics` — If you're new to programming
+- :doc:`running-existing-code` — If you inherited GAUSS code
+- :doc:`../data-management` — Loading and transforming data
+- :doc:`../command-reference` — Full function reference
+
+.. seealso::
+
+ :func:`loadd`, :func:`olsmt`, :func:`plotScatter`, :func:`plotXY`, :func:`meanc`, :func:`stdc`
diff --git a/docs/getting-started/running-existing-code.rst b/docs/getting-started/running-existing-code.rst
new file mode 100644
index 00000000..b1c7fc67
--- /dev/null
+++ b/docs/getting-started/running-existing-code.rst
@@ -0,0 +1,358 @@
+
+Running Existing Code
+=====================
+
+You've inherited GAUSS code from a colleague, downloaded replication files for a paper, or received code from your advisor. This guide helps you get it running.
+
+Before You Start
+----------------
+
+Before clicking Run, take a few minutes to inventory what you have:
+
+1. **Read any README or notes files** in the folder.
+2. **Identify the main program file.** This is the file you will run — usually named ``main``, ``run``, or ``master``, with a ``.gss`` or ``.prg`` extension. Files ending in ``.src`` contain helper procedures and should not be run directly — they are loaded by the main program. If no file has an obvious name, open each ``.gss`` file and look for the one with ``#include`` statements and data loading near the top — that is the entry point.
+3. **Check for ``#include`` lines.** Open the main file and scan for ``#include`` statements. Make sure you have all the files they reference.
+4. **Check for ``library`` lines.** These load add-on packages. Check Tools → Package Manager to see if the required packages are installed.
+5. **Check for data files.** Scan for ``loadd``, ``csvReadM``, or ``load`` statements. Make sure you have all the data files they reference.
+
+Opening and Running a File
+--------------------------
+
+GAUSS programs are plain text files. The modern convention is ``.gss`` for program files and ``.src`` for source files that only contain procedure definitions. Shared or older code may use other extensions such as ``.prg``, ``.gau``, ``.e``, or even ``.txt``. If a file has a ``.txt`` extension, use File → Save As to save it as ``.gss`` — this enables syntax highlighting.
+
+1. File → Open (or Ctrl+O / Cmd+O)
+2. Navigate to the main program file
+3. Click the **Run** button or press F5
+
+.. figure:: images/running-existing-code.png
+ :width: 100%
+ :alt: A GAUSS program file open in the editor with output in the Command Window
+
+ A program file open in the **Editor** with successful output in the **Command Window**.
+
+When a program runs successfully, results from ``print`` statements and estimation procedures appear in the **Command Window** at the bottom of the screen. Plots open in a separate window. Some programs save output to files — look for ``output file =`` or :func:`saved` statements in the code. If the program finishes without errors but you don't see output, check whether results were written to a file in your working directory.
+
+Common First-Run Errors
+-----------------------
+
+File Not Found
+^^^^^^^^^^^^^^
+
+::
+
+ error G0014 : 'loadd' : File not found: data.csv
+
+**Cause:** GAUSS can't find a data file the code references.
+
+**Solutions:**
+
+1. **Check the working directory.** The code may assume files are in a specific location.
+
+ ::
+
+ // See current working directory
+ print cdir(0);
+
+ // Change to the folder containing your data
+ chdir "/path/to/your/data";
+
+2. **Use absolute paths.** Edit the code to specify the full path:
+
+ ::
+
+ // Instead of:
+ data = loadd("mydata.csv");
+
+ // Use:
+ data = loadd("/Users/you/research/project/mydata.csv");
+
+3. **Copy data files** to the same folder as the program file.
+
+Undefined Symbol
+^^^^^^^^^^^^^^^^
+
+::
+
+ error G0025 : Undefined symbol: 'olsmt'
+
+**Cause:** The code uses a function that isn't loaded.
+
+**Solutions:**
+
+1. **Missing library statement.** Add at the top of the file:
+
+ ::
+
+ library tsmt, cmlmt; // Load required libraries
+
+2. **Missing add-on package.** Some functions require separately installed packages:
+
+ - ``olsmt``, ``glm`` → Base GAUSS (should work)
+ - ``varma``, ``varmares`` → TSMT (Time Series MT)
+ - ``dcc``, ``garch`` → FANPAC or TSMT
+ - ``cmlmt``, ``comt`` → Optimization packages
+ - ``dcm`` → Discrete Choice Models
+
+ Check Tools → Package Manager to see installed packages.
+
+3. **Missing procedure definition.** The code may call a custom procedure defined in another file. Look for:
+
+ ::
+
+ // Load procedures from another file
+ #include "helper_functions.src"
+
+ Make sure that file exists in the same directory or in your GAUSS source path.
+
+Library Not Found
+^^^^^^^^^^^^^^^^^
+
+::
+
+ error G0044 : Library not found: tsmt
+
+**Cause:** Code requires an add-on package you don't have.
+
+**Solution:** Contact Aptech to purchase/license the required package, or comment out the library statement and related code to see what else runs.
+
+Outdated ``load`` Statement
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Older code may load data with the ``load`` statement:
+
+::
+
+ load x[] = C:\data\mydata.prn;
+ load x[24,7] = C:\data\mydata.txt;
+
+**Do not use this pattern.** When dimensions are specified (e.g., ``x[24,7]``), GAUSS forces the data into that shape — silently recycling or truncating values and potentially putting data in the wrong columns. Replace ``load`` with :func:`csvReadM` for headerless numeric files:
+
+::
+
+ // Read numeric data with default comma separator
+ x = csvReadM("C:\\data\\mydata.txt");
+
+ // Specify a different separator: tab, space, or semicolon
+ x = csvReadM("C:\\data\\mydata.txt", "\t"); // tab
+ x = csvReadM("C:\\data\\mydata.txt", " "); // space
+ x = csvReadM("C:\\data\\mydata.txt", ";"); // semicolon
+
+If the file has column headers (or you can add them), rename it to ``.csv`` and use :func:`loadd` instead — this gives you a dataframe with named columns.
+
+Outdated ``pgraph`` Plotting
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Older code may use the ``pgraph`` library for plotting:
+
+::
+
+ library pgraph;
+ xy(x, y);
+
+The ``pgraph`` library and its functions (``xy``, ``bar``, ``hist``, ``surface``, ``contour``, etc.) have been replaced by modern built-in plotting functions. Remove the ``library pgraph;`` line and replace the old function calls:
+
+================= =========================
+Old (pgraph) Modern replacement
+================= =========================
+``xy(x, y)`` ``plotXY(x, y)``
+``bar(x, y)`` ``plotBar(x, y)``
+``hist(x, bins)`` ``plotHist(x, bins)``
+``surface(x)`` ``plotSurface(x)``
+``contour(x)`` ``plotContour(x)``
+================= =========================
+
+The modern ``plot`` functions support the same data but also offer customization through ``plotControl`` structures. See :doc:`quickstart` for an example.
+
+``library`` vs. ``#include``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These serve different purposes:
+
+- ``library tsmt;`` loads an installed add-on package. It makes all functions from that package available.
+- ``#include "file.src"`` reads in the contents of a specific file. Code from colleagues typically uses ``#include`` for their custom procedures and ``library`` for commercial GAUSS packages.
+
+Understanding ``#include``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Code often loads procedures from other files with ``#include``:
+
+::
+
+ #include "helper_functions.src"
+ #include "utilities.gau"
+
+This reads in the contents of that file before your program runs — it's how code reuses procedures defined elsewhere. GAUSS searches for included files in this order:
+
+1. Your current working directory (shown at the top of the GAUSS window)
+2. Directories listed in your source path (Edit → Preferences → Source Path)
+
+Note that GAUSS searches the **working directory**, not the directory containing the program file — these may be different. If you get a file-not-found error on an ``#include``, the easiest fix is to add ``#includedir`` (with no argument) at the very top of the program:
+
+::
+
+ #includedir
+ #include "helper_functions.src"
+
+This adds the program file's own directory to the source path, so GAUSS will find other files in the same folder regardless of your working directory. If the included files are in a subfolder, specify it as a relative path:
+
+::
+
+ #includedir src
+ #include "helper_functions.src"
+
+Some code uses many ``#include`` statements. Check that you received **all** the files, not just the main program.
+
+If you can't find an included file, ask the person who sent you the code — it likely contains custom procedures that the main program depends on.
+
+Understanding Code Structure
+----------------------------
+
+GAUSS programs typically follow this structure:
+
+::
+
+ // 1. Library declarations (only needed for add-on packages)
+ library tsmt;
+
+ // 2. Global settings or data paths
+ data_path = "/path/to/data/";
+
+ // 3. Load data
+ data = loadd(data_path $+ "mydata.csv");
+
+ // 4. Data preparation
+ y = data[., "gdp"];
+ x = data[., "date"];
+
+ // 5. Analysis
+ call adf(y, 4);
+
+ // 6. Output/plots
+ plotXY(x, y);
+
+Key Syntax to Recognize
+-----------------------
+
+**Semicolons** end statements (required):
+
+::
+
+ x = 5; // Correct
+ x = 5 // Error: missing semicolon
+
+**Comments:**
+
+::
+
+ // Single line comment
+ /* Multi-line
+ comment */
+
+**String concatenation** uses ``$+``:
+
+::
+
+ path = "/data/" $+ "file.csv";
+
+**Matrix indexing** uses square brackets (1-based):
+
+::
+
+ x[1, 2] // Row 1, column 2
+ x[1:5, .] // Rows 1-5, all columns
+ x[., 1] // All rows, column 1
+
+**Discarding return values** — use ``call`` to run a function for its printed output without storing the result:
+
+::
+
+ call olsmt(data, "y ~ x1 + x2"); // Print the report, discard the return value
+
+**Procedures** are defined with ``proc`` and ``endp``. The ``(1)`` is the number of return values. ``local`` declares variables that only exist inside the procedure — without it, variables are global:
+
+::
+
+ proc (1) = myfunction(x);
+ local result; // Local to this procedure
+ result = x^2;
+ retp(result); // Return the result
+ endp;
+
+**Structures** group related results together. Many GAUSS functions return a structure instead of a single value:
+
+::
+
+ struct olsmtOut out;
+ out = olsmt(data, "y ~ x1 + x2");
+
+ print out.b; // Coefficients
+ print out.stderr; // Standard errors
+
+Installing Required Libraries
+-----------------------------
+
+If code requires add-on packages:
+
+1. **Browse and install packages:** Tools → Package Manager
+2. **Install a downloaded package:** Tools → Install Application
+3. **Purchase add-ons:** Contact sales@aptech.com
+
+Common packages for econometrics:
+
+================= ===============================================
+Package Functions
+================= ===============================================
+TSMT Time series: VAR, GARCH, state-space, forecasting
+Optmum/CO/ML Optimization, maximum likelihood
+DCM Discrete choice models
+FANPAC Financial analysis, GARCH variants
+================= ===============================================
+
+Setting Up Source Paths
+-----------------------
+
+If code includes files from multiple directories, set paths in GAUSS:
+
+1. Edit → Preferences → Source Path
+2. Add directories containing your ``.src`` files
+
+This tells GAUSS where to find ``#include`` files and procedure definitions.
+
+Debugging Tips
+--------------
+
+**Print intermediate values:**
+
+::
+
+ print "x dimensions:" rows(x) cols(x);
+ print "First 5 rows:";
+ print x[1:5, .];
+
+**Step through code:** Use the GAUSS debugger (F8 to set breakpoint, F5 to run to breakpoint).
+
+**Check variable types:**
+
+::
+
+ print type(x); // 6 = matrix/dataframe, 13 = string, 21 = string array
+
+**Run code section by section:** Highlight lines and press F4 to run selection.
+
+Getting Help
+------------
+
+Press **F1** with the cursor on a function name to open its documentation. You can also use the Help menu to browse the Command Reference.
+
+If you're looking for a function but don't know its name, open the Help menu and search the Command Reference. The documentation page for each function shows which package it belongs to.
+
+.. seealso::
+
+ :doc:`quickstart` — Learn GAUSS basics from scratch
+
+ **Coming from another language?** Side-by-side guides for
+ :doc:`../coming-to-gauss/intro-gauss-for-stata-users`,
+ :doc:`../coming-to-gauss/intro-gauss-for-r-users`,
+ :doc:`../coming-to-gauss/intro-gauss-for-matlab-users`,
+ :doc:`../coming-to-gauss/intro-gauss-for-eviews-users`, and
+ :doc:`../coming-to-gauss/intro-gauss-for-python-users`.
diff --git a/docs/getting-started/what-is-gauss.rst b/docs/getting-started/what-is-gauss.rst
new file mode 100644
index 00000000..3df65033
--- /dev/null
+++ b/docs/getting-started/what-is-gauss.rst
@@ -0,0 +1,110 @@
+
+What is GAUSS?
+==============
+
+GAUSS is a matrix programming language designed for computationally intensive tasks in statistics, econometrics, and data analysis. Developed by Aptech Systems since 1984, it combines the speed of compiled code with the flexibility of an interpreted environment.
+
+Who Uses GAUSS?
+---------------
+
+GAUSS is used by:
+
+- **Central banks** for forecasting, policy analysis, and financial stability research
+- **Academic economists** for econometric research and teaching
+- **Financial institutions** for risk modeling and quantitative analysis
+- **Transportation researchers** for discrete choice modeling
+- **Government agencies** for economic forecasting
+
+Why Choose GAUSS?
+-----------------
+
+**Purpose-built for econometrics.** Unlike general-purpose languages, GAUSS was designed from the start for matrix mathematics and statistical computing. This means:
+
+- Matrix operations are first-class citizens, not library add-ons
+- Statistical functions work the way econometricians expect
+- Time series, panel data, and limited dependent variable tools are available out of the box or through specialized add-ons
+
+**Speed.** GAUSS compiles to native code and uses optimized numerical libraries. For computationally intensive work—Monte Carlo simulations, bootstrapping, large-scale optimization—this matters.
+
+**40 years of reliability.** Code written in GAUSS in the 1990s still runs today. When you build research infrastructure in GAUSS, it lasts.
+
+**Interactive and batch modes.** Explore data interactively in the GUI, then run production jobs in batch mode on servers.
+
+What Can You Do with GAUSS?
+---------------------------
+
+**Time series analysis:**
+
+- ARIMA, GARCH, VAR/VECM models
+- State-space models and Kalman filtering
+- Forecasting with multiple methods
+
+**Econometric estimation:**
+
+- OLS, GLS, IV, GMM
+- Maximum likelihood estimation
+- Bayesian methods (MCMC)
+
+**Panel data:**
+
+- Fixed and random effects
+- Dynamic panels
+- Clustered standard errors
+
+**Discrete choice:**
+
+- Logit, probit, multinomial models
+- Mixed logit with simulation
+- Nested logit structures
+
+**General computation:**
+
+- Matrix algebra and linear algebra
+- Numerical optimization
+- Simulation and Monte Carlo
+
+Core Concepts
+-------------
+
+**Everything is a matrix.** In GAUSS, scalars are 1×1 matrices, vectors are Nx1 or 1xN matrices, and multi-dimensional data lives in matrices or dataframes.
+
+**Dataframes** extend matrices with column names, types (numeric, string, date, category), and metadata—similar to dataframes in R or pandas.
+
+**Procedures** are user-defined functions. GAUSS ships with hundreds of built-in procedures; you can write your own or use add-on packages.
+
+**Libraries** group related procedures. Load them with ``library libname;`` to access specialized functionality.
+
+GAUSS vs. Other Tools
+---------------------
+
+=============== =============== =============== ===============
+Aspect GAUSS MATLAB Stata/EViews
+=============== =============== =============== ===============
+Primary focus Econometrics Engineering Statistics/Econ
+Matrix syntax Native Native Command-based
+Speed Fast Fast Moderate
+Custom code Easy Easy Limited
+Time series Strong (TSMT) Moderate Strong
+GUI workflow GUI + code GUI + code GUI-centric
+=============== =============== =============== ===============
+
+See our "Coming from..." guides for detailed comparisons:
+
+- :doc:`../coming-to-gauss/intro-gauss-for-stata-users`
+- :doc:`../coming-to-gauss/intro-gauss-for-eviews-users`
+- :doc:`../coming-to-gauss/intro-gauss-for-matlab-users`
+- :doc:`../coming-to-gauss/intro-gauss-for-r-users`
+- :doc:`../coming-to-gauss/intro-gauss-for-python-users`
+
+Getting Started
+---------------
+
+Ready to try GAUSS?
+
+1. :doc:`quickstart` — Run your first GAUSS code in 10 minutes
+2. :doc:`running-existing-code` — If you have existing GAUSS code to run
+3. :doc:`absolute-basics` — If you're new to programming
+
+.. seealso::
+
+ `Aptech Systems `_ — Company website, downloads, support
diff --git a/docs/glm.rst b/docs/glm.rst
index 158899a9..28ce23d6 100644
--- a/docs/glm.rst
+++ b/docs/glm.rst
@@ -373,8 +373,8 @@ After running the code above, the output is :
gear_ratio 8.4236 0.44635 18.872 1.3699e-29
===================================================================
-Running a no intercept model from a SAS sas7bdat file.
-++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Running a no intercept model from a Stata dataset.
++++++++++++++++++++++++++++++++++++++++++++++++++++
::
diff --git a/docs/gradmt.rst b/docs/gradmt.rst
index 51752aa0..4b7b77b0 100644
--- a/docs/gradmt.rst
+++ b/docs/gradmt.rst
@@ -63,3 +63,5 @@ Source
------
gradmt.src
+
+.. seealso:: Functions :func:`gradMTm`, :func:`gradMTT`, :func:`hessMT`
diff --git a/docs/gradmtm.rst b/docs/gradmtm.rst
index ad10f5c4..6b414ce9 100644
--- a/docs/gradmtm.rst
+++ b/docs/gradmtm.rst
@@ -67,3 +67,5 @@ Source
------
gradmt.src
+
+.. seealso:: Functions :func:`gradMT`, :func:`hessMT`
diff --git a/docs/gradmtt.rst b/docs/gradmtt.rst
index 796ccf80..395bdc6c 100644
--- a/docs/gradmtt.rst
+++ b/docs/gradmtt.rst
@@ -61,3 +61,5 @@ Source
------
gradmtt.src
+
+.. seealso:: Functions :func:`gradMT`, :func:`hessMT`
diff --git a/docs/gradmttm.rst b/docs/gradmttm.rst
index eed50570..1dbb5e98 100644
--- a/docs/gradmttm.rst
+++ b/docs/gradmttm.rst
@@ -67,3 +67,5 @@ Source
------
gradmtt.src
+
+.. seealso:: Functions :func:`gradMT`, :func:`hessMT`
diff --git a/docs/h.rst b/docs/h.rst
index dd09586c..72db7f0b 100644
--- a/docs/h.rst
+++ b/docs/h.rst
@@ -12,6 +12,7 @@ H
h5writeattribute
h5write
hacSE
+ hacse
hasimag
hasmetadata
head
@@ -32,4 +33,5 @@ H
histf
histp
hist
+ horizontal-concatenation
hsec
diff --git a/docs/h5create.rst b/docs/h5create.rst
index 34ae4fab..e0e05da8 100644
--- a/docs/h5create.rst
+++ b/docs/h5create.rst
@@ -138,14 +138,14 @@ Remarks
above string, do not yet exist, :func:`h5create` will create them.
- By default, HDF5 datasets may not change size. To make one of the
- dimensions expandable, set it to `__INFP`.
+ dimensions expandable, set it to ``__INFP``.
- All columns of an HDF5 dataset must be of the same data type.
However, multiple datasets with different data types may be created
in a single HDF5 file.
- Information about a dataset, called an attribute, may be attached to
a dataset in an HDF5 file with the function :func:`h5writeAttribute`.
- Chunk size must be specified when users create a dataset with more
- than 2 dimensions and one of those dimensions is unlimited (`__INFP`).
+ than 2 dimensions and one of those dimensions is unlimited (``__INFP``).
.. seealso:: Functions :func:`h5read`, :func:`h5write`, `open`, `create`, :func:`writer`, :func:`seekr`, :func:`eof`
diff --git a/docs/h5read.rst b/docs/h5read.rst
index 32d6a29e..651fe87c 100644
--- a/docs/h5read.rst
+++ b/docs/h5read.rst
@@ -40,7 +40,7 @@ Basic write then read entire contents of an HDF5 file
// Define a name of a dataset
dname = "/mydata";
- // Define a size of 4 rows and 3 columns
+ // Define a size of 3 rows and 2 columns
r = 3;
c = 2;
dims = r|c;
diff --git a/docs/hacse.rst b/docs/hacse.rst
index 79b9f5da..053a7934 100644
--- a/docs/hacse.rst
+++ b/docs/hacse.rst
@@ -24,7 +24,7 @@ Format
:param dataset: name of dataset.
:type dataset: string
- :param formula: `formula string` of the independent variables.
+ :param formula: ``formula string`` of the independent variables.
E.g :code:`"X1 + X2"`, '*X1*' and '*X2*' are names of independent variables;
:type formula: String
diff --git a/docs/header.rst b/docs/header.rst
index 55931115..b4e4f77a 100644
--- a/docs/header.rst
+++ b/docs/header.rst
@@ -68,3 +68,5 @@ Global Input
"f", "file name being analyzed is to be printed"
:__title: string, title for header.
+
+.. seealso:: Functions :func:`headermt`, :func:`output`
diff --git a/docs/headermt.rst b/docs/headermt.rst
index 7b0f819a..87692e88 100644
--- a/docs/headermt.rst
+++ b/docs/headermt.rst
@@ -81,3 +81,5 @@ Source
------
gaussmt.src
+
+.. seealso:: Functions :func:`header`, :func:`output`
diff --git a/docs/hessmt.rst b/docs/hessmt.rst
index 53cc4227..98c77504 100644
--- a/docs/hessmt.rst
+++ b/docs/hessmt.rst
@@ -67,3 +67,5 @@ Source
------
hessmt.src
+
+.. seealso:: Functions :func:`hessMTg`, :func:`hessMTm`, :func:`hessMTT`, :func:`gradMT`
diff --git a/docs/hessmtg.rst b/docs/hessmtg.rst
index e0621a59..0cdf5fd5 100644
--- a/docs/hessmtg.rst
+++ b/docs/hessmtg.rst
@@ -68,3 +68,5 @@ Source
------
hessmt.src
+
+.. seealso:: Functions :func:`hessMT`, :func:`gradMT`
diff --git a/docs/hessmtgw.rst b/docs/hessmtgw.rst
index f8debbea..bc57eb0f 100644
--- a/docs/hessmtgw.rst
+++ b/docs/hessmtgw.rst
@@ -74,3 +74,5 @@ Source
------
hessmt.src
+
+.. seealso:: Functions :func:`hessMT`, :func:`gradMT`
diff --git a/docs/hessmtm.rst b/docs/hessmtm.rst
index 55aa71f1..178f23e9 100644
--- a/docs/hessmtm.rst
+++ b/docs/hessmtm.rst
@@ -73,3 +73,5 @@ Source
------
hessmt.src
+
+.. seealso:: Functions :func:`hessMT`, :func:`gradMT`
diff --git a/docs/hessmtmw.rst b/docs/hessmtmw.rst
index fa2c9ab5..d78ea8b4 100644
--- a/docs/hessmtmw.rst
+++ b/docs/hessmtmw.rst
@@ -82,3 +82,5 @@ Source
------
hessmt.src
+
+.. seealso:: Functions :func:`hessMT`, :func:`gradMT`
diff --git a/docs/hessmtt.rst b/docs/hessmtt.rst
index 5da5a9a9..9c07341a 100644
--- a/docs/hessmtt.rst
+++ b/docs/hessmtt.rst
@@ -67,3 +67,5 @@ Source
------
hessmtt.src
+
+.. seealso:: Functions :func:`hessMT`, :func:`gradMT`
diff --git a/docs/hessmttg.rst b/docs/hessmttg.rst
index 13385a0b..38b9d15d 100644
--- a/docs/hessmttg.rst
+++ b/docs/hessmttg.rst
@@ -68,3 +68,5 @@ Source
------
hessmtt.src
+
+.. seealso:: Functions :func:`hessMT`, :func:`gradMT`
diff --git a/docs/hessmttgw.rst b/docs/hessmttgw.rst
index 61c9fb6a..c444f6ab 100644
--- a/docs/hessmttgw.rst
+++ b/docs/hessmttgw.rst
@@ -74,3 +74,5 @@ Source
------
hessmtt.src
+
+.. seealso:: Functions :func:`hessMT`, :func:`gradMT`
diff --git a/docs/hessmttm.rst b/docs/hessmttm.rst
index f89d4c19..ba384dfb 100644
--- a/docs/hessmttm.rst
+++ b/docs/hessmttm.rst
@@ -74,3 +74,5 @@ Source
------
hessmtt.src
+
+.. seealso:: Functions :func:`hessMT`, :func:`gradMT`
diff --git a/docs/hessmtw.rst b/docs/hessmtw.rst
index a5ebe453..c4a3d91f 100644
--- a/docs/hessmtw.rst
+++ b/docs/hessmtw.rst
@@ -75,3 +75,5 @@ Source
------
hessmt.src
+
+.. seealso:: Functions :func:`hessMT`, :func:`gradMT`
diff --git a/docs/i.rst b/docs/i.rst
index 300ca390..89f9c31f 100644
--- a/docs/i.rst
+++ b/docs/i.rst
@@ -12,6 +12,7 @@ I
includedir
indcv
indexcat
+ inequality
indices2
indicesfn
indicesf
diff --git a/docs/index.rst b/docs/index.rst
index e4524c59..377992a3 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,118 +1,137 @@
-.. title:: Explore
+.. title:: GAUSS Help
.. meta::
- :description: Looking for additional resources about GAUSS? Learn more about our built-in and Machine Learning functions. Find GAUSS documentation here.
+ :description: GAUSS in-app help. Search functions, browse by category, and find what's new.
-GAUSS documentation
-====================
-
-The GAUSS Platform provides a fully interactive environment for exploring data, performing calculations and analyzing results. These interactive features speed up your workflow, while the exceptionally fast GAUSS analytics engine will speed up your computations.
+GAUSS Help
+==========
.. role:: text-left
.. grid:: 2
- .. grid-item-card::
+ .. grid-item-card::
:shadow: none
- :class-header: text-center
+ :class-header: text-center
:class-body: text-center
- :link: command-reference
+ :link: getting-started/index
:link-type: doc
- API
- ^^^^^^
-
+ New to GAUSS?
+ ^^^^^^^^^^^^^
+
.. container:: icon-large
-
- :fa:`code`
-
+
+ :fa:`rocket`
+
.. container:: text-left
-
- View the comprehensive list of built-in commands and detailed help for each in GAUSS.
-
+
+ Start here with tutorials, quickstart guides, and language basics.
+
.. grid-item-card::
:shadow: none
- :class-header: text-center
+ :class-header: text-center
:class-body: text-center
- :link: learning-resources
+ :link: user-guide/index
:link-type: doc
- Learning Resources
- ^^^^^^^^^^^^^^^^^^^^
-
+ User Guide
+ ^^^^^^^^^^
+
.. container:: icon-large
-
- :fa:`graduation-cap`
-
+
+ :fa:`book`
+
.. container:: text-left
-
- Enhance your GAUSS usage with these valuable learning resources.
-
+
+ Language fundamentals — procedures, structures, formula strings, and more.
+
.. grid:: 2
.. grid-item-card::
:shadow: none
- :class-header: text-center
+ :class-header: text-center
:class-body: text-center
- :link: applications
+ :link: command-reference
:link-type: doc
- Apps
- ^^^^^
-
+ Command Reference
+ ^^^^^^^^^^^^^^^^^
+
.. container:: icon-large
-
- :fa:`rocket`
-
+
+ :fa:`code`
+
.. container:: text-left
-
- Save time with our pre-built applications.
-
+
+ Browse all 1,000+ built-in functions and keywords with detailed help for each.
+
.. grid-item-card::
:shadow: none
- :class-header: text-center
+ :class-header: text-center
:class-body: text-center
- :link: changelog
+ :link: command-reference
:link-type: doc
- Changelog
- ^^^^^^^^^
-
+ Functions by Category
+ ^^^^^^^^^^^^^^^^^^^^^
+
.. container:: icon-large
-
- :fa:`list`
-
+
+ :fa:`th-large`
+
.. container:: text-left
-
- View the list of updates for each version of GAUSS.
-.. grid:: 2
+ Time Series | Statistics | Matrix | I/O | Estimation | Graphics | String | Programming
+
+ .. grid-item-card::
+ :shadow: none
+ :class-header: text-center
+ :class-body: text-center
+ :link: applications
+ :link-type: doc
+
+ Applications
+ ^^^^^^^^^^^^
+
+ .. container:: icon-large
+
+ :fa:`puzzle-piece`
+
+ .. container:: text-left
+
+ Downloadable libraries that extend GAUSS with additional procedures and examples.
.. grid-item-card::
:shadow: none
- :class-header: text-center
+ :class-header: text-center
:class-body: text-center
- :link: https://www.aptech.com/resources/tutorials
+ :link: changelog
+ :link-type: doc
+
+ What's New in GAUSS 26
+ ^^^^^^^^^^^^^^^^^^^^^^
- Tutorials
- ^^^^^^^^^
-
.. container:: icon-large
-
- :fa:`external-link-alt`
-
+
+ :fa:`list`
+
.. container:: text-left
-
- View tutorials on the main aptech.com website.
-
+
+ Latest features, improvements, and new functions.
.. toctree::
- :maxdepth: 1
+ :maxdepth: 2
:hidden:
+ getting-started/index
+ user-guide/index
command-reference
+ data-management
learning-resources
+ machine-learning
applications
+ timeseries/index
+ ge/index
changelog
-
diff --git a/docs/insertcols.rst b/docs/insertcols.rst
index 378c7724..37f47fd1 100644
--- a/docs/insertcols.rst
+++ b/docs/insertcols.rst
@@ -145,4 +145,4 @@ In this example we will create an indicator variable to show whether the origina
Buick LeSabre 18 0 Average
Buick Opel 26 1 Average
-.. seealso:: Functions :func:`delif`, :func:`delrows`, :func:`selif`
+.. seealso:: Functions :func:`dfaddcol`, :func:`delif`, :func:`delrows`, :func:`selif`
diff --git a/docs/inthp2.rst b/docs/inthp2.rst
index 82251835..00cf4ab5 100644
--- a/docs/inthp2.rst
+++ b/docs/inthp2.rst
@@ -25,7 +25,7 @@ Format
"pds->dsname", "string."
"pds->type", "scalar."
- The contents, if any, are set by the user and are passed by :func:`inthp1` to the user-provided function without modification.
+ The contents, if any, are set by the user and are passed by :func:`inthp2` to the user-provided function without modification.
:type pds: scalar
diff --git a/docs/inthp3.rst b/docs/inthp3.rst
index 8ca2efca..925e5e46 100644
--- a/docs/inthp3.rst
+++ b/docs/inthp3.rst
@@ -26,7 +26,7 @@ Format
"pds->type", "scalar."
- The contents, if any, are set by the user and are passed by :func:`inthp1` to the user-provided function without modification.
+ The contents, if any, are set by the user and are passed by :func:`inthp3` to the user-provided function without modification.
:type pds: scalar
diff --git a/docs/inthp4.rst b/docs/inthp4.rst
index adc8cb40..d0c7cdfc 100644
--- a/docs/inthp4.rst
+++ b/docs/inthp4.rst
@@ -25,7 +25,7 @@ Format
"pds->dsname", "string."
"pds->type", "scalar."
- The contents, if any, are set by the user and are passed by :func:`inthp1` to the user-provided function without modification.
+ The contents, if any, are set by the user and are passed by :func:`inthp4` to the user-provided function without modification.
:type pds: scalar
diff --git a/docs/inthpcontrolcreate.rst b/docs/inthpcontrolcreate.rst
index 0dd68554..16e4c2c9 100644
--- a/docs/inthpcontrolcreate.rst
+++ b/docs/inthpcontrolcreate.rst
@@ -15,6 +15,23 @@ Format
:rtype c: struct
+Examples
+--------
+
+::
+
+ // Declare structure
+ struct inthpControl c;
+
+ // Initialize with default values
+ c = inthpControlCreate();
+
+ // Set maximum function evaluations
+ c.maxEvaluations = 50000;
+
+ // Set relative error bound
+ c.eps = 1e-8;
+
Source
------
diff --git a/docs/intsimp.rst b/docs/intsimp.rst
index 8740aed4..ad9a154f 100644
--- a/docs/intsimp.rst
+++ b/docs/intsimp.rst
@@ -39,7 +39,7 @@ Examples
xlims = { 1, 0 };
// Integrate using Simpson's method
- y = intsimp(&f, xl, 1e-8);
+ y = intsimp(&f, xlims, 1e-8);
print y;
The code above returns the following:
diff --git a/docs/invinvpd.rst b/docs/invinvpd.rst
index f245db08..0c52bed7 100644
--- a/docs/invinvpd.rst
+++ b/docs/invinvpd.rst
@@ -107,4 +107,4 @@ Positive definite matrices can be inverted by :func:`inv`. However, for
symmetric, positive definite matrices (such as moment matrices), :func:`invpd`
is about twice as fast as :func:`inv`.
-
+.. seealso:: Functions :func:`solpd`, :func:`chol`, :func:`det`, :func:`pinv`
diff --git a/docs/invswp.rst b/docs/invswp.rst
index 3f491c10..fbc23e3f 100644
--- a/docs/invswp.rst
+++ b/docs/invswp.rst
@@ -37,3 +37,21 @@ but with reduced degrees of freedom.
The tolerance used to determine if a pivot element is zero is taken from
the :func:`crout` singularity tolerance. The corresponding row and column are
zeroed out. See `Singularity Tolerance `_.
+
+Examples
+----------------
+
+::
+
+ x = { 4 2, 2 3 };
+
+ // Compute generalized sweep inverse
+ xi = invswp(x);
+ print xi;
+
+The code above produces the following output:
+
+::
+
+ 0.37500000 -0.25000000
+ -0.25000000 0.50000000
diff --git a/docs/iscplxf.rst b/docs/iscplxf.rst
index 574c562c..7d2d2269 100644
--- a/docs/iscplxf.rst
+++ b/docs/iscplxf.rst
@@ -18,4 +18,18 @@ Format
:rtype fh_iscplx: scalar
+Examples
+----------------
+
+::
+
+ // Open a dataset file
+ open fh = mydata.dat;
+
+ // Check if the dataset contains complex data
+ result = iscplxf(fh);
+ print result;
+
+ fh = close(fh);
+
.. seealso:: Functions :func:`hasimag`, :func:`iscplx`
diff --git a/docs/isinfnanmiss.rst b/docs/isinfnanmiss.rst
index 8ed1db09..0ea2071f 100644
--- a/docs/isinfnanmiss.rst
+++ b/docs/isinfnanmiss.rst
@@ -18,4 +18,24 @@ Format
:rtype y: scalar
+Examples
+----------------
+
+::
+
+ // Matrix with no special values
+ x = { 1 2, 3 4 };
+ print (isinfnanmiss(x));
+
+ // Matrix with a missing value
+ x = { 1 2, 3 . };
+ print (isinfnanmiss(x));
+
+The code above produces the following output:
+
+::
+
+ 0.0000000
+ 1.0000000
+
.. seealso:: Functions :func:`scalinfnanmiss`, :func:`ismiss`, :func:`scalmiss`
diff --git a/docs/jarquebera.rst b/docs/jarquebera.rst
index 707c28c3..2af76e70 100644
--- a/docs/jarquebera.rst
+++ b/docs/jarquebera.rst
@@ -47,4 +47,4 @@ The code above results in the following:
The p-value of 0.2464 indicates a failure to reject the null hypothesis that the residuals are distributed normally.
-.. seealso:: Functions :func:`skewness`, :func:`kurtosis`
+.. seealso:: Functions :func:`skewness`, :func:`kurtosis`, :func:`shapiroWilk`, :func:`mvnTest`
diff --git a/docs/k.rst b/docs/k.rst
index 6aaa5b3c..07c9a36c 100644
--- a/docs/k.rst
+++ b/docs/k.rst
@@ -11,4 +11,6 @@ K
key
keyword
keyw
+ kmeanscontrolcreate
+ kronecker-product
kurtosis
diff --git a/docs/keepdataloop.rst b/docs/keepdataloop.rst
index f0f4345d..2eac6d69 100644
--- a/docs/keepdataloop.rst
+++ b/docs/keepdataloop.rst
@@ -31,7 +31,7 @@ Commas are optional in *variable_list*.
Retains only the specified variables in the output dataset. Any
variables referenced must already exist, either as elements of the
-source dataset, or as the result of a previous `make`, `vector`, or `code`
+source dataset, or as the result of a previous `make`, ``vector``, or `code`
statement.
If neither `keep` nor `drop` is used, the output dataset will contain all
diff --git a/docs/keyav.rst b/docs/keyav.rst
index bc96c319..4d136420 100644
--- a/docs/keyav.rst
+++ b/docs/keyav.rst
@@ -15,4 +15,18 @@ Format
:rtype x: scalar
+Example
+-------
+
+::
+
+ // Check if a key has been pressed
+ // (interactive mode only)
+ k = keyav();
+ if k;
+ print "Key pressed:" k;
+ else;
+ print "No key available.";
+ endif;
+
.. seealso:: Functions :func:`keyw`, :func:`key`
diff --git a/docs/keyw.rst b/docs/keyw.rst
index eeab1e6d..23473074 100644
--- a/docs/keyw.rst
+++ b/docs/keyw.rst
@@ -56,4 +56,15 @@ Value Key Sequence
1132 :kbd:`Ctrl+PAGE UP`
=========== ================================
+Example
+-------
+
+::
+
+ // Wait for a keypress and display its ASCII value
+ // (interactive mode only)
+ print "Press any key...";
+ k = keyw;
+ print "You pressed key with ASCII value:" k;
+
.. seealso:: Functions :func:`key`, :func:`vals`, :func:`chrs`, :func:`upper`, :func:`lower`, :func:`con`, :func:`cons`
diff --git a/docs/keyword.rst b/docs/keyword.rst
index e526b173..a963e16a 100644
--- a/docs/keyword.rst
+++ b/docs/keyword.rst
@@ -68,4 +68,21 @@ This keyword will respond by printing:
Sum is: 15
+Example
+-------
+
+::
+
+ // Define a keyword that prints each word on a separate line
+ keyword showwords(str);
+ local tok;
+ do until str $== "";
+ { tok, str } = token(str);
+ print tok;
+ endo;
+ endp;
+
+ // Usage:
+ showwords hello world GAUSS;
+
.. seealso:: Functions `proc`, `local`, `endp`
diff --git a/docs/knnclassify.rst b/docs/knnclassify.rst
index c835da0e..fdfba0bd 100644
--- a/docs/knnclassify.rst
+++ b/docs/knnclassify.rst
@@ -12,7 +12,7 @@ Format
:param mdl: A :class:`knnModel` structure returned from a call to :func:`knnFit`.
:type mdl: struct
- :param X_train: The training features.
+ :param X: The training features.
:type X: NxP matrix, or string array.
:return y_hat: The predicted classes.
diff --git a/docs/l.rst b/docs/l.rst
index 0e124808..3592476d 100644
--- a/docs/l.rst
+++ b/docs/l.rst
@@ -5,6 +5,7 @@ L
:maxdepth: 1
:caption: Functions:
+ lag
lag1
lagdataloop
lagn
@@ -27,6 +28,8 @@ L
ldlp
ldl
ldlsol
+ less-or-equal
+ less-than
let
library
lib
@@ -60,6 +63,11 @@ L
loessmtcontrolcreate
loessmt
loess
+ logical-and
+ logical-eqv
+ logical-not
+ logical-or
+ logical-xor
loglog
log
logx
diff --git a/docs/lag.rst b/docs/lag.rst
new file mode 100644
index 00000000..03595d6b
--- /dev/null
+++ b/docs/lag.rst
@@ -0,0 +1,125 @@
+
+lag
+==============================================
+
+Purpose
+----------------
+
+Lags a matrix by one or more time periods for time series analysis.
+
+Format
+----------------
+.. function:: y = lag(x[, n_lags[, fill]])
+
+ :param x: data
+ :type x: NxK matrix or dataframe
+
+ :param n_lags: Optional, number of time periods to lag. Default = 1.
+ :type n_lags: scalar
+
+ :param fill: Optional, the value to fill newly missing observations. Default is a missing value, ``.``.
+ :type fill: scalar
+
+ :return y: *x* lagged *n_lags* periods.
+
+ :rtype y: NxK matrix
+
+Examples
+----------------
+
+Lag by one period
+++++++++++++++++++
+
+::
+
+ x = { 1.2,
+ 3.4,
+ 2.5,
+ 4.1,
+ 2.8 };
+
+ // Default: lag by one period
+ y = lag(x);
+
+After the above code, *y* will be:
+
+::
+
+ .
+ 1.2000000
+ 3.4000000
+ 2.5000000
+ 4.1000000
+
+Lag by multiple periods
+++++++++++++++++++++++++
+
+::
+
+ x = { 1.4, 2.7, 3.1, 2.9, 3.2, 2.5, 2.8 };
+
+ // Lag by 3 periods
+ y = lag(x, 3);
+
+After the above code, *y* will be:
+
+::
+
+ .
+ .
+ .
+ 1.4
+ 2.7
+ 3.1
+ 2.9
+
+Lag with a fill value
+++++++++++++++++++++++
+
+::
+
+ x = { 1.4, 2.7, 3.1, 2.9, 3.2, 2.5, 2.8 };
+
+ // Lag by 2, fill missing with 0
+ y = lag(x, 2, 0);
+
+After the above code, *y* will be:
+
+::
+
+ 0
+ 0
+ 1.4
+ 2.7
+ 3.1
+ 2.9
+ 3.2
+
+Use in formula strings
++++++++++++++++++++++++
+
+Because :func:`lag` accepts a single required argument, it can be used
+directly as a data transformation in formula strings:
+
+::
+
+ // Regress y on one lag of x
+ call olsmt(df, "y ~ lag(x)");
+
+Remarks
+-------
+
+If *n_lags* is positive, :func:`lag` shifts *x* back by *n_lags* time periods,
+so the first *n_lags* observations of *y* are filled with the *fill* value.
+
+:func:`lag` is equivalent to :func:`lag1` when called with one argument, and
+equivalent to :func:`lagn` when called with two or three arguments. It is
+provided as a convenience, particularly for use in formula strings where
+only single-argument functions are supported.
+
+Source
+------
+
+lag.src
+
+.. seealso:: Functions :func:`lag1`, :func:`lagn`, :func:`lagTrim`
diff --git a/docs/lag1.rst b/docs/lag1.rst
index 024b3348..51a0e31b 100644
--- a/docs/lag1.rst
+++ b/docs/lag1.rst
@@ -92,5 +92,5 @@ Source
lag.src
-.. seealso:: Functions :func:`lagn`, :func:`ismiss`, :func:`packr`
+.. seealso:: Functions :func:`lag`, :func:`lagn`, :func:`ismiss`, :func:`packr`
diff --git a/docs/lagdataloop.rst b/docs/lagdataloop.rst
index e83b41cb..e11d55b4 100644
--- a/docs/lagdataloop.rst
+++ b/docs/lagdataloop.rst
@@ -39,3 +39,15 @@ variable name is different from that of the variable to lag, the new
variable is first created and appended to a temporary dataset. This
temporary dataset becomes the input dataset for the dataloop, and is
then automatically deleted.
+
+Example
+-------
+
+::
+
+ // Inside a dataloop, create lagged variables
+ dataloop mydata.dat result.dat;
+ lag xlag = x:1; // 1-period lag of x
+ lag xlag2 = x:2; // 2-period lag of x
+ lag xlead = x:-1; // 1-period lead of x
+ endata;
diff --git a/docs/lagn.rst b/docs/lagn.rst
index 58c13306..c20070df 100644
--- a/docs/lagn.rst
+++ b/docs/lagn.rst
@@ -162,4 +162,4 @@ Source
lag.src
-.. seealso:: Functions :func:`lagtrim`
+.. seealso:: Functions :func:`lag`, :func:`lag1`, :func:`lagTrim`
diff --git a/docs/lapeighvb.rst b/docs/lapeighvb.rst
index 997e644c..2f1ed670 100644
--- a/docs/lapeighvb.rst
+++ b/docs/lapeighvb.rst
@@ -104,4 +104,4 @@ half open interval :math:`[vl, vu]`. :func:`lapeighvb` is based on the LAPACK dr
*DSYEVX* and *ZHEEVX*. Further documentation of these functions may be found
in the LAPACK User's Guide.
-
+.. seealso:: Functions :func:`eigh`, :func:`eighv`, :func:`lapgeig`
diff --git a/docs/lapgeig.rst b/docs/lapgeig.rst
index 50201db2..e95202e5 100644
--- a/docs/lapgeig.rst
+++ b/docs/lapgeig.rst
@@ -36,5 +36,20 @@ are not computed directly because some elements of *va2* may be zero,
i.e., the eigenvalues may be infinite. This procedure calls the LAPACK
routines *DGGEV* and *ZGGEV*.
-.. seealso:: Functions :func:`lapgeig`, :func:`lapgeigh`
+Example
+-------
+
+::
+
+ A = { 1 2, 3 4 };
+ B = { 2 0, 0 1 };
+
+ // Compute generalized eigenvalues of A*w = e*B*w
+ { va1, va2 } = lapgeig(A, B);
+
+ // Eigenvalues are va1 ./ va2
+ print "Generalized eigenvalues:";
+ print (va1 ./ va2);
+
+.. seealso:: Functions :func:`lapgeigh`
diff --git a/docs/lapgeigv.rst b/docs/lapgeigv.rst
index fb9c5f0f..6a42c2b4 100644
--- a/docs/lapgeigv.rst
+++ b/docs/lapgeigv.rst
@@ -57,4 +57,21 @@ and
This procedure calls the LAPACK routines *DGGEV* and *ZGGEV*.
+Example
+-------
+
+::
+
+ A = { 1 2, 3 4 };
+ B = { 2 0, 0 1 };
+
+ // Compute generalized eigenvalues and eigenvectors
+ { va1, va2, lve, rve } = lapgeigv(A, B);
+
+ // Eigenvalues are va1 ./ va2
+ print "Generalized eigenvalues:";
+ print (va1 ./ va2);
+ print "Right eigenvectors:";
+ print rve;
+
.. seealso:: Functions :func:`lapgeig`, :func:`lapgeigh`
diff --git a/docs/lapgsvdcst.rst b/docs/lapgsvdcst.rst
index bc92832a..0fc61508 100644
--- a/docs/lapgsvdcst.rst
+++ b/docs/lapgsvdcst.rst
@@ -124,4 +124,18 @@ produces the singular value decomposition of :math:`AB^{-1}`:
This procedure calls the LAPACK routines *DGGSVD* and *ZGGSVD*.
+Example
+-------
+
+::
+
+ A = { 1 2, 3 4 };
+ B = { 5 6, 7 8 };
+
+ // Compute GSVD with transformation matrices
+ { C, S, R, U, V, Q } = lapgsvdcst(A, B);
+
+ print "Singular values for A:"; print C;
+ print "Singular values for B:"; print S;
+
.. seealso:: Functions :func:`lapgsvds`, :func:`lapgsvdst`
diff --git a/docs/lapgsvds.rst b/docs/lapgsvds.rst
index 4b04b8d8..7a1bdce0 100644
--- a/docs/lapgsvds.rst
+++ b/docs/lapgsvds.rst
@@ -115,4 +115,18 @@ produces the singular value decomposition of :math:`AB^{-1}``:
This procedure calls the LAPACK routines *DGGSVD* and *ZGGSVD*.
+Example
+-------
+
+::
+
+ A = { 1 2 3, 4 5 6 };
+ B = { 7 8 9, 10 11 12, 13 14 15 };
+
+ // Compute generalized singular values
+ { C, S, R } = lapgsvds(A, B);
+
+ print "Singular values for A:"; print C;
+ print "Singular values for B:"; print S;
+
.. seealso:: Functions :func:`lapgsvdcst`, :func:`lapgsvdst`
diff --git a/docs/lapgsvdst.rst b/docs/lapgsvdst.rst
index 14e434ae..9e760e6d 100644
--- a/docs/lapgsvdst.rst
+++ b/docs/lapgsvdst.rst
@@ -127,4 +127,18 @@ produces the singular value decomposition of :math:`AB^{-1}`:
This procedure calls the LAPACK routines *DGGSVD* and *ZGGSVD*.
+Example
+-------
+
+::
+
+ A = { 1 2, 3 4 };
+ B = { 5 6, 7 8 };
+
+ // Compute GSVD returning diagonal and transformation matrices
+ { D1, D2, Z, U, V, Q } = lapgsvdst(A, B);
+
+ print "D1:"; print D1;
+ print "D2:"; print D2;
+
.. seealso:: Functions :func:`lapgsvds`, :func:`lapgsvdcst`
diff --git a/docs/learning-resources.rst b/docs/learning-resources.rst
index b509e428..74f9061f 100644
--- a/docs/learning-resources.rst
+++ b/docs/learning-resources.rst
@@ -1,13 +1,6 @@
Learning Resources
===================
-User Guide
------------
-.. toctree::
- :maxdepth: 2
-
- data-management
-
Academic Resources
-------------------
.. toctree::
@@ -21,4 +14,8 @@ Coming to GAUSS from somewhere else?
:maxdepth: 2
coming-to-gauss/intro-gauss-for-stata-users
+ coming-to-gauss/intro-gauss-for-eviews-users
+ coming-to-gauss/intro-gauss-for-matlab-users
+ coming-to-gauss/intro-gauss-for-r-users
+ coming-to-gauss/intro-gauss-for-python-users
diff --git a/docs/linesonlinesoff.rst b/docs/linesonlinesoff.rst
index 5d082e37..9cac39b0 100644
--- a/docs/linesonlinesoff.rst
+++ b/docs/linesonlinesoff.rst
@@ -5,10 +5,10 @@
Purpose
----------------
-The `#lineson` command causes GAUSS to embed line
+The ``#lineson`` command causes GAUSS to embed line
number and file name records in a program for the
purpose of reporting the location where an error occurs. The
-`#linesoff` command causes GAUSS to stop embedding line and file
+``#linesoff`` command causes GAUSS to stop embedding line and file
records in a program.
Format
@@ -38,7 +38,7 @@ typed in the window and run from the command line), since there are no
line numbers in such programs.
Line number tracking can be turned on and off through the user
-interface, but the `#lineson` and `#linesoff` commands will override that.
+interface, but the ``#lineson`` and ``#linesoff`` commands will override that.
The line numbers and file names given at run-time will reflect the last
record encountered in the code. If you have a mixture of procedures that
@@ -51,7 +51,21 @@ states that it was executing procedure *xyz* at line number *nnn* in file
*ABC* and *xyz* has no line *nnn* or is not in file *ABC*, you know that it just
did not encounter any line or file records in *xyz* before it crashed.
-When using `#include`'d files, the line number and file name will be
+When using ``#include``'d files, the line number and file name will be
correct for the file the error was in within the limits stated above.
+Examples
+--------
+
+::
+
+ // Enable line tracking for debugging
+ #lineson;
+
+ x = rndn(3, 3);
+ y = inv(x);
+
+ // Disable line tracking for performance
+ #linesoff;
+
.. seealso:: Functions :func:`trace`
diff --git a/docs/listwisedataloop.rst b/docs/listwisedataloop.rst
index 79500635..5382cfe8 100644
--- a/docs/listwisedataloop.rst
+++ b/docs/listwisedataloop.rst
@@ -29,3 +29,14 @@ not deleted.
The default is *read*.
+Examples
+--------
+
+::
+
+ // Delete rows with missing values before transformations
+ listwise read;
+
+ // Delete rows with missing values after transformations
+ listwise write;
+
diff --git a/docs/loadarray.rst b/docs/loadarray.rst
index d68ce7fc..f09f30fc 100644
--- a/docs/loadarray.rst
+++ b/docs/loadarray.rst
@@ -93,6 +93,22 @@ In the above program:
This will get the old `loadarray` path, set it to :file:`/data`, load :file:`a.fmt` and
:file:`b.fmt`, and reset the `loadarray` path to its original setting.
+Examples
+--------
+
+::
+
+ // Load an array from a .fmt file
+ loadarray x = myarray;
+
+ // Load from a specific path
+ loadarray path = /data;
+ loadarray a, b, c;
+
+ // Load using a string variable for the filename
+ filestr = "mydata/myarray";
+ loadarray x = ^filestr;
+
.. seealso:: Functions `load`, `save`, `let`, :func:`sysstate`
diff --git a/docs/loadd.rst b/docs/loadd.rst
index a1cad6b5..4adb87f0 100644
--- a/docs/loadd.rst
+++ b/docs/loadd.rst
@@ -153,7 +153,7 @@ Load specified columns of a GAUSS matrix file, .fmt.
// Load columns 2 and 4 from 'x.fmt'
x_2 = loadd("x.fmt", "X2 + X4");
-Load three specified variables from a SAS dataset, .sas7bdat.
+Load three specified variables from a Stata dataset.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
::
@@ -285,9 +285,9 @@ Remarks
- If *dataset* is a null string or 0, the dataset :file:`temp.dat` will be
loaded.
- To load a matrix file, use an :file:`.fmt` extension on dataset.
-- The supported dataset types are `CSV`, `Excel` (XLS, XLSX), `HDF5`, `GAUSS Matrix (FMT)`,
- `GAUSS Dataset (DAT)`, `Stata` (DTA) and `SAS` (SAS7BDAT, SAS7BCAT).
-- For `HDF5` file, the dataset must include schema and both file name and
+- The supported dataset types are ``CSV``, ``Excel`` (XLS, XLSX), ``HDF5``, ``GAUSS Matrix (FMT)``,
+ ``GAUSS Dataset (DAT)``, ``Stata`` (DTA) and ``SAS`` (SAS7BDAT, SAS7BCAT).
+- For ``HDF5`` file, the dataset must include schema and both file name and
dataset name must be provided, e.g.
::
diff --git a/docs/loaddsa.rst b/docs/loaddsa.rst
index 19ce5017..713951ec 100644
--- a/docs/loaddsa.rst
+++ b/docs/loaddsa.rst
@@ -13,7 +13,7 @@ Format
:param dataset: name of dataset.
:type dataset: string
- :param varnames: `Formula string` indicating which variable names to load from the dataset
+ :param varnames: ``Formula string`` indicating which variable names to load from the dataset
E.g ``"."``, include all variables;
@@ -134,11 +134,11 @@ Remarks
be small enough to fit in memory.
* If *dataset* is a null string or 0, the dataset :file:`temp.dat` will be
loaded.
-* The supported dataset types are `CSV`, `Excel (XLS, XLSX)`, `HDF5`, `GAUSS Matrix (FMT)`,
- `GAUSS Dataset (DAT)`, `Stata (DTA)` and `SAS (SAS7BDAT, SAS7BCAT)`.
-* Since `GAUSS Matrix files (FMT)` do not contain data type information, :func:`loaddSA` will assume
+* The supported dataset types are ``CSV``, ``Excel (XLS, XLSX)``, ``HDF5``, ``GAUSS Matrix (FMT)``,
+ ``GAUSS Dataset (DAT)``, ``Stata (DTA)`` and ``SAS (SAS7BDAT, SAS7BCAT)``.
+* Since ``GAUSS Matrix files (FMT)`` do not contain data type information, :func:`loaddSA` will assume
that the entire contents of the file are numeric.
-* For `HDF5` file, the dataset must include schema and both file name and
+* For ``HDF5`` file, the dataset must include schema and both file name and
dataset name must be provided, e.g.
::
@@ -153,4 +153,4 @@ saveload.src
See also
------------
-.. seealso:: `Formula String`, :func:`csvReadSA`, :func:`getHeaders`, :func:`loadd`, :func:`saved`
+.. seealso:: ``Formula String``, :func:`csvReadSA`, :func:`getHeaders`, :func:`loadd`, :func:`saved`
diff --git a/docs/loadloadfloadkloadmloadploads.rst b/docs/loadloadfloadkloadmloadploads.rst
index 47f113cc..a7bfa48e 100644
--- a/docs/loadloadfloadkloadmloadploads.rst
+++ b/docs/loadloadfloadkloadmloadploads.rst
@@ -249,4 +249,22 @@ In the above program:
This will get the old `loadm` path, set it to :file:`/data`, load :file:`x.fmt` and :file:`y.fmt`,
and reset the `loadm` path to its original setting.
+Examples
+--------
+
+::
+
+ // Load a matrix from a .fmt file
+ loadm x = mydata;
+
+ // Load ASCII data into a matrix
+ load x[100,5] = mydata.asc;
+
+ // Load a string from a .fst file
+ loads s = mystring;
+
+ // Load from a string variable filename
+ filestr = "results/output";
+ loadm y = ^filestr;
+
.. seealso:: Functions :func:`loadd`, :func:`dataload`, `save`, `let`, :func:`con`, :func:`cons`, :func:`sysstate`
diff --git a/docs/log.rst b/docs/log.rst
index c78068f2..ec7466b2 100644
--- a/docs/log.rst
+++ b/docs/log.rst
@@ -47,6 +47,8 @@ Then *y* will be equal to:
Remarks
-------
+:func:`log` computes the base-10 logarithm (common logarithm). For the natural logarithm (base *e*), use :func:`ln`.
+
:func:`log` is defined for :math:`x ≠ 0`.
You can turn the generation of complex numbers for negative inputs on or
diff --git a/docs/m.rst b/docs/m.rst
index 4b338ab9..4de38655 100644
--- a/docs/m.rst
+++ b/docs/m.rst
@@ -12,6 +12,8 @@ M
margin
matalloc
matinit
+ matrix-division
+ matrix-multiplication
mattoarray
maxbytes
maxc
@@ -31,6 +33,7 @@ M
missex
missmissrv
modec
+ modulo
momentd
moment
movingaveexpwgt
diff --git a/docs/machepsilon.rst b/docs/machepsilon.rst
index 5526d1bb..a80996c3 100644
--- a/docs/machepsilon.rst
+++ b/docs/machepsilon.rst
@@ -15,8 +15,23 @@ Format
:rtype eps: scalar
+Examples
+----------------
+
+::
+
+ eps = machEpsilon();
+ print eps;
+
+The code above produces the following output:
+
+::
+
+ 2.2300000e-16
+
Source
------
machconst.src
+.. seealso:: Functions :func:`sysstate`
diff --git a/docs/makedataloop.rst b/docs/makedataloop.rst
index 50bf703d..77755751 100644
--- a/docs/makedataloop.rst
+++ b/docs/makedataloop.rst
@@ -36,11 +36,11 @@ vector. If neither '``$``' nor '``#``' is specified, '``#``' is assumed.
The expression may contain explicit variable names and/or GAUSS
commands. Any variables referenced must already exist, either as
-elements of the source dataset, as `extern`'s, or as the result of a
-previous `make`, `vector`, or `code` statement. The variable name must be
+elements of the source dataset, as ``extern``'s, or as the result of a
+previous `make`, ``vector``, or `code` statement. The variable name must be
unique. A variable cannot be made more than once, or an error is
generated.
-.. seealso:: Functions `vector`
+.. seealso:: Functions ``vector``
diff --git a/docs/matalloc.rst b/docs/matalloc.rst
index 4c541256..9e20a145 100644
--- a/docs/matalloc.rst
+++ b/docs/matalloc.rst
@@ -29,5 +29,17 @@ that will be written to in sections using indexing or used with the
`Foreign Language Interface` as an output matrix for a function called
with `dllcall`.
+Examples
+--------
+
+::
+
+ // Allocate a 3x2 matrix, then fill it
+ y = matalloc(3, 2);
+ y[1, .] = 1~2;
+ y[2, .] = 3~4;
+ y[3, .] = 5~6;
+ print y;
+
.. seealso:: Functions :func:`matinit`, :func:`ones`, :func:`zeros`, :func:`eye`
diff --git a/docs/maxbytes.rst b/docs/maxbytes.rst
index 5d40d160..b690af6a 100644
--- a/docs/maxbytes.rst
+++ b/docs/maxbytes.rst
@@ -36,7 +36,7 @@ Remarks
:func:`maxbytes` returns the value in the global scalar *__maxbytes*, which can
be reset in the calling program.
-:func:`maxbytes` is called by `Run-Time Library` functions and applications
+:func:`maxbytes` is called by ``Run-Time Library`` functions and applications
when determining how many rows can be read from a dataset in one call
to :func:`readr`.
@@ -50,3 +50,4 @@ Source
system.src
+.. seealso:: Functions :func:`maxvec`, :func:`sysstate`
diff --git a/docs/maxvec.rst b/docs/maxvec.rst
index f555de7a..0e9bcfca 100644
--- a/docs/maxvec.rst
+++ b/docs/maxvec.rst
@@ -36,7 +36,7 @@ Remarks
:func:`maxvec` returns the value in the global scalar *__maxvec*, which can be
reset in the calling program.
-:func:`maxvec` is called by `Run-Time Library` functions and applications when
+:func:`maxvec` is called by ``Run-Time Library`` functions and applications when
determining how many rows can be read from a dataset in one call to
readr.
@@ -50,3 +50,4 @@ Source
system.src
+.. seealso:: Functions :func:`maxbytes`, :func:`sysstate`
diff --git a/docs/median.rst b/docs/median.rst
index 1bed9958..62f43b80 100644
--- a/docs/median.rst
+++ b/docs/median.rst
@@ -49,3 +49,5 @@ Source
------
median.src
+
+.. seealso:: Functions :func:`meanc`, :func:`quantile`
diff --git a/docs/minimize.rst b/docs/minimize.rst
index 49ee08dc..726fcac0 100644
--- a/docs/minimize.rst
+++ b/docs/minimize.rst
@@ -90,14 +90,25 @@ Example 1: Basic unconstrained minimization
struct minimizeOut out;
out = minimize(&rosenbrock, x0);
- print "Solution: " out.x';
+ print "Solution: " out.x';
print "Objective: " out.fval;
+ print "Iterations:" out.iterations;
+
+::
+
+ Solution: 1.0000000 0.99999999
+ Objective: 2.5073756e-17
+ Iterations: 37.000000
+
+The optimizer finds the known minimum at (1, 1) with an objective value near zero in 37 iterations.
Example 2: With data arguments
++++++++++++++++++++++++++++++++++++++++++++
::
+ rndseed 42;
+
// OLS objective function
proc (1) = ols_objective(beta, Y, X);
local resid;
@@ -117,8 +128,15 @@ Example 2: With data arguments
struct minimizeOut out;
out = minimize(&ols_objective, x0, Y, X);
- print "Estimated coefficients:";
- print out.x';
+ print "True coefficients: " beta_true';
+ print "Estimated coefficients: " out.x';
+
+::
+
+ True coefficients: 1.0000000 2.0000000 -1.0000000
+ Estimated coefficients: 0.94044862 2.0263110 -1.0269490
+
+Data arguments (*Y* and *X*) are passed directly through to the objective function without modification.
Example 3: Bound-constrained optimization
++++++++++++++++++++++++++++++++++++++++++++
@@ -141,6 +159,12 @@ Example 3: Bound-constrained optimization
print "Solution: " out.x';
+::
+
+ Solution: 0.0000000 0.0000000 0.0000000
+
+When ``ctl.bounds`` is a 1x2 vector, the same bounds apply to all parameters.
+
Example 4: Variable-specific bounds
++++++++++++++++++++++++++++++++++++++++++++
@@ -161,9 +185,14 @@ Example 4: Variable-specific bounds
struct minimizeOut out;
out = minimize(&myfunc, x0, ctl);
- // Solution will be constrained: x = {2, 2}
print "Solution: " out.x';
+::
+
+ Solution: 2.0000000 2.0000000
+
+The unconstrained minimum is at (2, 3), but the bound ``x[2] <= 2`` forces the solution to (2, 2). When ``ctl.bounds`` is Kx2, each row specifies bounds for the corresponding parameter.
+
Remarks
-------
@@ -199,5 +228,5 @@ The algorithm terminates when either:
If the starting point *x0* violates any bounds, it is automatically projected
into the feasible region before optimization begins.
-.. seealso:: Functions :func:`minimizeControlCreate`, :func:`sqpSolveMT`
+.. seealso:: Functions :func:`minimizeControlCreate`, :func:`sqpSolveMT`, :func:`QNewton`, :func:`optmt`
diff --git a/docs/mlmt/mlmt-ug-maxlikmt-procedure.rst b/docs/mlmt/mlmt-ug-maxlikmt-procedure.rst
index 596d10f5..01d3a68b 100644
--- a/docs/mlmt/mlmt-ug-maxlikmt-procedure.rst
+++ b/docs/mlmt/mlmt-ug-maxlikmt-procedure.rst
@@ -1,5 +1,5 @@
The maxlikmt Procedure
-===================
+======================
First Input Argument: Pointer to Procedure
----------------------------------------------
diff --git a/docs/moment.rst b/docs/moment.rst
index 65a22556..d4991ac6 100644
--- a/docs/moment.rst
+++ b/docs/moment.rst
@@ -54,8 +54,8 @@ Examples
// Find coefficients
b = ixx*missrv(x, 0)'y;
- print "b_true~b_est";
- b_true'~b_est;
+ print "b_true~b";
+ b_true'~b;
::
@@ -94,4 +94,4 @@ data sets that are small enough to fit into a single matrix. In
addition, the moment matrix and its inverse cannot be recovered if the ``/``
operator is used.
-
+.. seealso:: Functions :func:`momentd`, :func:`crossprd`
diff --git a/docs/momentd.rst b/docs/momentd.rst
index 52394de8..84c7889b 100644
--- a/docs/momentd.rst
+++ b/docs/momentd.rst
@@ -156,6 +156,8 @@ After the above code,
Remarks
-------
+.. note:: When ``__con = 1`` (the default), a column of ones is automatically prepended to the data before computing the moment matrix. This means the resulting matrix will be ``(K+1) x (K+1)`` rather than ``KxK``, where the first row and column correspond to the constant term. Set ``__con = 0`` to suppress this behavior.
+
- The supported dataset types are CSV, Excel, HDF5, GAUSS Matrix (FMT), GAUSS Dataset (DAT),
Stata (DTA) and SAS (SAS7BDAT, SAS7BCAT).
- Character vectors are supported for backward compatibility, but it has been deprecated.
@@ -168,4 +170,4 @@ momentd.src
See also
------------
-.. seealso:: `Formula String`
+.. seealso:: ``Formula String``
diff --git a/docs/movingaveexpwgt.rst b/docs/movingaveexpwgt.rst
index 40bf66ec..370ed7da 100644
--- a/docs/movingaveexpwgt.rst
+++ b/docs/movingaveexpwgt.rst
@@ -17,7 +17,7 @@ Format
:param d: order of moving average.
:type d: scalar
- :param p: smoothing coefficient where :math:`0 > p > 1`.
+ :param p: smoothing coefficient where :math:`0 < p < 1`.
:type p: scalar
:return y: filtered series. The first :math:`d-1` rows of *x* are set to missing values.
diff --git a/docs/movingavewgt.rst b/docs/movingavewgt.rst
index 1f5f0e19..20a38935 100644
--- a/docs/movingavewgt.rst
+++ b/docs/movingavewgt.rst
@@ -31,5 +31,30 @@ Remarks
The moving average as performed by column and thus it treats the NxK
matrix as *K* time series of length *N*.
+Examples
+----------------
+
+::
+
+ x = { 1, 3, 5, 7, 9, 11 };
+
+ // Equal weights for a 2-period moving average
+ w = { 0.5, 0.5 };
+ y = movingaveWgt(x, 2, w);
+ print y;
+
+The code above produces the following output:
+
+::
+
+ .
+ 2.0000000
+ 4.0000000
+ 6.0000000
+ 8.0000000
+ 10.000000
+
+The first element is missing because there are not enough prior observations for the window.
+
.. seealso:: Functions :func:`movingave`, :func:`movingaveExpwgt`
diff --git a/docs/mvntest.rst b/docs/mvntest.rst
index 63255675..f521e34e 100644
--- a/docs/mvntest.rst
+++ b/docs/mvntest.rst
@@ -87,28 +87,36 @@ Example 1: Basic usage with matrix input
::
+ rndseed 42;
+
// Generate multivariate normal data
X = rndn(100, 3);
// Test normality using default Henze-Zirkler method
out = mvnTest(X);
-Example 2: Using dataframe with formula
-+++++++++++++++++++++++++++++++++++++++++
-
::
- // Load data
- data = loadd("mydata.csv");
+ Multivariate Normality Test
+
+ Observations: 100 Variables: 3
+
+ Henze-Zirkler Test (Henze & Zirkler 1990)
+
+ Test Statistic p-value
+ HZ 0.6210 7.4283e-01
+ Beta 1.4788
- // Test specific variables
- out = mvnTest(data, "income + age + education");
+The large p-value (0.74) indicates a failure to reject normality, as expected for data generated from a multivariate normal distribution.
-Example 3: Run all tests with control structure
-++++++++++++++++++++++++++++++++++++++++++++++++
+Example 2: Run all tests
++++++++++++++++++++++++++
::
+ rndseed 42;
+ X = rndn(100, 3);
+
// Create control structure
struct mvnTestControl ctl;
ctl = mvnTestControlCreate();
@@ -117,9 +125,47 @@ Example 3: Run all tests with control structure
// Run all four tests
out = mvnTest(X, ctl);
- // Check individual results
+::
+
+ Multivariate Normality Tests
+
+ Observations: 100 Variables: 3
+
+ Mardia's Test (Mardia & Foster 1983)
+
+ Component Statistic p-value
+ Skewness -0.6600 7.4538e-01
+ Kurtosis -0.7006 7.5822e-01
+ Combined 0.7283 6.9480e-01
+
+ Henze-Zirkler Test (Henze & Zirkler 1990)
+
+ Test Statistic p-value
+ HZ 0.6210 7.4283e-01
+ Beta 1.4788
+
+ Doornik-Hansen Test (Doornik & Hansen 2008)
+
+ Test Statistic df p-value
+ DH 3.3778 6 7.6015e-01
+
+ Royston Test (Royston 1992)
+
+ Test Statistic eq.df p-value
+ H 1.4209 3.00 7.0081e-01
+
+All four tests fail to reject the null hypothesis of multivariate normality.
+
+Example 3: Checking individual results
++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Check individual results programmatically
if out.hzP < 0.05;
print "Henze-Zirkler rejects normality";
+ else;
+ print "Henze-Zirkler: fail to reject normality (p = " out.hzP ")";
endif;
Remarks
diff --git a/docs/n.rst b/docs/n.rst
index 4f1cd59d..5d796f00 100644
--- a/docs/n.rst
+++ b/docs/n.rst
@@ -11,6 +11,7 @@ N
nextwind
norm
normalizecollabels
+ not-equal
ntos
null1
null
diff --git a/docs/normalizecollabels.rst b/docs/normalizecollabels.rst
index 422f7311..051077c6 100644
--- a/docs/normalizecollabels.rst
+++ b/docs/normalizecollabels.rst
@@ -27,5 +27,17 @@ Remarks
The :func:`normalizecollabels` procedure is useful when cleaning and merging categorical variables that may come from different sources. This is primarily a convenience function utilized by multiple string-related functions and in general should not need to be called explicitly by an end-user.
+Examples
+--------
+
+::
+
+ // Create a dataframe with categorical data
+ x = asdf(1|2|3|1|2, "group");
+
+ // Normalize category labels so all are unique
+ x_norm = normalizecollabels(x);
+ print x_norm;
+
.. seealso:: :func:`dfappend`
diff --git a/docs/ols.rst b/docs/ols.rst
index 9d5985d0..be2252ec 100644
--- a/docs/ols.rst
+++ b/docs/ols.rst
@@ -318,7 +318,7 @@ After the above code,
Example 3
+++++++++
-Pass in a dataset name and a `Formula string`
+Pass in a dataset name and a ``Formula string``
::
@@ -364,7 +364,7 @@ Remarks
you want output to be placed in a file, you need to open an output
file before calling :func:`ols`.
- The supported dataset types are CSV, XLS, XLSX, HDF5, FMT, DAT
-- For HDF5 file, the dataset must include `file schema` and both file name and
+- For HDF5 file, the dataset must include ``file schema`` and both file name and
dataset name must be provided, e.g.
::
@@ -376,4 +376,4 @@ Source
ols.src
-.. seealso:: Functions :func:`olsqr`, `Formula string`
+.. seealso:: Functions :func:`olsqr`, ``Formula string``
diff --git a/docs/olsmt.rst b/docs/olsmt.rst
index e4dcda82..6d4e7d46 100644
--- a/docs/olsmt.rst
+++ b/docs/olsmt.rst
@@ -552,7 +552,7 @@ Remarks
you want output to be placed in a file, you need to open an output
file before calling :func:`olsmt`.
- The supported dataset types are CSV, XLS, XLSX, HDF5, FMT, DAT
-- For HDF5 file, the dataset must include `file schema` and both file name and
+- For HDF5 file, the dataset must include ``file schema`` and both file name and
dataset name must be provided, e.g.
::
@@ -564,4 +564,4 @@ Source
olsmt.src
-.. seealso:: Functions :func:`glm`, :func:`gmmFitIV`, :func:`olsmtControlCreate`, :func:`olsqrmt`, `Formula string`, :func:`clusterSE`, :func:`robustSE`
+.. seealso:: Functions :func:`glm`, :func:`gmmFitIV`, :func:`olsmtControlCreate`, :func:`olsqrmt`, ``Formula string``, :func:`clusterSE`, :func:`robustSE`
diff --git a/docs/olsqr.rst b/docs/olsqr.rst
index 533ab86b..7e763b70 100644
--- a/docs/olsqr.rst
+++ b/docs/olsqr.rst
@@ -36,6 +36,8 @@ Examples
// Solve OLS coefficient using QR decomposition
b = olsqr(y, x);
+.. note:: This example uses a square system (4 equations, 4 unknowns), which has an exact solution rather than a least squares fit. In practice, :func:`olsqr` is most useful when the system is overdetermined (more observations than parameters), where it computes the least squares solution.
+
Remarks
-------
diff --git a/docs/p.rst b/docs/p.rst
index 2f6c9fdf..3e15f678 100644
--- a/docs/p.rst
+++ b/docs/p.rst
@@ -128,6 +128,7 @@ P
plotsetxticcount
plotsetxticinterval
plotsetxticlabel
+ plotsetxticlabelfont
plotsetxticposition
plotsetygrid
plotsetygridpen
@@ -139,6 +140,7 @@ P
plotsetyticcount
plotsetyticinterval
plotsetyticlabel
+ plotsetyticlabelfont
plotsetyticposition
plotsetzlabel
plotsetzlevels
diff --git a/docs/pacf.rst b/docs/pacf.rst
index 112be0bf..275b769c 100644
--- a/docs/pacf.rst
+++ b/docs/pacf.rst
@@ -202,7 +202,7 @@ The following code plot autocorrelation (ACF) and sample partial autocorrelation
plotSetXLabel(&cow_ctl, "Lag");
// Place the 2nd plot in the second cell of a 2 by 1 grid
- plotLayout(2, 1, );
+ plotLayout(2, 1, 2);
// ACF plot
plotBar(cow_ctl, seqa(1, 1, k), data_acf);
diff --git a/docs/pause.rst b/docs/pause.rst
index 95fc2e2c..3062fb0e 100644
--- a/docs/pause.rst
+++ b/docs/pause.rst
@@ -19,6 +19,18 @@ Remarks
This function can be used to delay a program, allowing users time to
view graphics and/or data printed to the program output window.
+Examples
+----------------
+
+::
+
+ print "Processing...";
+
+ // Pause for 3 seconds
+ pause(3);
+
+ print "Done.";
+
Source
------
diff --git a/docs/pdbalance.rst b/docs/pdbalance.rst
index bf35929c..6a2f864c 100644
--- a/docs/pdbalance.rst
+++ b/docs/pdbalance.rst
@@ -185,4 +185,4 @@ This function evaluates whether each group in a panel dataset spans the maximum
The resulting dataframe contains each group and a corresponding indicator (`1` or `0`) to represent whether the group covers the full time span.
-.. seealso:: :func:`pdAllBalanced`, :func:`pdSummary`
+.. seealso:: :func:`pdAllBalanced`, :func:`pdSummary`, :func:`dfLonger`
diff --git a/docs/pdfcauchy.rst b/docs/pdfcauchy.rst
index 3cfe1ede..d10f3d59 100644
--- a/docs/pdfcauchy.rst
+++ b/docs/pdfcauchy.rst
@@ -22,7 +22,7 @@ Format
:return p: the probability density function for the Cauchy distribution for the elements in *x*.
- :rtypep: NxK matrix, Nx1 vector or scalar
+ :rtype p: NxK matrix, Nx1 vector or scalar
Remarks
-------
@@ -33,4 +33,25 @@ The probability density function for the Cauchy distribution is defined as:
f(x) = \bigg(\pi \sigma \Big(1+\Big(\frac{x−\mu}{\sigma}\Big)^2\Big)\bigg) ^{−1}
+Examples
+----------------
+
+::
+
+ // Data points
+ x = { -2, 0, 1, 2 };
+
+ // Cauchy PDF with location = 0, scale = 1
+ p = pdfCauchy(x, 0, 1);
+ print p;
+
+After the code above, *p* is equal to:
+
+::
+
+ 0.063661977
+ 0.31830989
+ 0.15915494
+ 0.063661977
+
.. seealso:: Functions :func:`cdfCauchy`
diff --git a/docs/pdfexp.rst b/docs/pdfexp.rst
index 3ca5644d..6b0e8910 100644
--- a/docs/pdfexp.rst
+++ b/docs/pdfexp.rst
@@ -34,4 +34,25 @@ exponential distribution, which is defined as
f(x) = \frac{1}{b} exp \big( − \frac{x−a}{b} \big)
+Examples
+----------------
+
+::
+
+ // Data points
+ x = { 0.5, 1, 2, 5 };
+
+ // Exponential PDF with location = 0, scale = 1
+ p = pdfexp(x, 0, 1);
+ print p;
+
+After the code above, *p* is equal to:
+
+::
+
+ 0.60653066
+ 0.36787944
+ 0.13533528
+ 0.0067379470
+
.. seealso:: Functions :func:`cdfexp`
diff --git a/docs/pdfgenpareto.rst b/docs/pdfgenpareto.rst
index af75e697..cee3c59d 100644
--- a/docs/pdfgenpareto.rst
+++ b/docs/pdfgenpareto.rst
@@ -41,4 +41,25 @@ is defined as
\frac{1}{\sigma}exp(\frac{x-\mu}{\sigma}), & k = 0
\end{cases}
+Examples
+----------------
+
+::
+
+ // Data points
+ x = { 0.5, 1, 2, 3 };
+
+ // Generalized Pareto PDF with location = 0, scale = 1, shape = 0.5
+ p = pdfGenPareto(x, 0, 1, 0.5);
+ print p;
+
+After the code above, *p* is equal to:
+
+::
+
+ 0.51200000
+ 0.29629630
+ 0.12500000
+ 0.064000000
+
.. seealso:: Functions :func:`cdfGenPareto`
diff --git a/docs/pdflaplace.rst b/docs/pdflaplace.rst
index 6acb2a19..02ee31f9 100644
--- a/docs/pdflaplace.rst
+++ b/docs/pdflaplace.rst
@@ -32,4 +32,26 @@ The probability density function for the Laplace distribution is defined as
f(x) = \frac{1}{2b} exp \bigg(- \frac{|x-a|}{b} \bigg)
+Examples
+----------------
+
+::
+
+ // Data points
+ x = { -2, -1, 0, 1, 2 };
+
+ // Laplace PDF with location = 0, scale = 1
+ p = pdfLaplace(x, 0, 1);
+ print p;
+
+After the code above, *p* is equal to:
+
+::
+
+ 0.067667642
+ 0.18393972
+ 0.50000000
+ 0.18393972
+ 0.067667642
+
.. seealso:: Functions :func:`cdfCauchy`, :func:`pdfCauchy`
diff --git a/docs/pdflogistic.rst b/docs/pdflogistic.rst
index 242d4408..2607ab04 100644
--- a/docs/pdflogistic.rst
+++ b/docs/pdflogistic.rst
@@ -34,4 +34,25 @@ defined as
f(x) = \frac{exp(z)}{b(1 + exp(z))^2}\\
z = - \bigg(\frac{x-a}{b}\bigg)
+Examples
+----------------
+
+::
+
+ // Data points
+ x = { -2, 0, 1, 2 };
+
+ // Logistic PDF with location = 0, scale = 1
+ p = pdflogistic(x, 0, 1);
+ print p;
+
+After the code above, *p* is equal to:
+
+::
+
+ 0.10499359
+ 0.25000000
+ 0.19661193
+ 0.10499359
+
.. seealso:: Functions :func:`cdflogistic`
diff --git a/docs/pdfrayleigh.rst b/docs/pdfrayleigh.rst
index 24dad970..52190096 100644
--- a/docs/pdfrayleigh.rst
+++ b/docs/pdfrayleigh.rst
@@ -30,4 +30,25 @@ as
f(x) = \frac{x}{b^2}exp(\frac{−x^2}{2b^2})
+Examples
+----------------
+
+::
+
+ // Data points
+ x = { 0.5, 1, 2, 3 };
+
+ // Rayleigh PDF with scale = 1
+ p = pdfRayleigh(x, 1);
+ print p;
+
+After the code above, *p* is equal to:
+
+::
+
+ 0.44124845
+ 0.60653066
+ 0.27067057
+ 0.033326990
+
.. seealso:: Functions :func:`cdfRayleighinv`
diff --git a/docs/pdftruncnorm.rst b/docs/pdftruncnorm.rst
index 2d403b2a..11e2be62 100644
--- a/docs/pdftruncnorm.rst
+++ b/docs/pdftruncnorm.rst
@@ -16,7 +16,7 @@ Format
:param a: lower limit of the integration window.
:type a: scalar
- :param b: lower limit of the integration window.
+ :param b: upper limit of the integration window.
:type b: scalar
:param mu_bar: mean parameter.
diff --git a/docs/pdfweibull.rst b/docs/pdfweibull.rst
index 89a7b7e6..d44f537d 100644
--- a/docs/pdfweibull.rst
+++ b/docs/pdfweibull.rst
@@ -17,7 +17,7 @@ Format
:type k: NxK matrix, Nx1 vector or scalar
:param lambda: Scale parameter, may be matrix, ExE conformable with *x*. *lambda* must be greater than 0.
- :type lambda: Nx1 vector or scalar
+ :type lambda: NxK matrix, Nx1 vector or scalar
:return p: the probability density function of a Weibull random variable evaluated at *x*.
:rtype p: NxK matrix, Nx1 vector or scalar
@@ -35,4 +35,25 @@ The probability density function of a Weibull random variable is defined as
\end{cases}
+Examples
+----------------
+
+::
+
+ // Data points
+ x = { 0.5, 1, 2, 3 };
+
+ // Weibull PDF with shape = 2, scale = 1
+ p = pdfWeibull(x, 2, 1);
+ print p;
+
+After the code above, *p* is equal to:
+
+::
+
+ 0.77880078
+ 0.73575888
+ 0.073262556
+ 0.00074045882
+
.. seealso:: Functions :func:`cdfWeibull`, :func:`cdfWeibullInv`
diff --git a/docs/pinv.rst b/docs/pinv.rst
index be3bdc64..eba85f60 100644
--- a/docs/pinv.rst
+++ b/docs/pinv.rst
@@ -64,3 +64,5 @@ Source
------
svd.src
+
+.. seealso:: Functions :func:`inv`, :func:`invpd`, :func:`solpd`
diff --git a/docs/pinvmt.rst b/docs/pinvmt.rst
index cb2125e6..9416cdfe 100644
--- a/docs/pinvmt.rst
+++ b/docs/pinvmt.rst
@@ -64,3 +64,5 @@ Source
------
svdmt.src
+
+.. seealso:: Functions :func:`pinv`, :func:`inv`
diff --git a/docs/plotaddbar.rst b/docs/plotaddbar.rst
index f98307eb..03a19812 100644
--- a/docs/plotaddbar.rst
+++ b/docs/plotaddbar.rst
@@ -38,4 +38,19 @@ Remarks
This function will not change any of the current graph's settings other
than to resize the view as necessary to display the new curve.
+Examples
+----------------
+
+::
+
+ // Create labels and bar heights
+ labels = "A" $| "B" $| "C";
+ ht = 10|20|15;
+
+ // Create initial bar graph
+ plotBar(labels, ht);
+
+ // Add bars for two new categories
+ plotAddBar("D" $| "E", 5|25);
+
.. seealso:: Functions :func:`plotAddHist`, :func:`plotAddHistF`, :func:`plotAddHistP`, :func:`plotAddPolar`, :func:`plotAddXY`
diff --git a/docs/plotaddbox.rst b/docs/plotaddbox.rst
index 6e70ddbf..14cb5663 100644
--- a/docs/plotaddbox.rst
+++ b/docs/plotaddbox.rst
@@ -27,4 +27,18 @@ Remarks
This function will not change any of the current graph's settings other
than to resize the view as necessary to display the new curve.
+Examples
+----------------
+
+::
+
+ // Create random data for three groups
+ x = rndn(100, 3);
+
+ // Create initial box plot
+ plotBox(0, x);
+
+ // Add a second set of box plots
+ plotAddBox(0, rndn(100, 2));
+
.. seealso:: Functions :func:`plotAddHist`, :func:`plotAddHistF`, :func:`plotAddHistP`, :func:`plotAddPolar`, :func:`plotAddXY`
diff --git a/docs/plotaddhist.rst b/docs/plotaddhist.rst
index 381da2c3..9ace9e18 100644
--- a/docs/plotaddhist.rst
+++ b/docs/plotaddhist.rst
@@ -35,4 +35,19 @@ Remarks
This function will not change any of the current graph's settings other
than to resize the view as necessary to display the new curve.
+Examples
+----------------
+
+::
+
+ // Create two sets of random data
+ x1 = rndn(500, 1);
+ x2 = rndn(500, 1) + 2;
+
+ // Plot first histogram with 20 bins
+ plotHist(x1, 20);
+
+ // Add second histogram to same graph
+ plotAddHist(x2, 20);
+
.. seealso:: Functions :func:`plotAddBar`, :func:`plotAddHistF`, :func:`plotAddHistP`, :func:`plotAddPolar`, :func:`plotAddXY`
diff --git a/docs/plotaddhistf.rst b/docs/plotaddhistf.rst
index 759e8877..2ef6b1a2 100644
--- a/docs/plotaddhistf.rst
+++ b/docs/plotaddhistf.rst
@@ -28,4 +28,20 @@ Remarks
This function will not change any of the current graph's settings other
than to resize the view as necessary to display the new curve.
+Examples
+----------------
+
+::
+
+ // Create frequency counts and category labels
+ f1 = 10|25|40|15|10;
+ c = 1|2|3|4|5;
+
+ // Plot initial frequency histogram
+ plotHistF(f1, c);
+
+ // Add a second frequency histogram
+ f2 = 5|20|30|25|20;
+ plotAddHistF(f2, c);
+
.. seealso:: Functions :func:`plotAddBar`, :func:`plotAddHist`, :func:`plotAddHistP`, :func:`plotAddPolar`, :func:`plotAddXY`
diff --git a/docs/plotaddhistp.rst b/docs/plotaddhistp.rst
index 53e07ace..78e90fd1 100644
--- a/docs/plotaddhistp.rst
+++ b/docs/plotaddhistp.rst
@@ -36,4 +36,19 @@ Remarks
This function will not change any of the current graph's settings other
than to resize the view as necessary to display the new curve.
+Examples
+----------------
+
+::
+
+ // Create two sets of random data
+ x1 = rndn(500, 1);
+ x2 = rndn(500, 1) + 2;
+
+ // Plot first percent histogram with 20 bins
+ plotHistP(x1, 20);
+
+ // Add second percent histogram to same graph
+ plotAddHistP(x2, 20);
+
.. seealso:: Functions :func:`plotAddBar`, :func:`plotAddHist`, :func:`plotAddHistF`, :func:`plotAddPolar`, :func:`plotAddXY`
diff --git a/docs/plotaddpolar.rst b/docs/plotaddpolar.rst
index 76549688..8d7f2097 100644
--- a/docs/plotaddpolar.rst
+++ b/docs/plotaddpolar.rst
@@ -27,4 +27,20 @@ Remarks
This function will not change any of the current graph's settings other
than to resize the view as necessary to display the new curve.
+Examples
+----------------
+
+::
+
+ // Create angle values
+ theta = seqa(0, 0.1, 63);
+
+ // Plot a circle with radius 2
+ r1 = ones(63, 1) * 2;
+ plotPolar(r1, theta);
+
+ // Add a cardioid curve to the same graph
+ r2 = 1 + cos(theta);
+ plotAddPolar(r2, theta);
+
.. seealso:: Functions :func:`plotAddBar`, :func:`plotAddHist`, :func:`plotAddHistF`, :func:`plotAddHistP`, :func:`plotAddXY`
diff --git a/docs/plotaddscatter.rst b/docs/plotaddscatter.rst
index fb5c6622..cb1e5abe 100644
--- a/docs/plotaddscatter.rst
+++ b/docs/plotaddscatter.rst
@@ -27,4 +27,21 @@ Remarks
This function will not change any of the current graph's settings other
than to resize the view as necessary to display the new curve.
+Examples
+----------------
+
+::
+
+ // Create first set of scatter data
+ x1 = rndn(50, 1);
+ y1 = rndn(50, 1);
+
+ // Create initial scatter plot
+ plotScatter(x1, y1);
+
+ // Add a second set of points
+ x2 = rndn(30, 1) + 2;
+ y2 = rndn(30, 1) + 2;
+ plotAddScatter(x2, y2);
+
.. seealso:: Functions :func:`plotAddBar`, :func:`plotAddHist`, :func:`plotAddHistF`, :func:`plotAddHistP`, :func:`plotAddScatter`, :func:`plotAddXY`
diff --git a/docs/plotcanvassize.rst b/docs/plotcanvassize.rst
index 6e792216..016c2789 100644
--- a/docs/plotcanvassize.rst
+++ b/docs/plotcanvassize.rst
@@ -58,12 +58,12 @@ Remarks
If the only input to :func:`plotCanvasSize` is the string ``"fill"``, then the graph
canvas will be expanded to fill the available area.
-:func:`plotSetCanvas` controls the size of the entire graph canvas, not just a
+:func:`plotCanvasSize` controls the size of the entire graph canvas, not just a
set of axes. Therefore when used with :func:`plotLayout` to create subplots,
-:func:`plotSetCanvas` will control the size of the bounding box allowed for all
+:func:`plotCanvasSize` will control the size of the bounding box allowed for all
of the subplots together.
-After a call to :func:`plotSetCanvas`, all subsequent graphs will be drawn in a
+After a call to :func:`plotCanvasSize`, all subsequent graphs will be drawn in a
canvas of the size specified even if a new plot tab is created with
:func:`plotOpenWindow`.
diff --git a/docs/plothistf.rst b/docs/plothistf.rst
index 38586264..3381bda2 100644
--- a/docs/plothistf.rst
+++ b/docs/plothistf.rst
@@ -25,5 +25,17 @@ Remarks
The axes are not automatically labeled. Use the functions :func:`plotSetXLabel` and :func:`plotSetYLabel`.
+Examples
+----------------
+
+::
+
+ // Create frequency counts and category labels
+ f = 10|25|40|15|10;
+ c = 1|2|3|4|5;
+
+ // Plot frequency histogram
+ plotHistF(f, c);
+
.. seealso:: Functions :func:`plotHist`, :func:`plotBar`, :func:`plotSetXLabel`
diff --git a/docs/plotloglog.rst b/docs/plotloglog.rst
index fa285c7b..87ed2f30 100644
--- a/docs/plotloglog.rst
+++ b/docs/plotloglog.rst
@@ -19,5 +19,19 @@ Format
:param y: Each column contains the Y values for a particular line.
:type y: Nx1 or NxM matrix
+Examples
+----------------
+
+::
+
+ // Create X data
+ x = seqa(1, 1, 50);
+
+ // Create Y as a power function of X
+ y = x .^ 2;
+
+ // Plot with log scaling on both axes
+ plotLogLog(x, y);
+
.. seealso:: Functions :func:`plotXY`, :func:`plotLogX`, :func:`plotLogY`
diff --git a/docs/plotlogx.rst b/docs/plotlogx.rst
index e5237103..b20341cd 100644
--- a/docs/plotlogx.rst
+++ b/docs/plotlogx.rst
@@ -19,4 +19,18 @@ Format
:param y: Each column contains the Y values for a particular line.
:type y: Nx1 or NxM matrix
+Examples
+----------------
+
+::
+
+ // Create X data
+ x = seqa(1, 1, 50);
+
+ // Create Y as the natural log of X
+ y = ln(x);
+
+ // Plot with log scaling on the x-axis
+ plotLogX(x, y);
+
.. seealso:: Functions :func:`plotXY`, :func:`plotLogY`, :func:`plotLogLog`
diff --git a/docs/plotlogy.rst b/docs/plotlogy.rst
index 75faec2c..fd4654f8 100644
--- a/docs/plotlogy.rst
+++ b/docs/plotlogy.rst
@@ -19,4 +19,18 @@ Format
:param y: Each column represents the Y values for a particular line.
:type y: Nx1 or NxM matrix
+Examples
+----------------
+
+::
+
+ // Create X data
+ x = seqa(1, 1, 50);
+
+ // Create exponentially growing Y data
+ y = exp(x ./ 10);
+
+ // Plot with log scaling on the y-axis
+ plotLogY(x, y);
+
.. seealso:: Functions :func:`plotXY`, :func:`plotLogX`, :func:`plotLogLog`
diff --git a/docs/plotsave.rst b/docs/plotsave.rst
index ad4fac98..9db247bb 100644
--- a/docs/plotsave.rst
+++ b/docs/plotsave.rst
@@ -18,7 +18,7 @@ Format
:type filename: string
- :param size: dimensions of the saved graph in specified *units*. Default *unit* is ``"cm"``. *size* is an optional input when saving a :file:`.plot` file, but is required for all other file types.
+ :param size: dimensions of the saved graph in specified *units*. Default *unit* is ``"px"``. *size* is an optional input when saving a :file:`.plot` file, but is required for all other file types.
:type size: 2x1 vector
:param unit: Optional input, type of units dimension is specified in. This value is ignored if the filename extension is :file:`.plot`. Valid options include:
@@ -90,7 +90,7 @@ Save as 11x8.5 inch PDF at 300 DPI
// Plot the data
plotXY(x, y);
- plotSave("mygraph.png", 11 | 8.5, "in", 300);
+ plotSave("mygraph.pdf", 11 | 8.5, "in", 300);
Remarks
-------
diff --git a/docs/plotscatter.rst b/docs/plotscatter.rst
index 1c5603bd..149f0682 100644
--- a/docs/plotscatter.rst
+++ b/docs/plotscatter.rst
@@ -99,7 +99,7 @@ Example 2: Customized plot without formula string
plotSetYGrid(&plt, "major", "dark gray");
// Draw plot
- plotScatter(plt, crabs[.,"frontal_lobe"], crabs[.,"rear_width"]);
+ plotScatter(plt, crabs[.,"rear_width"], crabs[.,"frontal_lobe"]);
diff --git a/docs/polychar.rst b/docs/polychar.rst
index 74a1256b..a66367cc 100644
--- a/docs/polychar.rst
+++ b/docs/polychar.rst
@@ -25,6 +25,27 @@ Remarks
The coefficient of :math:`x^n` is set to unity (:math:`c[1]=1`).
+Examples
+----------------
+
+::
+
+ x = { 2 1, 1 2 };
+
+ // Compute the characteristic polynomial
+ c = polychar(x);
+ print c;
+
+The code above produces the following output:
+
+::
+
+ 1.0000000
+ -4.0000000
+ 3.0000000
+
+This represents the polynomial :math:`p(\lambda) = \lambda^2 - 4\lambda + 3`.
+
Source
------
diff --git a/docs/polymake.rst b/docs/polymake.rst
index e722d3f5..7925a21c 100644
--- a/docs/polymake.rst
+++ b/docs/polymake.rst
@@ -66,7 +66,7 @@ This represents the polynomial:
.. math::
- x^3 - 6x^2 + 11^x - 6
+ x^3 - 6x^2 + 11x - 6
Remarks
-------
diff --git a/docs/polymat.rst b/docs/polymat.rst
index 5c0a06e1..a27a9dd8 100644
--- a/docs/polymat.rst
+++ b/docs/polymat.rst
@@ -32,6 +32,27 @@ To do polynomial regression use ols:
{ vnam, m, b, stb, vc, stderr, sigma, cx, rsq, resid, dwstat } = ols(0, y, polymat(x, p));
+Examples
+----------------
+
+::
+
+ x = { 1, 2, 3 };
+
+ // Create matrix with powers 1 through 3
+ y = polymat(x, 3);
+ print y;
+
+The code above produces the following output:
+
+::
+
+ 1.0000000 1.0000000 1.0000000
+ 2.0000000 4.0000000 8.0000000
+ 3.0000000 9.0000000 27.000000
+
+Each column contains the elements of *x* raised to the 1st, 2nd, and 3rd powers.
+
Source
------
diff --git a/docs/pop.rst b/docs/pop.rst
index 4df247c6..038ce61c 100644
--- a/docs/pop.rst
+++ b/docs/pop.rst
@@ -25,18 +25,18 @@ This is used with `gosub`, `goto`, and `return` statements with parameters. It
permits passing parameters to subroutines or labels, and returning
parameters from subroutines.
-The `gosub` syntax allows an implicit `push` statement. This syntax is
+The `gosub` syntax allows an implicit ``push`` statement. This syntax is
almost the same as that of a standard `gosub`, except that the matrices to
-be `push`'ed "into the subroutine" are in parentheses following the label
-name. The matrices to be `push`'ed back to the main body of the program
+be ``push``'ed "into the subroutine" are in parentheses following the label
+name. The matrices to be ``push``'ed back to the main body of the program
are in parentheses following the `return` statement. The only limit on the
number of matrices that can be passed to and from subroutines in this
way is the amount of room on the stack.
-No matrix expressions can be executed between the (implicit) `push` and
+No matrix expressions can be executed between the (implicit) ``push`` and
the `pop`. Execution of such expressions will alter what is on the stack.
-Matrices must be `pop`'ped in the reverse order that they are `push`'ed,
+Matrices must be `pop`'ped in the reverse order that they are ``push``'ed,
therefore in the statements:
::
@@ -60,5 +60,23 @@ After the code above:
Note that there must be a separate `pop` statement for each matrix popped.
+Examples
+--------
+
+::
+
+ // Use gosub with push/pop to pass data to a subroutine
+ x = 10;
+ y = 20;
+ gosub myLabel(x, y);
+ pop result;
+ print result;
+ stop;
+
+ myLabel:
+ pop b;
+ pop a;
+ return (a + b);
+
.. seealso:: Functions `gosub`, `goto`, :func:`return`
diff --git a/docs/print.rst b/docs/print.rst
index e85d12f3..9910b122 100644
--- a/docs/print.rst
+++ b/docs/print.rst
@@ -173,12 +173,7 @@ returns:
5.0000000
-.. NOTE:: Notice the parentheses in the code above. Remember that `print` statements in GAUSS take
- a space separated list of items to print. The parentheses tell GAUSS to first evaluate
- the expression and then print the result. Without the parentheses (i.e. ``print x + 2;``),
- the statement would tell GAUSS to print a list of three items (first ``print x``, then
- ``print +``, and finally ``print 2``. Since the second item in that list is an operator
- (the ``+`` sign), an error will occur.
+.. NOTE:: As of GAUSS 26, ``print`` supports expressions with binary operators directly: ``print x + 2;`` evaluates and prints the result (``5``). Parentheses (``print (x + 2);``) also work and are required in older versions. Be aware that whitespace matters: ``print x + 2;`` (spaces around ``+``) prints the sum, but ``print x +2;`` (no space before ``+2``) prints two items — ``x`` and ``+2`` — because GAUSS interprets ``+2`` as a positive number.
Example 3
+++++++++
diff --git a/docs/proc.rst b/docs/proc.rst
index 5188b6d5..0b99861e 100644
--- a/docs/proc.rst
+++ b/docs/proc.rst
@@ -88,4 +88,33 @@ Procedure definitions may not be nested.
For more details on writing procedures, see `Procedures and Keywords `_,
+Examples
+--------
+
+::
+
+ // Define a procedure that returns the sum of squares
+ proc (1) = sumSquares(x);
+ local ss;
+ ss = sumc(x .* x);
+ retp(ss);
+ endp;
+
+ // Call the procedure
+ x = seqa(1, 1, 5);
+ result = sumSquares(x);
+ print result;
+
+::
+
+ // Procedure returning multiple values
+ proc (2) = meanAndVar(x);
+ local m, v;
+ m = meanc(x);
+ v = stdc(x) .^ 2;
+ retp(m, v);
+ endp;
+
+ { avg, variance } = meanAndVar(rndn(100, 1));
+
.. seealso:: Functions `keyword`, `call`, `endp`, `local`, `retp`
diff --git a/docs/putf.rst b/docs/putf.rst
index f498ec08..9d54b174 100644
--- a/docs/putf.rst
+++ b/docs/putf.rst
@@ -62,6 +62,20 @@ the program with an error message, depending on the `trap` state. If bit 2
message. If bit 2 of the `trap` flag is 1, :func:`putf` will return an error code.
The value of the `trap` flag can be tested with `trapchk`.
+Examples
+--------
+
+::
+
+ // Write a string to a file in ASCII mode, overwriting
+ ret = putf("output.txt", "Hello, GAUSS!", 1, 13, 0, 0);
+ print (ret == 0); // 1 if successful
+
+::
+
+ // Append text to an existing file
+ ret = putf("output.txt", " More text.", 1, 11, 0, 1);
+
Source
------
diff --git a/docs/pvgetindex.rst b/docs/pvgetindex.rst
index 1650b966..3cad2eb9 100644
--- a/docs/pvgetindex.rst
+++ b/docs/pvgetindex.rst
@@ -21,6 +21,21 @@ Format
:rtype id: Kx1 vector
+Examples
+--------
+
+::
+
+ // Create and populate a PV structure
+ struct PV p1;
+ p1 = pvCreate;
+ p1 = pvPack(p1, 1|2|3, "beta");
+ p1 = pvPack(p1, 0.5~0.8, "gamma");
+
+ // Get the row indices of "beta" in the parameter vector
+ id = pvGetIndex(p1, "beta");
+ print id;
+
Source
------
diff --git a/docs/pvtest.rst b/docs/pvtest.rst
index fb13692c..bcd6cab0 100644
--- a/docs/pvtest.rst
+++ b/docs/pvtest.rst
@@ -21,6 +21,20 @@ Format
:rtype i: scalar
+Examples
+--------
+
+::
+
+ // Create a valid PV structure
+ struct PV p1;
+ p1 = pvCreate;
+ p1 = pvPack(p1, 1|2|3, "beta");
+
+ // Test if p1 is a valid PV structure
+ i = pvTest(p1);
+ print (i == 0); // 1 (true) means valid
+
Source
------
diff --git a/docs/pvunpack.rst b/docs/pvunpack.rst
index 1ea7fe1d..d3a57861 100644
--- a/docs/pvunpack.rst
+++ b/docs/pvunpack.rst
@@ -21,6 +21,23 @@ Format
:rtype x: matrix or array
+Examples
+--------
+
+::
+
+ // Create and populate a PV structure
+ struct PV p1;
+ p1 = pvCreate;
+ p1 = pvPack(p1, 1|2|3, "beta");
+ p1 = pvPack(p1, 0.5~0.8, "gamma");
+
+ // Unpack matrices by name
+ beta = pvUnpack(p1, "beta");
+ gamma = pvUnpack(p1, "gamma");
+ print beta;
+ print gamma;
+
Source
------
diff --git a/docs/qnewtonmtcontrolcreate.rst b/docs/qnewtonmtcontrolcreate.rst
index 18626909..1bf98108 100644
--- a/docs/qnewtonmtcontrolcreate.rst
+++ b/docs/qnewtonmtcontrolcreate.rst
@@ -14,6 +14,23 @@ Format
:rtype c: struct
+Examples
+--------
+
+::
+
+ // Declare structure
+ struct QNewtonmtControl c;
+
+ // Initialize with default values
+ c = QNewtonmtControlCreate();
+
+ // Set maximum iterations
+ c.MaxIters = 500;
+
+ // Print iteration information
+ c.PrintIters = 1;
+
Source
------
diff --git a/docs/qnewtonmtoutcreate.rst b/docs/qnewtonmtoutcreate.rst
index ba2c929a..f02fe8aa 100644
--- a/docs/qnewtonmtoutcreate.rst
+++ b/docs/qnewtonmtoutcreate.rst
@@ -14,6 +14,17 @@ Format
:rtype c: struct
+Examples
+--------
+
+::
+
+ // Declare output structure
+ struct QNewtonmtOut out;
+
+ // Initialize with default values
+ out = QNewtonmtOutCreate();
+
Source
------
diff --git a/docs/qnewtonset.rst b/docs/qnewtonset.rst
index e1ae5472..bf8bc43a 100644
--- a/docs/qnewtonset.rst
+++ b/docs/qnewtonset.rst
@@ -10,6 +10,21 @@ Format
----------------
.. function:: QNewtonSet()
+Examples
+--------
+
+::
+
+ // Change QNewton global settings
+ _qn_MaxIters = 500;
+ _qn_PrintIters = 1;
+ _qn_RelGradTol = 1e-8;
+
+ // ... run QNewton optimization ...
+
+ // Reset all QNewton globals to defaults
+ QNewtonSet();
+
Source
------
diff --git a/docs/qprog.rst b/docs/qprog.rst
index af5a4166..c3791eba 100644
--- a/docs/qprog.rst
+++ b/docs/qprog.rst
@@ -97,6 +97,32 @@ and bounds,
x_{low} ≤ x ≤ x_{up}
+Examples
+--------
+
+::
+
+ // Minimize 0.5*x'Q*x - x'R subject to x >= 0
+ Q = { 2 0, 0 2 };
+ R = { 1, 1 };
+
+ start = { 0.5, 0.5 };
+
+ // No equality or inequality constraints
+ A = 0;
+ b = 0;
+ C = 0;
+ d = 0;
+
+ // Bounds: x >= 0
+ bnds = (0 ~ 1e200) | (0 ~ 1e200);
+
+ { x, u1, u2, u3, u4, ret } = QProg(start, Q, R, A, b, C, d, bnds);
+
+ print "Solution:";
+ print x;
+ print "Return code:" ret;
+
Source
------
diff --git a/docs/qprogmt.rst b/docs/qprogmt.rst
index 2312e7f7..bff3d55d 100644
--- a/docs/qprogmt.rst
+++ b/docs/qprogmt.rst
@@ -78,6 +78,37 @@ and bounds,
x_{low} \leq x \leq x_{up}
+Examples
+--------
+
+::
+
+ // Create input structure
+ struct qprogMTIn qIn;
+ qIn = QProgmtInCreate();
+
+ // Minimize 0.5*x'Q*x - x'R subject to x >= 0
+ qIn.q = { 2 0, 0 2 };
+ qIn.r = { 1, 1 };
+ qIn.start = { 0.5, 0.5 };
+
+ // Bounds: x >= 0
+ qIn.bounds = (0 ~ 1e200) | (0 ~ 1e200);
+
+ // No equality or inequality constraints
+ qIn.a = 0;
+ qIn.b = 0;
+ qIn.c = 0;
+ qIn.d = 0;
+
+ // Solve
+ struct qprogMTOut qOut;
+ qOut = QProgmt(qIn);
+
+ print "Solution:";
+ print qOut.x;
+ print "Return code:" qOut.ret;
+
Source
------
diff --git a/docs/qprogmtincreate.rst b/docs/qprogmtincreate.rst
index 0eb3753e..2b020fea 100644
--- a/docs/qprogmtincreate.rst
+++ b/docs/qprogmtincreate.rst
@@ -14,6 +14,21 @@ Format
:rtype s: struct
+Examples
+--------
+
+::
+
+ // Create and initialize the input structure
+ struct qprogMTIn qIn;
+ qIn = QProgmtInCreate();
+
+ // Set up the quadratic programming problem
+ qIn.q = { 2 0, 0 2 };
+ qIn.r = { 1, 1 };
+ qIn.start = zeros(2, 1);
+ qIn.maxit = 500;
+
Source
------
diff --git a/docs/qqr.rst b/docs/qqr.rst
index 9a51c376..5e0f6227 100644
--- a/docs/qqr.rst
+++ b/docs/qqr.rst
@@ -86,6 +86,49 @@ systems. However, unless the linearly independent columns happen to be
the initial rows, such an analysis also requires pivoting (see :func:`qre` and
:func:`qrep`).
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Compute Q1 and R
+ { q1, r } = qqr(x);
+
+ print "Q1 (orthogonal factor):";
+ print q1;
+ print "R (upper triangular):";
+ print r;
+
+ // Verify that Q1*R reconstructs x
+ print "Q1*R (should equal x):";
+ print (q1 * r);
+
+The above code produces the following output:
+
+::
+
+ Q1 (orthogonal factor):
+
+ -0.16903085 0.89708523
+ -0.50709255 0.27602622
+ -0.84515425 -0.34503278
+
+ R (upper triangular):
+
+ -5.9160798 -7.4373574
+ 0.0000000 0.82807867
+
+ Q1*R (should equal x):
+
+ 1.0000000 2.0000000
+ 3.0000000 4.0000000
+ 5.0000000 6.0000000
+
Source
------
diff --git a/docs/qqre.rst b/docs/qqre.rst
index d550eb10..b8fdfca4 100644
--- a/docs/qqre.rst
+++ b/docs/qqre.rst
@@ -120,6 +120,56 @@ be avoided by using the function :func:`qtyre`.
For further discussion of QR factorizations see the remarks under :func:`qqr`.
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Compute Q1, R, and permutation vector E
+ { q1, r, e } = qqre(x);
+
+ print "Q1 (orthogonal factor):";
+ print q1;
+ print "R (upper triangular):";
+ print r;
+ print "Permutation vector E:";
+ print e;
+
+ // Verify: Q1*R should equal x with permuted columns
+ print "Q1*R (should equal x[.,E]):";
+ print (q1 * r);
+
+The above code produces the following output:
+
+::
+
+ Q1 (orthogonal factor):
+
+ -0.26726124 0.87287156
+ -0.53452248 0.21821789
+ -0.80178373 -0.43643578
+
+ R (upper triangular):
+
+ -7.4833148 -5.8797473
+ 0.0000000 -0.65465367
+
+ Permutation vector E:
+
+ 2.0000000
+ 1.0000000
+
+ Q1*R (should equal x[.,E]):
+
+ 2.0000000 1.0000000
+ 4.0000000 3.0000000
+ 6.0000000 5.0000000
+
Source
------
diff --git a/docs/qqrep.rst b/docs/qqrep.rst
index 0f0d0c55..3c6ef2dd 100644
--- a/docs/qqrep.rst
+++ b/docs/qqrep.rst
@@ -78,6 +78,59 @@ among the linearly independent columns using *pvt*.
If you want only the :math:`R` matrix, see :func:`qrep`. Not computing :math:`Q_1` can produce
significant improvements in computing time and memory usage.
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Pivot vector: all columns are free
+ pvt = { 0, 0 };
+
+ // Compute Q1, R, and permutation vector with controlled pivoting
+ { q1, r, e } = qqrep(x, pvt);
+
+ print "Q1 (orthogonal factor):";
+ print q1;
+ print "R (upper triangular):";
+ print r;
+ print "Permutation vector E:";
+ print e;
+
+ // Verify: Q1*R should equal x with permuted columns
+ print "Q1*R (should equal x[.,E]):";
+ print (q1 * r);
+
+The above code produces the following output:
+
+::
+
+ Q1 (orthogonal factor):
+
+ -0.26726124 0.87287156
+ -0.53452248 0.21821789
+ -0.80178373 -0.43643578
+
+ R (upper triangular):
+
+ -7.4833148 -5.8797473
+ 0.0000000 -0.65465367
+
+ Permutation vector E:
+
+ 2.0000000
+ 1.0000000
+
+ Q1*R (should equal x[.,E]):
+
+ 2.0000000 1.0000000
+ 4.0000000 3.0000000
+ 6.0000000 5.0000000
+
Source
------
diff --git a/docs/qr.rst b/docs/qr.rst
index 2c96788a..c9b53681 100644
--- a/docs/qr.rst
+++ b/docs/qr.rst
@@ -77,6 +77,33 @@ type of factorization is useful for the solution of underdetermined
systems. However, unless the linearly independent columns happen to be
the initial rows, such an analysis also requires pivoting (see :func:`qre` and :func:`qrep`).
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Compute the R matrix from QR decomposition
+ r = qr(x);
+
+ print "R (upper triangular):";
+ print r;
+
+The above code produces the following output:
+
+::
+
+ R (upper triangular):
+
+ -5.9160798 -7.4373574
+ 0.0000000 0.82807867
+
+.. note:: :func:`qr` returns only the *R* matrix. If you also need the *Q* matrix, use :func:`qqr`.
+
Source
------
diff --git a/docs/qre.rst b/docs/qre.rst
index 9a533b7d..5e83bfa6 100644
--- a/docs/qre.rst
+++ b/docs/qre.rst
@@ -122,6 +122,40 @@ The explicit formation here of :math:`Q`, which can be a very large matrix, can
For further discussion of QR factorizations see the remarks under :func:`qqr`.
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Compute R and permutation vector E
+ { r, e } = qre(x);
+
+ print "R (upper triangular):";
+ print r;
+ print "Permutation vector E:";
+ print e;
+
+The above code produces the following output:
+
+::
+
+ R (upper triangular):
+
+ -7.4833148 -5.8797473
+ 0.0000000 -0.65465367
+
+ Permutation vector E:
+
+ 2.0000000
+ 1.0000000
+
+The permutation vector *E* indicates that the columns of *x* were reordered (column 2 first, then column 1) so that :math:`X[.,E] = Q_1R`.
+
Source
------
diff --git a/docs/qrep.rst b/docs/qrep.rst
index 2b215b0b..98d78216 100644
--- a/docs/qrep.rst
+++ b/docs/qrep.rst
@@ -80,6 +80,41 @@ linear dependencies among the columns of :math:`X`, the column of ones for the
constant may get pivoted away. This column can be forced to be included
among the linearly independent columns using *pvt*.
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Pivot vector: all columns are free
+ pvt = { 0, 0 };
+
+ // Compute R and permutation vector with controlled pivoting
+ { r, e } = qrep(x, pvt);
+
+ print "R (upper triangular):";
+ print r;
+ print "Permutation vector E:";
+ print e;
+
+The above code produces the following output:
+
+::
+
+ R (upper triangular):
+
+ -7.4833148 -5.8797473
+ 0.0000000 -0.65465367
+
+ Permutation vector E:
+
+ 2.0000000
+ 1.0000000
+
Source
------
diff --git a/docs/qrsol.rst b/docs/qrsol.rst
index 1454bba0..8911fd7d 100644
--- a/docs/qrsol.rst
+++ b/docs/qrsol.rst
@@ -28,6 +28,38 @@ Remarks
the *R* matrix from a QR factorization. :func:`qrsol` may be used, however, in any situation
where *R* is upper triangular.
+Examples
+--------
+
+::
+
+ // Upper triangular matrix R and right-hand side b
+ r = { 3 1,
+ 0 2 };
+ b = { 7, 4 };
+
+ // Solve R*x = b
+ x = qrsol(b, r);
+
+ print "Solution x:";
+ print x;
+ print "R*x (should equal b):";
+ print (r * x);
+
+The above code produces the following output:
+
+::
+
+ Solution x:
+
+ 1.6666667
+ 2.0000000
+
+ R*x (should equal b):
+
+ 7.0000000
+ 4.0000000
+
Source
------
diff --git a/docs/qrtsol.rst b/docs/qrtsol.rst
index a9106710..bc867be9 100644
--- a/docs/qrtsol.rst
+++ b/docs/qrtsol.rst
@@ -31,6 +31,38 @@ triangular, transpose before calling :func:`qrtsol`.
If *R* is not transposed, use :func:`qrsol`.
+Examples
+--------
+
+::
+
+ // Upper triangular matrix R
+ r = { 3 1,
+ 0 2 };
+ b = { 7, 4 };
+
+ // Solve R'*x = b by passing R' (lower triangular) to qrtsol
+ x = qrtsol(b, r');
+
+ print "Solution x:";
+ print x;
+ print "R'*x (should equal b):";
+ print (r' * x);
+
+The above code produces the following output:
+
+::
+
+ Solution x:
+
+ 2.3333333
+ 0.83333333
+
+ R'*x (should equal b):
+
+ 7.0000000
+ 4.0000000
+
Source
------
diff --git a/docs/qtyre.rst b/docs/qtyre.rst
index 57d063a7..ad496a6d 100644
--- a/docs/qtyre.rst
+++ b/docs/qtyre.rst
@@ -153,6 +153,51 @@ it can be shown that
b = qrsol(Q'Y, R1)|zeros(N-P,1);
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Right-hand side vector
+ y = { 1,
+ 0,
+ 0 };
+
+ // Compute Q'*Y, R, and permutation vector E
+ { qty, r, e } = qtyre(y, x);
+
+ print "Q'*Y:";
+ print qty;
+ print "R (upper triangular):";
+ print r;
+ print "Permutation vector E:";
+ print e;
+
+The above code produces the following output:
+
+::
+
+ Q'*Y:
+
+ -0.26726124
+ 0.87287156
+ 0.40824829
+
+ R (upper triangular):
+
+ -7.4833148 -5.8797473
+ 0.0000000 -0.65465367
+
+ Permutation vector E:
+
+ 2.0000000
+ 1.0000000
+
Source
------
diff --git a/docs/qtyrep.rst b/docs/qtyrep.rst
index dea26886..6b24aa86 100644
--- a/docs/qtyrep.rst
+++ b/docs/qtyrep.rst
@@ -77,6 +77,54 @@ linear dependencies among the columns of :math:`X`, the column of ones for the
constant may get pivoted away. This column can be forced to be included
among the linearly independent columns using *pvt*.
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Right-hand side vector
+ y = { 1,
+ 0,
+ 0 };
+
+ // Pivot vector: all columns are free
+ pvt = { 0, 0 };
+
+ // Compute Q'*Y, R, and permutation vector with controlled pivoting
+ { qty, r, e } = qtyrep(y, x, pvt);
+
+ print "Q'*Y:";
+ print qty;
+ print "R (upper triangular):";
+ print r;
+ print "Permutation vector E:";
+ print e;
+
+The above code produces the following output:
+
+::
+
+ Q'*Y:
+
+ -0.26726124
+ 0.87287156
+ 0.40824829
+
+ R (upper triangular):
+
+ -7.4833148 -5.8797473
+ 0.0000000 -0.65465367
+
+ Permutation vector E:
+
+ 2.0000000
+ 1.0000000
+
Source
------
diff --git a/docs/quantile.rst b/docs/quantile.rst
index f16b7e7e..35f68108 100644
--- a/docs/quantile.rst
+++ b/docs/quantile.rst
@@ -88,3 +88,4 @@ Source
quantile.src
+.. seealso:: Functions :func:`median`, :func:`meanc`, :func:`percentile`
diff --git a/docs/quantiled.rst b/docs/quantiled.rst
index 40eb35b4..a14f0e85 100644
--- a/docs/quantiled.rst
+++ b/docs/quantiled.rst
@@ -157,4 +157,4 @@ Source
quantile.src
-.. seealso:: `Formula string`
+.. seealso:: ``Formula string``
diff --git a/docs/qyr.rst b/docs/qyr.rst
index f1de6aca..a3d8a606 100644
--- a/docs/qyr.rst
+++ b/docs/qyr.rst
@@ -57,6 +57,42 @@ where :math:`Y` is some NxL matrix, which will be a much smaller matrix.
If either :math:`Q'Y` or :math:`Q_1'Y` are required, see :func:`qtyr`.
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Set Y to a conformable identity to recover the full Q matrix
+ y = eye(3);
+
+ // Compute Q*Y and R
+ { qy, r } = qyr(y, x);
+
+ print "Q (full orthogonal matrix):";
+ print qy;
+ print "R (upper triangular):";
+ print r;
+
+The above code produces the following output:
+
+::
+
+ Q (full orthogonal matrix):
+
+ -0.16903085 0.89708523 0.40824829
+ -0.50709255 0.27602622 -0.81649658
+ -0.84515425 -0.34503278 0.40824829
+
+ R (upper triangular):
+
+ -5.9160798 -7.4373574
+ 0.0000000 0.82807867
+
Source
------
diff --git a/docs/qyre.rst b/docs/qyre.rst
index a511011b..37cc3945 100644
--- a/docs/qyre.rst
+++ b/docs/qyre.rst
@@ -73,6 +73,49 @@ If :math:`N < P`, the factorization assumes the form:
where :math:`R_1` is a PxP upper triangular matrix and :math:`R_2` is :math:`P \times (N-P)``. Thus :math:`Q`
is a PxP matrix and :math:`R` is a PxN matrix containing :math:`R_1` and :math:`R_2`.
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Set Y to identity to recover the full Q matrix
+ y = eye(3);
+
+ // Compute Q*Y, R, and permutation vector E
+ { qy, r, e } = qyre(y, x);
+
+ print "Q (full orthogonal matrix):";
+ print qy;
+ print "R (upper triangular):";
+ print r;
+ print "Permutation vector E:";
+ print e;
+
+The above code produces the following output:
+
+::
+
+ Q (full orthogonal matrix):
+
+ -0.26726124 0.87287156 0.40824829
+ -0.53452248 0.21821789 -0.81649658
+ -0.80178373 -0.43643578 0.40824829
+
+ R (upper triangular):
+
+ -7.4833148 -5.8797473
+ 0.0000000 -0.65465367
+
+ Permutation vector E:
+
+ 2.0000000
+ 1.0000000
+
Source
------
diff --git a/docs/qyrep.rst b/docs/qyrep.rst
index 765a7eb0..ff4cc713 100644
--- a/docs/qyrep.rst
+++ b/docs/qyrep.rst
@@ -91,6 +91,52 @@ If :math:`N < P`, the factorization assumes the form:
where :math:`R_1` is a PxP upper triangular matrix and :math:`R_2` is
Px(N-P). Thus :math:`Q` is a PxP matrix and :math:`R` is a PxN matrix containing :math:`R_1` and :math:`R_2`.
+Examples
+--------
+
+::
+
+ // Create a 3x2 matrix
+ x = { 1 2,
+ 3 4,
+ 5 6 };
+
+ // Set Y to identity to recover the full Q matrix
+ y = eye(3);
+
+ // Pivot vector: all columns are free
+ pvt = { 0, 0 };
+
+ // Compute Q*Y, R, and permutation vector with controlled pivoting
+ { qy, r, e } = qyrep(y, x, pvt);
+
+ print "Q (full orthogonal matrix):";
+ print qy;
+ print "R (upper triangular):";
+ print r;
+ print "Permutation vector E:";
+ print e;
+
+The above code produces the following output:
+
+::
+
+ Q (full orthogonal matrix):
+
+ -0.26726124 0.87287156 0.40824829
+ -0.53452248 0.21821789 -0.81649658
+ -0.80178373 -0.43643578 0.40824829
+
+ R (upper triangular):
+
+ -7.4833148 -5.8797473
+ 0.0000000 -0.65465367
+
+ Permutation vector E:
+
+ 2.0000000
+ 1.0000000
+
Source
------
diff --git a/docs/r.rst b/docs/r.rst
index e9cf03db..89f326e3 100644
--- a/docs/r.rst
+++ b/docs/r.rst
@@ -5,6 +5,7 @@ R
:maxdepth: 1
:caption: Functions:
+ range-operator
rankindx
rank
readr
@@ -20,6 +21,7 @@ R
recservar
renamefile
reordercatlabels
+ repmat
rerun
resetsourcepaths
rescale
diff --git a/docs/range-operator.rst b/docs/range-operator.rst
index 189a70b3..4d3af8b6 100644
--- a/docs/range-operator.rst
+++ b/docs/range-operator.rst
@@ -253,7 +253,7 @@ Two-Argument Form (start:end)
Three-Argument Form (start:step:end)
++++++++++++++++++++++++++++++++++++
-- The three-argument form ``start:step:end`` creates a sequence with custom step size, similar to MATLAB syntax.
+- The three-argument form ``start:step:end`` creates a sequence with custom step size.
- Outside of brackets, ``a:b:c`` is equivalent to ``seqa(a, b, floor((c-a)/b)+1)``.
diff --git a/docs/reclassifycuts.rst b/docs/reclassifycuts.rst
index 2474ee40..30533a38 100644
--- a/docs/reclassifycuts.rst
+++ b/docs/reclassifycuts.rst
@@ -17,6 +17,9 @@ Format
:type cut_pts: Kx1 vector
:param close_right: optional argument, 1 if the *cut_pts* should be the right end-point of the interval, or 0 if the values in *cut_pts* should start the next interval. Default = 0.
+
+ .. note:: When ``close_right = 0`` (default), intervals are closed on the right: ``(a, b]``. When ``close_right = 1``, intervals are closed on the left: ``[a, b)``.
+
:type close_right: Scalar
:return x_new: Contains the recoded values of *x*, will have the same dimensions as the input *x*.
diff --git a/docs/recodedataloop.rst b/docs/recodedataloop.rst
index 7dd68e57..c96f7279 100644
--- a/docs/recodedataloop.rst
+++ b/docs/recodedataloop.rst
@@ -75,8 +75,8 @@ If none of the expressions is ``TRUE`` for a given row (observation), its
value will remain unchanged.
Any variables referenced must already exist, either as elements of the
-source dataset, as `extern`'s, or as the result of a previous `make`,
-`vector`, or `code` statement.
+source dataset, as ``extern``'s, or as the result of a previous `make`,
+``vector``, or `code` statement.
.. seealso:: Functions `code`
diff --git a/docs/recserar.rst b/docs/recserar.rst
index 7624db13..4cae88b9 100644
--- a/docs/recserar.rst
+++ b/docs/recserar.rst
@@ -103,13 +103,13 @@ Typically, the result would be thought of as :math:`K` vectors of length :math:`
*y0* contains the first :math:`P` values of each of these vectors (thus, these are
prespecified). The remaining elements are constructed by computing a :math:`P^{th}`
-order "autoregressive" recursion, with weights given by *a*, and then by
+order "autoregressive" recursion, with weights given by *rho*, and then by
adding the result to the corresponding elements of *x*. That is, the :math:`t^{th}`
row of *y* is given by:
::
- y[t,.] = x[t,.] + a[1,.] * y[t-1,.] +...+ a[P,.] * y[t-p,.], t = P + 1,...N
+ y[t,.] = x[t,.] + rho[1,.] * y[t-1,.] +...+ rho[P,.] * y[t-p,.], t = P + 1,...N
and
diff --git a/docs/recservar.rst b/docs/recservar.rst
index 36a60cc0..bbf8ed4a 100644
--- a/docs/recservar.rst
+++ b/docs/recservar.rst
@@ -63,7 +63,7 @@ VAR(1) with constant
// Innovations
eps = rndn(100, 3);
- // Simulate AR(2) model with constant
+ // Simulate VAR(1) model with constant
y = recserVAR(eps + const, y0, pi_);
Remarks
diff --git a/docs/repmat.rst b/docs/repmat.rst
new file mode 100644
index 00000000..f8c9d000
--- /dev/null
+++ b/docs/repmat.rst
@@ -0,0 +1,91 @@
+
+repmat
+==============================================
+
+Purpose
+----------------
+Tiles (repeats) a matrix to create a larger matrix.
+
+Format
+----------------
+.. function:: B = repmat(A, m, n)
+
+ :param A: matrix to tile.
+ :type A: RxC matrix
+
+ :param m: number of times to tile vertically.
+ :type m: scalar
+
+ :param n: number of times to tile horizontally.
+ :type n: scalar
+
+ :return B: containing *m* x *n* copies of *A*.
+
+ :rtype B: (R*m)x(C*n) matrix
+
+Examples
+----------------
+
+Tile a matrix into a 2x3 grid
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ A = { 1 2,
+ 3 4 };
+
+ B = repmat(A, 2, 3);
+
+After the above code, ``B`` will equal:
+
+::
+
+ 1 2 1 2 1 2
+ 3 4 3 4 3 4
+ 1 2 1 2 1 2
+ 3 4 3 4 3 4
+
+Repeat a column vector across columns
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ v = { 10, 20, 30 };
+
+ B = repmat(v, 1, 4);
+
+After the above code, ``B`` will equal:
+
+::
+
+ 10 10 10 10
+ 20 20 20 20
+ 30 30 30 30
+
+Stack a row vector vertically
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ r = { 1 2 3 };
+
+ B = repmat(r, 3, 1);
+
+After the above code, ``B`` will equal:
+
+::
+
+ 1 2 3
+ 1 2 3
+ 1 2 3
+
+Remarks
+-------
+
+.. versionadded:: 26.0.1
+
+:func:`repmat` uses the Kronecker product to tile the input matrix. It is equivalent to::
+
+ B = ones(m, n) .*. A;
+
+.. seealso:: Functions :func:`reshape`, :func:`ones`, :func:`zeros`
diff --git a/docs/rerun.rst b/docs/rerun.rst
index 42157fee..887ff536 100644
--- a/docs/rerun.rst
+++ b/docs/rerun.rst
@@ -33,6 +33,17 @@ Remarks
:func:`rerun` is used by the :func:`endwind` function.
+Examples
+--------
+
+.. NOTE:: This function is for use with the deprecated PQG graphics.
+
+::
+
+ // Redisplay the most recently created graph
+ library pgraph;
+ rerun;
+
Source
------
diff --git a/docs/resetsourcepaths.rst b/docs/resetsourcepaths.rst
index 932a20b5..9ca3d4c0 100644
--- a/docs/resetsourcepaths.rst
+++ b/docs/resetsourcepaths.rst
@@ -9,14 +9,18 @@ Resets the source path to the original GAUSS startup values.
Format
----------------
-.. function:: ret = resetsourcepaths()
-
- :return ret: 1 if reset is successful, 0 otherwise.
-
- :rtype ret: string
+.. function:: resetsourcepaths()
Remarks
-------
The source path is set by the :file:`src_path` configuration variable in your
GAUSS configuration file, :file:`gauss.cfg`.
+
+Examples
+--------
+
+::
+
+ // Reset the source path to the gauss.cfg defaults
+ resetsourcepaths();
diff --git a/docs/reshape.rst b/docs/reshape.rst
index cbe904f8..2daed93b 100644
--- a/docs/reshape.rst
+++ b/docs/reshape.rst
@@ -137,4 +137,4 @@ to fill *y*, then when reshape runs out of elements, it goes back to the
first element of *x* and starts getting additional elements from there.
-.. seealso:: Functions :func:`submat`, :func:`vec`
+.. seealso:: Functions :func:`submat`, :func:`vec`, :func:`repmat`
diff --git a/docs/retp.rst b/docs/retp.rst
index 6a74ffc7..4e42da93 100644
--- a/docs/retp.rst
+++ b/docs/retp.rst
@@ -29,5 +29,28 @@ expressions. Items are separated by commas.
It is legal to return with no arguments, as long as the procedure is
defined to return 0 arguments.
+Examples
+--------
+
+::
+
+ // Procedure returning one value
+ proc (1) = addOne(x);
+ retp(x + 1);
+ endp;
+
+ y = addOne(5);
+ print y;
+
+::
+
+ // Procedure returning two values
+ proc (2) = minMax(x);
+ retp(minc(x), maxc(x));
+ endp;
+
+ { lo, hi } = minMax(seqa(1, 1, 10));
+ print lo hi;
+
.. seealso:: `proc`, `keyword`, `endp`
diff --git a/docs/return.rst b/docs/return.rst
index e65699e4..1c0b3cb0 100644
--- a/docs/return.rst
+++ b/docs/return.rst
@@ -26,5 +26,21 @@ Items are separated by commas.
It is legal to return with no arguments and therefore return nothing.
+Examples
+--------
+
+::
+
+ // Use return to pass values back from a gosub subroutine
+ gosub addNums(3, 7);
+ pop result;
+ print result;
+ stop;
+
+ addNums:
+ pop b;
+ pop a;
+ return (a + b);
+
.. seealso:: `gosub`, `pop`
diff --git a/docs/rfft.rst b/docs/rfft.rst
index bf6186fa..2af7dd0e 100644
--- a/docs/rfft.rst
+++ b/docs/rfft.rst
@@ -28,4 +28,33 @@ This uses a Temperton Fast Fourier algorithm.
If :math:`N` or :math:`K` is not a power of 2, *x* will be padded out with zeros before
computing the transform.
+Examples
+--------
+
+::
+
+ // Create an 8-element signal
+ x = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+ // Compute the real FFT
+ y = rfft(x);
+
+ print "Real FFT of x:";
+ print y;
+
+The above code produces the following output:
+
+::
+
+ Real FFT of x:
+
+ 4.5000000
+ -0.50000000 + 1.2071068i
+ -0.50000000 + 0.50000000i
+ -0.50000000 + 0.20710678i
+ -0.50000000
+ -0.50000000 - 0.20710678i
+ -0.50000000 - 0.50000000i
+ -0.50000000 - 1.2071068i
+
.. seealso:: Functions :func:`rffti`, :func:`fft`, :func:`ffti`, :func:`fftm`, :func:`fftmi`
diff --git a/docs/rffti.rst b/docs/rffti.rst
index 5c4404b1..b2efc281 100644
--- a/docs/rffti.rst
+++ b/docs/rffti.rst
@@ -24,4 +24,49 @@ Remarks
It is up to the user to guarantee that the input will return a real result. If in doubt, use :func:`ffti`.
+Examples
+--------
+
+::
+
+ // Create an 8-element signal
+ x = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+ // Forward FFT
+ y = rfft(x);
+
+ // Inverse FFT recovers the original signal
+ z = rffti(y);
+
+ print "Original x:";
+ print x;
+ print "Recovered via rffti:";
+ print z;
+
+The above code produces the following output:
+
+::
+
+ Original x:
+
+ 1.0000000
+ 2.0000000
+ 3.0000000
+ 4.0000000
+ 5.0000000
+ 6.0000000
+ 7.0000000
+ 8.0000000
+
+ Recovered via rffti:
+
+ 1.0000000
+ 2.0000000
+ 3.0000000
+ 4.0000000
+ 5.0000000
+ 6.0000000
+ 7.0000000
+ 8.0000000
+
.. seealso:: Functions :func:`rfft`, :func:`fft`, :func:`ffti`, :func:`fftm`, :func:`fftmi`
diff --git a/docs/rfftip.rst b/docs/rfftip.rst
index 7f6ef139..7653b34d 100644
--- a/docs/rfftip.rst
+++ b/docs/rfftip.rst
@@ -59,4 +59,49 @@ FFT, including negative frequency information, for input.
Do not pass :func:`rfftip` the output from :func:`rfft` or :func:`rfftn` - it will return
incorrect results. Use :func:`rffti` with those routines.
+Examples
+--------
+
+::
+
+ // Create an 8-element signal
+ x = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+ // Forward packed FFT
+ y = rfftp(x);
+
+ // Inverse packed FFT recovers the original signal
+ z = rfftip(y);
+
+ print "Original x:";
+ print x;
+ print "Recovered via rfftip:";
+ print z;
+
+The above code produces the following output:
+
+::
+
+ Original x:
+
+ 1.0000000
+ 2.0000000
+ 3.0000000
+ 4.0000000
+ 5.0000000
+ 6.0000000
+ 7.0000000
+ 8.0000000
+
+ Recovered via rfftip:
+
+ 1.0000000
+ 2.0000000
+ 3.0000000
+ 4.0000000
+ 5.0000000
+ 6.0000000
+ 7.0000000
+ 8.0000000
+
.. seealso:: Functions :func:`fft`, :func:`ffti`, :func:`fftm`, :func:`fftmi`, :func:`fftn`, :func:`rfft`, :func:`rffti`, :func:`rfftn`, :func:`rfftnp`, :func:`rfftp`
diff --git a/docs/rfftn.rst b/docs/rfftn.rst
index b4f655b2..67e2a056 100644
--- a/docs/rfftn.rst
+++ b/docs/rfftn.rst
@@ -75,4 +75,35 @@ vector.)
:func:`rfftn` scales the computed FFT by :math:`\frac{1}{(L*M)}`.
+Examples
+--------
+
+::
+
+ // Create an 8-element signal
+ x = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+ // Compute the real FFT using prime factor algorithm
+ y = rfftn(x);
+
+ print "rfftn result:";
+ print y;
+
+The above code produces the following output:
+
+::
+
+ rfftn result:
+
+ 4.5000000
+ -0.50000000 + 1.2071068i
+ -0.50000000 + 0.50000000i
+ -0.50000000 + 0.20710678i
+ -0.50000000
+ -0.50000000 - 0.20710678i
+ -0.50000000 - 0.50000000i
+ -0.50000000 - 1.2071068i
+
+.. note:: :func:`rfftn` handles dimensions that are products of 2, 3, 5, and 7, unlike :func:`rfft` which requires powers of 2.
+
.. seealso:: Functions :func:`fft`, :func:`ffti`, :func:`fftm`, :func:`fftmi`, :func:`fftn`, :func:`rfft`, :func:`rffti`, :func:`rfftip`, :func:`rfftnp`, :func:`rfftp`
diff --git a/docs/rfftnp.rst b/docs/rfftnp.rst
index 91520a50..1e4aa483 100644
--- a/docs/rfftnp.rst
+++ b/docs/rfftnp.rst
@@ -88,4 +88,32 @@ vector.)
:func:`rfftnp` scales the computed FFT by :math:`\frac{1}{L*M}`.
+Examples
+--------
+
+::
+
+ // Create an 8-element signal
+ x = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+ // Compute packed FFT (positive frequencies only)
+ y = rfftnp(x);
+
+ print "rfftnp result (packed format):";
+ print y;
+
+The above code produces the following output:
+
+::
+
+ rfftnp result (packed format):
+
+ 4.5000000
+ -0.50000000 + 1.2071068i
+ -0.50000000 + 0.50000000i
+ -0.50000000 + 0.20710678i
+ -0.50000000
+
+The packed format returns only positive frequencies and the Nyquist frequency, reducing output size by approximately half compared to :func:`rfftn`.
+
.. seealso:: Functions :func:`fft`, :func:`ffti`, :func:`fftm`, :func:`fftmi`, :func:`fftn`, :func:`rfft`, :func:`rffti`, :func:`rfftip`, :func:`rfftn`, :func:`rfftp`
diff --git a/docs/rfftp.rst b/docs/rfftp.rst
index e2368a57..2064a300 100644
--- a/docs/rfftp.rst
+++ b/docs/rfftp.rst
@@ -41,4 +41,32 @@ that return the negative frequencies as well.)
:func:`rfftp` uses the Temperton FFT algorithm.
+Examples
+--------
+
+::
+
+ // Create an 8-element signal
+ x = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+ // Compute packed FFT (positive frequencies only)
+ y = rfftp(x);
+
+ print "rfftp result (packed format):";
+ print y;
+
+The above code produces the following output:
+
+::
+
+ rfftp result (packed format):
+
+ 4.5000000
+ -0.50000000 + 1.2071068i
+ -0.50000000 + 0.50000000i
+ -0.50000000 + 0.20710678i
+ -0.50000000
+
+The packed format returns only positive frequencies and the Nyquist frequency. Use :func:`rfftip` to compute the inverse.
+
.. seealso:: Functions :func:`fft`, :func:`ffti`, :func:`fftm`, :func:`fftmi`, :func:`fftn`, :func:`rfft`, :func:`rffti`, :func:`rfftip`, :func:`rfftn`, :func:`rfftnp`
diff --git a/docs/ridgecpredict.rst b/docs/ridgecpredict.rst
index 981e8fee..7f301566 100644
--- a/docs/ridgecpredict.rst
+++ b/docs/ridgecpredict.rst
@@ -10,7 +10,7 @@ Format
.. function:: predictions = ridgeCPredict(mdl, x_test)
- :return mdl: An instance of a :class:`ridgeModel` structure. An instance named *mdl* will have the following members:
+ :param mdl: An instance of a :class:`ridgeModel` structure. An instance named *mdl* will have the following members:
.. csv-table::
:widths: auto
@@ -20,7 +20,7 @@ Format
"mdl.mse_train","(*nlambdas x 1 vector*) The mean squared error for each set of parameters, computed on the training set."
"mdl.lambda","(*nlambdas x 1 vector*) The *lambda* values used in the estimation."
- :rtype mdl: struct
+ :type mdl: struct
:param x_test: The independent variables.
:type x_test: NxP matrix
diff --git a/docs/rndbernoulli.rst b/docs/rndbernoulli.rst
index 60b8d4c5..20cc47e4 100644
--- a/docs/rndbernoulli.rst
+++ b/docs/rndbernoulli.rst
@@ -50,8 +50,8 @@ Examples
// binary data (i.e., yes/no, true/false), such as marital
// status.
- // Set the random seed for repeatable numbers.
- rndseed 723940439;
+ // Set seed for repeatable output
+ rndseed 12345;
// The percentage of married people in the population we
// would like to model.
@@ -66,7 +66,7 @@ Examples
::
- 0.70270000
+ 0.69750000
Remarks
-------
diff --git a/docs/rndbeta.rst b/docs/rndbeta.rst
index 293efa6b..9fecb08d 100644
--- a/docs/rndbeta.rst
+++ b/docs/rndbeta.rst
@@ -54,11 +54,25 @@ This example illustrates basic usage of :func:`rndBeta`, leaving the management
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
num_rows = 100;
num_cols = 5;
a = 3;
b = 2;
x = rndBeta(num_rows, num_cols, a, b);
+ print (meanc(x));
+
+::
+
+ 0.60359473
+ 0.58823075
+ 0.58101263
+ 0.61240728
+ 0.59562366
+
+The column means are each close to the expected value of a/(a+b) = 3/5 = 0.60.
Example 2
+++++++++
diff --git a/docs/rndcauchy.rst b/docs/rndcauchy.rst
index 6c8a1632..c5d2b6b5 100644
--- a/docs/rndcauchy.rst
+++ b/docs/rndcauchy.rst
@@ -57,4 +57,25 @@ The properties of the pseudo-random numbers in *x* are:
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x1 vector of standard Cauchy random numbers
+ // with location = 0 and scale = 1
+ x = rndCauchy(3, 1, 0, 1);
+ print x;
+
+After the code above, *x* is:
+
+::
+
+ 3.2446955
+ -0.17323020
+ 1.0822839
+
.. seealso:: Functions :func:`rndCreateState`, :func:`rndStateSkip`
diff --git a/docs/rndchisquare.rst b/docs/rndchisquare.rst
index d0f88a19..5efdb9a3 100644
--- a/docs/rndchisquare.rst
+++ b/docs/rndchisquare.rst
@@ -66,6 +66,25 @@ where:
\lambda = s\_ncp^2
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 100x1 vector of chi-squared
+ // random numbers with 5 degrees of freedom
+ x = rndChiSquare(100, 1, 5);
+ print (meanc(x));
+
+::
+
+ 4.8899054
+
+The sample mean is approximately 4.89, close to the expected value of 5 (the degrees of freedom).
+
Technical Notes
--------------------
diff --git a/docs/rndconrndmultrndseed.rst b/docs/rndconrndmultrndseed.rst
index a29ac957..e59151a3 100644
--- a/docs/rndconrndmultrndseed.rst
+++ b/docs/rndconrndmultrndseed.rst
@@ -80,4 +80,34 @@ that should not usually be a problem.
The parameters set by these commands remain in effect until new commands
are encountered, or until GAUSS is restarted.
+Examples
+----------------
+
+::
+
+ // Set a fixed seed for reproducible results
+ rndseed 54321;
+
+ x = rndu(3, 2);
+ print x;
+
+ // Reset the same seed to reproduce
+ // the same sequence of random numbers
+ rndseed 54321;
+
+ y = rndu(3, 2);
+ print y;
+
+Both ``x`` and ``y`` contain the same values, confirming that resetting the seed reproduces the sequence:
+
+::
+
+ 0.89660425 0.65692719
+ 0.021991147 0.054529152
+ 0.76761078 0.90491182
+
+ 0.89660425 0.65692719
+ 0.021991147 0.054529152
+ 0.76761078 0.90491182
+
.. seealso:: Functions :func:`rndu`, :func:`rndn`, :func:`rndi`, :func:`rndLCi`, :func:`rndKMi`
diff --git a/docs/rndcreatestate.rst b/docs/rndcreatestate.rst
index 3f77e3bc..4a728f27 100644
--- a/docs/rndcreatestate.rst
+++ b/docs/rndcreatestate.rst
@@ -127,6 +127,8 @@ After the code above, *r*, should be equal to:
Remarks
-------
+.. note:: For the quasi-random number generators (``"sobol"`` and ``"niederreiter"``), the second argument specifies the **dimension** of the sequence, not a seed. The maximum dimension for ``"sobol"`` sequences is 40, and for ``"niederreiter"`` it is 318.
+
The states returned from this function may NOT be used with :func:`rndMTu` or any of the :func:`rndKM` or :func:`rndLC` functions.
.. seealso:: Functions :func:`rndStateSkip`, :func:`rndn`, :func:`rndu`, :func:`rndBeta`
diff --git a/docs/rndexp.rst b/docs/rndexp.rst
index 1d783dd1..45832808 100644
--- a/docs/rndexp.rst
+++ b/docs/rndexp.rst
@@ -53,4 +53,25 @@ of the *scale* parameter sometimes called :math:`\beta`. This is the reciprocal
E(x) = scale = \beta = 1/rate = 1/\lambda\\
Var(x) = scale^2 =\beta^2 = 1/rate^2 = 1/\lambda^2
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x2 matrix of exponential
+ // random numbers with scale = 2
+ x = rndExp(3, 2, 2);
+ print x;
+
+After the code above, *x* is:
+
+::
+
+ 0.19999741 1.6175607
+ 0.54211710 4.0899319
+ 1.3480216 5.5601364
+
.. seealso:: Functions :func:`rndCreateState`, :func:`rndStateSkip`
diff --git a/docs/rndgam.rst b/docs/rndgam.rst
index ce1c691d..d204992e 100644
--- a/docs/rndgam.rst
+++ b/docs/rndgam.rst
@@ -39,6 +39,27 @@ The properties of the pseudo-random numbers in *x* are:
x > 0\\
\alpha > 0
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x2 matrix of gamma
+ // random numbers with shape = 5
+ x = rndgam(3, 2, 5);
+ print x;
+
+After the code above, *x* is:
+
+::
+
+ 4.3270396 9.4093462
+ 3.9689646 4.7393241
+ 6.1082705 5.6436564
+
Source
------
diff --git a/docs/rndgamma.rst b/docs/rndgamma.rst
index 8a37884e..c9ff1dc5 100644
--- a/docs/rndgamma.rst
+++ b/docs/rndgamma.rst
@@ -52,6 +52,9 @@ Example 1
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
num_rows = 5;
num_cols = 1;
shape = 3;
@@ -59,6 +62,16 @@ Example 1
x = rndGamma(num_rows, num_cols, shape, scale);
+After the code above, *x* is:
+
+::
+
+ 4.0057858
+ 5.4494189
+ 2.4490466
+ 4.3893173
+ 4.2732468
+
Example 2
+++++++++
@@ -77,11 +90,26 @@ reciprocal of the *rate* parameter as the fourth argument to :func:`rndGamma`.
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
shape = 3;
rate = 2;
x = rndGamma(5, 1, shape, 1/rate);
+After the code above, *x* is:
+
+::
+
+ 1.0014464
+ 1.3623547
+ 0.61226164
+ 1.0973293
+ 1.0683117
+
+The expected value is shape/rate = 3/2 = 1.5, and the sample values are centered around that.
+
Remarks
-------
diff --git a/docs/rndgeo.rst b/docs/rndgeo.rst
index 2953e6db..29aaeb26 100644
--- a/docs/rndgeo.rst
+++ b/docs/rndgeo.rst
@@ -55,4 +55,25 @@ The properties of the pseudo-random numbers in *y* are:
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x2 matrix of geometric
+ // random numbers with probability = 0.4
+ y = rndGeo(3, 2, 0.4);
+ print y;
+
+After the code above, *y* is:
+
+::
+
+ 0.0000000 1.0000000
+ 0.0000000 4.0000000
+ 1.0000000 5.0000000
+
.. seealso:: Functions :func:`rndCreateState`, :func:`rndStateSkip`
diff --git a/docs/rndgumbel.rst b/docs/rndgumbel.rst
index 7a57738e..ef584a3e 100644
--- a/docs/rndgumbel.rst
+++ b/docs/rndgumbel.rst
@@ -60,4 +60,25 @@ pseudo-random numbers in *y* are:
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x2 matrix of Gumbel
+ // random numbers with location = 0, scale = 1
+ x = rndGumbel(3, 2, 0, 1);
+ print x;
+
+After the code above, *x* is:
+
+::
+
+ -2.3025980 -0.21222789
+ -1.3054204 0.71538115
+ -0.39450916 1.0224755
+
.. seealso:: Functions :func:`rndCreateState`, :func:`rndStateSkip`
diff --git a/docs/rndhypergeo.rst b/docs/rndhypergeo.rst
index d54645fd..c41c0a46 100644
--- a/docs/rndhypergeo.rst
+++ b/docs/rndhypergeo.rst
@@ -58,17 +58,27 @@ Basic Example
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
// Population size
m = 100;
-
+
// Number of marked items
k = 25;
-
+
// Number of items drawn
n = 40;
-
+
// Compute 1 random number
x = rndHyperGeo(1, 1, m, k, n);
+ print x;
+
+::
+
+ 13.000000
+
+The expected value is n*k/m = 40*25/100 = 10. A single draw of 13 is a reasonable outcome.
Random matrix in which each column has different parameters.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/docs/rndi.rst b/docs/rndi.rst
index 2f8253e1..a6f2dc5a 100644
--- a/docs/rndi.rst
+++ b/docs/rndi.rst
@@ -51,6 +51,9 @@ Basic example
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
// Create a 10x5 vector of random
// integers between 0 and 2^32 - 1
r_int = rndi(10, 5);
@@ -60,11 +63,28 @@ Basic range
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
// Create a 10x1 vector of random
// integers between 1 and 100
range_start = 1;
range_end = 100;
idx = rndi(10, 1, range_start | range_end);
+ print idx;
+
+::
+
+ 91.000000
+ 45.000000
+ 77.000000
+ 13.000000
+ 51.000000
+ 7.0000000
+ 71.000000
+ 8.0000000
+ 84.000000
+ 92.000000
Sample with replacement from a dataset
++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/docs/rndkmbeta.rst b/docs/rndkmbeta.rst
index 06d0a5fc..a7d22911 100644
--- a/docs/rndkmbeta.rst
+++ b/docs/rndkmbeta.rst
@@ -61,6 +61,25 @@ The properties of the pseudo-random numbers in *x* are:
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Generate a 3x2 matrix of beta random numbers
+ // with shape parameters a = 2, b = 5
+ // using a fixed seed for repeatable output
+ { x, newstate } = rndKMbeta(3, 2, 2, 5, 12345);
+ print x;
+
+The output is a 3x2 matrix of beta-distributed values between 0 and 1. The sample mean is approximately 0.29, consistent with the theoretical mean of a/(a+b) = 2/7:
+
+::
+
+ 0.19288089 0.38057594
+ 0.51686669 0.57522795
+ 0.31832075 0.14046662
+
Technical Notes
---------------
:func:`rndKMbeta` uses the recur-with-carry KISS+Monster algorithm described in the :func:`rndKMi` Technical Notes.
diff --git a/docs/rndkmgam.rst b/docs/rndkmgam.rst
index c03f030f..99c9731c 100644
--- a/docs/rndkmgam.rst
+++ b/docs/rndkmgam.rst
@@ -73,6 +73,24 @@ has the properties
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Generate a 3x2 matrix of gamma random numbers
+ // with shape alpha = 5, using a fixed seed for repeatable output
+ { x, newstate } = rndKMgam(3, 2, 5, 12345);
+ print x;
+
+The output is a 3x2 matrix of gamma-distributed values. The sample mean is approximately 5, consistent with the theoretical mean of alpha:
+
+::
+
+ 5.6131502 2.6675772
+ 4.6622884 3.3561170
+ 4.9309951 6.8404543
+
Technical Notes
---------------
:func:`rndKMgam` uses the recur-with-carry KISS+Monster algorithm described in the :func:`rndKMi` Technical Notes.
diff --git a/docs/rndkmi.rst b/docs/rndkmi.rst
index 6f6bc1a9..44462262 100644
--- a/docs/rndkmi.rst
+++ b/docs/rndkmi.rst
@@ -63,6 +63,13 @@ generation of random numbers.
print "min " min;
print "max " max;
+produces the following output, showing that values span nearly the full range of :math:`0` to :math:`2^{32} - 1`:
+
+::
+
+ min 4222.0000
+ max 4.2949644e+09
+
Remarks
-------
diff --git a/docs/rndkmn.rst b/docs/rndkmn.rst
index cc2d0b92..12d8f26b 100644
--- a/docs/rndkmn.rst
+++ b/docs/rndkmn.rst
@@ -62,6 +62,12 @@ the next generation of random numbers.
mean = meanc(submean);
print mean;
+The overall mean is approximately zero, consistent with a standard normal distribution:
+
+::
+
+ -8.3387630e-05
+
Remarks
-------
diff --git a/docs/rndkmnb.rst b/docs/rndkmnb.rst
index 3fcdcd3c..5b5ce5b4 100644
--- a/docs/rndkmnb.rst
+++ b/docs/rndkmnb.rst
@@ -58,6 +58,25 @@ The properties of the pseudo-random numbers in *x* are:
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Generate a 3x2 matrix of negative binomial
+ // random numbers with k = 5 and p = 0.3
+ // using a fixed seed for repeatable output
+ { x, newstate } = rndKMnb(3, 2, 5, 0.3, 12345);
+ print x;
+
+The output is a 3x2 matrix of non-negative integers. The theoretical mean is k*p/(1-p) = 5*0.3/0.7, which is approximately 2.14:
+
+::
+
+ 3.0000000 1.0000000
+ 1.0000000 3.0000000
+ 1.0000000 1.0000000
+
Technical Notes
---------------
:func:`rndKMnb` uses the recur-with-carry KISS+Monster algorithm described in the :func:`rndKMi` Technical Notes.
diff --git a/docs/rndkmp.rst b/docs/rndkmp.rst
index c6a368ee..408d820f 100644
--- a/docs/rndkmp.rst
+++ b/docs/rndkmp.rst
@@ -53,6 +53,25 @@ The properties of the pseudo-random numbers in *x* are:
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Generate a 3x2 matrix of Poisson
+ // random numbers with lambda = 5
+ // using a fixed seed for repeatable output
+ { x, newstate } = rndKMp(3, 2, 5, 12345);
+ print x;
+
+The output is a 3x2 matrix of non-negative integers. The sample mean is approximately 5, consistent with the theoretical mean of lambda:
+
+::
+
+ 6.0000000 4.0000000
+ 4.0000000 7.0000000
+ 3.0000000 4.0000000
+
Technical Notes
---------------
:func:`rndKMp` uses the recur-with-carry KISS+Monster algorithm described in the :func:`rndKMi` Technical Notes.
diff --git a/docs/rndkmu.rst b/docs/rndkmu.rst
index 3b23d89d..93c451bb 100644
--- a/docs/rndkmu.rst
+++ b/docs/rndkmu.rst
@@ -61,6 +61,12 @@ next generation of random numbers.
mean = meanc(submean);
print 0.5-mean;
+The difference from 0.5 is approximately zero, confirming the mean of the uniform distribution:
+
+::
+
+ 0.00060519278
+
Remarks
-------
diff --git a/docs/rndkmvm.rst b/docs/rndkmvm.rst
index fcfec8b2..d61276fb 100644
--- a/docs/rndkmvm.rst
+++ b/docs/rndkmvm.rst
@@ -48,6 +48,25 @@ Remarks
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Generate a 3x2 matrix of von Mises
+ // random numbers with mean = pi, shape = 2
+ // using a fixed seed for repeatable output
+ { x, newstate } = rndKMvm(3, 2, 3.14, 2, 12345);
+ print x;
+
+The output is a 3x2 matrix of von Mises distributed values centered near the mean of 3.14 (pi):
+
+::
+
+ -1.9497965 -1.6210254
+ -3.0063623 -2.2778588
+ 2.6152190 2.6730616
+
Technical Notes
---------------
:func:`rndKMvm` uses the recur-with-carry KISS+Monster algorithm described in the :func:`rndKMi` Technical Notes.
diff --git a/docs/rndlaplace.rst b/docs/rndlaplace.rst
index 40e19a23..a2c0a4b5 100644
--- a/docs/rndlaplace.rst
+++ b/docs/rndlaplace.rst
@@ -56,4 +56,25 @@ The properties of the pseudo-random numbers in *x* are:
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x2 matrix of Laplacian
+ // random numbers with location = 0, scale = 1
+ x = rndLaplace(3, 2, 0, 1);
+ print x;
+
+After the code above, *x* is:
+
+::
+
+ 0.099998705 0.27105855
+ 0.67401079 0.34634625
+ -0.17962450 0.51272075
+
.. seealso:: Functions :func:`rndCreateState`, :func:`rndStateSkip`
diff --git a/docs/rndlcbeta.rst b/docs/rndlcbeta.rst
index 78e39993..7c74c0fd 100644
--- a/docs/rndlcbeta.rst
+++ b/docs/rndlcbeta.rst
@@ -65,6 +65,25 @@ Format
:rtype newstate: 4x1 vector
+Examples
+----------------
+
+::
+
+ // Generate a 3x2 matrix of beta random numbers
+ // with shape parameters a = 2, b = 5
+ // using a fixed seed for repeatable output
+ { x, newstate } = rndLCbeta(3, 2, 2, 5, 12345);
+ print x;
+
+The output is a 3x2 matrix of beta-distributed values between 0 and 1. The theoretical mean is a/(a+b) = 2/7, which is approximately 0.29:
+
+::
+
+ 0.81528086 0.26432401
+ 0.086956961 0.28779992
+ 0.23908762 0.047957242
+
Technical Notes
---------------
diff --git a/docs/rndlcgam.rst b/docs/rndlcgam.rst
index 7f435de4..6739ccf6 100644
--- a/docs/rndlcgam.rst
+++ b/docs/rndlcgam.rst
@@ -63,6 +63,24 @@ Format
:rtype newstate: 4x1 vector
+Examples
+----------------
+
+::
+
+ // Generate a 3x2 matrix of gamma random numbers
+ // with shape alpha = 5, using a fixed seed for repeatable output
+ { x, newstate } = rndLCgam(3, 2, 5, 12345);
+ print x;
+
+The output is a 3x2 matrix of gamma-distributed values. The sample mean is approximately 5, consistent with the theoretical mean of alpha:
+
+::
+
+ 4.3270396 9.4093462
+ 3.9689646 4.7393241
+ 6.1082705 5.6436564
+
Technical Notes
---------------
diff --git a/docs/rndlci.rst b/docs/rndlci.rst
index 472f4469..42ade0b4 100644
--- a/docs/rndlci.rst
+++ b/docs/rndlci.rst
@@ -83,6 +83,13 @@ Examples
print "min " min;
print "max " max;
+produces the following output, showing that values span nearly the full range of :math:`0` to :math:`2^{32} - 1`:
+
+::
+
+ min 0.0000000
+ max 4.2949673e+09
+
Remarks
-------
diff --git a/docs/rndlcn.rst b/docs/rndlcn.rst
index 0c42e8c3..7be8dcf0 100644
--- a/docs/rndlcn.rst
+++ b/docs/rndlcn.rst
@@ -79,6 +79,12 @@ Examples
mean = meanc(submean);
print mean;
+The overall mean is approximately zero, consistent with a standard normal distribution:
+
+::
+
+ 3.9836726e-06
+
Remarks
-------
diff --git a/docs/rndlcnb.rst b/docs/rndlcnb.rst
index b0a7d5b9..1eb1049a 100644
--- a/docs/rndlcnb.rst
+++ b/docs/rndlcnb.rst
@@ -66,6 +66,25 @@ Format
:rtype newstate: 4x1 vector
+Examples
+----------------
+
+::
+
+ // Generate a 3x2 matrix of negative binomial
+ // random numbers with k = 5 and p = 0.3
+ // using a fixed seed for repeatable output
+ { x, newstate } = rndLCnb(3, 2, 5, 0.3, 12345);
+ print x;
+
+The output is a 3x2 matrix of non-negative integers. The theoretical mean is k*p/(1-p) = 5*0.3/0.7, which is approximately 2.14:
+
+::
+
+ 0.0000000 0.0000000
+ 2.0000000 2.0000000
+ 5.0000000 0.0000000
+
Technical Notes
---------------
diff --git a/docs/rndlcp.rst b/docs/rndlcp.rst
index 8187e3bb..a0b4773a 100644
--- a/docs/rndlcp.rst
+++ b/docs/rndlcp.rst
@@ -62,6 +62,25 @@ Format
:rtype newstate: 4x1 vector
+Examples
+----------------
+
+::
+
+ // Generate a 3x2 matrix of Poisson
+ // random numbers with lambda = 5
+ // using a fixed seed for repeatable output
+ { x, newstate } = rndLCp(3, 2, 5, 12345);
+ print x;
+
+The output is a 3x2 matrix of non-negative integers. The sample mean is approximately 5, consistent with the theoretical mean of lambda:
+
+::
+
+ 1.0000000 1.0000000
+ 5.0000000 6.0000000
+ 8.0000000 2.0000000
+
Technical Notes
---------------
diff --git a/docs/rndlcu.rst b/docs/rndlcu.rst
index 5d85133b..c45fcde8 100644
--- a/docs/rndlcu.rst
+++ b/docs/rndlcu.rst
@@ -80,6 +80,12 @@ Examples
mean = meanc(submean);
print 0.5-mean;
+The difference from 0.5 is approximately zero, confirming the mean of the uniform distribution:
+
+::
+
+ 6.2762512e-06
+
Remarks
-------
diff --git a/docs/rndlcvm.rst b/docs/rndlcvm.rst
index cf5bfea1..66430a34 100644
--- a/docs/rndlcvm.rst
+++ b/docs/rndlcvm.rst
@@ -72,6 +72,25 @@ Remarks
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Generate a 3x2 matrix of von Mises
+ // random numbers with mean = pi, shape = 2
+ // using a fixed seed for repeatable output
+ { x, newstate } = rndLCvm(3, 2, 3.14, 2, 12345);
+ print x;
+
+The output is a 3x2 matrix of von Mises distributed values centered near the mean of 3.14 (pi):
+
+::
+
+ 3.1175039 -2.1479505
+ 2.4731394 1.5778518
+ 0.30247595 2.5394883
+
Technical Notes
---------------
diff --git a/docs/rndlognorm.rst b/docs/rndlognorm.rst
index 1d001957..3826650e 100644
--- a/docs/rndlognorm.rst
+++ b/docs/rndlognorm.rst
@@ -57,4 +57,25 @@ The properties of the pseudo-random numbers in *x* are:
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x2 matrix of lognormal
+ // random numbers with mu = 0, sigma = 1
+ x = rndLogNorm(3, 2, 0, 1);
+ print x;
+
+After the code above, *x* is:
+
+::
+
+ 3.7047831 0.87171778
+ 2.0433690 0.32325784
+ 1.0245128 0.21482781
+
.. seealso:: Functions :func:`rndCreateState`, :func:`rndStateSkip`
diff --git a/docs/rndmvn.rst b/docs/rndmvn.rst
index de7451c6..91dc616e 100644
--- a/docs/rndmvn.rst
+++ b/docs/rndmvn.rst
@@ -46,6 +46,9 @@ Examples
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
// covariance matrix
cov = { 1 0.3,
0.3 1 };
@@ -54,6 +57,14 @@ Examples
mu = { 0, 0 };
x = rndMVn(100, mu, cov);
+ print (meanc(x));
+
+::
+
+ -0.024045422
+ -0.0015723702
+
+The column means are both close to zero, the expected value for each dimension.
Remarks
-------
diff --git a/docs/rndmvt.rst b/docs/rndmvt.rst
index 64da30cc..727d6f18 100644
--- a/docs/rndmvt.rst
+++ b/docs/rndmvt.rst
@@ -46,6 +46,9 @@ Examples
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
// Degrees of freedom
df = 8;
@@ -54,6 +57,14 @@ Examples
0.3 1 };
x = rndMVt(100, sigma, df);
+ print (meanc(x));
+
+::
+
+ -0.055890701
+ -0.034103818
+
+The column means are both close to zero, the expected value for a multivariate t-distribution.
Remarks
-------
diff --git a/docs/rndn.rst b/docs/rndn.rst
index 1304afe8..b3883a64 100644
--- a/docs/rndn.rst
+++ b/docs/rndn.rst
@@ -46,9 +46,22 @@ Example 1
::
- //Create a 100 by 1 vector of standard normal numbers
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Create a 100 by 1 vector of standard normal numbers
my_var = rndn(100, 1);
+ print (meanc(my_var));
+ print (stdc(my_var));
+
+The sample mean is approximately zero and the standard deviation is approximately one, consistent with the standard normal distribution:
+
+::
+
+ -0.16514335
+ 1.0121976
+
Example 2
+++++++++
diff --git a/docs/rndnb.rst b/docs/rndnb.rst
index 0978569a..0bd11791 100644
--- a/docs/rndnb.rst
+++ b/docs/rndnb.rst
@@ -34,6 +34,27 @@ The properties of the pseudo-random numbers in *x* are:
.. figure:: _static/images/img832.png
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x2 matrix of negative binomial
+ // random numbers with k = 5 and p = 0.3
+ x = rndnb(3, 2, 5, 0.3);
+ print x;
+
+After the code above, *x* is:
+
+::
+
+ 0.0000000 0.0000000
+ 2.0000000 2.0000000
+ 5.0000000 0.0000000
+
Source
------
diff --git a/docs/rndnegbinomial.rst b/docs/rndnegbinomial.rst
index ca577a11..6334a4ad 100644
--- a/docs/rndnegbinomial.rst
+++ b/docs/rndnegbinomial.rst
@@ -54,12 +54,22 @@ Simulate the number of failures before 30 successes where each trial has a 70% p
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
num_obs = 100;
num_s = 30;
prob = 0.70;
num_f = rndNegBinomial(num_obs, 1, num_s, prob);
+ print (meanc(num_f));
+
+::
+
+ 12.180000
+
+The sample mean is approximately 12.18, close to the expected value of num_s*(1-prob)/prob = 30*0.3/0.7 = 12.86.
Example 2
+++++++++
diff --git a/docs/rndp.rst b/docs/rndp.rst
index 67b40c6f..abccc731 100644
--- a/docs/rndp.rst
+++ b/docs/rndp.rst
@@ -39,6 +39,27 @@ The properties of the pseudo-random numbers in *x* are:
| *lambda* | > | 0 |
+--------------+---+-----------+
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x2 matrix of Poisson
+ // random numbers with lambda = 5
+ x = rndp(3, 2, 5);
+ print x;
+
+After the code above, *x* is:
+
+::
+
+ 1.0000000 1.0000000
+ 5.0000000 6.0000000
+ 8.0000000 2.0000000
+
Source
------
diff --git a/docs/rndpoisson.rst b/docs/rndpoisson.rst
index 069fe184..a6a19022 100644
--- a/docs/rndpoisson.rst
+++ b/docs/rndpoisson.rst
@@ -47,9 +47,19 @@ The example below simulates 100 observations of a Poisson process with a mean of
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
lambda = 17;
x = rndPoisson(100, 1, lambda);
+ print (meanc(x));
+
+::
+
+ 16.320000
+
+The sample mean is approximately 16.32, close to the expected value of 17 (lambda).
Remarks
-------
diff --git a/docs/rndu.rst b/docs/rndu.rst
index ff04a3d3..9382521e 100644
--- a/docs/rndu.rst
+++ b/docs/rndu.rst
@@ -50,9 +50,20 @@ If a state or seed is not passed in, then only the random numbers are returned.
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
// Create a 100x1 vector of uniform random numbers
y = rndu(100, 1);
+ print (meanc(y));
+
+The sample mean is approximately 0.5, consistent with the uniform distribution on [0, 1):
+
+::
+
+ 0.46593467
+
Example 2
+++++++++
diff --git a/docs/rndvm.rst b/docs/rndvm.rst
index b9a03ed2..6f272258 100644
--- a/docs/rndvm.rst
+++ b/docs/rndvm.rst
@@ -27,6 +27,27 @@ Format
:rtype x: RxC matrix
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x2 matrix of von Mises
+ // random numbers with mean = pi, shape = 2
+ x = rndvm(3, 2, 3.14, 2);
+ print x;
+
+After the code above, *x* is:
+
+::
+
+ 3.1175039 -2.1479505
+ 2.4731394 1.5778518
+ 0.30247595 2.5394883
+
Source
------
diff --git a/docs/rndweibull.rst b/docs/rndweibull.rst
index 0177f4c8..390b813d 100644
--- a/docs/rndweibull.rst
+++ b/docs/rndweibull.rst
@@ -57,4 +57,25 @@ The properties of the pseudo-random numbers in *x* are:
*r* and *c* will be truncated to integers if necessary.
+Examples
+----------------
+
+::
+
+ // Set seed for repeatable output
+ rndseed 12345;
+
+ // Generate a 3x2 matrix of Weibull
+ // random numbers with shape = 2, scale = 1
+ x = rndWeibull(3, 2, 2, 1);
+ print x;
+
+After the code above, *x* is:
+
+::
+
+ 0.31622572 0.89932217
+ 0.52063284 1.4300231
+ 0.82098160 1.6673537
+
.. seealso:: Functions :func:`rndCreateState`, :func:`rndStateSkip`
diff --git a/docs/rndwishart.rst b/docs/rndwishart.rst
index fd787675..ead1126f 100644
--- a/docs/rndwishart.rst
+++ b/docs/rndwishart.rst
@@ -46,6 +46,9 @@ Examples
::
+ // Set seed for repeatable output
+ rndseed 12345;
+
// covariance matrix
cov = { 1 0.5,
0.5 1 };
@@ -54,11 +57,12 @@ Examples
df = 7;
X = rndWishart(1, cov, df);
+ print X;
::
- X = 7.6019339 4.7744799
- 4.7744799 7.7341260
+ 4.8754749 2.4840462
+ 2.4840462 5.3526816
Remarks
-------
diff --git a/docs/rndwishartinv.rst b/docs/rndwishartinv.rst
index 874d5646..aa5a5e86 100644
--- a/docs/rndwishartinv.rst
+++ b/docs/rndwishartinv.rst
@@ -25,22 +25,24 @@ Examples
::
- rndseed 223;
+ // Set seed for repeatable output
+ rndseed 12345;
+
cov = { 1 .5,
.5 1 };
df = 10;
-
+
// A random matrix from inverse Wishart distribution
y = rndWishartInv(cov, df);
-
+
print y;
-After above code,
+After the code above, *y* is:
::
- 0.081211791 0.036818644
- 0.036818644 0.097064472
+ 0.12810680 0.058073486
+ 0.058073486 0.11794912
.. seealso:: :func:`rndWishart`, :func:`rndMVn`, :func:`rndCreateState`
diff --git a/docs/rref.rst b/docs/rref.rst
index f97b381d..3626034e 100644
--- a/docs/rref.rst
+++ b/docs/rref.rst
@@ -71,3 +71,5 @@ Source
------
rref.src
+
+.. seealso:: Functions :func:`rank`, :func:`null`, :func:`orth`
diff --git a/docs/run.rst b/docs/run.rst
index b2053a8f..42cdb039 100644
--- a/docs/run.rst
+++ b/docs/run.rst
@@ -104,4 +104,4 @@ Programs can also be run by typing the filename on the OS command line
when starting GAUSS.
-.. seealso:: `#include`
+.. seealso:: ``#include``
diff --git a/docs/s.rst b/docs/s.rst
index 2319420d..fcc96d31 100644
--- a/docs/s.rst
+++ b/docs/s.rst
@@ -97,6 +97,10 @@ S
stof
stop
strcombine
+ string-combine
+ string-dereference
+ string-horizontal-concat
+ string-vertical-concat
strctodt
strctoposix
strjoin
@@ -121,6 +125,7 @@ S
submat
subscat
substute
+ subtraction
subvec
sumc
sumr
diff --git a/docs/saveall.rst b/docs/saveall.rst
index fa98a968..37d757f8 100644
--- a/docs/saveall.rst
+++ b/docs/saveall.rst
@@ -49,4 +49,19 @@ the following statement at the top of each:
use pgraph;
+Examples
+--------
+
+::
+
+ // Save all procedures and global variables to a compiled file
+ x = rndn(3, 3);
+
+ proc (1) = double(a);
+ retp(2 * a);
+ endp;
+
+ saveall mystate;
+ // Creates mystate.gcg which can be loaded later with 'run' or 'use'
+
.. seealso:: Functions `compile`, `run`, `use`
diff --git a/docs/scale.rst b/docs/scale.rst
index ecb806c4..bc3f5cb8 100644
--- a/docs/scale.rst
+++ b/docs/scale.rst
@@ -47,6 +47,21 @@ If you want direct control over the axes endpoints and tick marks, use
`xtics` or `ytics`. If `xtics` or `ytics` have been called after `scale`, they
will override `scale`.
+Examples
+--------
+
+.. NOTE:: This function is for use with the deprecated PQG graphics.
+
+::
+
+ library pgraph;
+
+ // Fix axis scaling based on data range
+ x = seqa(0, 0.1, 50);
+ y = sin(x);
+ scale(x, y);
+ xy(x, y);
+
Source
------
diff --git a/docs/scale3d.rst b/docs/scale3d.rst
index c41ffa41..841bc8a3 100644
--- a/docs/scale3d.rst
+++ b/docs/scale3d.rst
@@ -53,6 +53,21 @@ If you want direct control over the axes endpoints and tick marks, use
`xtics`, `ytics`, or `ztics`. If one of these functions have been called, they
will override `scale3d`.
+Examples
+--------
+
+.. NOTE:: This function is for use with the deprecated PQG graphics.
+
+::
+
+ library pgraph;
+
+ // Fix 3-D axis scaling based on data ranges
+ x = seqa(-3, 0.25, 25);
+ y = seqa(-3, 0.25, 25);
+ z = rndn(25, 25);
+ scale3d(x, y, z);
+
Source
------
diff --git a/docs/scalerr.rst b/docs/scalerr.rst
index c93dd708..481b5fb5 100644
--- a/docs/scalerr.rst
+++ b/docs/scalerr.rst
@@ -24,6 +24,8 @@ Examples
::
+ x = { 4 2, 2 3 };
+
trap 1;
cm = invpd(x);
trap 0;
diff --git a/docs/scalmiss.rst b/docs/scalmiss.rst
index fa80d788..58809ad2 100644
--- a/docs/scalmiss.rst
+++ b/docs/scalmiss.rst
@@ -32,7 +32,7 @@ Examples
continue;
endif;
- s = s +s umc(y);
+ s = s + sumc(y);
endo;
diff --git a/docs/searchsourcepath.rst b/docs/searchsourcepath.rst
index 8adc67db..2a290b9d 100644
--- a/docs/searchsourcepath.rst
+++ b/docs/searchsourcepath.rst
@@ -36,3 +36,12 @@ Remarks
The source path is set by the :file:`src_path` configuration variable in your
GAUSS configuration file, :file:`gauss.cfg`.
+
+Examples
+--------
+
+::
+
+ // Search the source path for pv.src, checking src subdir first
+ fpath = searchsourcepath("pv.src", 1);
+ print fpath;
diff --git a/docs/seekr.rst b/docs/seekr.rst
index 8552da01..d812e98a 100644
--- a/docs/seekr.rst
+++ b/docs/seekr.rst
@@ -35,4 +35,20 @@ If *r* = 0, the pointer will be moved to the end of the file, just past the end
.. DANGER:: Do NOT try to seek beyond the end of a file.
+Examples
+--------
+
+::
+
+ // Open a .dat file and seek to a specific row
+ open fh = mydata.dat;
+ y = seekr(fh, 5); // move to row 5
+ print y;
+
+ cur = seekr(fh, -1); // get current row number
+ print cur;
+
+ seekr(fh, 0); // move to end of file
+ fh = close(fh);
+
.. seealso:: Functions `open`, :func:`readr`, :func:`rowsf`
diff --git a/docs/selectdataloop.rst b/docs/selectdataloop.rst
index 284a9d0d..fe3e8f9b 100644
--- a/docs/selectdataloop.rst
+++ b/docs/selectdataloop.rst
@@ -28,8 +28,8 @@ Remarks
Selects only those rows for which *logical_expression* is ``TRUE``. Any
variables referenced must already exist, either as elements of the
-source dataset, as `extern`'s, or as the result of a previous `make`,
-`vector`, or `code` statement.
+source dataset, as ``extern``'s, or as the result of a previous `make`,
+``vector``, or `code` statement.
.. seealso:: `delete`
diff --git a/docs/selif.rst b/docs/selif.rst
index 8888b9cd..e12f988e 100644
--- a/docs/selif.rst
+++ b/docs/selif.rst
@@ -179,4 +179,4 @@ The argument *e* will usually be generated by a logical expression using
*y* will be a scalar missing if no rows are selected.
-.. seealso:: Functions :func:`delif`, :func:`scalmiss`
+.. seealso:: Functions :func:`delif`, :func:`findIdx`, :func:`scalmiss`
diff --git a/docs/seqaseqm.rst b/docs/seqaseqm.rst
index bea6e9c2..b2c26a41 100644
--- a/docs/seqaseqm.rst
+++ b/docs/seqaseqm.rst
@@ -44,7 +44,7 @@ Examples
::
- 2 4 8 16 32 64 128 512 1024
+ 2 4 8 16 32 64 128 256 512 1024
Note that the results have been transposed in this example. Both functions return Nx1 (column) vectors.
@@ -74,4 +74,4 @@ For instance,
will create a column vector containing the numbers ``10, 100,..., `10^10```.
-.. seealso:: Functions :func:`recserar`, :func:`recsercp`
+.. seealso:: :doc:`range-operator` (the ``:`` operator), :func:`recserar`, :func:`recsercp`
diff --git a/docs/setblocksize.rst b/docs/setblocksize.rst
index f30cc266..6cf77515 100644
--- a/docs/setblocksize.rst
+++ b/docs/setblocksize.rst
@@ -47,3 +47,4 @@ functions which can process datasets in chunks, such as :func:`olsmt` and :func:
loaded in code which is threaded with `threadbegin`/`threadstat` or
`threadfor`, you must call :func:`setBlockSize` before the threads are created.
+.. seealso:: Functions :func:`maxvec`, :func:`maxbytes`
diff --git a/docs/setcollabels.rst b/docs/setcollabels.rst
index 3d8fccbf..f3dd0a9f 100644
--- a/docs/setcollabels.rst
+++ b/docs/setcollabels.rst
@@ -14,7 +14,7 @@ Format
:param X: data.
:type X: NxK matrix or dataframe
- :param labels: Names or indices of the categorical variables in *X* to set labels for.
+ :param labels: Category labels (e.g., ``"low" $| "medium" $| "high"``) to assign to the values in the column specified by *columns*.
:type labels: Mx1 string array
:param values: Optional. Values to assign labels to. Default is 0 to rows(labels) - 1.
diff --git a/docs/shapirowilk.rst b/docs/shapirowilk.rst
index 8ddb2155..299b8c32 100644
--- a/docs/shapirowilk.rst
+++ b/docs/shapirowilk.rst
@@ -29,11 +29,13 @@ Format
Examples
----------------
-Example 1: Basic usage
+Example 1: Normal data
+++++++++++++++++++++++
::
+ rndseed 42;
+
// Generate normal data
x = rndn(100, 1);
@@ -42,35 +44,64 @@ Example 1: Basic usage
out = shapiroWilk(x);
print "W statistic:" out.w;
- print "p-value:" out.p;
+ print "p-value: " out.p;
+
+::
+
+ W statistic: 0.97879310
+ p-value: 0.10700545
+
+The p-value (0.107) is above 0.05, so we fail to reject normality — consistent with the data being generated from a normal distribution.
-Example 2: Testing non-normal data
+Example 2: Non-normal data
+++++++++++++++++++++++++++++++++++
::
+ rndseed 42;
+
// Generate exponential data (non-normal)
x = -ln(rndu(100, 1));
+ struct shapiroWilkOut out;
out = shapiroWilk(x);
- if out.p < 0.05;
- print "Reject normality at 5% level";
- endif;
+ print "W statistic:" out.w;
+ print "p-value: " out.p;
+
+::
+
+ W statistic: 0.91599435
+ p-value: 8.6824924e-06
+
+The very small p-value (< 0.001) strongly rejects normality, correctly detecting that exponential data is not normally distributed.
Example 3: With missing values
++++++++++++++++++++++++++++++
::
+ rndseed 42;
+
// Data with missing values
x = rndn(100, 1);
x[1] = miss(0, 0);
x[50] = miss(0, 0);
+ struct shapiroWilkOut out;
out = shapiroWilk(x);
- // out.n will be 98
+ print "W statistic:" out.w;
+ print "p-value: " out.p;
+ print "n: " out.n;
+
+::
+
+ W statistic: 0.97858132
+ p-value: 0.11011458
+ n: 98.000000
+
+Missing values are automatically removed. The effective sample size (``out.n = 98``) reflects the two removed observations.
Remarks
----------------
diff --git a/docs/sinh.rst b/docs/sinh.rst
index a4481e76..4a6c1fe4 100644
--- a/docs/sinh.rst
+++ b/docs/sinh.rst
@@ -41,3 +41,5 @@ Source
------
trig.src
+
+.. seealso:: Functions :func:`cosh`, :func:`tanh`, :func:`arcsin`
diff --git a/docs/sleep.rst b/docs/sleep.rst
index 8918834e..0867f98b 100644
--- a/docs/sleep.rst
+++ b/docs/sleep.rst
@@ -30,3 +30,19 @@ If a program sleeps for the full number of *secs* specified, :func:`sleep` retur
A program may sleep for longer than *secs* seconds, due to system scheduling.
+Examples
+----------------
+
+::
+
+ // Sleep for 2 seconds
+ unslept = sleep(2);
+ print unslept;
+
+If the program sleeps for the full 2 seconds, the output is:
+
+::
+
+ 0.0000000
+
+.. seealso:: Functions :func:`pause`, :func:`waitc`
diff --git a/docs/sortd.rst b/docs/sortd.rst
index 6864af85..cc9caed5 100644
--- a/docs/sortd.rst
+++ b/docs/sortd.rst
@@ -39,6 +39,15 @@ The dataset *infile* will be sorted on the variable *keyvar*, and will be placed
If the inputs are null ("" or 0), the procedure will ask for them.
+Examples
+----------------
+
+::
+
+ // Sort mydata.dat by the "Age" variable
+ // in ascending numeric order, saving to sorted.dat
+ sortd("mydata.dat", "sorted.dat", "Age", 1);
+
Source
------
diff --git a/docs/sortindsortindc.rst b/docs/sortindsortindc.rst
index 02890d15..cc92624f 100644
--- a/docs/sortindsortindc.rst
+++ b/docs/sortindsortindc.rst
@@ -61,3 +61,5 @@ This function can be used to sort several matrices in the same way that
some other reference matrix is sorted. To do this, create the index of
the reference matrix, then use :func:`submat` to rearrange the other matrices in
the same way.
+
+.. seealso:: Functions :func:`sortc`, :func:`sortcc`
diff --git a/docs/sortrsortrc.rst b/docs/sortrsortrc.rst
index 0f00833d..1ca56dbe 100644
--- a/docs/sortrsortrc.rst
+++ b/docs/sortrsortrc.rst
@@ -86,3 +86,5 @@ right in descending order (i.e., ascending right to left), use:
::
rev(sortr(x, r)')'
+
+.. seealso:: Functions :func:`sortc`, :func:`sortmc`
diff --git a/docs/spdiagrvmat.rst b/docs/spdiagrvmat.rst
index 4cf2339e..8a3602df 100644
--- a/docs/spdiagrvmat.rst
+++ b/docs/spdiagrvmat.rst
@@ -119,3 +119,5 @@ with zeros to :math:`MAX(L) \times MAX(P)`. For each plane in *a*, :func:`spDiag
the submatrix ``a[i, 1:size[i, 1], 1:size[i, 2]]`` and inserts that into *x* at
the location indicated by the corresponding row of *inds*. If *size* is a
scalar 0, then each LxP plane of *a* is inserted into *x* as is.
+
+.. seealso:: Functions :func:`diagrv`, :func:`spCreate`
diff --git a/docs/speigv.rst b/docs/speigv.rst
index a0fb5f70..dbbc9dc1 100644
--- a/docs/speigv.rst
+++ b/docs/speigv.rst
@@ -105,3 +105,5 @@ Technical Notes
----------------
:func:`spEigv` implements functions from the ARPACK library.
+
+.. seealso:: Functions :func:`eig`, :func:`eigv`
diff --git a/docs/spscale.rst b/docs/spscale.rst
index 090ac2f6..5194e219 100644
--- a/docs/spscale.rst
+++ b/docs/spscale.rst
@@ -59,3 +59,5 @@ Remarks
-------
:func:`spScale` scales the elements of the matrix by powers of 10 so that they are all within :math:`(-10,10)`.
+
+.. seealso:: Functions :func:`scalerr`, :func:`spCreate`
diff --git a/docs/sqpsolve.rst b/docs/sqpsolve.rst
index 4326bfc6..d8bfe07d 100644
--- a/docs/sqpsolve.rst
+++ b/docs/sqpsolve.rst
@@ -123,12 +123,12 @@ Global Input
::
- _sqp_EqProc = &ineqproc;
+ _sqp_IneqProc = &ineqproc;
- tells :func:`sqpSolve` that nonlinear equality constraints are to be placed on the parameters and
+ tells :func:`sqpSolve` that nonlinear inequality constraints are to be placed on the parameters and
where the procedure computing them is to be found. The procedure must have one input argument,
the Kx1 vector of parameters, and one output argument, the Rx1 vector of computed constraints that
- are to be equal to zero. For example, suppose that you wish to place the following constraint:
+ are to be greater than or equal to zero. For example, suppose that you wish to place the following constraint:
.. math:: p[1] * p[2] \geq p[3]
@@ -137,7 +137,7 @@ Global Input
::
proc ineqproc(p);
- retp(p[1]*[2]-p[3]);
+ retp(p[1]*p[2]-p[3]);
endp;
.. data:: _sqp_Bounds
@@ -253,3 +253,5 @@ Source
------
sqpsolve.src
+
+.. seealso:: Functions :func:`sqpSolveMT`, :func:`QNewton`
diff --git a/docs/sqpsolvemt.rst b/docs/sqpsolvemt.rst
index a0e63c73..73379435 100644
--- a/docs/sqpsolvemt.rst
+++ b/docs/sqpsolvemt.rst
@@ -87,6 +87,33 @@ Format
:rtype out: struct
+Examples
+--------
+
+::
+
+ // Declare and initialize control structure
+ struct sqpSolveMTControl c0;
+ c0 = sqpSolveMTControlCreate();
+
+ // Set bounds and print options
+ c0.bounds = 0 ~ 100;
+ c0.output = 1;
+
+ // Set up parameters using PV structure
+ struct PV par1;
+ par1 = pvCreate();
+ par1 = pvPack(par1, 1|1|1, "parameters");
+
+ // Solve (assuming 'myObj' is a user-defined objective procedure)
+ struct sqpSolveMTout out;
+ out = sqpSolveMT(&myObj, par1, c0);
+
+ // Retrieve estimated parameters
+ print pvUnpack(out.par, "parameters");
+
+See the Remarks section below for a complete working example.
+
Remarks
-------
@@ -203,4 +230,4 @@ Source
sqpsolvemt.src
-.. seealso:: Functions :func:`sqpSolveMTControlCreate`, :func:`sqpSolveMTlagrangeCreate`
+.. seealso:: Functions :func:`sqpSolveMTControlCreate`, :func:`sqpSolveMTlagrangeCreate`, :func:`minimize`
diff --git a/docs/sqpsolveset.rst b/docs/sqpsolveset.rst
index 027747ee..c0b69ac1 100644
--- a/docs/sqpsolveset.rst
+++ b/docs/sqpsolveset.rst
@@ -13,7 +13,17 @@ Format
+Examples
+--------
+
+::
+
+ // Reset sqpSolve global variables to defaults
+ sqpSolveSet;
+
Source
------
sqpsolve.src
+
+.. seealso:: Functions :func:`sqpSolve`, :func:`sqpSolveMT`
diff --git a/docs/sqrt.rst b/docs/sqrt.rst
index 95c625b5..e5ffd7d6 100644
--- a/docs/sqrt.rst
+++ b/docs/sqrt.rst
@@ -44,3 +44,5 @@ turn it off, :func:`sqrt` will generate an error for negative inputs.
If *x* is already complex, the complex number state does not matter; :func:`sqrt`
will compute a complex result.
+
+.. seealso:: Functions :func:`abs`, :func:`exp`
diff --git a/docs/stdc.rst b/docs/stdc.rst
index 0511eaf7..5a50f550 100644
--- a/docs/stdc.rst
+++ b/docs/stdc.rst
@@ -56,6 +56,6 @@ To convert to the population's standard deviation, multiply by
.. math::
- \sigma = s*\frac{n−1}{n}
+ \sigma = s \cdot \sqrt{\frac{n-1}{n}}
.. seealso:: Functions :func:`meanc`
diff --git a/docs/stof.rst b/docs/stof.rst
index 13ea4652..4703da0b 100644
--- a/docs/stof.rst
+++ b/docs/stof.rst
@@ -65,6 +65,8 @@ Remarks
- To convert string arrays to floating point numeric values, or to
convert strings representing complex data, use :func:`strtof`.
- If *x* is a null string (""), :func:`stof` will return a 0.
+
+.. warning:: ``stof("")`` returns 0, not a missing value. If your data may contain empty strings that should be treated as missing, check for empty strings before calling :func:`stof`.
- This uses the same input conversion routine as `loadm` and `let`. It will
convert character elements and missing values. :func:`stof` also converts
complex numbers in the same manner as `let`.
diff --git a/docs/stop.rst b/docs/stop.rst
index 63a68408..a016ef93 100644
--- a/docs/stop.rst
+++ b/docs/stop.rst
@@ -26,5 +26,17 @@ or the auxiliary output.
It is not necessary to put a `stop` or an `end` statement at the end of a
program. If neither is found, an implicit `stop` is executed.
+Examples
+--------
+
+::
+
+ // Stop program execution without closing files
+ x = rndn(3, 3);
+ print x;
+ stop;
+ // Code below this point will not execute
+ print "This will not print";
+
.. seealso:: Functions `end`, `new`, `system`
diff --git a/docs/strindx.rst b/docs/strindx.rst
index 85087611..a9bcc385 100644
--- a/docs/strindx.rst
+++ b/docs/strindx.rst
@@ -113,7 +113,7 @@ String array example
// Find the first instance of the
// letter 'a' starting from
// the front of the string
- strrindx(state, "a");
+ strindx(state, "a");
Since the search starts from the first character, the above code will print out:
diff --git a/docs/strput.rst b/docs/strput.rst
index 2c4d2833..8b490857 100644
--- a/docs/strput.rst
+++ b/docs/strput.rst
@@ -49,3 +49,5 @@ Source
------
strput.src
+
+.. seealso:: Functions :func:`strindx`, :func:`strsect`
diff --git a/docs/strtof.rst b/docs/strtof.rst
index 5568879c..bb02d10f 100644
--- a/docs/strtof.rst
+++ b/docs/strtof.rst
@@ -92,6 +92,8 @@ example, the string:
"1.2 1.9"
+.. warning:: If you are parsing delimited text data, split each element into a separate string before calling :func:`strtof`. Strings containing spaces or commas between numbers will be interpreted as complex numbers, not as separate values.
+
will be converted into the number:
::
diff --git a/docs/strtofcplx.rst b/docs/strtofcplx.rst
index 5ebf0a03..0360781c 100644
--- a/docs/strtofcplx.rst
+++ b/docs/strtofcplx.rst
@@ -25,4 +25,21 @@ Remarks
for real matrices. :func:`strtofcplx` requires the presence of the real part.
The imaginary part can be absent.
+Examples
+----------------
+
+::
+
+ // Spaces required around + and -
+ string sa = { "3 + 2i" "1 - 4i" };
+
+ x = strtofcplx(sa);
+ print x;
+
+The code above produces the following output:
+
+::
+
+ 3.0000000 + 2.0000000i 1.0000000 - 4.0000000i
+
.. seealso:: Functions :func:`strtof`, :func:`ftostrC`
diff --git a/docs/strtriml.rst b/docs/strtriml.rst
index 4ad2cbfe..1140c7be 100644
--- a/docs/strtriml.rst
+++ b/docs/strtriml.rst
@@ -17,6 +17,25 @@ Format
:rtype y: NxM string array
+Examples
+----------------
+
+::
+
+ // Create a string array with leading whitespace
+ sa = " hello" $| " world";
+
+ // Strip whitespace from the left
+ y = strtriml(sa);
+ print y;
+
+The code above produces the following output:
+
+::
+
+ hello
+ world
+
Source
------
diff --git a/docs/strtrimr.rst b/docs/strtrimr.rst
index 8ed7c713..8ddcee9c 100644
--- a/docs/strtrimr.rst
+++ b/docs/strtrimr.rst
@@ -18,6 +18,25 @@ Format
:rtype y: NxM string array
+Examples
+----------------
+
+::
+
+ // Create a string array with trailing whitespace
+ sa = "hello " $| "world ";
+
+ // Strip whitespace from the right
+ y = strtrimr(sa);
+ print y;
+
+The code above produces the following output:
+
+::
+
+ hello
+ world
+
Source
------
diff --git a/docs/strtruncl.rst b/docs/strtruncl.rst
index 9356476a..3acc72de 100644
--- a/docs/strtruncl.rst
+++ b/docs/strtruncl.rst
@@ -21,6 +21,24 @@ Format
:rtype y: string array
+Examples
+----------------
+
+::
+
+ sa = "Hello World" $| "GAUSS";
+
+ // Remove 3 characters from the left
+ y = strtruncl(sa, 3);
+ print y;
+
+The code above produces the following output:
+
+::
+
+ lo World
+ SS
+
Source
------
diff --git a/docs/strtruncpad.rst b/docs/strtruncpad.rst
index 97dc1013..7688399d 100644
--- a/docs/strtruncpad.rst
+++ b/docs/strtruncpad.rst
@@ -24,5 +24,27 @@ Format
:rtype y: NxK string array
+Examples
+----------------
+
+::
+
+ sa = "Hello" $| "Hi";
+
+ // Truncate or pad to exactly 8 characters
+ y = strtruncpad(sa, 8);
+ print y;
+ print (strlen(y));
+
+The code above produces the following output:
+
+::
+
+ Hello
+ Hi
+
+ 8.0000000
+ 8.0000000
+
.. seealso:: Functions :func:`strtriml`, :func:`strtrimr`, :func:`strtrunc`, :func:`strtruncl`, :func:`strtruncr`
diff --git a/docs/strtruncr.rst b/docs/strtruncr.rst
index a6cd6d32..9fc26fb0 100644
--- a/docs/strtruncr.rst
+++ b/docs/strtruncr.rst
@@ -21,6 +21,24 @@ Format
:rtype y: string array
+Examples
+----------------
+
+::
+
+ sa = "Hello World" $| "GAUSS";
+
+ // Remove 6 characters from the right
+ y = strtruncr(sa, 6);
+ print y;
+
+The code above produces the following output:
+
+::
+
+ Hello
+
+
Source
------
diff --git a/docs/subvec.rst b/docs/subvec.rst
index 424674bc..70c48faf 100644
--- a/docs/subvec.rst
+++ b/docs/subvec.rst
@@ -57,3 +57,5 @@ Remarks
Each element of *y* is from the corresponding row of *x* and the column set
by the corresponding row of *ci*. In other words, :math:`y[i] = x[i, ci[i]]`.
+
+.. seealso:: Functions :func:`trimr`, :func:`selif`
diff --git a/docs/sysstate.rst b/docs/sysstate.rst
index e46efe1f..25ea82b9 100644
--- a/docs/sysstate.rst
+++ b/docs/sysstate.rst
@@ -149,4 +149,25 @@ The available cases are as follows:
| | tolerance. |
+-----------------------------------+-----------------------------------+
+Examples
+--------
+
+::
+
+ // Get GAUSS version information
+ vi = sysstate(1, 0);
+ print "Major version:" vi[1];
+ print "Minor version:" vi[2];
+
+::
+
+ // Get LU decomposition singularity tolerance
+ tol = sysstate(13, 0);
+ print "LU tolerance:" tol;
+
+::
+
+ // Set Cholesky singularity tolerance
+ sysstate(14, 1e-14);
+
.. seealso:: Functions `outwidth`, :func:`croutp`, :func:`inv`, :func:`chol`, :func:`solpd`, `screen`, `output`, `format`, `print`, :func:`hasimag`, `dlibrary`, `dllcall`, :func:`rndcon`, :func:`rndn`, :func:`rndu`, :func:`croutp`, :func:`inv`, :func:`chol`, :func:`solpd`, :func:`hasimag`
diff --git a/docs/system.rst b/docs/system.rst
index 7c310a1e..f10d9161 100644
--- a/docs/system.rst
+++ b/docs/system.rst
@@ -29,5 +29,18 @@ The `system` command always returns an exit code to the operating system
or invoking program. If you don't supply one, it returns 0. This is
usually interpreted as indicating success.
+Examples
+--------
+
+::
+
+ // Quit GAUSS with default exit code 0
+ system;
+
+::
+
+ // Quit GAUSS with a custom exit code
+ system 1; // returns exit code 1 to the OS
+
.. seealso:: Functions :func:`exec`
diff --git a/docs/t.rst b/docs/t.rst
index c2ae5638..4a904dd3 100644
--- a/docs/t.rst
+++ b/docs/t.rst
@@ -34,6 +34,7 @@ T
topolar
trace
tracem
+ transpose
trapchk
trap
trigamma
diff --git a/docs/tab.rst b/docs/tab.rst
index 481546d9..a4ebdc84 100644
--- a/docs/tab.rst
+++ b/docs/tab.rst
@@ -43,3 +43,14 @@ expressions, write it like this instead:
print tab(20) (c + d * e);
+Examples
+--------
+
+::
+
+ // Use tab to align output in columns
+ print "Name" tab(20) "Score" tab(35) "Grade";
+ print "Alice" tab(20) 95 tab(35) "A";
+ print "Bob" tab(20) 82 tab(35) "B";
+
+.. seealso:: Functions :func:`print`, :func:`sprintf`
diff --git a/docs/tabulate.rst b/docs/tabulate.rst
index 5a49b327..3059c02c 100644
--- a/docs/tabulate.rst
+++ b/docs/tabulate.rst
@@ -52,7 +52,7 @@ Examples
----------------
Basic usage with a dataframe and a formula string
-++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++
::
diff --git a/docs/tanh.rst b/docs/tanh.rst
index b23b14b6..2b3d67f1 100644
--- a/docs/tanh.rst
+++ b/docs/tanh.rst
@@ -45,3 +45,5 @@ Source
------
trig.src
+
+.. seealso:: Functions :func:`sinh`, :func:`cosh`, :func:`atan`
diff --git a/docs/tempname.rst b/docs/tempname.rst
index 272537ac..e0ec7537 100644
--- a/docs/tempname.rst
+++ b/docs/tempname.rst
@@ -38,3 +38,19 @@ returns a null string.
.. WARNING:: GAUSS does not remove temporary files created by :func:`tempname`. It
is left to the user to remove them when they are no longer needed.
+Examples
+----------------
+
+::
+
+ // Create a temporary file name in /tmp
+ tname = tempname("/tmp", "gss", ".dat");
+ print tname;
+
+Example output:
+
+::
+
+ /tmp/gssABCD12345.dat
+
+.. seealso:: Functions :func:`fopen`, :func:`close`
diff --git a/docs/timediffdt.rst b/docs/timediffdt.rst
index 23bcd780..94453f40 100644
--- a/docs/timediffdt.rst
+++ b/docs/timediffdt.rst
@@ -30,7 +30,7 @@ Format
:return diff: the difference between *dt_1* and *dt_2* in terms of the specified units.
- :rtype diff: Scalar
+ :rtype diff: Scalar or NxK matrix
Examples
----------------
@@ -60,7 +60,7 @@ The above code will set *diff* equal to:
// April 15, 1947 07:53:00
dt_2 = 194704150753;
- // Increment by 18 months
+ // Compute the difference in terms of minutes
diff = timeDiffDT(dt_1, dt_2, "minutes");
The above code will set *diff* equal to:
diff --git a/docs/timedt.rst b/docs/timedt.rst
index bfd867b2..925df25f 100644
--- a/docs/timedt.rst
+++ b/docs/timedt.rst
@@ -31,6 +31,22 @@ represents:
07:15:11 or 7:15:11 AM on March 6, 2010.
+Examples
+--------
+
+::
+
+ // Get current date and time in DT scalar format
+ format /rd 16,0;
+ dt = timedt();
+ print dt;
+
+Example output (run on March 6, 2010, at 7:15:11 AM):
+
+::
+
+ 20100306071511
+
Source
------
diff --git a/docs/timeseries/arimacoeftable.rst b/docs/timeseries/arimacoeftable.rst
new file mode 100644
index 00000000..e44ff807
--- /dev/null
+++ b/docs/timeseries/arimacoeftable.rst
@@ -0,0 +1,64 @@
+arimaCoefTable
+==============
+
+Purpose
+-------
+Return the coefficient table from a fitted ARIMA model as a dataframe.
+
+Format
+------
+
+.. function:: tab = arimaCoefTable(result)
+
+ :param result: an instance of an :class:`arimaResult` structure returned by :func:`arimaFit`.
+ :type result: struct
+
+ :return tab: Kx6 dataframe with columns: Coef, SE, t-stat, p-value, CI_lo, CI_hi. Row names are the coefficient labels.
+ :rtype tab: dataframe
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+
+ result = arimaFit(y, p=1, d=1, q=1, period=12, quiet=1);
+
+ // Get coefficient table as dataframe
+ tab = arimaCoefTable(result);
+ print tab;
+
+::
+
+ Coef SE t-stat p-value CI_lo CI_hi
+ AR(1) 0.8731 0.0543 16.076 0.000 0.767 0.979
+ MA(1) -0.4018 0.1237 -3.248 0.001 -0.644 -0.159
+ SMA(1) -0.5569 0.0730 -7.630 0.000 -0.700 -0.414
+
+Remarks
+-------
+
+The returned dataframe can be used for programmatic access to coefficients:
+
+::
+
+ // Extract p-values column
+ pvals = tab[., "p-value"];
+
+ // Find significant coefficients (p < 0.05)
+ sig = selif(tab, tab[., "p-value"] .< 0.05);
+
+Library
+-------
+timeseries
+
+Source
+------
+arima.src
+
+.. seealso:: Functions :func:`arimaFit`, :func:`arimaResults`
diff --git a/docs/timeseries/arimacontrolcreate.rst b/docs/timeseries/arimacontrolcreate.rst
new file mode 100644
index 00000000..b0a0a555
--- /dev/null
+++ b/docs/timeseries/arimacontrolcreate.rst
@@ -0,0 +1,54 @@
+arimaControlCreate
+==================
+
+Purpose
+-------
+Create an :class:`arimaControl` structure with default values.
+
+Format
+------
+
+.. function:: ctl = arimaControlCreate()
+
+ :return ctl: An instance of an :class:`arimaControl` structure with the following default values:
+
+ .. include:: include/arimacontrol.rst
+
+ :rtype ctl: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ // Create control structure with defaults
+ ctl = arimaControlCreate();
+
+ // Customize: BIC selection, ML estimation
+ ctl.ic = "bic";
+ ctl.method = "ml";
+
+ // Use with arimaFit
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+ result = arimaFit(y, ctl, period=12);
+
+Remarks
+-------
+
+All members of the :class:`arimaControl` structure apply only to auto-selection.
+When fixed *p*, *d*, *q* are passed to :func:`arimaFit`, the search-related members
+(*max_p*, *max_q*, *max_d*, *ic*, *stepwise*, etc.) are ignored.
+
+Library
+-------
+timeseries
+
+Source
+------
+arima.src
+
+.. seealso:: Functions :func:`arimaFit`
diff --git a/docs/timeseries/arimafit.rst b/docs/timeseries/arimafit.rst
new file mode 100644
index 00000000..f16f35d0
--- /dev/null
+++ b/docs/timeseries/arimafit.rst
@@ -0,0 +1,448 @@
+arimaFit
+========
+
+Purpose
+-------
+Fit ARIMA, SARIMA, or ARIMAX models. Automatically selects orders when ``p``, ``d``, ``q`` are not specified.
+
+Format
+------
+
+.. function:: result = arimaFit(y)
+ result = arimaFit(y, p=p, d=d, q=q)
+ result = arimaFit(y, p=p, d=d, q=q, sp=P, sd=D, sq=Q, period=s)
+ result = arimaFit(y, xreg=X)
+ result = arimaFit(y, ctl)
+
+ :param y: time series data.
+ :type y: Nx1 vector
+
+ :param ctl: Optional input, an instance of an :class:`arimaControl` structure. An instance is initialized by calling :func:`arimaControlCreate` and the following members can be set:
+
+ .. include:: include/arimacontrol.rst
+
+ :type ctl: struct
+
+ :param p: Optional keyword, autoregressive order. If omitted, automatically selected by minimizing the information criterion specified in *ctl.ic*. Set to -1 to auto-select.
+ :type p: scalar
+
+ :param d: Optional keyword, differencing order. If omitted, automatically selected. Set to -1 to auto-select.
+ :type d: scalar
+
+ :param q: Optional keyword, moving average order. If omitted, automatically selected. Set to -1 to auto-select.
+ :type q: scalar
+
+ :param sp: Optional keyword, seasonal autoregressive order. If omitted with *period* set, auto-selected.
+ :type sp: scalar
+
+ :param sd: Optional keyword, seasonal differencing order. If omitted with *period* set, auto-selected.
+ :type sd: scalar
+
+ :param sq: Optional keyword, seasonal moving average order. If omitted with *period* set, auto-selected.
+ :type sq: scalar
+
+ :param period: Optional keyword, seasonal period (e.g., 12 for monthly, 4 for quarterly). Required for seasonal models.
+ :type period: scalar
+
+ :param xreg: Optional keyword, exogenous regressors. Fits a regression with ARIMA errors: :math:`y_t = X_t'\beta + \eta_t` where :math:`\eta_t` follows an ARIMA process.
+ :type xreg: NxM matrix
+
+ :param xreg_names: Optional keyword, column names for *xreg*. If omitted, defaults to ``"X1"``, ``"X2"``, etc.
+ :type xreg_names: Mx1 string array
+
+ :param lambda: Optional keyword, Box-Cox variance stabilization.
+
+ ============= =========================================================
+ ``"auto"`` Select lambda via profile likelihood (recommended). Fits
+ ARIMA(1,1,1) pilot at each candidate λ ∈ {-1, -0.5, 0,
+ 0.5, 1, 1.5, 2} and picks the one that maximizes the
+ Jacobian-corrected log-likelihood.
+ ``0`` Log transform (λ = 0).
+ ``0.5`` Square root transform.
+ (omitted) No transform (default, backward compatible).
+ ============= =========================================================
+
+ When active, the data is transformed before fitting and forecasts are
+ automatically back-transformed to the original scale (median, no bias
+ correction). The selected lambda is stored in ``result.lambda``.
+
+ Requires strictly positive data. Silently skipped if data contains
+ zeros or negative values.
+
+ :type lambda: string or scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Overrides *ctl.quiet*.
+ :type quiet: scalar
+
+ :return result: An instance of an :class:`arimaResult` structure containing:
+
+ .. include:: include/arimaresult.rst
+
+ :rtype result: struct
+
+Examples
+--------
+
+Auto ARIMA on Airline Passengers
+++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+
+ // Automatic ARIMA — selects order via AICc
+ result = arimaFit(y);
+
+Output:
+
+::
+
+ ================================================================================
+ Model: ARIMA(1,1,0) Observations: 144
+ Method: CSS-ML Log-Likelihood: -504.920
+ AIC: 1015.84 AICc: 1016.02
+ BIC: 1024.78 Sigma^2: 132.428
+ ================================================================================
+ Coef Std.Err. t-stat p-value [0.025 0.975]
+ --------------------------------------------------------------------------------
+ AR(1) 0.3185 0.0832 3.828 0.000 0.156 0.481
+ Drift 2.6672 0.7781 3.428 0.001 1.142 4.193
+ ================================================================================
+ Ljung-Box(10): Q=65.21 p=0.000
+ Jarque-Bera: JB=1.83 p=0.401
+ ================================================================================
+
+Seasonal ARIMA on Monthly Data
+++++++++++++++++++++++++++++++
+
+The classic Box-Jenkins airline model — SARIMA(0,1,1)(0,1,1)[12]:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+
+ // Auto SARIMA with period=12
+ result = arimaFit(y, period=12);
+
+Selects SARIMA(0,1,1)(0,1,1)[12] — the same model identified by Box & Jenkins (1970)
+on this dataset. The seasonal MA(1) coefficient captures the within-year pattern, while
+regular differencing and seasonal differencing handle trend and annual cycles.
+
+Fixed Order with Diagnostics
++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+
+ // Force SARIMA(1,1,1)(0,1,1)[12]
+ result = arimaFit(y, p=1, d=1, q=1, sp=0, sd=1, sq=1, period=12);
+
+Check the Ljung-Box statistic for residual autocorrelation: p > 0.05 indicates no
+remaining serial correlation. Check Jarque-Bera for normality: p > 0.05 indicates
+Gaussian residuals.
+
+ARIMAX: GDP with Leading Indicators
+++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth");
+ X = loadd(fname, "cpi_inflation + fed_funds");
+
+ // Regression with ARIMA errors
+ result = arimaFit(y, xreg=X, xreg_names="CPI"$|"FFR");
+
+The exogenous coefficients are reported alongside the ARIMA parameters.
+Use :func:`arimaForecast` with ``xreg=X_future`` to produce forecasts conditional
+on projected regressor values.
+
+Partial Auto-Selection
+++++++++++++++++++++++
+
+Fix :math:`d = 1` but auto-select :math:`p` and :math:`q`:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+
+ // Fix d=1, auto-select p and q
+ // period=12, fix d=1, auto-select p and q (use -1)
+ result = arimaFit(y, period=12, p=-1, d=1, q=-1);
+
+Using BIC for Model Selection
++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+
+ ctl = arimaControlCreate();
+ ctl.ic = "bic";
+
+ result = arimaFit(y, ctl, period=12);
+
+BIC penalizes model complexity more than AICc, typically selecting more parsimonious models.
+
+Model
+-----
+
+**ARIMA(p,d,q):**
+After differencing :math:`d` times, the series :math:`w_t = (1-L)^d y_t` follows a
+stationary ARMA(p,q) process:
+
+.. math::
+
+ w_t = \phi_1 w_{t-1} + \cdots + \phi_p w_{t-p} + \varepsilon_t + \theta_1 \varepsilon_{t-1} + \cdots + \theta_q \varepsilon_{t-q}
+
+where :math:`\varepsilon_t \sim N(0, \sigma^2)`. In backshift operator notation:
+
+.. math::
+
+ \phi(L)(1 - L)^d \, y_t = \theta(L) \, \varepsilon_t
+
+**SARIMA(p,d,q)(P,D,Q)[s]:**
+Adds seasonal differencing and seasonal ARMA terms:
+
+.. math::
+
+ \Phi(L^s) \, \phi(L) \, (1 - L)^d (1 - L^s)^D \, y_t = \Theta(L^s) \, \theta(L) \, \varepsilon_t
+
+where :math:`\Phi(L^s) = 1 - \Phi_1 L^s - \cdots - \Phi_P L^{Ps}` and
+:math:`\Theta(L^s) = 1 + \Theta_1 L^s + \cdots + \Theta_Q L^{Qs}`.
+
+**ARIMAX (regression with ARIMA errors):**
+When exogenous regressors :math:`X_t` are provided:
+
+.. math::
+
+ y_t = X_t' \beta + \eta_t, \qquad \phi(L)(1-L)^d \, \eta_t = \theta(L) \, \varepsilon_t
+
+This is a *regression with ARIMA errors* model (Hyndman & Athanasopoulos 2021, Ch. 10),
+not a transfer function model. The distinction matters: the AR/MA structure applies to
+the regression residuals, not directly to :math:`y_t`.
+
+Algorithm
+---------
+
+**Estimation (CSS-ML):**
+
+1. **Conditional sum of squares (CSS):** Condition on the first :math:`\max(p, s \cdot P)` observations and minimize the sum of squared one-step-ahead prediction errors. This provides fast initial parameter estimates. Complexity: :math:`O(N)`.
+
+2. **Maximum likelihood refinement (ML):** Starting from the CSS estimates, maximize the exact Gaussian log-likelihood via the state-space representation and Kalman filter. The likelihood is:
+
+ .. math::
+
+ \log \mathcal{L} = -\frac{N}{2} \log(2\pi) - \frac{1}{2} \sum_{t=1}^{N} \left( \log f_t + \frac{v_t^2}{f_t} \right)
+
+ where :math:`v_t` and :math:`f_t` are the innovation and its variance from the Kalman filter. Optimization uses L-BFGS-B with parameter transforms to enforce stationarity and invertibility.
+
+**Auto-selection (stepwise):**
+
+When ``p``, ``d``, ``q`` are omitted, the Hyndman-Khandakar (2008) stepwise algorithm is used:
+
+1. Determine :math:`d` via KPSS unit root tests (Kwiatkowski et al. 1992).
+2. Determine :math:`D` via OCSB seasonal unit root tests (Osborn, Chui, Smith & Birchenhall 1988), if seasonal.
+3. Fit an initial model, then search neighboring orders in a stepwise fashion, minimizing AICc (default) or the criterion in *ctl.ic*.
+4. Total models evaluated is typically 15-30 (vs. hundreds for exhaustive search).
+
+Set ``ctl.stepwise = 0`` for exhaustive search over all :math:`(p, q, P, Q)` combinations up to *ctl.max_order*.
+
+Troubleshooting
+---------------
+
+**Optimizer did not converge:**
+Increase ``ctl.max_iter`` (default 1000) or switch to ``ctl.method = "css"`` for a
+quick approximate estimate. Non-convergence often indicates the model is
+over-parameterized for the data — try a simpler order.
+
+**Near-unit-root MA coefficient:**
+If :math:`|\theta_q|` or :math:`|\Theta_Q|` is close to 1.0, the model is near
+the boundary of invertibility. The MA polynomial is nearly non-invertible, which
+causes numerical issues. Solutions:
+
+- Increase the differencing order by 1 (replace MA near-unit-root with a difference).
+- Use ``ctl.method = "ml"`` instead of ``"css-ml"`` — CSS initialization can sometimes
+ find a near-boundary starting point that ML refinement cannot escape.
+
+**CSS and ML give different answers:**
+CSS conditions on initial values and optimizes a different objective than exact ML.
+Small discrepancies (< 0.02 in coefficients) are normal. Large discrepancies suggest
+the likelihood surface has multiple modes — try ``ctl.method = "ml"`` with different
+starting values, or simplify the model.
+
+**Auto-selection picks a simple model when you expected a complex one:**
+AICc penalizes complexity. If you believe a more complex model is correct, fix the
+order explicitly with ``p=p, d=d, q=q`` and compare the diagnostic statistics. Remember
+that more parsimonious models often forecast better even when the true DGP is complex
+(Hyndman & Athanasopoulos 2021, Section 8.6).
+
+**Residual autocorrelation (Ljung-Box p < 0.05):**
+The model has not captured all the serial dependence. Try:
+
+- Increasing the AR order (higher p).
+- Adding seasonal terms if the data has a seasonal pattern.
+- Adding exogenous regressors if there is an omitted variable.
+
+Box-Cox Variance Stabilization
+++++++++++++++++++++++++++++++
+
+For series with variance that grows with the level (e.g., airline passengers),
+Box-Cox transformation stabilizes the variance before fitting:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline_passengers.csv");
+ y = loadd(fname, "passengers");
+
+ // Auto-select lambda via profile likelihood
+ result = arimaFit(y, period=12, lambda="auto");
+
+ // The selected lambda
+ print "Lambda:" result.lambda;
+
+ // Forecasts are automatically back-transformed
+ fc = arimaForecast(result, 24);
+
+You can also specify a fixed lambda:
+
+::
+
+ // Log transform (lambda = 0)
+ result_log = arimaFit(y, period=12, lambda=0);
+
+ // Square root transform (lambda = 0.5)
+ result_sqrt = arimaFit(y, period=12, lambda=0.5);
+
+.. note::
+
+ Profile likelihood selects the lambda that maximizes the model's
+ Jacobian-corrected log-likelihood. Unlike Guerrero's heuristic, this
+ uses the actual ARIMA fit to choose the transform — if no transform
+ helps, it selects λ = 1 (identity).
+
+ Requires strictly positive data. Silently skipped for series with
+ zeros or negative values.
+
+Remarks
+-------
+
+**Auto-selection algorithm:**
+When *p*, *d*, *q* are omitted, :func:`arimaFit` performs stepwise model selection
+(Hyndman & Khandakar 2008) minimizing the information criterion specified
+in *ctl.ic*. The algorithm considers up to *ctl.max_order* total ARMA terms
+(p+q+P+Q). Set *ctl.stepwise* = 0 for exhaustive search.
+
+**Deterministic terms (include logic):**
+The default ``ctl.include = "auto"`` automatically determines whether to
+include a constant:
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - d
+ - D
+ - Behavior
+ - Label
+ * - 0
+ - 0
+ - Include mean of stationary series
+ - Mean
+ * - 1
+ - 0
+ - Include drift (linear trend)
+ - Drift
+ * - 0
+ - >= 1
+ - No constant
+ -
+ * - >= 2
+ - any
+ - No constant
+ -
+
+This matches the behavior of R's ``auto.arima`` (Hyndman & Khandakar 2008).
+
+**Estimation method:**
+The default ``"css-ml"`` method uses conditional sum of squares to obtain
+starting values, then refines via maximum likelihood. Use ``"ml"`` for
+direct ML optimization (may be slower but avoids CSS approximation issues
+with some models).
+
+**Coefficient ordering:**
+Coefficients in *result.coefs* are ordered: AR(1), ..., AR(p), MA(1), ...,
+MA(q), SAR(1), ..., SAR(P), SMA(1), ..., SMA(Q), Mean/Drift (if present),
+X1, ..., Xm (if xreg). The *result.coef_names* string array provides labels
+in the same order.
+
+Verification
+------------
+
+Verified against **three** independent reference implementations:
+
+**R forecast package (Hyndman et al.):**
+Cross-validated on 15+ classic time series datasets (Nile, AirPassengers, USAccDeaths,
+CO2, LakeHuron, WWWusage, sunspot.year, nottem, UKgas, JohnsonJohnson, austres, lynx)
+covering ARIMA, SARIMA, and ARIMAX models. Tests verify coefficients, standard errors,
+log-likelihood, information criteria, and forecasts.
+
+**Python statsmodels SARIMAX:**
+Same datasets and model specifications re-verified against Python's state-space SARIMAX
+implementation. Coefficients match to :math:`10^{-4}` on most models.
+
+**Julia:**
+Additional cross-validation on a subset of datasets against Julia time series packages.
+
+**Unit root tests:**
+KPSS test verified against R ``urca::ur.kpss()`` on 5 datasets. OCSB seasonal unit
+root test (``nsdiffs``) verified against R ``forecast::nsdiffs()`` on 4 seasonal series.
+
+Total: **65 passing tests** across R, Python, and Julia references.
+See ``gausslib-ts/tests/r_regression.rs``.
+
+References
+----------
+
+- Box, G.E.P. and G.M. Jenkins (1970). *Time Series Analysis: Forecasting and Control*. Holden-Day.
+- Brockwell, P.J. and R.A. Davis (2002). *Introduction to Time Series and Forecasting*. 2nd ed., Springer.
+- Hyndman, R.J. and Y. Khandakar (2008). "Automatic time series forecasting: The forecast package for R." *Journal of Statistical Software*, 27(3).
+- Hyndman, R.J. and G. Athanasopoulos (2021). *Forecasting: Principles and Practice*. 3rd ed., OTexts.
+- Kwiatkowski, D., P.C.B. Phillips, P. Schmidt, and Y. Shin (1992). "Testing the null hypothesis of stationarity against the alternative of a unit root." *Journal of Econometrics*, 54(1-3), 159-178.
+
+Library
+-------
+timeseries
+
+Source
+------
+arima.src
+
+.. seealso:: Functions :func:`arimaForecast`, :func:`arimaControlCreate`, :func:`arimaResults`, :func:`arimaCoefTable`, :func:`stlDecompose`
diff --git a/docs/timeseries/arimaforecast.rst b/docs/timeseries/arimaforecast.rst
new file mode 100644
index 00000000..3ba97158
--- /dev/null
+++ b/docs/timeseries/arimaforecast.rst
@@ -0,0 +1,241 @@
+arimaForecast
+=============
+
+Purpose
+-------
+Generate h-step-ahead forecasts with prediction intervals from a fitted ARIMA model.
+
+Format
+------
+
+.. function:: fc = arimaForecast(result, h)
+ fc = arimaForecast(result, h, xreg=X_future)
+ fc = arimaForecast(result, h, level=0.99)
+
+ :param result: an instance of an :class:`arimaResult` structure returned by :func:`arimaFit`.
+ :type result: struct
+
+ :param h: forecast horizon (number of steps ahead).
+ :type h: scalar
+
+ :param xreg: Optional keyword, future values of exogenous regressors. Required if the model was fit with *xreg*.
+ :type xreg: hxM matrix
+
+ :param level: Optional keyword, confidence level for prediction intervals. Default = 0.95.
+ :type level: scalar
+
+ :return fc: An instance of a :class:`forecastResult` structure containing:
+
+ .. include:: include/forecastresult.rst
+
+ :rtype fc: struct
+
+Examples
+--------
+
+24-Month Seasonal Forecast
+++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+
+ // Fit seasonal ARIMA
+ result = arimaFit(y, period=12, quiet=1);
+
+ // Forecast 24 months
+ fc = arimaForecast(result, 24);
+
+ // Point forecasts and 95% prediction intervals
+ print " h Forecast Lower Upper";
+ for i (1, 24, 1);
+ print i;; print fc.forecasts[i];; print fc.lower[i];; print fc.upper[i];
+ endfor;
+
+Custom Confidence Level
++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+ result = arimaFit(y, p=1, d=1, q=1, sp=0, sd=1, sq=1, period=12);
+
+ // 99% prediction intervals (wider than 95%)
+ fc = arimaForecast(result, 12, level=0.99);
+
+ARIMAX with Future Regressors
++++++++++++++++++++++++++++++
+
+When the model includes exogenous regressors, you must provide their future values:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth");
+ X = loadd(fname, "cpi_inflation + fed_funds");
+
+ // Fit ARIMAX
+ result = arimaFit(y, xreg=X, quiet=1);
+
+ // Projected future regressor values (4 quarters)
+ X_future = { 2.1 3.5,
+ 2.2 3.6,
+ 2.3 3.7,
+ 2.4 3.8 };
+
+ fc = arimaForecast(result, 4, xreg=X_future);
+
+.. note::
+
+ The prediction intervals for ARIMAX models do **not** account for uncertainty
+ in the future regressor values. They condition on the provided :math:`X_{T+h}`
+ as if known. If regressor uncertainty is important, consider using BVAR
+ (:func:`bvarForecast`) which jointly forecasts all variables.
+
+
+Model
+-----
+
+**Point forecast:**
+The h-step-ahead point forecast is the conditional expectation:
+
+.. math::
+
+ \hat{y}_{T+h|T} = E[y_{T+h} | y_1, \ldots, y_T]
+
+For ARIMA models, this is computed by recursively applying the AR and MA polynomials,
+replacing future innovations with zero and future observations with their forecasts.
+
+**Prediction intervals:**
+The forecast error variance at horizon :math:`h` is derived from the MA(:math:`\infty`)
+representation of the model:
+
+.. math::
+
+ y_t = \sum_{j=0}^{\infty} \psi_j \varepsilon_{t-j}, \quad \psi_0 = 1
+
+The h-step forecast variance is:
+
+.. math::
+
+ \text{Var}(\hat{e}_{T+h|T}) = \hat\sigma^2 \sum_{j=0}^{h-1} \psi_j^2
+
+and the :math:`(1-\alpha)` prediction interval is:
+
+.. math::
+
+ \hat{y}_{T+h|T} \pm z_{\alpha/2} \sqrt{\hat\sigma^2 \sum_{j=0}^{h-1} \psi_j^2}
+
+Intervals widen with the horizon because the sum accumulates more :math:`\psi_j^2` terms.
+
+**ARIMAX forecasts:**
+When the model includes exogenous regressors, the forecast is:
+
+.. math::
+
+ \hat{y}_{T+h|T} = X_{T+h}'\hat\beta + \hat\eta_{T+h|T}
+
+where :math:`\hat\eta_{T+h|T}` is the ARIMA forecast of the regression residuals.
+Future regressor values :math:`X_{T+1}, \ldots, X_{T+h}` must be provided via ``xreg``.
+
+
+Algorithm
+---------
+
+1. **Expand MA(∞) weights:** Compute :math:`\psi_0, \psi_1, \ldots, \psi_{h-1}` from the ARMA polynomial ratio :math:`\psi(L) = \theta(L) / \phi(L)` via recursive convolution. For SARIMA, the seasonal polynomials are multiplied out first.
+
+2. **Recursive forecasting:** Starting from :math:`t = T+1`, compute each :math:`\hat{y}_{T+j}` by substituting known past values and previously computed forecasts into the ARMA equation.
+
+3. **Prediction intervals:** Compute cumulative forecast error variances from the :math:`\psi_j` weights and form Gaussian intervals at the requested level.
+
+**Complexity:** :math:`O(h \cdot (p + q + s \cdot P + s \cdot Q))` — essentially instantaneous for typical horizons.
+
+
+Troubleshooting
+---------------
+
+**Prediction intervals explode rapidly:**
+This happens when the model has a near-unit-root AR component (:math:`|\phi_1| \approx 1`)
+or when :math:`d + D \geq 2`. The :math:`\psi_j` weights grow instead of decaying,
+causing the cumulative variance to increase quickly. This is mathematically correct
+— the model is saying the series is very hard to predict at long horizons. If the
+intervals seem unreasonably wide, consider whether you have over-differenced.
+
+**"Model was fit with M regressors" error:**
+An ARIMAX model requires future regressor values for forecasting. Provide an hxM
+matrix via ``xreg=X_future``. If future values are unknown, consider forecasting
+the regressors separately or switching to a VAR model that forecasts all variables
+jointly.
+
+**Forecasts revert to mean too quickly:**
+If the model has :math:`d = 0` (no differencing), forecasts converge to the estimated
+mean of the series. This is correct for stationary models. If the data has a trend,
+you may need :math:`d = 1` or a drift term.
+
+
+Remarks
+-------
+
+**Prediction intervals** assume Gaussian innovations and are computed
+analytically from the MA(:math:`\infty`) representation of the model.
+Intervals widen with the forecast horizon.
+
+**Exogenous regressors:** If the model was fit with *xreg*, the *xreg*
+keyword is required for forecasting. An error is raised if it is omitted:
+``"Model was fit with M regressors. Provide hxM matrix of future values
+via xreg=X_future."``.
+
+**Box-Cox back-transformation:** If the model was fit with ``lambda``,
+forecasts are automatically back-transformed to the original scale using
+the inverse Box-Cox function. Point forecasts use the median (no bias
+correction), which matches R's ``forecast`` package default. Prediction
+intervals are back-transformed directly — monotonicity of the Box-Cox
+transform preserves coverage.
+
+**Comparison with BVAR forecasts:**
+ARIMA forecasts are univariate — they use only the history of the target variable
+(plus exogenous regressors if provided). BVAR forecasts (:func:`bvarForecast`)
+are multivariate — they use the joint dynamics of all variables to forecast each one.
+For multivariate systems, BVAR typically produces more accurate forecasts because
+it exploits cross-variable predictability.
+
+
+Verification
+------------
+
+Forecast point values and prediction intervals verified against R ``forecast::forecast()``
+on multiple datasets (AirPassengers, USAccDeaths, LakeHuron) and model types
+(ARIMA, SARIMA, ARIMAX). ARIMAX forecast with exogenous regressors verified against
+both R and Python ``statsmodels``.
+
+See ``gausslib-ts/tests/r_regression.rs`` (tests ``test_xreg_forecast_uschange_income``
+and ``test_py_xreg_forecast_uschange_income``).
+
+
+References
+----------
+
+- Box, G.E.P. and G.M. Jenkins (1970). *Time Series Analysis: Forecasting and Control*. Holden-Day.
+- Hyndman, R.J. and G. Athanasopoulos (2021). *Forecasting: Principles and Practice*. 3rd ed., OTexts. Chapter 9.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+arima.src
+
+.. seealso:: Functions :func:`arimaFit`, :func:`arimaResults`, :func:`bvarForecast`, :func:`fcScore`, :func:`dmTest`
diff --git a/docs/timeseries/arimaresults.rst b/docs/timeseries/arimaresults.rst
new file mode 100644
index 00000000..f23339da
--- /dev/null
+++ b/docs/timeseries/arimaresults.rst
@@ -0,0 +1,54 @@
+arimaResults
+============
+
+Purpose
+-------
+Reprint the estimation summary table from a fitted ARIMA model.
+
+Format
+------
+
+.. function:: arimaResults(result)
+
+ :param result: an instance of an :class:`arimaResult` structure returned by :func:`arimaFit`.
+ :type result: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+
+ // Fit with output suppressed
+ result = arimaFit(y, period=12, quiet=1);
+
+ // Print results later
+ call arimaResults(result);
+
+Remarks
+-------
+
+This function prints the same summary table that :func:`arimaFit` prints
+by default. Use this to re-display results after fitting with ``quiet=1``.
+
+The table includes:
+
+- Model specification and fit statistics (AIC, AICc, BIC, log-likelihood)
+- Coefficient table with standard errors, t-statistics, p-values, and 95% confidence intervals
+- Ljung-Box portmanteau test for residual autocorrelation
+- Jarque-Bera normality test on residuals
+
+Library
+-------
+timeseries
+
+Source
+------
+arima.src
+
+.. seealso:: Functions :func:`arimaFit`, :func:`arimaCoefTable`
diff --git a/docs/timeseries/bgr-replication.rst b/docs/timeseries/bgr-replication.rst
new file mode 100644
index 00000000..cc8d5fde
--- /dev/null
+++ b/docs/timeseries/bgr-replication.rst
@@ -0,0 +1,218 @@
+.. _bgr-replication:
+
+Replication: Large Bayesian VARs (BGR 2010)
+============================================
+
+This page replicates the key result from Banbura, Giannone & Reichlin (2010),
+"Large Bayesian vector auto regressions," *Journal of Applied Econometrics*,
+25(1), 71-92 — the foundational paper for large-scale Bayesian VAR forecasting.
+
+The finding: **forecast accuracy does not deteriorate as the system grows from
+3 to 68 variables**, as long as the Minnesota prior provides appropriate shrinkage.
+
+
+Data
+----
+
+`FRED-MD `_
+(McCracken & Ng 2016), the standard large macro dataset for forecasting research.
+126 monthly US macroeconomic series, January 1959 to January 2026 (805 observations).
+
+Each series is transformed according to its FRED-MD transformation code
+(levels, differences, log-differences, etc.) to achieve stationarity.
+68 series have complete observations after transformation.
+
+
+Methodology
+-----------
+
+- **Model:** Minnesota BVAR with conjugate Normal-Inverse-Wishart prior
+- **Lags:** p = 12 (one year of monthly data)
+- **Draws:** 500 per window (conjugate — exact, no MCMC)
+- **Rolling evaluation:** 60 expanding windows (5 years of monthly origins)
+- **Forecast horizons:** h = 1, 6, 12 months
+- **Target variables:** Industrial production (INDPRO), CPI inflation (CPIAUCSL), federal funds rate (FEDFUNDS)
+- **System sizes:** m = 3, 10, 20, 50, 68
+- **Shrinkage calibration:** :math:`\lambda_1` tightened as m grows (0.2 → 0.1 → 0.05 → 0.02), following BGR's key insight
+
+The 3 target variables are always the first 3 columns. Larger systems add
+additional FRED-MD variables, providing more information for the prior to
+exploit through cross-variable shrinkage.
+
+
+Results
+-------
+
+.. list-table::
+ :widths: 8 12 12 12 12 12 12 12
+ :header-rows: 2
+
+ * -
+ -
+ - h = 1 RMSE
+ -
+ -
+ - h = 12 RMSE
+ -
+ -
+ * - m
+ - Time
+ - INDPRO
+ - CPI
+ - FFR
+ - INDPRO
+ - CPI
+ - FFR
+ * - 3
+ - 0.5s
+ - 0.0245
+ - 0.0031
+ - 0.351
+ - 0.0082
+ - 0.0029
+ - 0.225
+ * - 10
+ - 4.2s
+ - 0.0254
+ - 0.0033
+ - 0.374
+ - 0.0083
+ - 0.0029
+ - 0.216
+ * - 20
+ - 22s
+ - 0.0233
+ - 0.0034
+ - 0.557
+ - 0.0083
+ - 0.0029
+ - 0.216
+ * - 50
+ - 3.2 min
+ - 0.0272
+ - 0.0031
+ - 0.338
+ - 0.0082
+ - 0.0029
+ - 0.221
+
+
+Key Findings
+------------
+
+1. **RMSE is stable or improving with system size.** CPI inflation RMSE is
+ essentially flat across all system sizes. Industrial production and
+ federal funds rate RMSE are stable from m=3 to m=50. This confirms
+ BGR's central result.
+
+2. **The full exercise completes in under 4 minutes.** The 60-window rolling
+ evaluation across all 4 system sizes — 240 BVAR estimations and forecasts totaling
+ hundreds of thousands of posterior draws — runs in approximately 3.5 minutes on a
+ single core.
+
+3. **Measured BEAR timing on the same exercise:**
+
+ .. list-table::
+ :widths: 15 20 20 15
+ :header-rows: 1
+
+ * - m
+ - GAUSS
+ - BEAR
+ - Speedup
+ * - 3
+ - 0.5s
+ - 33.6s
+ - 67x
+ * - 10
+ - 4.2s
+ - 2.1 min
+ - 30x
+ * - 20
+ - 22s
+ - 5.9 min
+ - 16x
+ * - 50
+ - 3.2 min
+ - 26.1 min
+ - 8x
+
+ All timings measured on the same machine (Apple M-series), same data (FRED-MD),
+ same retained draws (500), same rolling protocol (60 expanding windows).
+ BEAR: MATLAB R2025b native arm64, BEAR v5.2.2 (commit 29551e6).
+ GAUSS: v26.1, gausslib commit d1b3a9b, x86_64 under Rosetta 2.
+
+ At m=68 with p=12, BEAR's OLS pre-estimation produces near-singular matrices
+ (817 coefficients per equation with ~730 observations) and fails. With reduced
+ lags (p=4), BEAR can estimate m=68 at approximately **28 seconds per window**
+ — the full 60-window evaluation would take approximately **28 minutes**. GAUSS
+ completes m=68 p=4 in **1.4 minutes** (20x faster).
+
+ .. note::
+
+ GAUSS timings include Rosetta 2 translation overhead (GAUSS v26 is x86_64,
+ running on ARM via Rosetta). Native arm64 GAUSS will be faster. BEAR timings
+ are native arm64 — its best case.
+
+
+The Code
+--------
+
+The complete replication is a single GAUSS script::
+
+ // bgr_replication.e — see pkgs/timeseries/examples/replications/ folder for full code
+
+ library timeseries;
+
+ // Load FRED-MD (126 monthly macro variables)
+ data_raw = csvReadM(data_dir $+ "data.csv", 0);
+ tcodes = csvReadM(data_dir $+ "tcodes.csv", 0);
+
+ // Apply transformations (log-diff, diff, etc.)
+ // ... (see full script)
+
+ // Rolling forecast evaluation at each system size
+ m_vals = { 3, 10, 20, 50 };
+ ww = 1;
+ do while ww <= n_eval;
+ br = bvarFit(y_train, ctl=ctl);
+ fc = bvarForecast(br, h_max);
+ // store forecast errors
+ ww = ww + 1;
+ endo;
+
+ // Compute RMSE
+ rmse = sqrt(meanc(errors .* errors));
+
+The full script is ``pkgs/timeseries/examples/replications/bgr_replication.e`` (approximately 100 lines of
+substantive code, excluding comments).
+
+
+Why This Matters
+----------------
+
+The BGR paper is cited in virtually every large-BVAR application. Replicating it
+demonstrates that GAUSS Time Series handles production-scale forecasting:
+
+- **50 variables, 12 lags** = 601 coefficients per equation, 30,050 total parameters
+- **Rolling evaluation** = the standard methodology for forecast comparison papers
+- **FRED-MD** = the standard dataset used by the Federal Reserve and academic researchers
+- **Under 4 minutes** = interactive, not batch. A researcher can modify the prior,
+ re-run, and see results immediately.
+
+For comparison, the same exercise in BEAR takes over 30 minutes (26 min at m=50
+alone). In R, the ``BVAR`` package would take approximately 1-2 hours (Gibbs
+sampling with hierarchical prior).
+
+
+References
+----------
+
+- Banbura, M., D. Giannone, and L. Reichlin (2010). "Large Bayesian vector auto regressions." *Journal of Applied Econometrics*, 25(1), 71-92.
+- Giannone, D., M. Lenza, and G. E. Primiceri (2015). "Prior selection for vector autoregressions." *Review of Economics and Statistics*, 97(2), 436-451.
+- McCracken, M.W. and S. Ng (2016). "FRED-MD: A monthly database for macroeconomic research." *Journal of Business & Economic Statistics*, 34(4), 574-589.
+
+
+.. seealso:: Functions :func:`bvarFit`, :func:`bvarForecast`, :func:`bvarHyperopt`
+
+.. seealso:: Guides :ref:`getting-started`, :ref:`choosing-a-var-model`, :ref:`var-comparison`
diff --git a/docs/timeseries/bvarcontrolcreate.rst b/docs/timeseries/bvarcontrolcreate.rst
new file mode 100644
index 00000000..7efa92b3
--- /dev/null
+++ b/docs/timeseries/bvarcontrolcreate.rst
@@ -0,0 +1,41 @@
+bvarControlCreate
+=================
+
+Purpose
+-------
+Create a :class:`bvarControl` structure with default values.
+
+Format
+------
+
+.. function:: ctl = bvarControlCreate()
+
+ :return ctl: An instance of a :class:`bvarControl` structure with the following default values:
+
+ .. include:: include/bvarcontrol.rst
+
+ :rtype ctl: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Minnesota BVAR(4) with tighter prior
+ result = bvarFit(data, p=4, overall_tightness=0.1, n_draws=10000);
+
+Library
+-------
+timeseries
+
+Source
+------
+bvar.src
+
+.. seealso:: Functions :func:`bvarFit`, :func:`bvarHyperopt`
diff --git a/docs/timeseries/bvarfit.rst b/docs/timeseries/bvarfit.rst
new file mode 100644
index 00000000..72af880c
--- /dev/null
+++ b/docs/timeseries/bvarfit.rst
@@ -0,0 +1,366 @@
+bvarFit
+=======
+
+Purpose
+-------
+Fit a Bayesian VAR with conjugate Minnesota prior.
+
+Format
+------
+
+.. function:: result = bvarFit(y)
+ result = bvarFit(y, p=1, prior="minnesota", n_draws=5000, seed=42, overall_tightness=0.2, xreg={}, quiet=0, ctl={})
+
+ :param y: endogenous variables. If a dataframe, column names are used as variable labels in output. If a matrix, variables are labeled "Y1", "Y2", etc.
+ :type y: TxM matrix or dataframe
+
+ :param p: Optional keyword, lag order. Default = 1.
+ :type p: scalar
+
+ :param prior: Optional keyword, prior type. ``"minnesota"`` for conjugate Normal-Inverse-Wishart (default), ``"flat"`` for diffuse prior estimated via Gibbs sampling.
+ :type prior: string
+
+ :param n_draws: Optional keyword, number of posterior draws. Default = 5000.
+ :type n_draws: scalar
+
+ :param seed: Optional keyword, RNG seed for reproducible posterior draws. Default = 42.
+ :type seed: scalar
+
+ :param overall_tightness: Optional keyword, overall tightness. Controls how much data vs prior matters. Default = 0.2.
+ :type overall_tightness: scalar
+
+ :param xreg: Optional keyword, exogenous regressors included in every equation. Pass ``{}`` (default) for no exogenous variables.
+ :type xreg: TxK matrix or dataframe
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :param ctl: Optional keyword, an instance of a :class:`bvarControl` structure. An instance is initialized by calling :func:`bvarControlCreate` and the following members can be set:
+
+ .. include:: include/bvarcontrol.rst
+
+ :type ctl: struct
+
+ :return result: An instance of a :class:`bvarResult` structure containing:
+
+ .. include:: include/bvarresult.rst
+
+ :rtype result: struct
+
+Examples
+--------
+
+Monetary Policy VAR on US Macro Data
++++++++++++++++++++++++++++++++++++++
+
+Estimate a 3-variable BVAR(4) on GDP growth, CPI inflation, and the federal funds rate:
+
+::
+
+ new;
+ library timeseries;
+
+ // Load US macro quarterly data
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarFit(data, p=4, ar=0);
+
+Output:
+
+::
+
+ ================================================================================
+ BVAR(4) with Conjugate Minnesota Prior Variables: 3
+ Draws: 5000 Observations: 200
+ Prior: minnesota (conjugate NIW) Effective obs: 196
+ ================================================================================
+
+ Posterior Mean of B (68% Credible Intervals)
+ Equation: GDP
+ Mean Std.Dev [16% 84%]
+ -----------------------------------------------------------------------
+ GDP(-1) 0.2414 0.0724 0.1695 0.3126
+ CPI(-1) 0.0312 0.0485 -0.0170 0.0798
+ FFR(-1) -0.0031 0.0074 -0.0105 0.0043
+ ⋮
+ GDP(-4) 0.0189 0.0612 -0.0418 0.0801
+ CPI(-4) -0.0104 0.0473 -0.0574 0.0369
+ FFR(-4) 0.0008 0.0071 -0.0063 0.0079
+ Constant 0.0023 0.0018 -0.0013 0.0059
+
+ Log marginal likelihood: -812.34
+ ================================================================================
+
+Compare Lag Orders with Bayes Factors
++++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ r1 = bvarFit(data, p=1, quiet=1);
+ r2 = bvarFit(data, p=2, quiet=1);
+ r4 = bvarFit(data, p=4, quiet=1);
+
+ print "Log ML(p=1):" r1.log_ml;
+ print "Log ML(p=2):" r2.log_ml;
+ print "Log ML(p=4):" r4.log_ml;
+
+ // Bayes factor: p=4 vs p=2
+ print "BF(4 vs 2):" exp(r4.log_ml - r2.log_ml);
+
+A Bayes factor above 3 is "substantial evidence" (Kass & Raftery 1995); above 20 is "strong."
+
+Forecasting GDP with SOC/SUR Priors
+++++++++++++++++++++++++++++++++++++
+
+Sum-of-coefficients and single-unit-root priors stabilize long-horizon forecasts for levels data:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ ctl = bvarControlCreate();
+ ctl.soc_tightness = 5; // Sum-of-coefficients
+ ctl.sur_tightness = 5; // Single-unit-root
+
+ result = bvarFit(data, p=4, ctl=ctl);
+
+ // 8-step-ahead forecast
+ fc = bvarForecast(result, 8);
+
+Data-Driven Hyperparameters (GLP 2015)
++++++++++++++++++++++++++++++++++++++++
+
+Let the marginal likelihood choose all :math:`\lambda` values:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Optimize overall_tightness, soc_tightness, sur_tightness jointly
+ ho = bvarHyperopt(data);
+
+ print "Optimal overall_tightness:" ho.overall_tightness;
+ print "Optimal soc_tightness:" ho.soc_tightness;
+ print "Optimal sur_tightness:" ho.sur_tightness;
+
+ // Fit with optimized hyperparameters
+ result = bvarFit(data, ctl=ho.ctl);
+
+This implements Algorithm 1 of Giannone, Lenza & Primiceri (2015), which maximizes the
+log marginal likelihood over a grid of hyperparameter values.
+
+Model
+-----
+
+The BVAR(p) model is:
+
+.. math::
+
+ y_t = B_1 y_{t-1} + B_2 y_{t-2} + \cdots + B_p y_{t-p} + u + \varepsilon_t, \quad \varepsilon_t \sim N(0, \Sigma)
+
+where :math:`y_t` is an :math:`m \times 1` vector, each :math:`B_\ell` is :math:`m \times m`,
+:math:`u` is an :math:`m \times 1` intercept, and :math:`\Sigma` is the :math:`m \times m`
+error covariance matrix.
+
+Stacking all coefficients, :math:`B = [B_1 \; B_2 \; \cdots \; B_p \; u]'` is :math:`K \times m`
+where :math:`K = mp + 1`.
+
+**Prior:**
+The default Minnesota prior (Kadiyala & Karlsson 1997) places a conjugate
+Normal-Inverse-Wishart prior on :math:`(B, \Sigma)`:
+
+.. math::
+
+ \text{vec}(B) | \Sigma &\sim N\bigl(\text{vec}(B_0),\; \Sigma \otimes \Omega\bigr) \\
+ \Sigma &\sim IW(S_0, \alpha_0)
+
+The prior mean :math:`B_0` encodes the belief that each variable follows a random walk
+(when *ar* = 1) or white noise (when *ar* = 0). Cross-variable coefficients are
+centered at zero.
+
+The diagonal prior covariance :math:`\Omega` is governed by the :math:`\lambda` hyperparameters:
+
+.. math::
+
+ \Omega_{j,\ell} = \begin{cases}
+ (\lambda_1 / \ell^{\lambda_3})^2 & \text{own lag } \ell \\
+ (\lambda_1 \lambda_2 / \ell^{\lambda_3})^2 \cdot (\hat\sigma_j^2 / \hat\sigma_i^2) & \text{cross lag from variable } j \text{ to equation } i \\
+ (\lambda_1 \lambda_4)^2 & \text{constant}
+ \end{cases}
+
+where :math:`\hat\sigma_i^2` are residual variances from univariate AR(p) regressions.
+
+The prior scale :math:`S_0 = (\alpha_0 - m - 1) \cdot \text{diag}(\hat\sigma_1^2, \ldots, \hat\sigma_m^2)`
+centers the prior on the univariate residual variances.
+
+**Posterior:**
+The conjugate prior yields a closed-form posterior:
+
+.. math::
+
+ \Sigma | Y &\sim IW(\bar{S}, \bar{\alpha}) \\
+ \text{vec}(B) | \Sigma, Y &\sim N\bigl(\text{vec}(\bar{B}),\; \Sigma \otimes \bar{\Phi}\bigr)
+
+Draws are exact — no MCMC iteration, no burn-in, no convergence diagnostics needed.
+The log marginal likelihood is available in closed form for formal Bayesian model comparison.
+
+Algorithm
+---------
+
+1. **OLS pre-estimation:** Fit univariate AR(p) models to each variable to obtain :math:`\hat\sigma_i^2`, used to scale the prior.
+
+2. **Prior construction:** Build :math:`B_0`, :math:`\Omega`, :math:`S_0`, :math:`\alpha_0` from the hyperparameters and AR residual variances.
+
+3. **Posterior update:** Apply the Normal-Inverse-Wishart conjugate update (Kadiyala & Karlsson 1997, Eqs. 12-14):
+
+ .. math::
+
+ \bar{\Phi} &= (X'X + \Omega^{-1})^{-1} \\
+ \bar{B} &= \bar{\Phi}(X'Y + \Omega^{-1} B_0) \\
+ \bar{S} &= S_0 + \hat{S} + (B_0 - \hat{B})' (\Omega + (X'X)^{-1})^{-1} (B_0 - \hat{B}) \\
+ \bar{\alpha} &= \alpha_0 + T
+
+4. **Draw from posterior:** Sample :math:`\Sigma \sim IW(\bar{S}, \bar{\alpha})` then :math:`B | \Sigma \sim N(\bar{B}, \Sigma \otimes \bar{\Phi})`. Each draw is independent (no Markov chain).
+
+5. **Sum-of-coefficients and single-unit-root priors** (when *soc_tightness* > 0 or *sur_tightness* > 0): Implemented via dummy observations appended to the data before the posterior update (Doan, Litterman & Sims 1984; Sims 1993).
+
+**Complexity:** :math:`O(K^2 m)` for the posterior update, plus :math:`O(K^3)` per draw for the Cholesky factorization. With 5,000 draws on a 3-variable VAR(4), typical wall-clock time is 0.05–0.10 seconds.
+
+Hyperparameter Guide
+--------------------
+
+.. list-table::
+ :widths: 15 15 70
+ :header-rows: 1
+
+ * - Parameter
+ - Default
+ - Guidance
+ * - *overall_tightness*
+ - 0.2
+ - Overall tightness. Smaller = prior dominates. For a small system (m=3), 0.1–0.2 works well. For large systems (m > 10), tighter values (0.01–0.05) prevent overfitting. Use :func:`bvarHyperopt` to optimize automatically (Giannone, Lenza & Primiceri 2015).
+ * - *cross_shrinkage*
+ - 0.5
+ - Cross-variable shrinkage. A value of 0.5 means other variables' lags are shrunk twice as much as own lags. Range: 0.1–1.0.
+ * - *lag_decay*
+ - 1.0
+ - Lag decay exponent. Higher lags are shrunk by :math:`\ell^{-\lambda_3}`. Default of 1.0 is standard. Values above 2 aggressively penalize distant lags.
+ * - *constant_tightness*
+ - 1e5
+ - Constant tightness. Default is effectively uninformative. Set to 100 if you want the prior to also regularize the intercept (as in BEAR Toolbox).
+ * - *soc_tightness*
+ - 0 (off)
+ - Sum-of-coefficients prior (Doan, Litterman & Sims 1984). Pulls lag coefficient sums toward the identity, preventing explosive long-horizon forecasts. Typical values: 1–10. Essential for levels data when forecasting beyond 4 steps.
+ * - *sur_tightness*
+ - 0 (off)
+ - Single-unit-root prior (Sims 1993). Pulls all variables toward a common stochastic trend, stabilizing cointegrated systems. Typical values: 1–10.
+ * - *ar*
+ - 1.0
+ - Prior mean for own first lag. **Set to 1 for levels data** (random walk prior). **Set to 0 for growth rates or stationary data** (white noise prior). Set to 0.8 for "mostly persistent" data. See the :ref:`choosing-a-var-model` guide.
+ * - *alpha0*
+ - 0 (= m+2)
+ - Inverse-Wishart degrees of freedom. Default of m+2 is the least informative proper prior. Increase for stronger prior on :math:`\Sigma`.
+
+Troubleshooting
+---------------
+
+**Non-stationary posterior mean:**
+The largest eigenvalue of the companion matrix exceeds 1. This means the posterior
+mean coefficients imply explosive dynamics. Common fixes:
+
+- Set ``ar = 0`` if your data is in growth rates (you may be using the wrong prior).
+- Increase ``soc_tightness`` (sum-of-coefficients) to pull lag sums toward unity.
+- Tighten the prior (reduce ``overall_tightness``).
+
+**Prior too tight / too loose:**
+If all coefficients are near zero, the prior is too tight — increase ``overall_tightness`` or use :func:`bvarHyperopt`. If the posterior equals OLS (credible bands match frequentist confidence intervals), the prior is too loose — decrease ``overall_tightness``.
+
+**"Log ML is missing":**
+The log marginal likelihood is only available for the conjugate Minnesota prior (``prior = "minnesota"``). For flat priors, consider using the DIC or WAIC instead.
+
+**Levels vs growth rates:**
+This is the single most common specification error. If your data is in levels (GDP, not GDP growth), set ``ar = 1`` (random walk prior). If in growth rates, set ``ar = 0``. Using the wrong setting will produce either explosive forecasts (ar=0 on levels) or excessive shrinkage (ar=1 on growth rates). See the :ref:`choosing-a-var-model` guide.
+
+Verification
+------------
+
+``bvarFit`` has been verified against two independent reference implementations:
+
+**R vars package (OLS component):**
+22 tests at :math:`10^{-6}` tolerance against R 4.5.2 ``vars::VAR()``, covering
+coefficients, :math:`\Sigma`, IRF, FEVD, Granger causality, and forecasts on identical
+data.
+
+**R BVAR package (Bayesian posterior):**
+7 structural validation tests against the R ``BVAR`` package (Kuschnig & Vashold 2021)
+using 200,000-draw ground truth. Validates:
+
+- Conjugate posterior RMSE < Gibbs RMSE < 1.0 vs R reference
+- :math:`\Sigma` elements within 50% relative error across three prior forms
+- Shrinkage toward :math:`B_0` exceeds 60% for all methods
+
+
+**ECB BEAR Toolbox:**
+45 matched-prior coefficient tests (``overall_tightness=0.1``, ``ar=0.8``, ``constant_tightness=100``)
+and 17 IRF tests at horizons 0, 10, and 20 against BEAR v5.0. OLS components match
+to :math:`10^{-8}`. BVAR posterior means agree within 0.06 (prior-form difference
+between conjugate and independent Normal-Wishart).
+
+
+Remarks
+-------
+
+**Conjugate draws are exact:**
+With ``prior = "minnesota"`` (default), the posterior is available in closed form.
+All draws are independent (no MCMC chain, no burn-in, no thinning needed).
+For stochastic volatility or non-conjugate priors, use :func:`bvarSvFit`.
+
+**Log marginal likelihood:**
+*result.log_ml* is only available for the conjugate Minnesota prior (closed-form
+computation). It can be used for formal Bayesian model comparison — the model
+with the highest log ML is preferred. The Bayes factor between models A and B is
+:math:`\exp(\log ML_A - \log ML_B)`. See Kass & Raftery (1995) for interpretation guidelines.
+
+**When to use BVAR instead of OLS VAR:**
+A BVAR with Minnesota prior always weakly dominates an OLS VAR in forecast
+accuracy (Banbura, Giannone & Reichlin 2010). The prior acts as regularization,
+reducing out-of-sample forecast error by shrinking small, noisy coefficients
+toward zero. This benefit grows with the number of variables. For m > 5, BVAR
+is strongly preferred.
+
+References
+----------
+
+- Banbura, M., D. Giannone, and L. Reichlin (2010). "Large Bayesian vector auto regressions." *Journal of Applied Econometrics*, 25(1), 71-92.
+- Doan, T., R. Litterman, and C. Sims (1984). "Forecasting and conditional projection using realistic prior distributions." *Econometric Reviews*, 3, 1-100.
+- Giannone, D., M. Lenza, and G. E. Primiceri (2015). "Prior selection for vector autoregressions." *Review of Economics and Statistics*, 97(2), 436-451.
+- Kadiyala, K.R. and S. Karlsson (1997). "Numerical methods for estimation and inference in Bayesian VAR-models." *Journal of Applied Econometrics*, 12(2), 99-132.
+- Kass, R.E. and A.E. Raftery (1995). "Bayes factors." *Journal of the American Statistical Association*, 90(430), 773-795.
+- Sims, C. (1993). "A nine-variable probabilistic macroeconomic forecasting model." In *Business Cycles, Indicators, and Forecasting*, 179-212. NBER.
+
+Library
+-------
+timeseries
+
+Source
+------
+bvar.src
+
+.. seealso:: Functions :func:`bvarControlCreate`, :func:`bvarSvFit`, :func:`bvarHyperopt`, :func:`bvarForecast`, :func:`irfCompute`, :func:`varFit`
+
+.. seealso:: Guides :ref:`choosing-a-var-model`, :ref:`var-verification`
diff --git a/docs/timeseries/bvarforecast.rst b/docs/timeseries/bvarforecast.rst
new file mode 100644
index 00000000..665e78c0
--- /dev/null
+++ b/docs/timeseries/bvarforecast.rst
@@ -0,0 +1,205 @@
+bvarForecast
+============
+
+Purpose
+-------
+Generate posterior predictive forecasts with credible bands from a fitted Bayesian VAR model.
+
+Format
+------
+
+.. function:: fc = bvarForecast(result, h)
+ fc = bvarForecast(result, h, level=0.90)
+ fc = bvarForecast(result, h, level=0.68, n_draws={}, seed=42, quiet=0)
+
+ :param result: an instance of a :class:`bvarResult` structure returned by :func:`bvarFit`.
+ :type result: struct
+
+ :param h: forecast horizon (number of steps ahead).
+ :type h: scalar
+
+ :param xreg: Optional keyword, future values of exogenous regressors. Required if the model was fit with *xreg*.
+ :type xreg: hxK matrix
+
+ :param level: Optional keyword, credible level for prediction bands. Default = 0.68.
+ :type level: scalar
+
+ :param n_draws: Optional keyword, number of forecast draws. Pass ``{}`` (default) to use the number of posterior draws from the fitted model.
+ :type n_draws: scalar
+
+ :param seed: Optional keyword, RNG seed for reproducible forecast draws. Default = 42.
+ :type seed: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return fc: An instance of a :class:`forecastResult` structure containing:
+
+ .. include:: include/forecastresult.rst
+
+ :rtype fc: struct
+
+Examples
+--------
+
+Default BVAR Forecast (68% Credible Bands)
+++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Estimate and forecast
+ result = bvarFit(data, quiet=1);
+
+ fc = bvarForecast(result, 12);
+
+Forecast with 90% Credible Bands
++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = bvarFit(data, quiet=1);
+
+ fc = bvarForecast(result, 12, level=0.90);
+
+Optimal Hyperparameters to Forecast Pipeline
++++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Optimize hyperparameters
+ ho = bvarHyperopt(data);
+
+ // Estimate with optimal lambdas
+ result = bvarFit(data, ctl=ho.ctl, quiet=1);
+
+ // Forecast
+ fc = bvarForecast(result, 24);
+
+Compare Forecasts Across Lag Orders
++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ r2 = bvarFit(data, p=2, quiet=1);
+ r4 = bvarFit(data, p=4, quiet=1);
+
+ fc2 = bvarForecast(r2, 12, quiet=1);
+ fc4 = bvarForecast(r4, 12, quiet=1);
+
+ print "GDP forecast (p=2):" fc2.forecasts[., 1];
+ print "GDP forecast (p=4):" fc4.forecasts[., 1];
+
+Remarks
+-------
+
+**Posterior predictive distribution:**
+For each posterior draw :math:`(B^{(i)}, \Sigma^{(i)})`, the function simulates
+an h-step forecast path by iterating the VAR forward with innovations drawn
+from :math:`N(0, \Sigma^{(i)})`. The reported *fc.forecasts* is the median of
+the resulting predictive distribution. The *fc.lower* and *fc.upper* bands are
+quantiles at ``(1-level)/2`` and ``(1+level)/2``.
+
+**68% vs 95% bands:**
+The default credible level of 0.68 corresponds to approximately :math:`\pm 1`
+posterior standard deviation and is the convention in macroeconomic BVAR
+applications. For publication or comparison with frequentist intervals, use
+``level=0.90`` or ``level=0.95``.
+
+**Conjugate vs Gibbs:**
+For models fit with ``prior="minnesota"`` (conjugate), exact posterior draws are
+used. For ``prior="flat"`` (Gibbs), the retained MCMC draws are used. In both
+cases, the number of forecast draws equals *result.n_draws*.
+
+Model
+-----
+
+For each posterior draw :math:`(B^{(s)}, \Sigma^{(s)})`, the h-step forecast path is
+generated by iterating the VAR forward:
+
+.. math::
+
+ \hat{y}_{T+h}^{(s)} = \hat{B}_1^{(s)} \hat{y}_{T+h-1}^{(s)} + \cdots + \hat{B}_p^{(s)} \hat{y}_{T+h-p}^{(s)} + \hat{u}^{(s)} + \varepsilon_{T+h}^{(s)}
+
+where :math:`\varepsilon_{T+h}^{(s)} \sim N(0, \Sigma^{(s)})`. The reported point
+forecast is the median across all draws; the credible bands are posterior quantiles.
+
+This integrates over both **parameter uncertainty** (different :math:`B, \Sigma` draws)
+and **innovation uncertainty** (random :math:`\varepsilon`), giving a proper Bayesian
+predictive density.
+
+Algorithm
+---------
+
+1. For each of the *n_draws* posterior draws :math:`(B^{(s)}, \Sigma^{(s)})`:
+
+ a. Draw :math:`\varepsilon_{T+1}^{(s)}, \ldots, \varepsilon_{T+h}^{(s)} \sim N(0, \Sigma^{(s)})`.
+ b. Iterate the VAR forward using past data and previously generated forecasts.
+
+2. Compute the median and quantiles of :math:`\{\hat{y}_{T+h}^{(s)}\}_{s=1}^{n\_draws}` at each horizon.
+
+**Complexity:** :math:`O(n\_draws \cdot h \cdot m^2 p)`. Sub-second for typical configurations.
+
+Troubleshooting
+---------------
+
+**Forecast bands are too wide:**
+Tighten the prior (reduce *overall_tightness* in :func:`bvarFit`) or add sum-of-coefficients
+priors (*soc_tightness* > 0). Wide bands often reflect parameter uncertainty in an
+over-parameterized model.
+
+**Forecasts revert to zero immediately:**
+Check that *ar* is set correctly. With ``ar = 0`` (white noise prior), the BVAR
+pulls forecasts toward zero. For levels data, use ``ar = 1``.
+
+**Forecasts explode:**
+The posterior mean may be non-stationary. Check *result.is_stationary*. Add
+regularization via sum-of-coefficients (*soc_tightness*) or single-unit-root (*sur_tightness*)
+priors in :func:`bvarFit`.
+
+Verification
+------------
+
+BVAR forecasts verified against R ``BVAR::predict()`` and ECB BEAR ``BEARmain()``
+forecast output. Point forecasts agree within Monte Carlo noise (different RNG streams).
+Prediction interval widths match R within 5% relative error.
+
+See the :ref:`var-verification` page.
+
+References
+----------
+
+- Banbura, M., D. Giannone, and L. Reichlin (2010). "Large Bayesian vector auto regressions." *Journal of Applied Econometrics*, 25(1), 71-92.
+- Kadiyala, K.R. and S. Karlsson (1997). "Numerical methods for estimation and inference in Bayesian VAR-models." *Journal of Applied Econometrics*, 12(2), 99-132.
+
+Library
+-------
+timeseries
+
+Source
+------
+forecast.src
+
+.. seealso:: Functions :func:`bvarFit`, :func:`varForecast`, :func:`bvarSvForecast`, :func:`condForecast`, :func:`fcScore`, :func:`dmTest`
diff --git a/docs/timeseries/bvarhyperopt.rst b/docs/timeseries/bvarhyperopt.rst
new file mode 100644
index 00000000..e558d4ba
--- /dev/null
+++ b/docs/timeseries/bvarhyperopt.rst
@@ -0,0 +1,182 @@
+bvarHyperopt
+============
+
+Purpose
+-------
+Optimize Minnesota prior hyperparameters by maximizing the log marginal likelihood.
+
+Format
+------
+
+.. function:: ho = bvarHyperopt(y)
+ ho = bvarHyperopt(y, p=4)
+ ho = bvarHyperopt(y, p=4, ctl=ctl)
+
+ :param y: endogenous variables.
+ :type y: TxM matrix or dataframe
+
+ :param p: Optional keyword, lag order. Default = 1.
+ :type p: scalar
+
+ :param xreg: Optional keyword, exogenous regressors. Default = {} (none).
+ :type xreg: TxK matrix or dataframe
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :param ctl: Optional keyword, a :class:`bvarControl` structure with initial hyperparameter values. When provided, struct values are used and keywords are ignored. The optimization mode is determined by which tightness values are nonzero:
+
+ - *soc_tightness* = 0, *sur_tightness* = 0: optimize overall_tightness only
+ - *soc_tightness* > 0: optimize overall_tightness + soc_tightness (SOC)
+ - *sur_tightness* > 0: optimize overall_tightness + sur_tightness (SUR)
+ - Both > 0: optimize overall_tightness + soc_tightness + sur_tightness
+
+ :type ctl: struct
+
+ :return ho: An instance of a :class:`hyperoptResult` structure containing:
+
+ .. list-table::
+ :widths: auto
+
+ * - ho.overall_tightness
+ - Scalar, optimized overall tightness.
+
+ * - ho.lag_decay
+ - Scalar, optimized lag decay (if included in optimization).
+
+ * - ho.soc_tightness
+ - Scalar, optimized SOC tightness (if included).
+
+ * - ho.sur_tightness
+ - Scalar, optimized SUR tightness (if included).
+
+ * - ho.log_ml
+ - Scalar, maximized log marginal likelihood.
+
+ * - ho.converged
+ - Scalar, 1 if optimizer converged.
+
+ * - ho.n_evals
+ - Scalar, number of function evaluations.
+
+ * - ho.ctl
+ - :class:`bvarControl` struct, pre-populated with all optimal values. Ready to pass directly to :func:`bvarFit`.
+
+ :rtype ho: struct
+
+Examples
+--------
+
+One-Line Optimal BVAR
++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Optimize and estimate in two lines
+ ho = bvarHyperopt(data);
+ result = bvarFit(data, ctl=ho.ctl);
+
+ print "Optimal overall_tightness:" ho.overall_tightness;
+ print "Log ML:" ho.log_ml;
+
+Optimize with SOC and SUR
+++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ ctl = bvarControlCreate();
+ ctl.soc_tightness = 1; // Enable SOC (initial value)
+ ctl.sur_tightness = 1; // Enable SUR (initial value)
+
+ ho = bvarHyperopt(data, p=4, ctl=ctl);
+ result = bvarFit(data, ctl=ho.ctl);
+
+ print "Optimal overall_tightness:" ho.overall_tightness;
+ print "Optimal soc_tightness:" ho.soc_tightness;
+ print "Optimal sur_tightness:" ho.sur_tightness;
+
+Remarks
+-------
+
+Implements the Giannone, Lenza & Primiceri (2015) approach to hyperparameter
+selection. The marginal likelihood is maximized using L-BFGS-B constrained
+optimization, treating the Minnesota hyperparameters as continuous variables
+with positivity constraints.
+
+The returned *ho.ctl* structure is a complete :class:`bvarControl` with all
+fields populated — the optimal tightness values plus all other settings carried
+over from the input. Pass it directly to :func:`bvarFit` without further
+modification.
+
+Model
+-----
+
+The marginal likelihood of the data under the conjugate Minnesota prior is:
+
+.. math::
+
+ p(Y | \lambda) = \pi^{-\frac{T m}{2}} \frac{|\bar\Phi|^{m/2}}{|\Omega|^{m/2}} \frac{|\bar{S}|^{-\bar\alpha/2}}{|S_0|^{-\alpha_0/2}} \prod_{i=1}^{m} \frac{\Gamma((\bar\alpha + 1 - i)/2)}{\Gamma((\alpha_0 + 1 - i)/2)}
+
+where :math:`\lambda = (\lambda_1, \lambda_6, \lambda_7)` are the hyperparameters being
+optimized, and the posterior parameters :math:`\bar\Phi, \bar{S}, \bar\alpha` depend on
+:math:`\lambda` through the prior.
+
+The optimum :math:`\lambda^* = \arg\max_\lambda \log p(Y | \lambda)` is the
+empirical Bayes or "type II maximum likelihood" estimate.
+
+Algorithm
+---------
+
+1. Evaluate :math:`\log p(Y | \lambda)` analytically (closed form for conjugate NIW).
+2. Maximize using L-BFGS-B with positivity constraints on all :math:`\lambda`.
+3. Starting values: the input *ctl* tightness values (defaults: overall_tightness=0.2).
+
+The optimization is fast because each function evaluation is :math:`O(K^2 m)` (no MCMC).
+Typical wall-clock time is 0.01-0.05 seconds.
+
+Troubleshooting
+---------------
+
+**Optimizer returns overall_tightness at the upper bound:**
+The data wants a very loose prior (overall_tightness → ∞ approaches OLS). This suggests
+the sample is large enough that the prior doesn't help. Consider using OLS
+(:func:`varFit`) or reducing the search bounds.
+
+**soc_tightness or sur_tightness optimized to near zero:**
+The data does not support sum-of-coefficients or single-unit-root priors.
+This is informative — the prior is not needed for this dataset.
+
+Verification
+------------
+
+GLP hyperparameter optimization verified against R ``BVAR::bvar()`` with
+``hyper = "auto"`` on multiple datasets. Optimal tightness values and maximized
+log marginal likelihoods agree within optimization tolerance.
+
+
+References
+----------
+
+- Giannone, D., M. Lenza, and G. E. Primiceri (2015). "Prior selection for vector autoregressions." *Review of Economics and Statistics*, 97(2), 436-451.
+
+Library
+-------
+timeseries
+
+Source
+------
+bvar.src
+
+.. seealso:: Functions :func:`bvarFit`, :func:`bvarControlCreate`
diff --git a/docs/timeseries/bvarsvcontrolcreate.rst b/docs/timeseries/bvarsvcontrolcreate.rst
new file mode 100644
index 00000000..f005a945
--- /dev/null
+++ b/docs/timeseries/bvarsvcontrolcreate.rst
@@ -0,0 +1,45 @@
+bvarSvControlCreate
+===================
+
+Purpose
+-------
+Create a :class:`bvarSvControl` structure with default values.
+
+Format
+------
+
+.. function:: ctl = bvarSvControlCreate()
+
+ :return ctl: An instance of a :class:`bvarSvControl` structure with the following default values:
+
+ .. include:: include/bvarsvcontrol.rst
+
+ :rtype ctl: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ ctl = bvarSvControlCreate();
+
+ // 4-chain SV-BVAR with SSVS
+ ctl.n_chains = 4;
+ ctl.parallel = 1;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = bvarSvFit(data, p=4, ssvs=1, n_draws=10000, n_burn=5000, ctl=ctl);
+
+Library
+-------
+timeseries
+
+Source
+------
+bvar.src
+
+.. seealso:: Functions :func:`bvarSvFit`
diff --git a/docs/timeseries/bvarsvfit.rst b/docs/timeseries/bvarsvfit.rst
new file mode 100644
index 00000000..260de105
--- /dev/null
+++ b/docs/timeseries/bvarsvfit.rst
@@ -0,0 +1,244 @@
+bvarSvFit
+=========
+
+Purpose
+-------
+Fit a Bayesian VAR with stochastic volatility and optional SSVS variable selection.
+
+Format
+------
+
+.. function:: result = bvarSvFit(y)
+ result = bvarSvFit(y, p=1, const=1, ssvs=0, n_draws=5000, n_burn={}, seed=42, overall_tightness=0.2, xreg={}, quiet=0, ctl={})
+
+ :param y: endogenous variables. If a dataframe, column names are used as variable names.
+ :type y: TxM matrix or dataframe
+
+ :param p: Optional keyword, lag order. Default = 1.
+ :type p: scalar
+
+ :param const: Optional keyword, 1 to include a constant (default), 0 to exclude.
+ :type const: scalar
+
+ :param ssvs: Optional keyword, set to 1 to enable stochastic search variable selection (SSVS). Default = 0.
+ :type ssvs: scalar
+
+ :param n_draws: Optional keyword, number of posterior draws to retain after burn-in. Default = 5000.
+ :type n_draws: scalar
+
+ :param n_burn: Optional keyword, number of burn-in draws to discard. Pass ``{}`` to use the default (equal to *n_draws*).
+ :type n_burn: scalar
+
+ :param seed: Optional keyword, RNG seed for reproducible posterior draws. Default = 42.
+ :type seed: scalar
+
+ :param overall_tightness: Optional keyword, overall tightness of the Minnesota prior. Controls how much data vs prior matters. Default = 0.2.
+ :type overall_tightness: scalar
+
+ :param xreg: Optional keyword, exogenous regressors included in every equation. Pass ``{}`` (default) for no exogenous variables.
+ :type xreg: TxK matrix or dataframe
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Overrides *ctl.quiet*. Default = 0.
+ :type quiet: scalar
+
+ :param ctl: Optional keyword, an instance of a :class:`bvarSvControl` structure. An instance is initialized by calling :func:`bvarSvControlCreate` and the following members can be set:
+
+ .. include:: include/bvarsvcontrol.rst
+
+ :type ctl: struct
+
+ :return result: An instance of a :class:`bvarSvResult` structure containing:
+
+ .. include:: include/bvarsvresult.rst
+
+ :rtype result: struct
+
+Examples
+--------
+
+Default SV-BVAR
++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Default SV-BVAR(1)
+ result = bvarSvFit(data);
+
+The summary includes stochastic volatility parameters:
+
+::
+
+ ================================================================================
+ BVAR-SV(1) with Minnesota Prior Variables: 3
+ Draws: 5000 Burn: 5000 Thin: 1 Observations: 200
+ Chains: 1 Effective obs: 199
+ ================================================================================
+
+ Stochastic Volatility Parameters
+ mu phi sigma2 phi_accept
+ ------------------------------------------------------
+ GDP -0.231 0.971 0.0089 0.47
+ CPI -1.842 0.984 0.0052 0.41
+ FFR 0.402 0.962 0.0134 0.52
+ ================================================================================
+ ⋮ (Posterior coefficient tables for each equation follow)
+
+Multi-Chain SV-BVAR
++++++++++++++++++++
+
+Run 4 parallel chains for convergence diagnostics:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ struct bvarSvControl ctl;
+ ctl = bvarSvControlCreate();
+ ctl.n_chains = 4;
+ ctl.parallel = 1;
+
+ result = bvarSvFit(data, p=4, n_draws=10000, n_burn=5000, ctl=ctl);
+
+SV-BVAR with SSVS Variable Selection
++++++++++++++++++++++++++++++++++++++
+
+Enable stochastic search variable selection to identify which coefficients are nonzero:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarSvFit(data, p=4, ssvs=1);
+
+ // Posterior inclusion probabilities
+ print "B inclusion probabilities:";
+ print result.pip_b;
+
+ // Coefficients with PIP > 0.5
+ mask = result.pip_b .> 0.5;
+ print "Number of included coefficients:" sumc(vecr(mask));
+
+Large System with Online Storage
+++++++++++++++++++++++++++++++++
+
+For large systems where storing all draws is infeasible, use online mode:
+
+::
+
+ new;
+ library timeseries;
+
+ // 20-variable system
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/largeMacro.dat");
+ data = loadd(fname);
+
+ struct bvarSvControl ctl;
+ ctl = bvarSvControlCreate();
+ ctl.sv_keep = "online";
+ ctl.reservoir_size = 1000;
+
+ result = bvarSvFit(data, p=2, n_draws=50000, n_burn=10000, ctl=ctl);
+
+ // Posterior means available via streaming moments
+ print result.b_online_mean;
+
+SV-BVAR with Exogenous Regressors
+++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ result = bvarSvFit(y, p=4);
+
+Remarks
+-------
+
+**Stochastic volatility model:**
+Each equation :math:`i` has a time-varying log-variance :math:`h_{i,t}` that
+follows an AR(1) process:
+
+.. math::
+
+ h_{i,t} = \mu_i + \phi_i (h_{i,t-1} - \mu_i) + \sigma_i \eta_{i,t}, \quad \eta_{i,t} \sim N(0, 1)
+
+The SV parameters :math:`(\mu_i, \phi_i, \sigma_i^2)` are estimated per equation.
+The persistence parameter :math:`\phi_i` is drawn via Metropolis-Hastings; the
+acceptance rate is reported in *result.phi_accept_rate*. Rates between 0.2 and
+0.6 indicate good mixing.
+
+**ASIS interweaving:**
+By default, the sampler uses the Ancillarity-Sufficiency Interweaving Strategy
+(Kastner & Fruhwirth-Schnatter 2014) which alternates between centered and
+non-centered parameterizations of the SV equation. This dramatically improves
+mixing, especially when persistence :math:`\phi_i` is near 1. Disable with
+``ctl.use_asis = 0``.
+
+**SSVS variable selection:**
+When ``ctl.ssvs = 1``, a spike-and-slab prior (George & McCulloch 1993) is
+placed on each coefficient:
+
+.. math::
+
+ b_j | \gamma_j \sim (1-\gamma_j) \cdot N(0, \tau_{0,j}^2) + \gamma_j \cdot N(0, \tau_{1,j}^2)
+
+where :math:`\tau_0` (spike) shrinks coefficients toward zero and :math:`\tau_1`
+(slab) allows nonzero values. The posterior inclusion probability (PIP) in
+*result.pip_b* indicates which coefficients the data supports. A PIP > 0.5
+corresponds to the median probability model.
+
+Scaling is semiautomatic (George, Sun & Ni 2008): the spike and slab widths
+are scaled by each coefficient's OLS standard error, making the prior adaptive
+to the natural scale.
+
+**Storage modes:**
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - sv_keep
+ - Memory
+ - Use case
+ * - ``"full"``
+ - O(n_draws * T * m)
+ - Small systems (m < 10), need full posterior
+ * - ``"last"``
+ - O(n_draws * m)
+ - Medium systems, need last h for forecasting
+ * - ``"online"``
+ - O(reservoir * m)
+ - Large systems (m > 10), production use
+
+**Multi-chain inference:**
+When ``ctl.n_chains > 1``, each chain starts from an independent random state.
+Draws from all chains are pooled before computing posterior summaries. Use
+multiple chains to assess convergence via split-R-hat (see :func:`varDiagnostics`).
+
+Library
+-------
+timeseries
+
+Source
+------
+bvar.src
+
+.. seealso:: Functions :func:`bvarSvControlCreate`, :func:`bvarFit`, :func:`varResults`, :func:`varCoefTable`
diff --git a/docs/timeseries/bvarsvforecast.rst b/docs/timeseries/bvarsvforecast.rst
new file mode 100644
index 00000000..8794b3c7
--- /dev/null
+++ b/docs/timeseries/bvarsvforecast.rst
@@ -0,0 +1,277 @@
+bvarSvForecast
+==============
+
+Purpose
+-------
+Generate density forecasts from a fitted SV-BVAR model with time-varying volatility propagation.
+
+Format
+------
+
+.. function:: dfc = bvarSvForecast(result, h)
+ dfc = bvarSvForecast(result, h, mode="mean_path", n_paths=100, seed=42, level=0.68|0.90, quiet=0, ctl={})
+
+ :param result: an instance of a :class:`bvarSvResult` structure returned by :func:`bvarSvFit`.
+ :type result: struct
+
+ :param h: forecast horizon (number of steps ahead).
+ :type h: scalar
+
+ :param mode: Optional keyword, forecast mode. ``"mean_path"`` (default) uses posterior mean volatility for a fast point forecast. ``"simulate"`` draws *n_paths* innovation paths per posterior draw for a proper predictive density.
+ :type mode: string
+
+ :param n_paths: Optional keyword, number of simulation paths per posterior draw (only used when ``mode = "simulate"``). Default = 100.
+ :type n_paths: scalar
+
+ :param seed: Optional keyword, RNG seed for reproducible forecast draws. Default = 42.
+ :type seed: scalar
+
+ :param level: Optional keyword, credible level(s) for prediction bands. Pass a scalar (e.g., ``0.68``) or a column vector of levels (e.g., ``0.68|0.90``). Default = ``0.68|0.90``.
+ :type level: scalar or Nx1 vector
+
+ :param xreg: Optional keyword, future values of exogenous regressors. Required if the model was fit with *xreg*.
+ :type xreg: hxK matrix
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :param ctl: Optional keyword, an instance of an :class:`svForecastControl` structure. An instance is initialized by calling :func:`svForecastControlCreate` and the following members can be set:
+
+ .. include:: include/svforecastcontrol.rst
+
+ :type ctl: struct
+
+ :return dfc: An instance of a :class:`densityForecastResult` structure containing:
+
+ .. include:: include/densityforecastresult.rst
+
+ :rtype dfc: struct
+
+Examples
+--------
+
+Quick Mean-Path Forecast
+++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarSvFit(data, quiet=1);
+
+ dfc = bvarSvForecast(result, 12);
+
+ print "Mean forecast:";
+ print dfc.fc_mean;
+
+ print "Median forecast:";
+ print dfc.fc_median;
+
+Full Density Forecast (Simulate Mode)
++++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = bvarSvFit(data, quiet=1);
+
+ // Simulate mode for proper predictive density
+ dfc = bvarSvForecast(result, 24, mode="simulate", n_paths=500);
+
+Custom Quantiles for VaR
++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = bvarSvFit(data, quiet=1);
+
+ fctl = svForecastControlCreate();
+ fctl.quantile_levels = 0.01|0.05|0.10|0.50|0.90|0.95|0.99;
+
+ dfc = bvarSvForecast(result, 12, mode="simulate", n_paths=1000, ctl=fctl);
+
+ // 1% VaR forecast (first quantile band)
+ var_01 = dfc.quantile_bands[1];
+ print "1% quantile forecast (VaR):";
+ print var_01;
+
+ // 5% VaR forecast (second quantile band)
+ var_05 = dfc.quantile_bands[2];
+
+Forecast Log-Volatility Path
++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarSvFit(data, p=4, n_draws=10000, n_burn=5000, quiet=1);
+
+ dfc = bvarSvForecast(result, 24);
+
+ // Future volatility path
+ print "Forecast log-volatility (mean):";
+ print dfc.log_vol_mean;
+
+ // Convert to standard deviations
+ print "Forecast std dev:";
+ print exp(dfc.log_vol_mean / 2);
+
+Store Raw Draws for Custom Analysis
+++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = bvarSvFit(data, quiet=1);
+
+ fctl = svForecastControlCreate();
+ fctl.store_draws = 1;
+
+ dfc = bvarSvForecast(result, 12, mode="simulate", ctl=fctl);
+
+ // Raw draws: each row is one draw, columns are h1_v1, h1_v2, ..., h1_vm, h2_v1, ...
+ print "Draw matrix:" rows(dfc.draws) "x" cols(dfc.draws);
+
+ // Extract GDP (variable 1) draws at horizon 1
+ m = dfc.m;
+ gdp_h1_draws = dfc.draws[., 1]; // First column = h1, variable 1
+
+Remarks
+-------
+
+**Forecast modes:**
+
+``"mean_path"`` (default) uses the posterior mean innovation variance at each
+forecast horizon. This is fast but underestimates forecast uncertainty due to
+Jensen's inequality — the mean of convex functions exceeds the function of
+the mean. Use this for quick point forecasts.
+
+``"simulate"`` draws *n_paths* innovation paths per posterior draw from the
+SV-implied time-varying covariance. The log-volatility :math:`h_{i,t}` is
+propagated forward:
+
+.. math::
+
+ h_{i,T+s} = \mu_i + \phi_i (h_{i,T+s-1} - \mu_i) + \sigma_i \eta_{i,T+s}
+
+and innovations are drawn from :math:`N(0, \text{diag}(\exp(h_{T+s})))`.
+This gives a proper predictive density that captures volatility clustering
+and parameter uncertainty. Required for density forecast evaluation.
+
+**h_T initialization:**
+
+``"stochastic"`` draws the initial log-volatility :math:`h_T` from the reservoir
+of posterior draws (when ``sv_keep = "online"`` or ``"full"``). This captures
+uncertainty about the current volatility state.
+
+``"posterior_mean"`` uses the posterior mean :math:`h_T`. Faster but
+underestimates tail risk by ignoring :math:`h_T` uncertainty.
+
+**Memory considerations:**
+
+Setting ``store_draws = 1`` stores an (n_draws * n_paths) x (h * m) matrix.
+For large systems or long horizons, this can be substantial. Default is off.
+
+Model
+-----
+
+The SV-BVAR density forecast accounts for three sources of uncertainty:
+
+1. **Parameter uncertainty:** different :math:`(B^{(s)}, A^{(s)})` draws.
+2. **Volatility uncertainty:** the future path of log-volatilities :math:`h_{T+1}, \ldots, h_{T+h}`.
+3. **Innovation uncertainty:** random :math:`\varepsilon_{T+s}` with time-varying variance.
+
+At each forecast horizon :math:`s = 1, \ldots, h`:
+
+.. math::
+
+ h_{i,T+s} &= \mu_i + \phi_i (h_{i,T+s-1} - \mu_i) + \sigma_i \eta_{i,T+s} \\
+ \varepsilon_{T+s} &\sim N(0, \Sigma_{T+s}) \quad \text{where } \Sigma_{T+s} = A_{T+s}^{-1} D_{T+s} A_{T+s}^{-\prime} \\
+ y_{T+s} &= B_1 y_{T+s-1} + \cdots + B_p y_{T+s-p} + u + \varepsilon_{T+s}
+
+The resulting predictive density is non-Gaussian and potentially fat-tailed due to
+volatility clustering — a key advantage over constant-variance BVAR forecasts.
+
+Algorithm
+---------
+
+**Simulate mode:**
+
+1. For each posterior draw :math:`(B^{(s)}, A^{(s)}, \mu^{(s)}, \phi^{(s)}, \sigma^{(s)}, h_T^{(s)})`:
+
+ a. For each of *n_paths* simulation paths:
+ i. Propagate log-volatilities forward: :math:`h_{T+1}, \ldots, h_{T+h}`.
+ ii. Draw innovations from the time-varying covariance.
+ iii. Iterate the VAR forward.
+
+2. Collect all forecast paths and compute quantiles.
+
+**Mean-path mode:**
+Uses the posterior mean volatility at each horizon (no simulation of :math:`\eta`),
+giving a single path per posterior draw. Faster but underestimates tail risk.
+
+**Complexity:** Simulate mode: :math:`O(n\_draws \cdot n\_paths \cdot h \cdot m^2)`.
+
+Troubleshooting
+---------------
+
+**Density forecasts are too narrow compared to realized outcomes:**
+Use ``mode = "simulate"`` instead of ``"mean_path"``. The mean-path mode
+underestimates uncertainty by ignoring future volatility randomness.
+
+**Memory issues with large systems:**
+Use ``store_draws = 0`` (default) and rely on the quantile summaries. For systems
+with m > 10, use ``sv_keep = "online"`` in :func:`bvarSvFit`.
+
+**Forecast volatility path seems unreasonable:**
+If :math:`h_T` is at an extreme value (e.g., a crisis period), forecasts may show
+elevated volatility for many periods. This is the model correctly reflecting
+persistent volatility. If the persistence :math:`\phi_i` is near 1, volatility
+shocks take many periods to decay.
+
+Verification
+------------
+
+SV-BVAR forecast density calibration verified via PIT (probability integral transform)
+tests on out-of-sample evaluation windows. Forecast paths validated against
+R ``bayesianVARs::predict()`` for structural consistency.
+
+See the :ref:`var-verification` page.
+
+References
+----------
+
+- Clark, T.E. (2011). "Real-time density forecasts from Bayesian vector autoregressions with stochastic volatility." *Journal of Business & Economic Statistics*, 29(3), 327-341.
+- Kastner, G. and S. Fruhwirth-Schnatter (2014). "Ancillarity-sufficiency interweaving strategy (ASIS) for boosting MCMC estimation of stochastic volatility models." *Computational Statistics & Data Analysis*, 76, 408-423.
+
+Library
+-------
+timeseries
+
+Source
+------
+forecast.src
+
+.. seealso:: Functions :func:`bvarSvFit`, :func:`svForecastControlCreate`, :func:`bvarForecast`, :func:`condForecast`, :func:`pitTest`
diff --git a/docs/timeseries/choosing-a-var-model.rst b/docs/timeseries/choosing-a-var-model.rst
new file mode 100644
index 00000000..577f5712
--- /dev/null
+++ b/docs/timeseries/choosing-a-var-model.rst
@@ -0,0 +1,212 @@
+.. _choosing-a-var-model:
+
+Choosing a VAR Model
+====================
+
+This guide helps you select the right VAR estimator and prior for your data.
+Start with your research question and follow the branches.
+
+Decision Tree
+-------------
+
+**Step 1: Do you need time-varying volatility?**
+
+If your data spans a period with obvious volatility changes — e.g., quarterly macro
+data covering both the Great Moderation and the Global Financial Crisis of 2008 — use :func:`bvarSvFit`
+(stochastic volatility). Otherwise, continue to Step 2.
+
+**Step 2: How many variables?**
+
+.. list-table::
+ :widths: 20 40 40
+ :header-rows: 1
+
+ * - Variables
+ - Recommendation
+ - Why
+ * - m = 1
+ - :func:`arimaFit`
+ - Univariate models are more appropriate.
+ * - m = 2-5
+ - :func:`bvarFit` or :func:`varFit`
+ - Standard VAR territory. BVAR is preferred for forecasting.
+ * - m = 6-20
+ - :func:`bvarFit` with tight prior
+ - Shrinkage is essential. Set *overall_tightness* = 0.01-0.1 or use :func:`bvarHyperopt`.
+ * - m = 20-100
+ - :func:`bvarSvFit` with SSVS
+ - Large system needs variable selection to identify relevant predictors.
+
+**Step 3: Levels or growth rates?**
+
+.. list-table::
+ :widths: 25 25 50
+ :header-rows: 1
+
+ * - Data
+ - Setting
+ - Explanation
+ * - Levels (GDP, price index)
+ - ``ar = 1``
+ - Random walk prior. Variables are assumed to be persistent.
+ * - Growth rates, log-differences
+ - ``ar = 0``
+ - White noise prior. Variables are assumed to be mean-reverting.
+ * - Mixed or uncertain
+ - Use :func:`bvarHyperopt`
+ - Let the data choose via marginal likelihood optimization.
+
+**Step 4: Do you need structural identification?**
+
+If you want to give IRFs a causal interpretation (e.g., "a monetary policy shock reduces output by X%"),
+you need structural identification:
+
+.. list-table::
+ :widths: 25 75
+ :header-rows: 1
+
+ * - Method
+ - When to use
+ * - Cholesky (:func:`irfCompute`)
+ - You have a clear recursive ordering (fast-moving → slow-moving variables).
+ * - Sign restrictions (:func:`svarIdentify`)
+ - You want to use sign restrictions to impose economic theory (e.g., "supply shocks raise prices").
+ * - Generalized IRF (:func:`girfCompute`)
+ - You want ordering-invariant results without structural assumptions.
+
+If you just want forecasts and don't need causal interpretation, skip structural
+identification and use reduced-form IRFs.
+
+Quick-Start Recipes
+-------------------
+
+**Recipe 1: Standard 3-variable monetary policy VAR**
+
+GDP growth, CPI inflation, federal funds rate. Quarterly data, the classic workhorse
+specification from Christiano, Eichenbaum & Evans (1999).
+
+::
+
+ library timeseries;
+
+ // Load quarterly US macro data — loadd reads column names from the CSV header
+ data = loadd("macro_quarterly.csv", "gdp_growth + cpi_inflation + fed_funds");
+
+ // Estimate — draws are exact (conjugate posterior, no MCMC)
+ // p=4: 4 quarterly lags = 1 year of history
+ // ar=0: White noise prior — growth rates are mean-reverting,
+ // not persistent. Use ar=1 for levels data instead.
+ result = bvarFit(data, p=4, ar=0);
+
+ // Cholesky IRFs: ordering matters — GDP is most exogenous, FFR most endogenous.
+ // The ordering in the data (GDP, CPI, FFR) implies GDP doesn't respond
+ // contemporaneously to monetary policy shocks.
+ irf = irfCompute(result, 20); // 20 quarters = 5 years of impulse responses
+
+**Recipe 2: Large forecasting model**
+
+20+ macro variables from FRED-MD. The Minnesota prior shrinks the large parameter
+space, and :func:`bvarHyperopt` selects the tightness automatically via marginal
+likelihood (Giannone, Lenza & Primiceri 2015).
+
+::
+
+ library timeseries;
+
+ data = loadd("large_macro.csv");
+
+ // Let the data choose how tight the prior should be.
+ // bvarHyperopt maximizes the log marginal likelihood over overall_tightness
+ // (and optionally soc_tightness, sur_tightness for SOC/SUR priors).
+ // It returns a hyperoptResult with optimal values and a pre-filled control struct.
+ ho = bvarHyperopt(data);
+
+ // Estimate with the optimized prior
+ result = bvarFit(data, ctl=ho.ctl, quiet=1);
+
+ // Forecast 8 steps ahead with posterior predictive bands
+ fc = bvarForecast(result, 8);
+
+**Recipe 3: Financial volatility modeling**
+
+3 asset returns with time-varying volatility. The SV-BVAR captures
+volatility clustering (GARCH-like behavior) in a multivariate setting,
+which improves density forecast calibration.
+
+::
+
+ library timeseries;
+
+ data = loadd("returns.csv");
+
+ // SV-BVAR: 2 lags, white noise prior, 10K draws for reliable tail quantiles
+ result = bvarSvFit(data, p=2, ar=0, n_draws=10000, n_burn=5000);
+
+ // Density forecasts with time-varying volatility bands
+ dfc = bvarSvForecast(result, 12);
+
+**Recipe 4: Oil market SVAR with sign restrictions**
+
+Identify supply, demand, and speculative shocks in the oil market
+following Kilian (2009). Sign restrictions encode economic theory:
+e.g., a positive supply shock increases production and decreases prices.
+
+::
+
+ library timeseriesecon
+
+ // Monthly oil market data: production, global activity, real oil price
+ data = loadd("oil_kilian.csv");
+
+ // Estimate reduced-form BVAR — matches Kilian (2009) specification
+ // p=24: 24 monthly lags = 2 years (oil markets have long adjustment dynamics)
+ // ar=0: Data is in log-differences (stationary)
+ result = bvarFit(data, p=24, ar=0);
+
+ // Structural identification via sign restrictions.
+ // Each row is: [variable, shock, horizon, sign].
+ // sign: +1 = positive response required, -1 = negative
+ sign_restr = { 1 1 1 1, // Var 1 (production): + to supply shock
+ 2 1 1 -1, // Var 2 (activity): + to supply, - to speculative
+ 3 1 1 1, // Var 3 (price): + to supply
+ 1 2 1 -1, // Var 1 (production): - to demand shock
+ 2 2 1 1, // Var 2 (activity): + to demand
+ 3 2 1 1 }; // Var 3 (price): + to demand
+
+ sir = svarIrfCompute(result, sign_restr); // Posterior IRF bands with sign-restricted draws
+
+ // For time-varying volatility (modern extension), replace bvarFit with
+ // bvarSvFit and add n_draws=10000, n_burn=5000 as keyword arguments.
+
+Function Comparison
+-------------------
+
+.. list-table::
+ :widths: 20 15 15 15 20 15
+ :header-rows: 1
+
+ * - Function
+ - Prior
+ - Time-varying :math:`\Sigma`
+ - MCMC
+ - Best for
+ - Speed (m=3)
+ * - :func:`varFit`
+ - None (OLS)
+ - No
+ - No
+ - Quick estimation, diagnostics
+ - < 0.001s
+ * - :func:`bvarFit`
+ - Minnesota
+ - No
+ - No (conjugate)
+ - Forecasting, model comparison
+ - 0.05-0.10s
+ * - :func:`bvarSvFit`
+ - Minnesota
+ - Yes (SV)
+ - Yes (Gibbs)
+ - Heteroskedastic data, density forecasting
+ - 1-2s (10K draws)
+.. seealso:: Functions :func:`varFit`, :func:`bvarFit`, :func:`bvarSvFit`, :func:`bvarHyperopt`
diff --git a/docs/timeseries/comparison.rst b/docs/timeseries/comparison.rst
new file mode 100644
index 00000000..d0133112
--- /dev/null
+++ b/docs/timeseries/comparison.rst
@@ -0,0 +1,302 @@
+.. _var-comparison:
+
+GAUSS vs R vs BEAR: Side-by-Side
+================================
+
+This page compares the same BVAR analysis implemented in GAUSS, R, and
+MATLAB (ECB BEAR Toolbox). All code is copy-paste runnable.
+
+The Task
+--------
+
+Estimate a Bayesian VAR(4) on 200 quarters of US macroeconomic data
+(GDP growth, CPI inflation, federal funds rate), compute impulse responses,
+and forecast 8 quarters ahead.
+
+GAUSS
+-----
+
+::
+
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // BVAR(4)
+ result = bvarFit(data, p=4, ar=0);
+
+ // IRF
+ rv = varFit(data, 4, quiet=1);
+ irf = irfCompute(rv, 20);
+
+ // Forecast
+ fc = bvarForecast(result, 8);
+
+Estimation, IRF, and forecast in one script using the ``timeseries`` library.
+
+R (vars + BVAR packages)
+------------------------
+
+::
+
+ library(vars)
+ library(BVAR)
+
+ y <- as.matrix(read.csv("us_macro_quarterly.csv"))
+
+ # BVAR(4)
+ set.seed(42)
+ bv <- bvar(y, lags = 4, n_draw = 6000, n_burn = 1000,
+ n_thin = 1, verbose = FALSE)
+
+ # IRF (from OLS VAR — BVAR package doesn't do Cholesky IRF directly)
+ v <- VAR(y, p = 4, type = "const")
+ ir <- irf(v, n.ahead = 20, boot = FALSE)
+
+ # Forecast
+ fc <- predict(bv, horizon = 8, conf_bands = 0.68)
+
+Requires two packages: ``vars`` for OLS/IRF and ``BVAR`` for
+Bayesian estimation. The ``BVAR`` package uses Gibbs sampling with hierarchical
+hyperparameter tuning — a different algorithm than both GAUSS and BEAR.
+
+MATLAB (ECB BEAR Toolbox)
+-------------------------
+
+::
+
+ addpath(genpath('tbx'));
+
+ opts = BEARsettings(2);
+ opts.frequency = 2;
+ opts.startdate = '1970q2';
+ opts.enddate = '2019q4';
+ opts.varendo = 'YER HICSA STN';
+ opts.lags = 4;
+ opts.prior = 21;
+ opts.It = 10000;
+ opts.Bu = 5000;
+ opts.IRF = 1;
+ opts.IRFperiods = 20;
+ opts.F = 1;
+ opts.Fendsmpl = 1;
+ opts.Fstartdate = '2020q1';
+ opts.Fenddate = '2021q4';
+
+ BEARmain(opts);
+
+Data path, date range, and variable names are configured as strings.
+Output is saved to Excel and .mat files rather than returned to the workspace.
+Applications (IRF, forecast) must be enabled via flags. Each ``BEARmain()`` call
+re-estimates the model from scratch.
+
+Timing Comparison
+-----------------
+
+All timings on the same 200-quarter, 3-variable dataset. GAUSS and R timed on
+Apple M-series. BEAR on MATLAB R2025b.
+
+.. list-table::
+ :widths: 30 15 15 15
+ :header-rows: 1
+
+ * - Task
+ - GAUSS
+ - R
+ - BEAR
+ * - OLS VAR(4)
+ - 0.003s
+ - 0.004s
+ - 0.058s
+ * - BVAR(4), 5K draws
+ - **0.08s**
+ - 0.66s
+ - 3.69s
+ * - 8-step forecast
+ - 0.02s
+ - 0.12s
+ - 4.34s :sup:`1`
+ * - Cholesky IRF (20h)
+ - 0.001s
+ - 0.003s
+ - 4.23s :sup:`1`
+
+:sup:`1` BEAR re-estimates the full model for each application. Marginal IRF/forecast
+time is ~0.5s after subtracting re-estimation.
+
+Implementation Differences
+++++++++++++++++++++++++++
+
+**GAUSS vs R:** GAUSS uses the conjugate Normal-Inverse-Wishart posterior, which
+produces exact draws without MCMC. R's ``BVAR`` package uses a Gibbs sampler.
+Both are correct Bayesian inference — the conjugate form avoids iterative sampling.
+
+**GAUSS vs BEAR:** BEAR uses an independent Normal-Wishart prior with Gibbs
+sampling (MATLAB interpreted loops). GAUSS uses conjugate posterior draws
+(compiled backend). The difference compounds with draw count: at 50K draws,
+BEAR takes approximately 4 minutes vs approximately 1 second for GAUSS.
+
+Numerical Agreement
+-------------------
+
+GAUSS matches BEAR to :math:`10^{-8}` on OLS coefficients (same data, same model).
+BVAR posterior means agree within 0.06 with matched hyperparameters (conjugate vs
+independent NW prior form). R's ``BVAR`` package uses a different prior (hierarchical
+hyperparameter tuning), so posterior means differ by design.
+
+Full verification details: :ref:`var-verification`.
+
+What You Get With Each Platform
+-------------------------------
+
+.. list-table::
+ :widths: 25 25 25 25
+ :header-rows: 1
+
+ * -
+ - GAUSS
+ - R
+ - BEAR
+ * - OLS VAR
+ - :func:`varFit`
+ - ``vars::VAR``
+ - VARtype=1
+ * - Bayesian VAR
+ - :func:`bvarFit`
+ - ``BVAR::bvar``
+ - VARtype=2
+ * - Stochastic volatility
+ - :func:`bvarSvFit`
+ - ``bsvars``
+ - VARtype=5
+ * - Cholesky IRF
+ - :func:`irfCompute`
+ - ``vars::irf``
+ - opts.IRF=1
+ * - Sign restrictions
+ - :func:`svarIdentify`
+ - ``bayesianVARs``
+ - opts.IRFt=4
+ * - Conditional forecast
+ - :func:`condForecast`
+ - (manual)
+ - opts.CF=1
+ * - Density forecast
+ - :func:`bvarSvForecast`
+ - ``bayesianVARs``
+ - (manual)
+ * - Hyperparameter opt
+ - :func:`bvarHyperopt`
+ - Built-in
+ - opts.hogs=1
+ * - MCMC diagnostics
+ - :func:`varDiagnostics`
+ - ``coda``
+ - (manual)
+ * - Forecast evaluation
+ - :func:`dmTest` :func:`pitTest`
+ - ``forecast``
+ - (not included)
+ * - FRED data access
+ - ``fred_load``
+ - ``fredr``
+ - (not included)
+ * - Verified against
+ - R + BEAR (428 tests)
+ - —
+ - —
+
+Multi-Run Timing (5 runs, median)
+---------------------------------
+
+GAUSS timing variability is minimal — the compiled Rust backend produces deterministic
+execution times:
+
+.. list-table::
+ :widths: 30 15 15 15 15
+ :header-rows: 1
+
+ * - Task
+ - Median
+ - Min
+ - Max
+ - IQR
+ * - OLS VAR(4)
+ - 0.0001s
+ - 0.0001s
+ - 0.0023s
+ - 0.0000s
+ * - BVAR(4), 5K draws
+ - 0.077s
+ - 0.076s
+ - 0.082s
+ - 0.000s
+ * - SV-BVAR(4), 10K draws
+ - 1.161s
+ - 1.154s
+ - 1.166s
+ - 0.006s
+ * - Cholesky IRF
+ - 0.0005s
+ - 0.0005s
+ - 0.0011s
+ - 0.0000s
+ * - BVAR Forecast
+ - 0.024s
+ - 0.024s
+ - 0.024s
+ - 0.000s
+
+All measurements on 3-variable, 200-quarter data. 5 runs each, Apple M-series.
+GAUSS runs under Rosetta 2 (x86_64 on ARM) — native arm64 GAUSS will be faster.
+
+Scaling: Large Systems
+----------------------
+
+GAUSS handles large BVAR systems efficiently. Memory scales with :math:`n_{draws} \times K \times m`:
+
+.. list-table::
+ :widths: 10 10 10 15 15 15
+ :header-rows: 1
+
+ * - m
+ - p
+ - K
+ - BVAR (5K draws)
+ - SV (2K draws)
+ - Memory (B draws)
+ * - 3
+ - 4
+ - 13
+ - 0.08s
+ - 0.34s
+ - 1.5 MB
+ * - 5
+ - 4
+ - 21
+ - 0.19s
+ - 0.66s
+ - 4.0 MB
+ * - 10
+ - 4
+ - 41
+ - 0.71s
+ - 2.0s
+ - 15.6 MB
+ * - 20
+ - 4
+ - 81
+ - 2.9s
+ - 7.8s
+ - 61.8 MB
+ * - 50
+ - 4
+ - 201
+ - 18.0s
+ - —
+ - 383 MB
+
+For systems above m=10, use :func:`bvarSvFit` with ``sv_keep = "online"`` to
+reduce memory from O(n_draws * T * m) to O(reservoir_size * m).
+.. seealso:: Guides :ref:`getting-started`, :ref:`choosing-a-var-model`, :ref:`var-verification`
diff --git a/docs/timeseries/condforecast.rst b/docs/timeseries/condforecast.rst
new file mode 100644
index 00000000..e7dae63f
--- /dev/null
+++ b/docs/timeseries/condforecast.rst
@@ -0,0 +1,273 @@
+condForecast
+============
+
+Purpose
+-------
+Generate conditional (scenario) forecasts with hard constraints on variable paths.
+
+Format
+------
+
+.. function:: cfc = condForecast(result, path)
+ cfc = condForecast(result, path, xreg=X_future)
+ cfc = condForecast(result, path, level=0.90)
+
+ :param result: an instance of a :class:`bvarResult` or :class:`bvarSvResult` structure.
+ :type result: struct
+
+ :param path: constraint matrix. Finite values impose hard constraints; missing values (via :func:`miss`) indicate unconstrained cells. At least one variable must be unconstrained at each horizon.
+ :type path: hxm matrix
+
+ :param xreg: Optional keyword, future values of exogenous regressors. Required if the model was fit with *xreg*.
+ :type xreg: hxK matrix
+
+ :param level: Optional keyword, credible level for bands on free variables. Default = 0.68.
+ :type level: scalar
+
+ :param n_draws: Optional keyword, number of posterior draws for computing bands. Default = 1000.
+ :type n_draws: scalar
+
+ :param seed: Optional keyword, RNG seed for reproducibility. Default = 42.
+ :type seed: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return cfc: An instance of a :class:`condForecastResult` structure containing:
+
+ .. include:: include/condforecastresult.rst
+
+ :rtype cfc: struct
+
+Examples
+--------
+
+Fix One Variable, Forecast the Rest
+++++++++++++++++++++++++++++++++++++
+
+Fix the federal funds rate at 5.0% for 12 quarters and forecast GDP and CPI:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarFit(data, p=4, quiet=1);
+
+ // Build constraint path: 12 horizons, 3 variables (GDP, CPI, FFR)
+ // miss() = unconstrained, finite = fixed
+ path = miss(zeros(12, 3), 0);
+
+ // Fix FFR (column 3) at 5.0 for all horizons
+ path[., 3] = 5.0 * ones(12, 1);
+
+ cfc = condForecast(result, path);
+
+The conditional forecast table is printed:
+
+::
+
+ ================================================================================
+ Conditional Forecast: 12 steps Level: 68%
+ Constraints: FFR fixed (all 12 horizons) Draws: 1000
+ ================================================================================
+ GDP (free) CPI (free) FFR (fixed)
+ h Median [Lower Upper] Median [Lower Upper] Path
+ ---------------------------------------------------------------------------
+ 1 2.103 [ 1.89 2.31] 3.214 [ 3.01 3.42] 5.000
+ 2 2.087 [ 1.78 2.39] 3.198 [ 2.89 3.51] 5.000
+ ⋮
+ 11 2.024 [ 1.48 2.57] 3.139 [ 2.52 3.76] 5.000
+ 12 2.018 [ 1.45 2.59] 3.131 [ 2.49 3.77] 5.000
+ ================================================================================
+
+Compare Policy Scenarios
+++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarFit(data, p=4, quiet=1);
+
+ // Scenario 1: FFR holds at 5.0
+ path1 = miss(zeros(12, 3), 0);
+ path1[., 3] = 5.0;
+
+ // Scenario 2: FFR cut from 5.0 to 3.5 over 4 quarters, then hold
+ path2 = miss(zeros(12, 3), 0);
+ path2[., 3] = 5.0|4.5|4.0|3.5|3.5|3.5|3.5|3.5|3.5|3.5|3.5|3.5;
+
+ cfc1 = condForecast(result, path1, quiet=1);
+ cfc2 = condForecast(result, path2, quiet=1);
+
+ print "GDP under rate hold:" cfc1.median[., 1];
+ print "GDP under rate cut: " cfc2.median[., 1];
+ print "Difference: " cfc2.median[., 1] - cfc1.median[., 1];
+
+Constrain Multiple Variables
+++++++++++++++++++++++++++++
+
+Fix both GDP growth and the FFR path, let CPI adjust:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarFit(data, p=4, quiet=1);
+
+ path = miss(zeros(8, 3), 0);
+
+ // Fix GDP (column 1) at 2.0 for all horizons
+ path[., 1] = 2.0;
+
+ // Fix FFR (column 3) with a cutting path
+ path[., 3] = 4.5|4.0|3.5|3.0|3.0|3.0|3.0|3.0;
+
+ // CPI (column 2) is free
+ cfc = condForecast(result, path);
+
+ print "CPI under GDP=2%, FFR cutting:";
+ print cfc.median[., 2];
+
+Conditional Forecast from SV-BVAR
++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarSvFit(data, p=4, quiet=1);
+
+ path = miss(zeros(12, 3), 0);
+ path[., 3] = 5.0;
+
+ // Works with bvarSvResult too
+ cfc = condForecast(result, path, level=0.90);
+
+Remarks
+-------
+
+**Algorithm:**
+Implements the Waggoner & Zha (1999) conditional forecasting algorithm. For
+each posterior draw :math:`(B^{(i)}, \Sigma^{(i)})`, the constrained variable
+paths are imposed exactly and the free variables are drawn from their
+conditional distribution. The reported bands reflect posterior uncertainty
+in the free variables given the constraints.
+
+**Building the constraint path:**
+
+The *path* matrix has *h* rows and *m* columns (same number of variables as
+the model). Use :func:`miss` to mark unconstrained cells:
+
+::
+
+ // Start with all-missing matrix (nothing constrained)
+ path = miss(zeros(h, m), 0);
+
+ // Fix variable j at value v for all horizons
+ path[., j] = v * ones(h, 1);
+
+ // Fix variable j at specific path
+ path[., j] = v1|v2|v3|v4;
+
+ // Fix at specific horizons only
+ path[1:4, j] = v1|v2|v3|v4; // Fix first 4, free after
+
+**At least one variable must be unconstrained** at each horizon. Constraining
+all variables leaves no degrees of freedom for the model.
+
+**Credible bands** on free variables come from the posterior distribution of
+:math:`(B, \Sigma)`. With more posterior draws (*n_draws*), the bands are
+smoother but computation takes longer. Default of 1000 is typically sufficient.
+
+Model
+-----
+
+The conditional forecast solves: given that certain variables follow a prescribed
+path, what is the posterior predictive distribution of the remaining (free) variables?
+
+For a VAR with structural form :math:`\varepsilon_t = P^{-1} u_t` where
+:math:`u_t = y_t - B_1 y_{t-1} - \cdots - B_p y_{t-p} - c`, the Waggoner & Zha (1999)
+algorithm finds the structural shocks :math:`\varepsilon_{T+1}, \ldots, \varepsilon_{T+h}`
+that satisfy the constraints exactly while being drawn from the correct conditional
+distribution for the free variables.
+
+The constrained forecast at horizon :math:`s` is:
+
+.. math::
+
+ y_{T+s} = B_1 y_{T+s-1} + \cdots + B_p y_{T+s-p} + c + P \varepsilon_{T+s}
+
+where :math:`\varepsilon_{T+s}` is partitioned into constrained and free components,
+and the free components are drawn from their conditional posterior.
+
+Algorithm
+---------
+
+For each posterior draw :math:`(B^{(i)}, \Sigma^{(i)})`:
+
+1. Compute :math:`P = \text{chol}(\Sigma^{(i)})'`.
+2. Compute unconditional forecasts :math:`\tilde{y}_{T+1}, \ldots, \tilde{y}_{T+h}`.
+3. For each constrained horizon, solve for the structural shocks that enforce the constraint: :math:`y_{T+s}^{\text{constrained}} - \tilde{y}_{T+s} = R \varepsilon_{T+s}^*` where :math:`R` selects the constrained variables.
+4. Draw the free-variable shocks from :math:`N(0, I)`.
+5. Combine constrained and free shocks, propagate through the VAR.
+
+**Complexity:** :math:`O(n\_draws \cdot h \cdot m^3)`.
+
+Troubleshooting
+---------------
+
+**"All variables constrained" error:**
+At least one variable must be free at each horizon. The model needs degrees of
+freedom to satisfy the constraints. If you need to fix all variables, you don't
+need a forecast — you already know the answer.
+
+**Free variable bands are very wide:**
+This is expected when the constrained path is far from the unconditional forecast.
+The model is telling you the scenario requires large structural shocks, which
+create uncertainty in the free variables. Tighter priors help.
+
+**Constraints are not exactly satisfied in output:**
+Check for rounding in the print output. Internally, constraints are satisfied
+to machine precision. The printed table rounds for display.
+
+Verification
+------------
+
+Conditional forecasts verified against the ECB BEAR Toolbox conditional forecast
+module on the 3-variable ECB dataset with FFR path constraints. Free-variable
+forecasts agree within Monte Carlo noise.
+
+See the :ref:`var-verification` page.
+
+References
+----------
+
+- Waggoner, D.F. and T. Zha (1999). "Conditional forecasts in dynamic multivariate models." *Review of Economics and Statistics*, 81(4), 639-651.
+- Banbura, M., D. Giannone, and M. Lenza (2015). "Conditional forecasts and scenario analysis with vector autoregressions for large cross-sections." *International Journal of Forecasting*, 31(3), 739-756.
+
+Library
+-------
+timeseries
+
+Source
+------
+forecast.src
+
+.. seealso:: Functions :func:`bvarFit`, :func:`bvarSvFit`, :func:`bvarForecast`, :func:`bvarSvForecast`
diff --git a/docs/timeseries/cwtest.rst b/docs/timeseries/cwtest.rst
new file mode 100644
index 00000000..3bf8ee4f
--- /dev/null
+++ b/docs/timeseries/cwtest.rst
@@ -0,0 +1,81 @@
+cwTest
+======
+
+Purpose
+-------
+Clark-West test for comparing nested forecast models.
+
+Format
+------
+
+.. function:: t = cwTest(e_r, e_u, fc_r, fc_u)
+ t = cwTest(e_r, e_u, fc_r, fc_u, quiet=1)
+
+ :param e_r: forecast errors from the restricted (simpler) model.
+ :type e_r: Nx1 vector
+
+ :param e_u: forecast errors from the unrestricted (larger) model.
+ :type e_u: Nx1 vector
+
+ :param fc_r: point forecasts from the restricted model.
+ :type fc_r: Nx1 vector
+
+ :param fc_u: point forecasts from the unrestricted model.
+ :type fc_u: Nx1 vector
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :return t: An instance of a :class:`testResult` structure.
+ :rtype t: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ // Restricted: AR(1), Unrestricted: VAR(4)
+ t = cwTest(e_ar1, e_var4, fc_ar1, fc_var4);
+ print "CW statistic:" t.statistic;
+ print "p-value:" t.p_value;
+
+Remarks
+-------
+
+The standard Diebold-Mariano test is biased in favor of the restricted model
+when models are nested (Clark & West 2007). This test adjusts for the noise
+in the unrestricted model's parameter estimates.
+
+Model
+-----
+
+The Clark-West adjusted statistic adds a correction term for the noise in the
+unrestricted model's forecasts:
+
+.. math::
+
+ \tilde{d}_t = (e_{R,t})^2 - \left[(e_{U,t})^2 - (\hat{y}_{R,t} - \hat{y}_{U,t})^2\right]
+
+where :math:`e_R` and :math:`e_U` are forecast errors from the restricted and unrestricted
+models, and the squared difference in forecasts corrects for the bias. The test statistic
+is the t-statistic of :math:`\bar{\tilde{d}}` with HAC standard errors.
+
+
+References
+----------
+
+- Clark, T.E. and K.D. West (2007). "Approximately normal tests for equal predictive accuracy in nested models." *Journal of Econometrics*, 138(1), 291-311.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+scoring.src
+
+.. seealso:: Functions :func:`dmTest`, :func:`mcsTest`
diff --git a/docs/timeseries/density-forecast-evaluation.rst b/docs/timeseries/density-forecast-evaluation.rst
new file mode 100644
index 00000000..bdc8b860
--- /dev/null
+++ b/docs/timeseries/density-forecast-evaluation.rst
@@ -0,0 +1,87 @@
+Density Forecast Evaluation
+===========================
+
+This guide walks through a complete density forecast evaluation workflow:
+estimate multiple models, generate density forecasts, score them with
+proper scoring rules, and compare using statistical tests.
+
+.. contents:: On this page
+ :local:
+
+Quick Example
+-------------
+
+::
+
+ new;
+ library timeseries;
+
+ // Load data
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ // Estimate two competing models
+ r1 = bvarFit(y, p=2);
+ r2 = bvarFit(y, p=4);
+
+ // Generate density forecasts (h=4 quarters ahead)
+ fc1 = bvarForecast(r1, 4);
+ fc2 = bvarForecast(r2, 4);
+
+ // Score against actuals using CRPS
+ actual = y[rows(y)-3:rows(y), .]; // last 4 observations
+ crps1 = fcScore(fc1, actual, "crps");
+ crps2 = fcScore(fc2, actual, "crps");
+
+ print "CRPS (lower is better):";
+ print " VAR(2):" crps1;
+ print " VAR(4):" crps2;
+
+Step-by-Step Workflow
+---------------------
+
+**Step 1: Estimate competing models**
+
+Any combination of models that produce density forecasts:
+
+- ``bvarFit`` → conjugate BVAR (iid draws)
+- ``bvarSvFit`` → SV-BVAR (Gibbs draws)
+- ``arimaFit`` → ARIMA/ETS (ML + simulation)
+
+**Step 2: Generate density forecasts**
+
+Each model's forecast function returns draws from the predictive distribution:
+
+- ``bvarForecast`` → point + interval from conjugate posterior
+- ``bvarSvForecast`` → density with volatility propagation
+- ``arimaForecast`` → point + interval from ML
+
+**Step 3: Score with proper scoring rules**
+
+Use :func:`fcScore` with one of:
+
+- ``"crps"`` — Continuous Ranked Probability Score (lower is better)
+- ``"logscore"`` — Log Predictive Score (higher is better)
+- ``"energy"`` — Energy Score for multivariate forecasts (lower is better)
+
+**Step 4: Test for significant differences**
+
+- :func:`dmTest` — Diebold-Mariano test (pairwise comparison)
+- :func:`cwTest` — Clark-West test (nested model comparison)
+- :func:`mcsTest` — Model Confidence Set (select best subset from many models)
+
+**Step 5: Calibration diagnostics**
+
+- :func:`pitTest` — Probability Integral Transform test for calibration
+- :func:`pitHistogram` — Visual PIT histogram (should be uniform for well-calibrated forecasts)
+
+See Also
+--------
+
+- :func:`fcScore` — Scoring rule computation
+- :func:`dmTest` — Diebold-Mariano pairwise test
+- :func:`cwTest` — Clark-West nested model test
+- :func:`mcsTest` — Hansen-Lunde-Nason Model Confidence Set
+- :func:`pitTest` — PIT calibration test
+- :func:`pitHistogram` — PIT histogram plot
+- :doc:`getting-started` — Basic BVAR tutorial
diff --git a/docs/timeseries/dmtest.rst b/docs/timeseries/dmtest.rst
new file mode 100644
index 00000000..fb7780c8
--- /dev/null
+++ b/docs/timeseries/dmtest.rst
@@ -0,0 +1,95 @@
+dmTest
+======
+
+Purpose
+-------
+Diebold-Mariano test for equal predictive ability between two forecast models.
+
+Format
+------
+
+.. function:: t = dmTest(loss_a, loss_b)
+ t = dmTest(loss_a, loss_b, h=1, quiet=0)
+
+ :param loss_a: loss series for model A (e.g., squared forecast errors).
+ :type loss_a: Nx1 vector
+
+ :param loss_b: loss series for model B.
+ :type loss_b: Nx1 vector
+
+ :param h: Optional keyword, forecast horizon for HLN small-sample correction (Harvey, Leybourne & Newbold 1997). Default = 1 (no correction).
+ :type h: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return t: An instance of a :class:`testResult` structure containing statistic, p_value, p_value_one_sided, and n.
+ :rtype t: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ // Squared errors from two models
+ loss_a = e_arima .^ 2;
+ loss_b = e_bvar .^ 2;
+
+ t = dmTest(loss_a, loss_b);
+
+ print "DM statistic:" t.statistic;
+ print "p-value (two-sided):" t.p_value;
+ print "p-value (A better):" t.p_value_one_sided;
+
+ // With HLN correction for h=4 ahead
+ t = dmTest(loss_a, loss_b, h=4);
+
+Remarks
+-------
+
+Tests H0: models A and B have equal predictive ability. A negative statistic
+indicates model A is better. Uses HAC standard errors (Newey-West) to account
+for serial correlation in multi-step forecast errors.
+
+The HLN correction adjusts for small-sample bias when the forecast horizon
+*h* > 1.
+
+Model
+-----
+
+The DM test statistic is:
+
+.. math::
+
+ DM = \frac{\bar{d}}{\hat\sigma_d / \sqrt{T}}
+
+where :math:`d_t = L(e_{A,t}) - L(e_{B,t})` is the loss differential and :math:`\hat\sigma_d`
+is the HAC (Newey-West) standard error with bandwidth :math:`h-1` (forecast horizon).
+Under H0 of equal predictive ability, :math:`DM \sim N(0,1)`.
+
+The Harvey, Leybourne & Newbold (1997) correction adjusts for small-sample bias:
+
+.. math::
+
+ DM_{\text{HLN}} = DM \cdot \sqrt{\frac{T + 1 - 2h + h(h-1)/T}{T}}
+
+
+References
+----------
+
+- Diebold, F.X. and R.S. Mariano (1995). "Comparing predictive accuracy." *Journal of Business & Economic Statistics*, 13(3), 253-263.
+- Harvey, D., S. Leybourne, and P. Newbold (1997). "Testing the equality of prediction mean squared errors." *International Journal of Forecasting*, 13(2), 281-291.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+scoring.src
+
+.. seealso:: Functions :func:`cwTest`, :func:`mcsTest`, :func:`fcScore`
diff --git a/docs/timeseries/fcmetrics.rst b/docs/timeseries/fcmetrics.rst
new file mode 100644
index 00000000..6e0c52e5
--- /dev/null
+++ b/docs/timeseries/fcmetrics.rst
@@ -0,0 +1,99 @@
+fcMetrics
+=========
+
+Purpose
+-------
+Compute forecast accuracy metrics: RMSE, MASE, and sMAPE.
+
+Format
+------
+
+.. function:: { rmse_val, mase_val, smape_val } = fcMetrics(actual, predicted)
+ { rmse_val, mase_val, smape_val } = fcMetrics(actual, predicted, train=y_train, period=12)
+
+ :param actual: realized values.
+ :type actual: Nx1 vector
+
+ :param predicted: point forecasts.
+ :type predicted: Nx1 vector
+
+ :param train: Optional keyword, training data for MASE normalization. MASE is missing if not provided.
+ :type train: vector
+
+ :param period: Optional keyword, seasonality for MASE (seasonal naive baseline). Default = 1.
+ :type season: scalar
+
+ :return rmse_val: root mean squared error.
+ :rtype rmse_val: scalar
+
+ :return mase_val: mean absolute scaled error. Missing if *train* not provided.
+ :rtype mase_val: scalar
+
+ :return smape_val: symmetric mean absolute percentage error (0-200 scale).
+ :rtype smape_val: scalar
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ // Forecast accuracy
+ { rmse_val, mase_val, smape_val } = fcMetrics(actual, predicted,
+ train=y_train, period=12);
+
+ print "RMSE:" rmse_val;
+ print "MASE:" mase_val;
+ print "sMAPE:" smape_val;
+
+Without Training Data
++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ { rmse_val, mase_val, smape_val } = fcMetrics(actual, predicted);
+
+ print "RMSE:" rmse_val;
+ // mase_val is miss() — training data required
+
+Remarks
+-------
+
+- **RMSE:** scale-dependent, useful for comparing models on the same series.
+- **MASE:** scale-free, compares against a seasonal naive baseline. MASE < 1
+ means the forecast beats the naive. Requires training data.
+- **sMAPE:** percentage-based (0-200 scale), symmetric to over/under prediction.
+
+Model
+-----
+
+.. math::
+
+ \text{RMSE} &= \sqrt{\frac{1}{T} \sum_{t=1}^{T} (y_t - \hat{y}_t)^2} \\
+ \text{MASE} &= \frac{\frac{1}{T} \sum_{t=1}^{T} |y_t - \hat{y}_t|}{\frac{1}{T_{\text{train}} - s} \sum_{t=s+1}^{T_{\text{train}}} |y_t^{\text{train}} - y_{t-s}^{\text{train}}|} \\
+ \text{sMAPE} &= \frac{200}{T} \sum_{t=1}^{T} \frac{|y_t - \hat{y}_t|}{|y_t| + |\hat{y}_t|}
+
+MASE (Hyndman & Koehler 2006) is the recommended scale-free metric. MASE < 1 means
+the forecast is better than a seasonal naive baseline; MASE > 1 means worse.
+
+
+References
+----------
+
+- Hyndman, R.J. and A.B. Koehler (2006). "Another look at measures of forecast accuracy." *International Journal of Forecasting*, 22(4), 679-688.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+metrics.src
+
+.. seealso:: Functions :func:`fcScore`
diff --git a/docs/timeseries/fcscore.rst b/docs/timeseries/fcscore.rst
new file mode 100644
index 00000000..7e70a362
--- /dev/null
+++ b/docs/timeseries/fcscore.rst
@@ -0,0 +1,119 @@
+fcScore
+=======
+
+Purpose
+-------
+Compute forecast scoring rules for point and density forecasts.
+
+Format
+------
+
+.. function:: sc = fcScore(actual)
+ sc = fcScore(actual, predicted={}, train={}, period=1, quiet=0)
+
+ :param actual: realized values.
+ :type actual: hx1 or hxm matrix
+
+ :param predicted: Optional keyword, a :class:`forecastResult` struct or hxm matrix of point forecasts.
+ :type predicted: struct or matrix
+
+ :param train: Optional keyword, training data for MASE normalization.
+ :type train: Nx1 or Nxm matrix
+
+ :param period: Optional keyword, seasonality for MASE. Default = 1.
+ :type period: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :return sc: An instance of a :class:`scoreResult` structure containing RMSE, MASE, SMAPE, CRPS, LPS, energy score, PI coverage, and PI width.
+ :rtype sc: struct
+
+Examples
+--------
+
+Point Forecast Scores
++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4, quiet=1);
+ fc = varForecast(result, 12, quiet=1);
+
+ sc = fcScore(actual, fc, train=data);
+ print "RMSE:" sc.rmse;
+ print "MASE:" sc.mase;
+ print "sMAPE:" sc.smape;
+
+Density Forecast Scores
++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = bvarSvFit(data, quiet=1);
+
+ fctl = svForecastControlCreate();
+ fctl.mode = "simulate";
+ fctl.store_draws = 1;
+ dfc = bvarSvForecast(result, 12, fctl, quiet=1);
+
+ sc = fcScore(actual, draws=dfc.draws);
+ print "CRPS:" sc.crps;
+ print "LPS:" sc.lps;
+
+Remarks
+-------
+
+**Point scores** (RMSE, MASE, SMAPE) require point forecasts. **Density scores**
+(CRPS, LPS) require the raw draw matrix. **Interval scores** (PI coverage, PI
+width) require a :class:`forecastResult` with lower/upper bounds.
+
+MASE requires training data for the naive-forecast normalization. If *train*
+is not provided, *sc.mase* is missing.
+
+Model
+-----
+
+**Point scores:**
+
+.. math::
+
+ \text{RMSE} &= \sqrt{\frac{1}{T} \sum_{t=1}^{T} (y_t - \hat{y}_t)^2} \\
+ \text{MASE} &= \frac{\sum |y_t - \hat{y}_t|}{\frac{T}{T_{\text{train}} - s} \sum |y_{t}^{\text{train}} - y_{t-s}^{\text{train}}|}
+
+**Density scores:**
+
+.. math::
+
+ \text{CRPS} &= \frac{1}{T} \sum_{t=1}^{T} \left(\frac{1}{S} \sum_{s=1}^{S} |\hat{y}_t^{(s)} - y_t| - \frac{1}{2S^2} \sum_{s,s'} |\hat{y}_t^{(s)} - \hat{y}_t^{(s')}|\right) \\
+ \text{LPS} &= -\frac{1}{T} \sum_{t=1}^{T} \log \hat{f}_t(y_t)
+
+where CRPS (Continuous Ranked Probability Score) is a proper scoring rule for density
+forecasts and LPS (Log Predictive Score) is the negative log predictive likelihood
+evaluated at the realized value.
+
+References
+----------
+
+- Gneiting, T. and A.E. Raftery (2007). "Strictly proper scoring rules, prediction, and estimation." *Journal of the American Statistical Association*, 102(477), 359-378.
+- Hyndman, R.J. and A.B. Koehler (2006). "Another look at measures of forecast accuracy." *International Journal of Forecasting*, 22(4), 679-688.
+
+Library
+-------
+timeseries
+
+Source
+------
+scoring.src
+
+.. seealso:: Functions :func:`dmTest`, :func:`pitTest`, :func:`fcMetrics`
diff --git a/docs/timeseries/fevdcompute.rst b/docs/timeseries/fevdcompute.rst
new file mode 100644
index 00000000..39b3640e
--- /dev/null
+++ b/docs/timeseries/fevdcompute.rst
@@ -0,0 +1,172 @@
+fevdCompute
+===========
+
+Purpose
+-------
+Compute forecast error variance decomposition.
+
+Format
+------
+
+.. function:: fevd = fevdCompute(irf)
+ fevd = fevdCompute(result, n_ahead)
+
+ :param irf: an instance of an :class:`irfResult` structure from :func:`irfCompute`.
+ :type irf: struct
+
+ :param result: alternatively, a :class:`varResult` or :class:`bvarResult` structure (IRF is computed internally).
+ :type result: struct
+
+ :param n_ahead: number of horizons (required when passing *result*).
+ :type n_ahead: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return fevd: An instance of a :class:`fevdResult` structure containing:
+
+ .. include:: include/fevdresult.rst
+
+ :rtype fevd: struct
+
+Examples
+--------
+
+From Pre-Computed IRF
++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4);
+
+ irf = irfCompute(result, 20, quiet=1);
+
+ fevd = fevdCompute(irf);
+
+Direct from Estimation Result
++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4);
+
+ // Skip the explicit IRF step
+ fevd = fevdCompute(result, 20);
+
+Accessing Decomposition
++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4);
+ fevd = fevdCompute(result, 20, quiet=1);
+
+ // Fraction of GDP variance explained by each shock at h=20
+ print "GDP variance decomposition at h=20:";
+ print fevd.var_names';
+ print fevd.fevd[21, 1, .];
+
+ // Verify rows sum to 1
+ print "Sum:" sumc(fevd.fevd[21, 1, .]');
+
+ // Track how FFR's contribution to GDP evolves over horizons
+ print "FFR contribution to GDP over time:";
+ for h (0, 20, 1);
+ print h;; print " ";; print fevd.fevd[h+1, 1, 3];
+ endfor;
+
+Remarks
+-------
+
+**The FEVD partitions** the h-step-ahead forecast error variance of each
+variable into contributions from each orthogonal shock. At horizon h, row i
+of ``fevd.fevd[h+1, i, .]`` gives the fraction of variable i's forecast uncertainty
+attributable to each shock. Each row sums to 1.0.
+
+**At h=0 (impact),** the decomposition reflects the contemporaneous Cholesky
+structure: variable 1's variance is 100% from its own shock, other variables'
+variance includes contributions from earlier-ordered variables.
+
+**As h increases,** the decomposition typically converges to long-run shares
+that reflect the relative importance of each shock in driving each variable.
+
+**This function accepts either** a pre-computed :class:`irfResult` (if you
+already computed IRFs) or an estimation result (computes IRFs internally).
+Both produce identical results.
+
+Model
+-----
+
+The FEVD partitions the h-step forecast error variance of variable :math:`i` into
+contributions from each orthogonal shock :math:`j`:
+
+.. math::
+
+ \text{FEVD}_{i,j}(h) = \frac{\sum_{\ell=0}^{h-1} (\Theta_\ell[i,j])^2}{\sum_{\ell=0}^{h-1} \sum_{k=1}^{m} (\Theta_\ell[i,k])^2}
+
+where :math:`\Theta_\ell` is the structural IRF at horizon :math:`\ell`. Each row sums to 1.
+
+At :math:`h \to \infty`, the FEVD converges to the long-run variance shares.
+
+
+Algorithm
+---------
+
+1. Compute Cholesky IRF matrices :math:`\Theta_0, \ldots, \Theta_{h-1}` (from :func:`irfCompute` or internally).
+2. For each horizon, compute cumulative squared responses and normalize.
+
+**Complexity:** :math:`O(h \cdot m^2)` on top of the IRF computation.
+
+
+Troubleshooting
+---------------
+
+**FEVD shares don't change much across horizons:**
+The model has weak dynamic interactions — shocks are mostly absorbed within
+the first few periods. This is common in growth-rate data.
+
+**One shock dominates everything:**
+Check the variable ordering. With Cholesky identification, the first variable's
+shock can absorb variance that should be attributed to other shocks.
+Try :func:`girfCompute` or :func:`svarIdentify` for alternative decompositions.
+
+
+Verification
+------------
+
+FEVD verified against R ``vars::fevd()`` at :math:`10^{-6}` tolerance on a
+2-variable VAR(1), confirming row-sum-to-one property and individual shares
+at h=1 and h=10.
+
+
+
+References
+----------
+
+- Lutkepohl, H. (2005). *New Introduction to Multiple Time Series Analysis*. Springer. Section 2.3.3.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+fevd.src
+
+.. seealso:: Functions :func:`irfCompute`, :func:`hdCompute`, :func:`irfPlotData`
diff --git a/docs/timeseries/getting-started-arima.rst b/docs/timeseries/getting-started-arima.rst
new file mode 100644
index 00000000..df12cc2d
--- /dev/null
+++ b/docs/timeseries/getting-started-arima.rst
@@ -0,0 +1,268 @@
+.. _getting-started-arima:
+
+Getting Started: ARIMA
+======================
+
+This tutorial walks through univariate time series analysis: decompose a series,
+fit an ARIMA model, forecast, and evaluate. You will have results in under 30 seconds.
+
+The 30-Second Version
+---------------------
+
+If you just want working code, copy this:
+
+::
+
+ library timeseries;
+
+ // Load monthly airline passenger data
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline_passengers.csv");
+ y = loadd(fname, "passengers");
+
+ // Auto SARIMA — GAUSS picks the best model
+ result = arimaFit(y, period=12);
+
+ // Forecast 24 months ahead
+ fc = arimaForecast(result, 24);
+
+That's it. The rest of this page explains what each step does and why.
+
+Step 1: Load and Examine the Data
+---------------------------------
+
+::
+
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline_passengers.csv");
+ y = loadd(fname, "passengers");
+
+ print rows(y) "monthly observations";
+
+You should see::
+
+ 144 monthly observations
+
+This is the classic Box-Jenkins airline passenger dataset — monthly totals from
+1949 to 1960. It has two key features:
+
+- **Trend**: passenger numbers increase over time.
+- **Seasonality**: regular peaks every 12 months (summer travel).
+
+Both must be handled before fitting an ARIMA model.
+
+Step 2: Decompose the Series
+----------------------------
+
+STL (Seasonal-Trend decomposition using LOESS) separates the series into
+trend, seasonal, and remainder components:
+
+::
+
+ stl = stlDecompose(y, 12);
+
+ // Visualize the decomposition
+ plotStl(y, stl);
+
+ print "Seasonal pattern (first year):";
+ print stl.seasonal[1:12]';
+
+The seasonal component shows the repeating 12-month pattern. The trend component
+shows the long-run growth. The remainder is what's left — ideally stationary noise.
+
+**Why decompose?** Understanding the structure helps you choose the right model.
+Strong seasonality → use seasonal ARIMA. Strong trend → need differencing.
+
+Step 3: Automatic Model Selection
+----------------------------------
+
+Let GAUSS choose the best SARIMA model automatically:
+
+::
+
+ result = arimaFit(y, period=12);
+
+You should see::
+
+ ================================================================================
+ SARIMA(0,1,1)(0,1,1)[12]
+ Method: CSS-ML Observations: 144
+ ================================================================================
+ Log-Lik: -508.32 AICc: 1020.85
+ ================================================================================
+ Coef Std.Err. t-stat p-value
+ --------------------------------------------------------------------------------
+ MA(1) -0.4018 0.0896 -4.4841 0.000
+ SMA(1) -0.5569 0.0731 -7.6168 0.000
+ ================================================================================
+ Ljung-Box(12): 17.12 p = 0.145
+ ================================================================================
+
+**What this tells you:**
+
+- GAUSS selected SARIMA(0,1,1)(0,1,1)[12] — the classic "airline model."
+ This means: one regular MA term, one seasonal MA term, differencing at both
+ regular (d=1) and seasonal (D=1) levels. No AR terms needed.
+- **MA(1) = -0.40**: negative moving average coefficient, highly significant.
+- **SMA(1) = -0.56**: seasonal MA coefficient, also highly significant.
+- **Ljung-Box p = 0.145**: no significant residual autocorrelation (p > 0.05). The model adequately captures the serial dependence.
+- **AICc = 1020.85**: used internally for model comparison during auto-selection.
+
+**How auto-selection works:**
+
+1. Unit root tests (KPSS) determine the differencing order d
+2. Seasonal unit root test (OCSB) determines seasonal differencing D
+3. Stepwise search over (p, q) and (P, Q) minimizes AICc
+4. CSS (Conditional Sum of Squares) initialization followed by ML (maximum
+ likelihood) refinement via Kalman filter
+
+This implements the Hyndman-Khandakar (2008) algorithm — the same method
+behind R's ``auto.arima()``.
+
+.. note::
+
+ The auto-selected model may vary slightly depending on the data sample and
+ platform. The stepwise search can take different paths through the model
+ space. The airline dataset reliably selects SARIMA(0,1,1)(0,1,1)[12],
+ but other datasets may produce different results across runs if the AICc
+ values are close.
+
+Step 4: Forecast 24 Months
+--------------------------
+
+::
+
+ fc = arimaForecast(result, 24);
+
+You should see::
+
+ ================================================================================
+ Forecast: 24 steps ahead Level: 95%
+ ================================================================================
+ h Forecast Lower Upper
+ --------------------------------------------------------------------------------
+ 1 432.3 402.6 462.0
+ 2 410.2 376.1 444.3
+ 3 466.8 428.7 504.9
+ ⋮
+ 22 487.1 412.3 561.9
+ 23 510.4 432.8 588.0
+ 24 478.9 398.7 559.1
+
+**Reading the forecast table:**
+
+- **Forecast**: point prediction (conditional mean).
+- **Lower/Upper**: 95% prediction interval. These account for both parameter
+ uncertainty and future shock uncertainty.
+- **Bands widen over time**: longer-horizon forecasts are less certain.
+- **Seasonal pattern is visible**: the forecasts show the same 12-month cycle
+ as the training data.
+
+.. note::
+
+ ARIMA uses 95% prediction intervals by default (frequentist convention).
+ Bayesian VAR forecasts from :func:`bvarForecast` use 68% credible bands by
+ default (one posterior standard deviation). Both can be changed via the
+ *level* parameter.
+
+Step 5: Compare Models
+----------------------
+
+Try a different specification and compare:
+
+::
+
+ // Auto ARIMA (no seasonal component)
+ r_noseas = arimaFit(y);
+
+ // Fixed ARIMA(1,1,1) — simple AR + MA with differencing
+ r_simple = arimaFit(y, period=12, p=1, d=1, q=1);
+
+ print "Auto SARIMA AICc:" result.aicc;
+ print "Auto ARIMA AICc: " r_noseas.aicc;
+ print "ARIMA(1,1,1) AICc:" r_simple.aicc;
+
+Lower AICc is better. The seasonal model should win decisively — airline
+passenger data has strong seasonality that a non-seasonal model can't capture.
+
+Step 6: Evaluate Forecast Accuracy
+----------------------------------
+
+Split the data and measure out-of-sample performance:
+
+::
+
+ // Hold out last 24 months
+ y_train = y[1:120];
+ y_test = y[121:144];
+
+ // Fit on training data, forecast the holdout period
+ r_train = arimaFit(y_train, period=12);
+ fc_eval = arimaForecast(r_train, 24);
+
+ // Compute accuracy metrics
+ { rmse, mase, smape } = fcMetrics(y_test, fc_eval.forecasts);
+ print "RMSE:" rmse;
+ print "MASE:" mase;
+ print "sMAPE:" smape;
+
+- **RMSE**: root mean squared error (same units as the data).
+- **MASE**: mean absolute scaled error (< 1 means better than naive forecast).
+- **sMAPE**: symmetric mean absolute percentage error.
+
+Complete Script
+---------------
+
+Everything above, in one runnable file:
+
+::
+
+ new;
+ library timeseries;
+
+ // ---- Data ----
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline_passengers.csv");
+ y = loadd(fname, "passengers");
+
+ // ---- Decompose ----
+ stl = stlDecompose(y, 12);
+
+ // ---- Auto SARIMA ----
+ result = arimaFit(y, period=12);
+
+ // ---- Forecast ----
+ fc = arimaForecast(result, 24);
+
+ // ---- Evaluate ----
+ y_train = y[1:120];
+ y_test = y[121:144];
+ r_train = arimaFit(y_train, period=12, quiet=1);
+ fc_eval = arimaForecast(r_train, 24);
+ { rmse, mase, smape } = fcMetrics(y_test, fc_eval.forecasts);
+ print "";
+ print "=== Out-of-sample accuracy ===";
+ print "RMSE:" rmse;
+ print "MASE:" mase;
+ print "sMAPE:" smape;
+
+What's Next
+-----------
+
+You've decomposed a series, fit ARIMA, forecasted, and evaluated accuracy.
+Here's where to go next:
+
+.. list-table::
+ :widths: 30 70
+
+ * - **Exogenous regressors**
+ - Add external predictors with ``arimaFit(y, xreg=X)`` for ARIMAX models.
+ * - **Model diagnostics**
+ - Check residual autocorrelation and normality with :func:`arimaResults`.
+ * - **Multiple series**
+ - Switch to :func:`varFit` or :func:`bvarFit` for multivariate analysis. See the :ref:`getting-started` guide.
+ * - **Seasonal decomposition**
+ - Use :func:`stlDecompose` for trend extraction and deseasonalization.
+ * - **Forecast comparison**
+ - Compare ARIMA against alternatives with :func:`dmTest` (Diebold-Mariano test).
+ * - **Choosing the right model**
+ - See the :ref:`choosing-a-var-model` decision tree.
diff --git a/docs/timeseries/getting-started.rst b/docs/timeseries/getting-started.rst
new file mode 100644
index 00000000..efd3c99e
--- /dev/null
+++ b/docs/timeseries/getting-started.rst
@@ -0,0 +1,269 @@
+.. _getting-started:
+
+Getting Started
+===============
+
+This tutorial walks through a complete macroeconomic analysis: estimate a Bayesian
+VAR, compute impulse responses, forecast GDP, and evaluate the forecast — all in
+one script. You will have results in under a minute.
+
+The 30-Second Version
+---------------------
+
+If you just want working code, copy this:
+
+::
+
+ library timeseries;
+
+ // Load US macro data (GDP growth, CPI inflation, Fed Funds rate)
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Estimate Bayesian VAR(4)
+ result = bvarFit(data, p=4, ar=0, quiet=1);
+
+ // Impulse responses: what happens when the Fed raises rates?
+ rv = varFit(data, p=4);
+ irf = irfCompute(rv, 20);
+
+ // Forecast the next 8 quarters
+ fc = bvarForecast(result, 8);
+
+That's it. The rest of this page explains what each step does and why.
+
+Step 1: Load the Data
+---------------------
+
+::
+
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ print rows(data) "observations," cols(data) "variables";
+ print getcolnames(data)';
+
+You should see::
+
+ 200 observations, 4 variables
+ gdp_growth cpi_inflation fed_funds unemployment
+
+The dataset contains 200 quarters of US macroeconomic data:
+
+- **gdp_growth**: real GDP growth (annualized, %)
+- **cpi_inflation**: CPI inflation (annualized, %)
+- **fed_funds**: federal funds rate (%)
+- **unemployment**: unemployment rate (%)
+
+We'll use the first three variables — a classic monetary policy VAR.
+
+Step 2: Estimate a Bayesian VAR
+-------------------------------
+
+::
+
+ // Select variables
+ vars = "gdp_growth" $| "cpi_inflation" $| "fed_funds";
+
+ // Estimate BVAR(4) with white noise prior (data is in growth rates)
+ result = bvarFit(data[., vars], p=4, ar=0);
+
+You should see::
+
+ ================================================================================
+ BVAR(4) with Minnesota Prior Variables: 3
+ Draws: 5000 Observations: 200
+ Effective obs: 196
+ ================================================================================
+ Log ML: -657.84
+ ================================================================================
+
+ Equation 1: GDP
+ Mean SD 16% 84%
+ --------------------------------------------------------------------------------
+ GDP(-1) 0.7363 0.0663 0.6705 0.8012
+ CPI(-1) 0.1528 0.1124 0.0415 0.2645
+ FFR(-1) -0.0846 0.1179 -0.2027 0.0327
+ ⋮
+ GDP(-4) 0.0412 0.0598 -0.0181 0.1007
+ CPI(-4) -0.0233 0.1098 -0.1327 0.0865
+ FFR(-4) 0.0518 0.1143 -0.0622 0.1653
+ Constant 0.0015 0.0019 -0.0004 0.0034
+
+**What this tells you:**
+
+- GDP is persistent: its own first lag is 0.74 (strong positive effect).
+- CPI has a positive effect on GDP: higher inflation is associated with higher growth in the next quarter.
+- The FFR coefficient on GDP is -0.08 with wide credible interval [-0.20, 0.03] — a contractionary effect, but not precisely estimated.
+- The log marginal likelihood (-657.84) can be used to compare with other lag orders or priors.
+
+**Checkpoint:** If you see the coefficient table with named equations (GDP, CPI, FFR), you're on track. If you see "Y1, Y2, Y3" instead, pass a dataframe with column names for labeled output.
+
+Step 3: What Happens When the Fed Raises Rates?
+------------------------------------------------
+
+Impulse response functions trace the dynamic effect of a one-standard-deviation
+shock to one variable on all variables:
+
+::
+
+ // Estimate OLS VAR for IRF computation
+ rv = varFit(data[., vars], p=4, quiet=1);
+
+ // Compute Cholesky IRFs, 20 quarters ahead
+ irf = irfCompute(rv, 20);
+
+You should see a table like::
+
+ ================================================================================
+ Impulse Response Functions (cholesky)
+ Horizons: 0-20
+ ================================================================================
+
+ Shock to: GDP
+ h GDP CPI FFR
+ --------------------------------------------------------------------------------
+ 0 0.9765 0.0485 -0.0876
+ 1 0.7241 0.0848 0.0110
+ 2 0.6199 0.0838 0.0498
+ ⋮
+ 18 0.0412 0.0105 0.0153
+ 19 0.0318 0.0089 0.0128
+ 20 0.0247 0.0074 0.0107
+
+**Reading the IRF table:**
+
+- **Column = shock source.** "Shock to GDP" means an unexpected increase in GDP growth.
+- **Rows = response over time.** h=0 is the impact quarter, h=1 is one quarter later, etc.
+- **Each cell = response size.** A shock of 1 standard deviation to GDP raises CPI by 0.049 on impact.
+
+The variable ordering matters for Cholesky identification: GDP is ordered first
+(most exogenous — it takes time for policy to affect output), FFR last (the central
+bank can respond within the quarter). This is the standard monetary policy ordering.
+
+**Checkpoint:** The impact matrix (h=0) should be lower-triangular — zeros above the diagonal. If it's not, something went wrong.
+
+Step 4: Forecast GDP
+--------------------
+
+::
+
+ fc = bvarForecast(result, 8);
+
+You should see::
+
+ ================================================================================
+ Forecast: 8 steps ahead Level: 68%
+ ================================================================================
+ h GDP [Lower Upper] CPI [Lower Upper] FFR [Lower Upper]
+ --------------------------------------------------------------------------------
+ 1 1.483 [ 0.971 1.998 ] 2.397 [ 2.091 2.717 ] 4.133 [ 3.836 4.424 ]
+ 2 1.509 [ 0.980 2.033 ] 2.464 [ 2.133 2.776 ] 4.110 [ 3.810 4.404 ]
+ ⋮
+ 7 1.472 [ 0.812 2.134 ] 2.512 [ 2.014 3.009 ] 4.087 [ 3.541 4.632 ]
+ 8 1.468 [ 0.793 2.142 ] 2.524 [ 2.003 3.046 ] 4.081 [ 3.517 4.645 ]
+
+**Reading the forecast table:**
+
+- The point forecast is the **median** of the posterior predictive distribution.
+- The **68% bands** (default) show approximately :math:`\pm 1` standard deviation. For wider intervals, use ``level=0.90`` or ``level=0.95``.
+- **Bands widen over time** — forecasts become less certain at longer horizons. This is expected.
+
+The BVAR forecast accounts for both **parameter uncertainty** (we don't know the true coefficients) and **shock uncertainty** (future shocks are random). This makes BVAR bands wider and more honest than simple plug-in VAR forecast intervals.
+
+Step 5: Is the Model Any Good?
+------------------------------
+
+Compare lag orders using the log marginal likelihood — the Bayesian gold standard
+for model selection:
+
+::
+
+ r1 = bvarFit(data[., vars], ar=0, quiet=1);
+ r2 = bvarFit(data[., vars], p=2, ar=0, quiet=1);
+ r4 = bvarFit(data[., vars], p=4, ar=0, quiet=1);
+
+ print "Log ML(p=1):" r1.log_ml;
+ print "Log ML(p=2):" r2.log_ml;
+ print "Log ML(p=4):" r4.log_ml;
+
+ // Bayes factor: p=4 vs p=2
+ print "BF(4 vs 2):" exp(r4.log_ml - r2.log_ml);
+
+If the Bayes factor is above 3, there's "substantial evidence" in favor of p=4.
+Above 20 is "strong evidence." Below 1 means p=2 is better.
+
+Or let the data choose automatically:
+
+::
+
+ ho = bvarHyperopt(data[., vars]);
+ print "Optimal overall_tightness:" ho.overall_tightness;
+ result_opt = bvarFit(data[., vars], ctl=ho.ctl);
+
+This maximizes the marginal likelihood over the hyperparameters (Giannone, Lenza &
+Primiceri 2015), finding the best balance between prior shrinkage and data fit.
+
+Complete Script
+---------------
+
+Everything above, in one runnable file:
+
+::
+
+ new;
+ library timeseries;
+
+ // ---- Data ----
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ vars = "gdp_growth" $| "cpi_inflation" $| "fed_funds";
+
+ // ---- BVAR(4) with white noise prior ----
+ result = bvarFit(data[., vars], p=4, ar=0);
+
+ // ---- Impulse responses ----
+ rv = varFit(data[., vars], p=4, quiet=1);
+
+ irf = irfCompute(rv, 20);
+
+ // ---- Bayesian IRFs with posterior bands ----
+ // For SV-BVAR, use irfSvCompute for proper uncertainty bands:
+ // svIrf = irfSvCompute(svResult, 20);
+ // See :func:`irfSvCompute` for details.
+
+ // ---- Forecast ----
+ fc = bvarForecast(result, 8);
+
+ // ---- Model comparison ----
+ r2 = bvarFit(data[., vars], p=2, ar=0, quiet=1);
+
+ print "";
+ print "=== Model Comparison ===";
+ print "Log ML(p=2):" r2.log_ml;
+ print "Log ML(p=4):" result.log_ml;
+ print "BF(4 vs 2):" exp(result.log_ml - r2.log_ml);
+
+What's Next
+-----------
+
+You've estimated a BVAR, computed IRFs, generated forecasts, and compared models.
+Here's where to go next:
+
+.. list-table::
+ :widths: 30 70
+
+ * - **Time-varying volatility**
+ - Your data has heteroskedastic errors? Use :func:`bvarSvFit` for stochastic volatility.
+ * - **Structural shocks**
+ - Cholesky ordering too restrictive? Use :func:`svarIdentify` for sign restrictions.
+ * - **Conditional forecasts**
+ - "What if the Fed holds rates at 5%?" Use :func:`condForecast` for scenario analysis.
+ * - **Automatic hyperparameters**
+ - Unsure about overall_tightness? Use :func:`bvarHyperopt` to let the data decide.
+ * - **ARIMA / univariate**
+ - Single variable? Use :func:`arimaFit` with automatic order selection.
+ * - **Choosing the right model**
+ - Unsure which function to use? See the :ref:`choosing-a-var-model` decision tree.
diff --git a/docs/timeseries/girfcompute.rst b/docs/timeseries/girfcompute.rst
new file mode 100644
index 00000000..8184d31d
--- /dev/null
+++ b/docs/timeseries/girfcompute.rst
@@ -0,0 +1,143 @@
+girfCompute
+===========
+
+Purpose
+-------
+Compute generalized impulse response functions (Pesaran & Shin 1998).
+
+Format
+------
+
+.. function:: girf = girfCompute(result, n_ahead)
+
+ :param result: an instance of a :class:`varResult` or :class:`bvarResult` structure.
+ :type result: struct
+
+ :param n_ahead: number of horizons to compute.
+ :type n_ahead: scalar
+
+ :param var_names: Optional keyword, override variable names.
+ :type var_names: Mx1 string array
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return girf: An instance of an :class:`irfResult` structure with ``ident = "generalized"`` containing:
+
+ .. include:: include/irfresult.rst
+
+ :rtype girf: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4);
+
+ // Generalized IRF — invariant to variable ordering
+ girf = girfCompute(result, 20);
+
+Compare Cholesky and Generalized
++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4);
+
+ irf = irfCompute(result, 20, quiet=1);
+ girf = girfCompute(result, 20, quiet=1);
+
+ // For variable 1's own shock, Cholesky and GIRF are identical
+ print "Cholesky GDP→GDP h=5:" irf.irf[6, 1, 1];
+ print "GIRF GDP→GDP h=5:" girf.irf[6, 1, 1];
+
+ // For cross-variable responses, they differ
+ print "Cholesky FFR→GDP h=5:" irf.irf[6, 1, 3];
+ print "GIRF FFR→GDP h=5:" girf.irf[6, 1, 3];
+
+Remarks
+-------
+
+**Generalized IRFs** do not require a causal ordering and are invariant to the
+ordering of variables in the data. They measure the response to a shock of
+one standard deviation to variable j, integrating out the effects of other
+shocks using the historical error covariance.
+
+**Key difference from Cholesky IRF:** GIRF shocks are *not orthogonal*. The
+GIRF to a shock in variable j accounts for the typical contemporaneous
+correlation with other variables, rather than isolating a pure structural
+shock. This means GIRF variance decompositions do not sum to 1.
+
+**When to use GIRF vs Cholesky:**
+
+- Use **Cholesky** when you have a defensible recursive ordering (e.g.,
+ monetary policy VAR with slow/fast variable classification).
+- Use **GIRF** when no ordering is defensible, or as a robustness check
+ against ordering sensitivity.
+- Use **sign/zero restrictions** (SVAR) for theory-driven non-recursive
+ identification.
+
+Model
+-----
+
+The generalized IRF (Pesaran & Shin 1998) for a shock to variable :math:`j` is:
+
+.. math::
+
+ \text{GIRF}_j(h) = \frac{\Phi_h \Sigma e_j}{\sqrt{\Sigma_{jj}}}
+
+where :math:`\Phi_h = J F^h J'` is the reduced-form IRF, :math:`\Sigma` is the error
+covariance, and :math:`e_j` is the j-th unit vector. The denominator normalizes to a
+one-standard-deviation shock.
+
+Unlike Cholesky IRF, the GIRF accounts for the typical contemporaneous correlation
+structure rather than imposing orthogonality. The result is invariant to variable ordering.
+
+**Important caveat:** GIRF shocks are correlated, so the GIRF-based FEVD does not sum
+to 1. Use Cholesky (:func:`irfCompute`) or sign-restricted SVAR (:func:`svarIdentify`)
+for a proper variance decomposition.
+
+
+Algorithm
+---------
+
+1. Compute reduced-form IRF matrices :math:`\Phi_0, \ldots, \Phi_h` from the companion form.
+2. For each variable :math:`j`, scale by :math:`\Sigma e_j / \sqrt{\Sigma_{jj}}`.
+
+**Complexity:** Same as :func:`irfCompute`.
+
+
+Verification
+------------
+
+GIRF verified against the analytical relationship with Cholesky IRF: for the
+first variable, GIRF and Cholesky IRF are identical (both equal
+:math:`\Phi_h P e_1`). Tested on the R benchmark data.
+
+
+References
+----------
+
+- Pesaran, M.H. and Y. Shin (1998). "Generalized impulse response analysis in linear multivariate models." *Economics Letters*, 58(1), 17-29.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+irf.src
+
+.. seealso:: Functions :func:`irfCompute`, :func:`fevdCompute`, :func:`svarIdentify`
diff --git a/docs/timeseries/grangertest.rst b/docs/timeseries/grangertest.rst
new file mode 100644
index 00000000..b126737d
--- /dev/null
+++ b/docs/timeseries/grangertest.rst
@@ -0,0 +1,158 @@
+grangerTest
+===========
+
+Purpose
+-------
+Test whether one variable Granger-causes another in a fitted VAR model.
+
+Format
+------
+
+.. function:: g = grangerTest(result, cause, effect)
+
+ :param result: an instance of a :class:`varResult` structure from :func:`varFit`.
+ :type result: struct
+
+ :param cause: index (1 to m) of the potential cause variable.
+ :type cause: scalar
+
+ :param effect: index (1 to m) of the effect variable.
+ :type effect: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :return g: An instance of a :class:`grangerResult` structure containing:
+
+ .. list-table::
+ :widths: auto
+
+ * - g.f_stat
+ - Scalar, F-statistic.
+
+ * - g.p_value
+ - Scalar, p-value.
+
+ * - g.df1
+ - Scalar, numerator degrees of freedom (number of restricted lags = p).
+
+ * - g.df2
+ - Scalar, denominator degrees of freedom.
+
+ * - g.cause_name
+ - String, name of the cause variable.
+
+ * - g.effect_name
+ - String, name of the effect variable.
+
+ :rtype g: struct
+
+Examples
+--------
+
+Single Pair
++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4);
+
+ // Does FFR Granger-cause GDP?
+ g = grangerTest(result, 3, 1);
+
+ print g.cause_name "Granger-causes" g.effect_name "?";
+ print "F =" g.f_stat "p =" g.p_value;
+
+All Pairs
++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4);
+
+ for i (1, 3, 1);
+ for j (1, 3, 1);
+ if i /= j;
+ g = grangerTest(result, i, j, quiet=1);
+ print g.cause_name "->" g.effect_name ": p=" g.p_value;
+ endif;
+ endfor;
+ endfor;
+
+Remarks
+-------
+
+Tests H0: all p lags of the cause variable are jointly zero in the effect
+variable's equation. Uses an F-test with p numerator and (T - mp - 1)
+denominator degrees of freedom.
+
+**Granger causality is a predictive concept,** not a structural one. "X
+Granger-causes Y" means X contains information useful for forecasting Y
+beyond what Y's own lags provide. It does not imply X structurally causes Y.
+
+Model
+-----
+
+The Granger causality test (Granger 1969) tests the null hypothesis that all :math:`p`
+lags of the cause variable are jointly zero in the effect variable's equation:
+
+.. math::
+
+ H_0: B_{\text{cause},1} = B_{\text{cause},2} = \cdots = B_{\text{cause},p} = 0
+
+in the equation for the effect variable. The F-statistic is:
+
+.. math::
+
+ F = \frac{(\text{RSS}_r - \text{RSS}_u) / p}{\text{RSS}_u / (T - mp - 1)} \sim F(p, T - mp - 1)
+
+where :math:`\text{RSS}_r` and :math:`\text{RSS}_u` are residual sums of squares from
+the restricted and unrestricted regressions.
+
+
+Troubleshooting
+---------------
+
+**Significant Granger causality in both directions:**
+This is possible and common — it means both variables contain predictive information
+about each other. This does not imply feedback causation in a structural sense.
+
+**Result depends on lag order:**
+Granger causality tests are sensitive to p. Use :func:`varLagSelect` to choose p
+before testing.
+
+
+Verification
+------------
+
+Granger causality F-statistics and p-values verified against R ``vars::causality()``
+at :math:`10^{-6}` tolerance on a 2-variable VAR(1) with known DGP. Both directions
+tested (Y1→Y2 and Y2→Y1).
+
+
+References
+----------
+
+- Granger, C.W.J. (1969). "Investigating causal relations by econometric models and cross-spectral methods." *Econometrica*, 37(3), 424-438.
+- Lutkepohl, H. (2005). *New Introduction to Multiple Time Series Analysis*. Springer. Section 3.6.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+granger.src
+
+.. seealso:: Functions :func:`varFit`, :func:`varLagSelect`
diff --git a/docs/timeseries/hdcompute.rst b/docs/timeseries/hdcompute.rst
new file mode 100644
index 00000000..e389f843
--- /dev/null
+++ b/docs/timeseries/hdcompute.rst
@@ -0,0 +1,193 @@
+hdCompute
+=========
+
+Purpose
+-------
+Compute historical decomposition of observed series into structural shock contributions.
+
+Format
+------
+
+.. function:: hd = hdCompute(result)
+ hd = hdCompute(result, n_steps)
+
+ :param result: an instance of a :class:`varResult` or :class:`bvarResult` structure.
+ :type result: struct
+
+ :param n_steps: Optional, number of MA steps for the decomposition. Default = T-p (full sample).
+ :type n_steps: scalar
+
+ :param var_names: Optional keyword, override variable names.
+ :type var_names: Mx1 string array
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return hd: An instance of an :class:`hdResult` structure containing:
+
+ .. include:: include/hdresult.rst
+
+ :rtype hd: struct
+
+Examples
+--------
+
+Full Historical Decomposition
++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = varFit(data, 4);
+
+ hd = hdCompute(result);
+
+Shock Contributions to a Variable
+++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4);
+ hd = hdCompute(result, quiet=1);
+
+ // FFR shock (shock 3) contribution to GDP (variable 1) over time
+ ffr_to_gdp = hd.hd[3, ., 1];
+ print "FFR shock contribution to GDP:";
+ print ffr_to_gdp;
+
+ // CPI shock (shock 2) contribution to GDP
+ cpi_to_gdp = hd.hd[2, ., 1];
+
+Verify Decomposition Sums to Observed
+++++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4);
+ hd = hdCompute(result, quiet=1);
+
+ // Reconstruct GDP from shock contributions + initial conditions
+ gdp_reconstructed = hd.initial[., 1];
+ for j (1, hd.m, 1);
+ gdp_reconstructed = gdp_reconstructed + hd.hd[j, ., 1];
+ endfor;
+
+ // Compare with observed GDP (should match within numerical precision)
+ gdp_observed = result.y[result.p+1:rows(result.y), 1];
+ print "Max reconstruction error:" maxc(abs(gdp_reconstructed - gdp_observed));
+
+Extract Structural Shocks
++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4, quiet=1);
+ hd = hdCompute(result, quiet=1);
+
+ // Structural (orthogonalized) shocks
+ print "Structural shocks:";
+ print hd.shocks[1:5, .];
+
+Remarks
+-------
+
+**Historical decomposition** expresses each observed variable as the sum of
+contributions from each structural shock plus initial conditions:
+
+.. math::
+
+ y_t = \sum_{j=1}^{m} \text{contribution}_{j,t} + \text{initial}_t
+
+The contributions are computed by filtering the structural shocks through the
+MA(:math:`\infty`) representation (truncated at *n_steps*).
+
+**Structural shocks** are obtained by applying the Cholesky decomposition of
+:math:`\Sigma` to the reduced-form residuals: :math:`\varepsilon_t = P^{-1} u_t`
+where :math:`\Sigma = PP'`.
+
+**Interpretation:** ``hd.hd[j, t, i]`` answers the question: "How much of
+variable i's value at time t is attributable to the cumulative effect of
+shock j up to time t?"
+
+**For BVAR,** the decomposition is computed at the posterior mean of B and
+:math:`\Sigma`.
+
+Model
+-----
+
+The observed series is decomposed as:
+
+.. math::
+
+ y_t = \underbrace{\sum_{j=1}^{m} \sum_{s=p+1}^{t} \Theta_{t-s} P^{-1} \hat{u}_s}_{\text{cumulative shock contributions}} + \underbrace{y_t^{\text{init}}}_{\text{initial conditions}}
+
+where :math:`\Theta_h` is the structural IRF at horizon h, :math:`P = \text{chol}(\Sigma)'`,
+and :math:`\hat{u}_t` are the reduced-form residuals. The structural shocks are
+:math:`\hat\varepsilon_t = P^{-1} \hat{u}_t`.
+
+The contribution of shock :math:`j` to variable :math:`i` at time :math:`t` is:
+
+.. math::
+
+ \text{hd}_{j,t,i} = \sum_{s=p+1}^{t} \Theta_{t-s}[i,j] \cdot \hat\varepsilon_{j,s}
+
+
+Algorithm
+---------
+
+1. Compute structural shocks :math:`\hat\varepsilon_t = P^{-1} \hat{u}_t` for all :math:`t`.
+2. Compute IRF matrices :math:`\Theta_0, \ldots, \Theta_{T-p-1}`.
+3. For each time :math:`t`, accumulate shock contributions via MA convolution.
+4. Compute initial conditions as the residual: :math:`y_t^{\text{init}} = y_t - \sum_j \text{hd}_{j,t}`.
+
+**Complexity:** :math:`O(T^2 m^2)` — quadratic in sample size due to the convolution.
+
+
+Troubleshooting
+---------------
+
+**Reconstruction error is not zero:**
+The decomposition should reconstruct the observed series exactly (to machine precision).
+If the error exceeds :math:`10^{-10}`, there may be a mismatch between the estimation
+result and the data. Re-estimate the model.
+
+**One shock dominates the decomposition:**
+Same as FEVD — check the variable ordering and consider alternative identification.
+
+
+References
+----------
+
+- Lutkepohl, H. (2005). *New Introduction to Multiple Time Series Analysis*. Springer. Section 2.3.4.
+- Kilian, L. and H. Lutkepohl (2017). *Structural Vector Autoregressive Analysis*. Cambridge University Press.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+hd.src
+
+.. seealso:: Functions :func:`irfCompute`, :func:`fevdCompute`, :func:`varFit`, :func:`bvarFit`
diff --git a/docs/timeseries/include/arimacontrol.rst b/docs/timeseries/include/arimacontrol.rst
new file mode 100644
index 00000000..567c05ef
--- /dev/null
+++ b/docs/timeseries/include/arimacontrol.rst
@@ -0,0 +1,67 @@
+.. list-table::
+ :widths: auto
+
+ * - ctl.max_p
+ - Scalar, maximum AR order for auto-selection. Default = 5.
+
+ * - ctl.max_q
+ - Scalar, maximum MA order for auto-selection. Default = 5.
+
+ * - ctl.max_d
+ - Scalar, maximum differencing order. Default = 2.
+
+ * - ctl.max_sp
+ - Scalar, maximum seasonal AR order. Default = 2.
+
+ * - ctl.max_sq
+ - Scalar, maximum seasonal MA order. Default = 2.
+
+ * - ctl.max_sd
+ - Scalar, maximum seasonal differencing order. Default = 1.
+
+ * - ctl.max_order
+ - Scalar, maximum total order (p+q+P+Q). Default = 5.
+
+ * - ctl.ic
+ - String, information criterion for auto-selection.
+
+ =========== =======================================
+ ``"aicc"`` Corrected Akaike. (Default)
+ ``"aic"`` Akaike.
+ ``"bic"`` Bayesian (Schwarz).
+ =========== =======================================
+
+ * - ctl.stepwise
+ - Scalar, search strategy for auto-selection.
+
+ === ======================================================
+ 1 Stepwise search (faster, recommended). (Default)
+ 0 Exhaustive search (slower, guaranteed global optimum).
+ === ======================================================
+
+ * - ctl.method
+ - String, estimation method.
+
+ ============== ====================================================
+ ``"css-ml"`` CSS for starting values, then ML refinement. (Default)
+ ``"ml"`` Maximum likelihood only.
+ ============== ====================================================
+
+ * - ctl.include
+ - String, deterministic terms.
+
+ ============ ==================================================================
+ ``"auto"`` Automatic: mean if d=0, drift if d=1, none if d>=2. (Default)
+ ``"mean"`` Force include mean.
+ ``"drift"`` Force include drift.
+ ``"none"`` No deterministic term.
+ ============ ==================================================================
+
+ * - ctl.quiet
+ - Scalar, output control. Set to 1 to suppress printed output. Default = 0.
+
+ * - ctl.max_iter
+ - Scalar, maximum optimizer iterations. Default = 1000.
+
+ * - ctl.tol
+ - Scalar, convergence tolerance. Default = 1e-8.
diff --git a/docs/timeseries/include/arimaresult.rst b/docs/timeseries/include/arimaresult.rst
new file mode 100644
index 00000000..44dd812a
--- /dev/null
+++ b/docs/timeseries/include/arimaresult.rst
@@ -0,0 +1,86 @@
+.. list-table::
+ :widths: auto
+
+ * - result.order
+ - 3x1 vector, estimated or specified ARIMA order {p, d, q}.
+
+ * - result.sorder
+ - 3x1 vector, seasonal order {P, D, Q}. Empty matrix if non-seasonal.
+
+ * - result.period
+ - Scalar, seasonal period. 0 if non-seasonal.
+
+ * - result.include_mean
+ - Scalar, 1 if mean/drift was included, 0 otherwise.
+
+ * - result.coefs
+ - Kx1 vector, estimated coefficients in order: AR, MA, SAR, SMA, Mean/Drift, Xreg.
+
+ * - result.se
+ - Kx1 vector, standard errors.
+
+ * - result.tstat
+ - Kx1 vector, t-statistics.
+
+ * - result.pval
+ - Kx1 vector, two-sided p-values.
+
+ * - result.ci_lower
+ - Kx1 vector, lower 95% confidence bounds.
+
+ * - result.ci_upper
+ - Kx1 vector, upper 95% confidence bounds.
+
+ * - result.coef_names
+ - Kx1 string array, coefficient labels (e.g., ``"AR(1)"``, ``"MA(1)"``, ``"Mean"``).
+
+ * - result.sigma2
+ - Scalar, estimated innovation variance.
+
+ * - result.loglik
+ - Scalar, maximized log-likelihood.
+
+ * - result.aic
+ - Scalar, Akaike information criterion.
+
+ * - result.aicc
+ - Scalar, corrected Akaike information criterion.
+
+ * - result.bic
+ - Scalar, Bayesian information criterion (Schwarz).
+
+ * - result.residuals
+ - Nx1 vector, standardized residuals.
+
+ * - result.fitted
+ - Nx1 vector, in-sample fitted values.
+
+ * - result.n_obs
+ - Scalar, number of observations used in estimation.
+
+ * - result.converged
+ - Scalar, 1 if optimizer converged, 0 otherwise.
+
+ * - result.y
+ - Nx1 vector, original series (stored for use by :func:`arimaForecast`).
+
+ * - result.xreg
+ - NxM matrix, original exogenous regressors. Empty matrix if none.
+
+ * - result.ar_coefs
+ - Vector, expanded AR polynomial coefficients (used internally by :func:`arimaForecast`).
+
+ * - result.ma_coefs
+ - Vector, expanded MA polynomial coefficients (used internally by :func:`arimaForecast`).
+
+ * - result.xreg_coefs
+ - Mx1 vector, regression coefficients. Empty matrix if no regressors.
+
+ * - result.intercept
+ - Scalar, mean or drift value. Missing if none.
+
+ * - result.vcov
+ - KxK matrix, variance-covariance matrix of estimated coefficients.
+
+ * - result.lambda
+ - Scalar, Box-Cox lambda used for variance stabilization. Missing if no transform was applied. When present, :func:`arimaForecast` automatically back-transforms forecasts to the original scale.
diff --git a/docs/timeseries/include/bvarcontrol.rst b/docs/timeseries/include/bvarcontrol.rst
new file mode 100644
index 00000000..de5884ca
--- /dev/null
+++ b/docs/timeseries/include/bvarcontrol.rst
@@ -0,0 +1,60 @@
+.. list-table::
+ :widths: auto
+
+ * - ctl.p
+ - Scalar, lag order. Default = 1.
+
+ * - ctl.const
+ - Scalar, 1 to include a constant, 0 to exclude. Default = 1.
+
+ * - ctl.prior
+ - String, prior type.
+
+ ================= ==========================================================
+ ``"minnesota"`` Conjugate Normal-Inverse-Wishart Minnesota prior. (Default)
+ ``"flat"`` Diffuse prior with Gibbs sampling.
+ ================= ==========================================================
+
+ * - ctl.overall_tightness
+ - Scalar, overall tightness. Controls how much data vs prior matters. Smaller values = tighter prior. Default = 0.2.
+
+ * - ctl.cross_shrinkage
+ - Scalar, cross-variable shrinkage. Other variables' lags are shrunk by this factor relative to own lags. Default = 0.5.
+
+ * - ctl.lag_decay
+ - Scalar, lag decay. Higher lags are shrunk by :math:`\ell^{-\lambda_3}`. Default = 1.0.
+
+ * - ctl.constant_tightness
+ - Scalar, constant tightness. Default = 1e5 (effectively uninformative).
+
+ * - ctl.exogenous_tightness
+ - Scalar, exogenous variable tightness. Default = 1.0.
+
+ * - ctl.soc_tightness
+ - Scalar, sum-of-coefficients tightness (Doan, Litterman & Sims 1984). Set to 0 to disable. Typical range: 1-10. Default = 0 (disabled).
+
+ * - ctl.sur_tightness
+ - Scalar, single-unit-root tightness (Sims 1993). Set to 0 to disable. Typical range: 1-10. Default = 0 (disabled).
+
+ * - ctl.exogenous_scale
+ - Scalar, exogenous regressor prior tightness. Default = 1.0.
+
+ * - ctl.ar
+ - Scalar, AR(1) prior mean for own-lag coefficients.
+
+ ===== =====================================================
+ 1.0 Random walk prior (for levels data). (Default)
+ 0.0 White noise prior (for stationary/growth rate data).
+ ===== =====================================================
+
+ * - ctl.alpha0
+ - Scalar, Inverse-Wishart degrees of freedom. Default = 0, which uses m+2 (least informative proper prior).
+
+ * - ctl.n_draws
+ - Scalar, number of posterior draws. Default = 5000.
+
+ * - ctl.seed
+ - Scalar, random number generator seed for reproducibility. Default = 42.
+
+ * - ctl.quiet
+ - Scalar, set to 1 to suppress printed output. Default = 0.
diff --git a/docs/timeseries/include/bvarresult.rst b/docs/timeseries/include/bvarresult.rst
new file mode 100644
index 00000000..8904afbe
--- /dev/null
+++ b/docs/timeseries/include/bvarresult.rst
@@ -0,0 +1,83 @@
+.. list-table::
+ :widths: auto
+
+ * - result.m
+ - Scalar, number of endogenous variables.
+
+ * - result.p
+ - Scalar, lag order.
+
+ * - result.n_obs
+ - Scalar, effective number of observations (T - p).
+
+ * - result.n_total
+ - Scalar, total number of observations (T).
+
+ * - result.const
+ - Scalar, 1 if a constant was included.
+
+ * - result.var_names
+ - Mx1 string array, variable names.
+
+ * - result.prior_type
+ - String, ``"minnesota"`` or ``"flat"``.
+
+ * - result.b_mean
+ - Kxm matrix, posterior mean of B.
+
+ * - result.b_median
+ - Kxm matrix, posterior median of B.
+
+ * - result.b_sd
+ - Kxm matrix, posterior standard deviation of B.
+
+ * - result.b_lower
+ - Kxm matrix, 16th percentile of posterior (lower 68% credible band).
+
+ * - result.b_upper
+ - Kxm matrix, 84th percentile of posterior (upper 68% credible band).
+
+ * - result.sigma_mean
+ - mxm matrix, posterior mean of the error covariance :math:`\Sigma`.
+
+ * - result.log_ml
+ - Scalar, log marginal likelihood. Only available for conjugate Minnesota prior; missing otherwise.
+
+ * - result.aic
+ - Scalar, Akaike information criterion (evaluated at posterior mean).
+
+ * - result.bic
+ - Scalar, Bayesian information criterion.
+
+ * - result.hq
+ - Scalar, Hannan-Quinn information criterion.
+
+ * - result.companion_mean
+ - (mp)x(mp) matrix, companion matrix at posterior mean.
+
+ * - result.is_stationary
+ - Scalar, 1 if stationary at posterior mean.
+
+ * - result.max_eigenvalue
+ - Scalar, largest eigenvalue modulus at posterior mean.
+
+ * - result.residuals
+ - (T-p)xm matrix, residuals at posterior mean.
+
+ * - result.b_draws
+ - (n_draws*K)xm matrix, stacked raw posterior draws of B. Draw d is rows [(d-1)*K+1 : d*K, .].
+
+ * - result.sigma_draws
+ - (n_draws*m)xm matrix, stacked raw posterior draws of :math:`\Sigma`. Draw d is rows [(d-1)*m+1 : d*m, .].
+
+ * - result.y
+ - Txm matrix, original data.
+
+ * - result.xreg
+ - TxK matrix, exogenous regressors. Empty matrix if none.
+
+ * - result.n_draws
+ - Scalar, number of retained draws.
+
+ * - result.seed
+ - Scalar, RNG seed used.
diff --git a/docs/timeseries/include/bvarsvcontrol.rst b/docs/timeseries/include/bvarsvcontrol.rst
new file mode 100644
index 00000000..4a4cd4a6
--- /dev/null
+++ b/docs/timeseries/include/bvarsvcontrol.rst
@@ -0,0 +1,116 @@
+.. list-table::
+ :widths: auto
+
+ * - ctl.p
+ - Scalar, lag order. Default = 1.
+
+ * - ctl.const
+ - Scalar, 1 to include a constant, 0 to exclude. Default = 1.
+
+ * - ctl.b_prior
+ - String, prior type for B coefficients.
+
+ ================= ================================================
+ ``"minnesota"`` Minnesota prior with lambda hyperparameters. (Default)
+ ``"flat"`` Diffuse prior with variance *ctl.b_prior_var*.
+ ``"horseshoe"`` Horseshoe prior (Carvalho, Polson & Scott 2010) for adaptive shrinkage. Each coefficient gets a local shrinkage λ²_ij and a global τ² with half-Cauchy priors. Replaces Minnesota/SSVS for large systems (m=50+). Reuses *ctl.b_prior_var* as initial τ².
+ ================= ================================================
+
+ * - ctl.overall_tightness
+ - Scalar, overall tightness (Minnesota only). Default = 0.2.
+
+ * - ctl.cross_shrinkage
+ - Scalar, cross-variable shrinkage (Minnesota only). Default = 0.5.
+
+ * - ctl.lag_decay
+ - Scalar, lag decay (Minnesota only). Default = 1.0.
+
+ * - ctl.constant_tightness
+ - Scalar, constant tightness (Minnesota only). Default = 1e5.
+
+ * - ctl.exogenous_tightness
+ - Scalar, exogenous tightness (Minnesota only). Default = 1.0.
+
+ * - ctl.soc_tightness
+ - Scalar, sum-of-coefficients (Minnesota only). 0 = disabled. Default = 0.
+
+ * - ctl.sur_tightness
+ - Scalar, single-unit-root (Minnesota only). 0 = disabled. Default = 0.
+
+ * - ctl.exogenous_scale
+ - Scalar, exogenous regressor tightness (Minnesota only). Default = 1.0.
+
+ * - ctl.ar
+ - Scalar, AR(1) prior mean for own lags (Minnesota only). 1.0 = random walk, 0.0 = white noise. Default = 1.0.
+
+ * - ctl.b_prior_var
+ - Scalar, B prior variance (flat prior only). Default = 10.0.
+
+ * - ctl.sv_mu
+ - Scalar, SV level prior mean. Default = 0.0.
+
+ * - ctl.sv_phi_mean
+ - Scalar, SV persistence prior mean. Default = 0.97.
+
+ * - ctl.sv_phi_std
+ - Scalar, SV persistence prior standard deviation. Default = 0.1.
+
+ * - ctl.sv_sigma2
+ - Scalar, SV innovation variance scale. Default = 0.01.
+
+ * - ctl.ssvs
+ - Scalar, enable SSVS variable selection. 0 = off (default), 1 = on.
+
+ * - ctl.ssvs_c0
+ - Scalar, SSVS spike multiplier. Default = 0.1.
+
+ * - ctl.ssvs_c1
+ - Scalar, SSVS slab multiplier. Default = 10.0.
+
+ * - ctl.ssvs_pi_b
+ - Scalar, prior inclusion probability for B. Default = 0.5.
+
+ * - ctl.ssvs_pi_u
+ - Scalar, prior inclusion probability for U off-diagonals. Default = 0.5.
+
+ * - ctl.ssvs_hierarchical
+ - Scalar, 1 for hierarchical prior on inclusion probability, 0 for fixed. Default = 0.
+
+ * - ctl.n_draws
+ - Scalar, number of posterior draws. Default = 5000.
+
+ * - ctl.n_burn
+ - Scalar, burn-in draws. Default = 5000.
+
+ * - ctl.n_thin
+ - Scalar, thinning interval. Default = 1.
+
+ * - ctl.seed
+ - Scalar, RNG seed. Default = 42.
+
+ * - ctl.n_chains
+ - Scalar, number of MCMC chains. Default = 1.
+
+ * - ctl.parallel
+ - Scalar, 1 for parallel chains, 0 for sequential. Default = 0.
+
+ * - ctl.use_asis
+ - Scalar, 1 to enable ASIS interweaving for SV (Kastner & Fruhwirth-Schnatter 2014). Default = 1.
+
+ * - ctl.sv_keep
+ - String, storage mode for stochastic volatility draws.
+
+ ============= ==================================================================
+ ``"full"`` Store all draws (default). Requires most memory.
+ ``"last"`` Store only the last draw of log-volatilities per iteration.
+ ``"online"`` Store running moments and a reservoir. Best for large systems.
+ ============= ==================================================================
+
+ * - ctl.reservoir_size
+ - Scalar, reservoir size for ``sv_keep = "online"``. Default = 500.
+
+ * - ctl.u_bandwidth
+ - Scalar, band-limited Cholesky U estimation. 0 = full lower-triangular U (default, m(m-1)/2 parameters). k > 0 = only first k off-diagonals per column estimated, rest fixed at zero. Reduces parameters from m(m-1)/2 to m*k. For m=50, k=3: 150 vs 1225 parameters. **Note:** this changes the model (approximation), not just computation.
+
+ * - ctl.quiet
+ - Scalar, set to 1 to suppress printed output. Default = 0.
diff --git a/docs/timeseries/include/bvarsvresult.rst b/docs/timeseries/include/bvarsvresult.rst
new file mode 100644
index 00000000..e42b7363
--- /dev/null
+++ b/docs/timeseries/include/bvarsvresult.rst
@@ -0,0 +1,77 @@
+.. list-table::
+ :widths: auto
+
+ * - result.m
+ - Scalar, number of endogenous variables.
+
+ * - result.p
+ - Scalar, lag order.
+
+ * - result.n_obs
+ - Scalar, effective number of observations (T - p).
+
+ * - result.n_total
+ - Scalar, total number of observations (T).
+
+ * - result.const
+ - Scalar, 1 if a constant was included.
+
+ * - result.var_names
+ - Mx1 string array, variable names.
+
+ * - result.b_prior_type
+ - String, ``"minnesota"`` or ``"flat"``.
+
+ * - result.has_ssvs
+ - Scalar, 1 if SSVS was active.
+
+ * - result.b_mean
+ - Kxm matrix, posterior mean of B.
+
+ * - result.b_sd
+ - Kxm matrix, posterior standard deviation of B.
+
+ * - result.b_lower
+ - Kxm matrix, 16th percentile (lower 68% credible band).
+
+ * - result.b_upper
+ - Kxm matrix, 84th percentile (upper 68% credible band).
+
+ * - result.sv_mu
+ - mx1 vector, posterior mean of SV level parameter per equation.
+
+ * - result.sv_phi
+ - mx1 vector, posterior mean of SV persistence per equation.
+
+ * - result.sv_sigma2
+ - mx1 vector, posterior mean of SV innovation variance per equation.
+
+ * - result.sv_mu_sd
+ - mx1 vector, posterior standard deviation of SV level.
+
+ * - result.sv_phi_sd
+ - mx1 vector, posterior standard deviation of SV persistence.
+
+ * - result.sv_sigma2_sd
+ - mx1 vector, posterior standard deviation of SV innovation variance.
+
+ * - result.pip_b
+ - Kxm matrix, posterior inclusion probabilities for B coefficients (SSVS only).
+
+ * - result.pip_u
+ - (m*(m-1)/2)x1 vector, posterior inclusion probabilities for U off-diagonals (SSVS only).
+
+ * - result.phi_accept_rate
+ - mx1 vector, Metropolis-Hastings acceptance rates for SV persistence. Values between 0.2 and 0.6 indicate good mixing.
+
+ * - result.y
+ - Txm matrix, original data.
+
+ * - result.xreg
+ - TxK matrix, exogenous regressors. Empty matrix if none.
+
+ * - result.n_draws
+ - Scalar, number of retained draws.
+
+ * - result.seed
+ - Scalar, RNG seed used.
diff --git a/docs/timeseries/include/condforecastresult.rst b/docs/timeseries/include/condforecastresult.rst
new file mode 100644
index 00000000..6789ad7a
--- /dev/null
+++ b/docs/timeseries/include/condforecastresult.rst
@@ -0,0 +1,29 @@
+.. list-table::
+ :widths: auto
+
+ * - cfc.median
+ - hxm matrix, median conditional forecast.
+
+ * - cfc.lower
+ - hxm matrix, lower credible bound.
+
+ * - cfc.upper
+ - hxm matrix, upper credible bound.
+
+ * - cfc.level
+ - Scalar, credible level used.
+
+ * - cfc.h
+ - Scalar, forecast horizon.
+
+ * - cfc.m
+ - Scalar, number of variables.
+
+ * - cfc.n_draws
+ - Scalar, number of posterior draws used.
+
+ * - cfc.constraint_path
+ - hxm matrix, the constraint path as provided. Missing values indicate unconstrained cells; finite values are the imposed constraints.
+
+ * - cfc.var_names
+ - Mx1 string array, variable names.
diff --git a/docs/timeseries/include/densityforecastresult.rst b/docs/timeseries/include/densityforecastresult.rst
new file mode 100644
index 00000000..0547bd8c
--- /dev/null
+++ b/docs/timeseries/include/densityforecastresult.rst
@@ -0,0 +1,41 @@
+.. list-table::
+ :widths: auto
+
+ * - dfc.fc_mean
+ - hxm matrix, mean forecast across posterior draws.
+
+ * - dfc.fc_median
+ - hxm matrix, median forecast across posterior draws.
+
+ * - dfc.bands
+ - Array of :class:`credibleBand` structures. Access via ``dfc.bands[i].level``, ``dfc.bands[i].lower``, ``dfc.bands[i].upper``.
+
+ * - dfc.quantile_bands
+ - Array of hxm matrices, one per quantile level. Access the i-th quantile band as ``dfc.quantile_bands[i]``.
+
+ * - dfc.quantile_levels
+ - n_quantiles x 1 vector, quantile levels corresponding to each band (e.g., 0.05, 0.16, 0.50, 0.84, 0.95).
+
+ * - dfc.log_vol_mean
+ - hxm matrix, mean forecast log-volatility per equation.
+
+ * - dfc.log_vol_median
+ - hxm matrix, median forecast log-volatility per equation.
+
+ * - dfc.h
+ - Scalar, forecast horizon.
+
+ * - dfc.m
+ - Scalar, number of variables.
+
+ * - dfc.n_draws
+ - Scalar, effective number of posterior draws used.
+
+ * - dfc.mode
+ - String, forecast mode used: ``"mean_path"`` or ``"simulate"``.
+
+ * - dfc.var_names
+ - Mx1 string array, variable names.
+
+ * - dfc.draws
+ - (n_draws)x(h*m) matrix, raw forecast draws. Empty matrix unless ``ctl.store_draws = 1``. Row layout: each row is one draw, columns ordered as h1_v1, h1_v2, ..., h1_vm, h2_v1, ...
diff --git a/docs/timeseries/include/diagresult.rst b/docs/timeseries/include/diagresult.rst
new file mode 100644
index 00000000..d1c904de
--- /dev/null
+++ b/docs/timeseries/include/diagresult.rst
@@ -0,0 +1,62 @@
+.. list-table::
+ :widths: auto
+
+ * - diag.converged
+ - Scalar, 1 if all convergence checks pass, 0 if any warnings.
+
+ * - diag.max_rhat
+ - Scalar, worst (highest) split-R-hat across all parameters.
+
+ * - diag.min_bulk_ess
+ - Scalar, worst (lowest) bulk effective sample size.
+
+ * - diag.min_tail_ess
+ - Scalar, worst (lowest) tail effective sample size.
+
+ * - diag.b_rhat
+ - Kxm matrix, split-R-hat for each B coefficient.
+
+ * - diag.b_bulk_ess
+ - Kxm matrix, bulk ESS for each B coefficient.
+
+ * - diag.b_tail_ess
+ - Kxm matrix, tail ESS for each B coefficient.
+
+ * - diag.sv_mu_rhat
+ - mx1 vector, R-hat for SV level parameters (SV-BVAR only).
+
+ * - diag.sv_phi_rhat
+ - mx1 vector, R-hat for SV persistence parameters (SV-BVAR only).
+
+ * - diag.sv_sigma2_rhat
+ - mx1 vector, R-hat for SV innovation variance (SV-BVAR only).
+
+ * - diag.phi_accept_rate
+ - mx1 vector, Metropolis-Hastings acceptance rates for SV phi (SV-BVAR only). Values between 0.2 and 0.6 indicate good mixing.
+
+ * - diag.b_geweke
+ - Kxm matrix, Geweke z-statistics (single-chain only). Values outside [-2, 2] suggest non-stationarity.
+
+ * - diag.ssvs_pip
+ - Kxm matrix, posterior inclusion probabilities (SSVS only). Empty if SSVS inactive.
+
+ * - diag.ssvs_switch_rate
+ - Kxm matrix, indicator switching rates (SSVS only). Rate of 0 means the indicator never switched.
+
+ * - diag.warnings
+ - String array, human-readable warning messages with parameter names and corrective suggestions.
+
+ * - diag.n_warnings
+ - Scalar, number of warnings.
+
+ * - diag.n_draws
+ - Scalar, number of posterior draws.
+
+ * - diag.n_chains
+ - Scalar, number of chains (1 for single-chain).
+
+ * - diag.m
+ - Scalar, number of variables.
+
+ * - diag.var_names
+ - Mx1 string array, variable names.
diff --git a/docs/timeseries/include/fevdresult.rst b/docs/timeseries/include/fevdresult.rst
new file mode 100644
index 00000000..2f6b3d41
--- /dev/null
+++ b/docs/timeseries/include/fevdresult.rst
@@ -0,0 +1,14 @@
+.. list-table::
+ :widths: auto
+
+ * - fevd.fevd
+ - Array of (n_ahead+1) mxm matrices. ``fevd.fevd[h+1][i, j]`` is the fraction of variable i's forecast error variance at horizon h explained by shock j. Each row sums to 1.0.
+
+ * - fevd.n_ahead
+ - Scalar, number of horizons computed.
+
+ * - fevd.m
+ - Scalar, number of variables.
+
+ * - fevd.var_names
+ - Mx1 string array, variable names.
diff --git a/docs/timeseries/include/forecastresult.rst b/docs/timeseries/include/forecastresult.rst
new file mode 100644
index 00000000..b09f621e
--- /dev/null
+++ b/docs/timeseries/include/forecastresult.rst
@@ -0,0 +1,26 @@
+.. list-table::
+ :widths: auto
+
+ * - fc.forecasts
+ - hxm matrix, point forecasts. hx1 for univariate (ARIMA), hxm for multivariate (VAR/BVAR).
+
+ * - fc.se
+ - hxm matrix, forecast standard errors.
+
+ * - fc.lower
+ - hxm matrix, lower confidence or credible bound.
+
+ * - fc.upper
+ - hxm matrix, upper confidence or credible bound.
+
+ * - fc.level
+ - Scalar, confidence or credible level used (e.g., 0.95).
+
+ * - fc.h
+ - Scalar, forecast horizon.
+
+ * - fc.m
+ - Scalar, number of variables (1 for ARIMA).
+
+ * - fc.var_names
+ - Mx1 string array, variable names. Empty for univariate models.
diff --git a/docs/timeseries/include/hdresult.rst b/docs/timeseries/include/hdresult.rst
new file mode 100644
index 00000000..98dcdb09
--- /dev/null
+++ b/docs/timeseries/include/hdresult.rst
@@ -0,0 +1,20 @@
+.. list-table::
+ :widths: auto
+
+ * - hd.hd
+ - Array of m (T-p)xm matrices. ``hd.hd[j]`` is the contribution of shock j to all variables over time. Column i of ``hd.hd[j]`` is the time series of shock j's contribution to variable i.
+
+ * - hd.shocks
+ - (T-p)xm matrix, structural (Cholesky-rotated) shocks.
+
+ * - hd.initial
+ - (T-p)xm matrix, contribution of initial conditions to each variable.
+
+ * - hd.t_eff
+ - Scalar, effective number of observations (T-p).
+
+ * - hd.m
+ - Scalar, number of variables.
+
+ * - hd.var_names
+ - Mx1 string array, variable names.
diff --git a/docs/timeseries/include/irfresult.rst b/docs/timeseries/include/irfresult.rst
new file mode 100644
index 00000000..c2dc429c
--- /dev/null
+++ b/docs/timeseries/include/irfresult.rst
@@ -0,0 +1,17 @@
+.. list-table::
+ :widths: auto
+
+ * - irf.irf
+ - Array of (n_ahead+1) mxm matrices. ``irf.irf[h+1]`` is the mxm impulse response matrix at horizon h. Element [i, j] is the response of variable i to a one-standard-deviation shock to variable j. Index 1 is the impact response (h=0).
+
+ * - irf.n_ahead
+ - Scalar, number of horizons computed.
+
+ * - irf.m
+ - Scalar, number of variables.
+
+ * - irf.var_names
+ - Mx1 string array, variable names.
+
+ * - irf.ident
+ - String, identification method: ``"cholesky"`` or ``"generalized"``.
diff --git a/docs/timeseries/include/longrunsvarcontrol.rst b/docs/timeseries/include/longrunsvarcontrol.rst
new file mode 100644
index 00000000..fe57accb
--- /dev/null
+++ b/docs/timeseries/include/longrunsvarcontrol.rst
@@ -0,0 +1,11 @@
+.. list-table::
+ :widths: auto
+
+ * - adv.const
+ - Scalar, 1 to include a constant (intercept), 0 to exclude. Default = 1.
+
+ * - adv.xreg
+ - TxK matrix, exogenous regressors. Default = empty (no exogenous variables).
+
+ * - adv.quiet
+ - Scalar, set to 1 to suppress printed output. Default = 0.
diff --git a/docs/timeseries/include/longrunsvarresult.rst b/docs/timeseries/include/longrunsvarresult.rst
new file mode 100644
index 00000000..0150f406
--- /dev/null
+++ b/docs/timeseries/include/longrunsvarresult.rst
@@ -0,0 +1,20 @@
+.. list-table::
+ :widths: auto
+
+ * - lr.impact
+ - mxm matrix, structural impact matrix :math:`B_0`. Column j gives the contemporaneous effect of structural shock j on all variables.
+
+ * - lr.irf
+ - An instance of an :class:`irfResult` structure containing orthogonalized impulse responses identified via long-run restrictions. See :func:`irfCompute` for the :class:`irfResult` layout.
+
+ * - lr.m
+ - Scalar, number of endogenous variables.
+
+ * - lr.p
+ - Scalar, lag order.
+
+ * - lr.n_ahead
+ - Scalar, number of forecast horizons.
+
+ * - lr.var_names
+ - Mx1 string array, variable names.
diff --git a/docs/timeseries/include/svarcontrol.rst b/docs/timeseries/include/svarcontrol.rst
new file mode 100644
index 00000000..7c49872d
--- /dev/null
+++ b/docs/timeseries/include/svarcontrol.rst
@@ -0,0 +1,39 @@
+.. list-table::
+ :widths: auto
+
+ * - adv.zero_restr
+ - Nx3 matrix, zero restrictions on impulse responses. Each row specifies one restriction with columns:
+
+ === ==================================================================
+ 1 Variable index (1 to m) -- the responding variable.
+ 2 Shock index (1 to m) -- the structural shock.
+ 3 Horizon (0 = impact, 1 = one step ahead, etc.).
+ === ==================================================================
+
+ Zero restrictions are satisfied **exactly** by construction using the ARW2018 null-space algorithm. When ``zero_restr`` is non-empty, the algorithm is automatically set to ARW2018. Default = ``{}`` (no zero restrictions).
+
+ * - adv.narrative_restr
+ - Nx6 matrix, narrative restrictions on the historical decomposition. Each row specifies one restriction with columns:
+
+ === ==================================================================
+ 1 Type: 1 = shock_sign, 2 = shock_dominance, 3 = decomposition_sign.
+ 2 Variable index (1 to m).
+ 3 Shock index (1 to m).
+ 4 Date 1: observation index (1-indexed), or start of range.
+ 5 Date 2: end observation (0 if unused).
+ 6 Sign: 1 for positive, -1 for negative.
+ === ==================================================================
+
+ When ``narrative_restr`` is non-empty, the v3 narrative engine is used automatically. Default = ``{}`` (no narrative restrictions).
+
+ * - adv.algorithm
+ - Scalar, algorithm selection. Default = 0 (auto-detect).
+
+ === ==================================================================
+ 0 Auto: uses RRW2010 for pure sign, ARW2018 if ``zero_restr`` is non-empty, v3 narrative engine if ``narrative_restr`` is non-empty.
+ 1 Accept-reject (RRW2010). Efficient for pure sign restrictions. Cannot handle zero restrictions.
+ 2 ARW2018 null-space construction. Required for zero restrictions. Also works for pure sign restrictions.
+ === ==================================================================
+
+ * - adv.quiet
+ - Scalar, set to 1 to suppress printed output. Default = 0.
diff --git a/docs/timeseries/include/svarposteriorresult.rst b/docs/timeseries/include/svarposteriorresult.rst
new file mode 100644
index 00000000..77bc2ad1
--- /dev/null
+++ b/docs/timeseries/include/svarposteriorresult.rst
@@ -0,0 +1,38 @@
+.. list-table::
+ :widths: auto
+
+ * - sir.irf_median
+ - Array of (n_ahead+1) mxm matrices, posterior median impulse responses. ``sir.irf_median[h+1][i, j]`` is the median response of variable i to shock j at horizon h.
+
+ * - sir.irf_bands
+ - Array of :class:`credibleBand` structures. Default length 2 (68% and 90%). Access via ``sir.irf_bands[1].level``, ``sir.irf_bands[1].lower``, ``sir.irf_bands[1].upper``. Each ``.lower`` and ``.upper`` is an array of (n_ahead+1) mxm matrices.
+
+ * - sir.cirf_median
+ - Array of (n_ahead+1) mxm matrices, posterior median cumulative IRF.
+
+ * - sir.cirf_bands
+ - Array of :class:`credibleBand` structures. Default length 2 (68% and 90%). Access via ``sir.cirf_bands[1].level``, ``sir.cirf_bands[1].lower``, ``sir.cirf_bands[1].upper``. Each ``.lower`` and ``.upper`` is an array of (n_ahead+1) mxm matrices.
+
+ * - sir.fevd_median
+ - Array of (n_ahead+1) mxm matrices, posterior median FEVD. Each row sums to 1.0.
+
+ * - sir.fevd_bands
+ - Array of :class:`credibleBand` structures. Default length 2 (68% and 90%). Access via ``sir.fevd_bands[1].level``, ``sir.fevd_bands[1].lower``, ``sir.fevd_bands[1].upper``. Each ``.lower`` and ``.upper`` is an array of (n_ahead+1) mxm matrices.
+
+ * - sir.n_attempted
+ - Scalar, total posterior draws attempted.
+
+ * - sir.n_accepted
+ - Scalar, draws that yielded a valid rotation.
+
+ * - sir.accept_rate
+ - Scalar, acceptance rate (n_accepted / n_attempted).
+
+ * - sir.n_ahead
+ - Scalar, number of horizons.
+
+ * - sir.m
+ - Scalar, number of variables.
+
+ * - sir.var_names
+ - Mx1 string array, variable names.
diff --git a/docs/timeseries/include/svforecastcontrol.rst b/docs/timeseries/include/svforecastcontrol.rst
new file mode 100644
index 00000000..d43310e2
--- /dev/null
+++ b/docs/timeseries/include/svforecastcontrol.rst
@@ -0,0 +1,27 @@
+.. list-table::
+ :widths: auto
+
+ * - ctl.h
+ - Scalar, forecast horizon. Default = 12.
+
+ * - ctl.mode
+ - String, forecast mode.
+
+ ================= ==================================================================
+ ``"mean_path"`` Deterministic h-path using posterior mean innovations. Fast but
+ underestimates forecast variance (Jensen's inequality). (Default)
+ ``"simulate"`` Draw innovation paths from the SV-implied time-varying covariance.
+ Gives proper predictive density.
+ ================= ==================================================================
+
+ * - ctl.n_paths
+ - Scalar, number of simulation paths per posterior draw (``"simulate"`` mode only). Default = 100.
+
+ * - ctl.levels
+ - Vector, credible band levels. Default = 0.68|0.90.
+
+ * - ctl.store_draws
+ - Scalar, 1 to store raw forecast draws in *dfc.draws*, 0 to discard. Default = 0.
+
+ * - ctl.seed
+ - Scalar, RNG seed for simulation mode. Default = 42.
diff --git a/docs/timeseries/include/svirfresult.rst b/docs/timeseries/include/svirfresult.rst
new file mode 100644
index 00000000..299e7adb
--- /dev/null
+++ b/docs/timeseries/include/svirfresult.rst
@@ -0,0 +1,20 @@
+.. list-table::
+ :widths: auto
+
+ * - irf.median
+ - Array of (n_ahead+1) mxm matrices, posterior median impulse responses.
+
+ * - irf.bands
+ - Array of :class:`credibleBand` structures. Default length 2 (68% and 90%). Access via ``irf.bands[1].level``, ``irf.bands[1].lower``, ``irf.bands[1].upper``. Each ``.lower`` and ``.upper`` is an array of (n_ahead+1) mxm matrices.
+
+ * - irf.n_ahead
+ - Scalar, number of horizons computed.
+
+ * - irf.m
+ - Scalar, number of variables.
+
+ * - irf.n_draws
+ - Scalar, number of posterior draws used.
+
+ * - irf.var_names
+ - Mx1 string array, variable names.
diff --git a/docs/timeseries/include/tvpsvcontrol.rst b/docs/timeseries/include/tvpsvcontrol.rst
new file mode 100644
index 00000000..2da2cce0
--- /dev/null
+++ b/docs/timeseries/include/tvpsvcontrol.rst
@@ -0,0 +1,41 @@
+.. list-table::
+ :widths: auto
+
+ * - adv.const
+ - Scalar, include constant (1) or not (0). Default = 1.
+
+ * - adv.n_thin
+ - Scalar, thinning factor. Default = 1 (keep every draw).
+
+ * - adv.seed
+ - Scalar, RNG seed for reproducibility. Default = 42.
+
+ * - adv.use_asis
+ - Scalar, enable ASIS interweaving for SV (recommended). Default = 1.
+
+ * - adv.q_b_shape
+ - Scalar, IG prior shape for B drift covariance Q_B diagonal elements. Q_B,jj ~ IG(shape, scale). Default = 6.0.
+
+ * - adv.q_b_scale
+ - Scalar, IG prior scale for Q_B. Default = 0.01 (slow drift).
+
+ * - adv.q_u_shape
+ - Scalar, IG prior shape for U drift covariance Q_U diagonal elements. Default = 6.0.
+
+ * - adv.q_u_scale
+ - Scalar, IG prior scale for Q_U. Default = 0.01.
+
+ * - adv.p0_b_kappa
+ - Scalar, diffuse initialization scale for B FFBS. P_0 = kappa * I. Default = 10.0.
+
+ * - adv.p0_u_kappa
+ - Scalar, diffuse initialization scale for U FFBS. Default = 10.0.
+
+ * - adv.u_bandwidth
+ - Scalar, band-limited drifting U. 0 = full (default), k > 0 = first k off-diagonals per column. Reduces parameters from m(m-1)/2 to m*k for large systems.
+
+ * - adv.xreg
+ - Matrix, exogenous regressors (T x K). Empty = none.
+
+ * - adv.quiet
+ - Scalar, set to 1 to suppress printed output. Default = 0.
diff --git a/docs/timeseries/include/tvpsvresult.rst b/docs/timeseries/include/tvpsvresult.rst
new file mode 100644
index 00000000..3af5f815
--- /dev/null
+++ b/docs/timeseries/include/tvpsvresult.rst
@@ -0,0 +1,50 @@
+.. list-table::
+ :widths: auto
+
+ * - result.m
+ - Scalar, number of endogenous variables.
+
+ * - result.p
+ - Scalar, lag order.
+
+ * - result.n_obs
+ - Scalar, effective sample size (T - p).
+
+ * - result.n_total
+ - Scalar, total number of observations (T).
+
+ * - result.n_draws
+ - Scalar, number of posterior draws kept.
+
+ * - result.const
+ - Scalar, 1 if a constant was included.
+
+ * - result.var_names
+ - Mx1 string array, variable names (from dataframe column names, or default).
+
+ * - result.b_mean
+ - K x m matrix, posterior mean of terminal B_T (coefficients at the last observation).
+
+ * - result.b_sd
+ - K x m matrix, posterior standard deviation of terminal B_T.
+
+ * - result.sv_mu
+ - m x 1 vector, posterior mean of SV level parameters mu_i.
+
+ * - result.sv_phi
+ - m x 1 vector, posterior mean of SV persistence parameters phi_i.
+
+ * - result.sv_sigma2
+ - m x 1 vector, posterior mean of SV innovation variance sigma^2_i.
+
+ * - result.phi_accept_rate
+ - m x 1 vector, Metropolis-Hastings acceptance rate for phi per equation. Healthy range: 20-60%.
+
+ * - result.y
+ - Txm matrix, original data (stored for forecasting).
+
+ * - result.xreg
+ - TxK matrix, exogenous regressors. Empty matrix if none.
+
+ * - result.seed
+ - Scalar, RNG seed used.
diff --git a/docs/timeseries/include/varcontrol.rst b/docs/timeseries/include/varcontrol.rst
new file mode 100644
index 00000000..937755aa
--- /dev/null
+++ b/docs/timeseries/include/varcontrol.rst
@@ -0,0 +1,14 @@
+.. list-table::
+ :widths: auto
+
+ * - ctl.p
+ - Scalar, lag order. Default = 1.
+
+ * - ctl.const
+ - Scalar, 1 to include a constant (intercept), 0 to exclude. Default = 1.
+
+ * - ctl.xreg
+ - TxN matrix or dataframe, exogenous regressors. Default = empty (no exogenous variables).
+
+ * - ctl.quiet
+ - Scalar, set to 1 to suppress printed output. Default = 0.
diff --git a/docs/timeseries/include/varresult.rst b/docs/timeseries/include/varresult.rst
new file mode 100644
index 00000000..c0eead37
--- /dev/null
+++ b/docs/timeseries/include/varresult.rst
@@ -0,0 +1,71 @@
+.. list-table::
+ :widths: auto
+
+ * - result.m
+ - Scalar, number of endogenous variables.
+
+ * - result.p
+ - Scalar, lag order.
+
+ * - result.n_obs
+ - Scalar, effective number of observations (T - p).
+
+ * - result.n_total
+ - Scalar, total number of observations (T).
+
+ * - result.const
+ - Scalar, 1 if a constant was included.
+
+ * - result.var_names
+ - Mx1 string array, variable names.
+
+ * - result.b
+ - Kxm matrix, OLS coefficient estimates. Row layout: lag 1 coefficients (m rows), lag 2 (m rows), ..., lag p (m rows), exogenous (if any), constant (last row if included). Column j = equation j.
+
+ * - result.se
+ - Kxm matrix, standard errors.
+
+ * - result.tstat
+ - Kxm matrix, t-statistics.
+
+ * - result.pval
+ - Kxm matrix, two-sided p-values.
+
+ * - result.sigma
+ - mxm matrix, residual covariance (ML estimate).
+
+ * - result.vcov
+ - (Km)x(Km) matrix, full variance-covariance of vec(B).
+
+ * - result.loglik
+ - Scalar, log-likelihood.
+
+ * - result.aic
+ - Scalar, Akaike information criterion.
+
+ * - result.bic
+ - Scalar, Bayesian information criterion (Schwarz).
+
+ * - result.hq
+ - Scalar, Hannan-Quinn information criterion.
+
+ * - result.companion
+ - (mp)x(mp) matrix, companion form.
+
+ * - result.is_stationary
+ - Scalar, 1 if all companion eigenvalues are inside the unit circle.
+
+ * - result.max_eigenvalue
+ - Scalar, modulus of the largest companion eigenvalue.
+
+ * - result.residuals
+ - (T-p)xm matrix, residuals.
+
+ * - result.fitted
+ - (T-p)xm matrix, fitted values.
+
+ * - result.y
+ - Txm matrix, original data.
+
+ * - result.xreg
+ - TxK matrix, exogenous regressors. Empty matrix if none.
diff --git a/docs/timeseries/index.rst b/docs/timeseries/index.rst
new file mode 100644
index 00000000..b5f1535d
--- /dev/null
+++ b/docs/timeseries/index.rst
@@ -0,0 +1,317 @@
+GAUSS Time Series
+==================
+
+A comprehensive time series analysis package for GAUSS, covering ARIMA/SARIMA,
+VAR/BVAR with stochastic volatility, structural identification, forecasting,
+and forecast evaluation.
+
+Description
+-----------
+
+**GAUSS Time Series** consolidates TSMT, SSLIB, and FANPAC into a single product.
+It provides:
+
+- **Univariate models:** ARIMA, SARIMA, ARIMAX with automatic order selection
+- **Vector autoregression:** OLS VAR, Bayesian VAR (Minnesota prior), BVAR with stochastic volatility
+- **Structural identification:** Cholesky IRF, generalized IRF, sign-restricted SVAR
+- **Forecasting:** Point, density, and conditional (scenario) forecasts
+- **Model comparison:** Marginal likelihood, Diebold-Mariano test, Model Confidence Set
+- **Diagnostics:** MCMC convergence (R-hat, ESS), forecast calibration (PIT)
+
+Installation
+------------
+
+Please `contact us `_ for pricing and installation information.
+
+Requires GAUSS v26 or higher.
+
+Usage::
+
+ library timeseries;
+
+Commands
+--------
+
+ARIMA / Univariate
++++++++++++++++++++
+
+.. list-table::
+ :widths: auto
+
+ * - :func:`arimaFit`
+ - Fit ARIMA, SARIMA, or ARIMAX models with automatic or fixed order selection.
+ * - :func:`arimaForecast`
+ - Generate h-step-ahead forecasts with prediction intervals.
+ * - :func:`arimaControlCreate`
+ - Create control structure with default settings.
+ * - :func:`arimaResults`
+ - Reprint estimation summary table.
+ * - :func:`arimaCoefTable`
+ - Return coefficient table as dataframe.
+
+VAR Estimation
++++++++++++++++
+
+.. list-table::
+ :widths: auto
+
+ * - :func:`varFit`
+ - Fit VAR(p) by OLS with stability diagnostics.
+ * - :func:`bvarFit`
+ - Fit Bayesian VAR with conjugate Minnesota or flat prior.
+ * - :func:`bvarSvFit`
+ - Fit BVAR with stochastic volatility and optional SSVS variable selection.
+ * - :func:`varLagSelect`
+ - Select lag order by AIC, BIC, or Hannan-Quinn.
+ * - :func:`bvarHyperopt`
+ - Optimize Minnesota hyperparameters via marginal likelihood (GLP 2015).
+
+VAR Forecasting
+++++++++++++++++
+
+.. list-table::
+ :widths: auto
+
+ * - :func:`varForecast`
+ - Point forecasts with confidence intervals from VAR.
+ * - :func:`bvarForecast`
+ - Posterior predictive forecasts with credible bands.
+ * - :func:`bvarSvForecast`
+ - Density forecasts from SV-BVAR with time-varying volatility.
+ * - :func:`condForecast`
+ - Conditional (scenario) forecasts with hard constraints.
+
+Dynamic Analysis (IRF / FEVD / HD)
++++++++++++++++++++++++++++++++++++
+
+.. list-table::
+ :widths: auto
+
+ * - :func:`irfCompute`
+ - Orthogonalized (Cholesky) impulse response functions.
+ * - :func:`irfSvCompute`
+ - Posterior IRF bands from SV-BVAR draws.
+ * - :func:`girfCompute`
+ - Generalized IRF (Pesaran & Shin 1998), ordering-invariant.
+ * - :func:`fevdCompute`
+ - Forecast error variance decomposition.
+ * - :func:`hdCompute`
+ - Historical decomposition into structural shock contributions.
+ * - :func:`irfPlotData`
+ - Reshape IRF results into plot-ready dataframe.
+
+SVAR Identification
+++++++++++++++++++++
+
+.. list-table::
+ :widths: auto
+
+ * - :func:`longRunSvar`
+ - Blanchard-Quah (1989) long-run SVAR identification and structural IRF.
+ * - :func:`svarIdentify`
+ - Find a sign-restricted structural rotation.
+ * - :func:`svarIrfCompute`
+ - Posterior sign-restricted IRF, cumulative IRF, and FEVD bands.
+
+Model Diagnostics
++++++++++++++++++++
+
+.. list-table::
+ :widths: auto
+
+ * - :func:`varDiagnostics`
+ - MCMC convergence diagnostics (R-hat, ESS, acceptance rates).
+ * - :func:`varDiagnosticsMulti`
+ - Multi-chain convergence diagnostics.
+ * - :func:`varDiagnosticsPrint`
+ - Reprint diagnostics summary.
+ * - :func:`grangerTest`
+ - Granger causality F-test.
+
+Forecast Evaluation
+++++++++++++++++++++
+
+.. list-table::
+ :widths: auto
+
+ * - :func:`fcScore`
+ - Compute scoring rules (RMSE, MASE, sMAPE).
+ * - :func:`dmTest`
+ - Diebold-Mariano test for equal predictive ability.
+ * - :func:`cwTest`
+ - Clark-West test for nested model comparison.
+ * - :func:`mcsTest`
+ - Model Confidence Set (Hansen, Lunde & Nason 2011).
+ * - :func:`pitTest`
+ - PIT calibration tests (KS, chi-squared, Berkowitz).
+ * - :func:`pitHistogram`
+ - PIT histogram bin counts.
+
+Utilities
+++++++++++
+
+.. list-table::
+ :widths: auto
+
+ * - :func:`varCompanion`
+ - Extract companion matrix, eigenvalues, and stability indicator.
+ * - :func:`varCoefTable`
+ - Return coefficient table as dataframe.
+ * - :func:`varResults`
+ - Reprint estimation summary for any result type.
+ * - :func:`stlDecompose`
+ - Seasonal-Trend decomposition via LOESS (STL).
+ * - :func:`fcMetrics`
+ - Compute RMSE, MASE, and sMAPE.
+
+Plotting
++++++++++
+
+.. list-table::
+ :widths: auto
+
+ * - :func:`plotForecast`
+ - Forecast fan chart with historical data and prediction bands.
+ * - :func:`plotIrf`
+ - Impulse response function grid (m × m).
+ * - :func:`plotSvIrf`
+ - Posterior IRF grid with credible bands from SV-BVAR.
+ * - :func:`plotResiduals`
+ - Residual diagnostics: time plot, ACF, histogram.
+ * - :func:`plotStl`
+ - STL decomposition: data, trend, seasonal, remainder.
+
+Control Structure Creators
++++++++++++++++++++++++++++
+
+.. list-table::
+ :widths: auto
+
+ * - :func:`varControlCreate`
+ - Create :class:`varControl` with defaults.
+ * - :func:`bvarControlCreate`
+ - Create :class:`bvarControl` with defaults.
+ * - :func:`bvarSvControlCreate`
+ - Create :class:`bvarSvControl` with defaults.
+ * - :func:`svForecastControlCreate`
+ - Create :class:`svForecastControl` with defaults.
+ * - :func:`svarControlCreate`
+ - Create :class:`svarControl` with defaults.
+ * - :func:`longRunSvarControlCreate`
+ - Create :class:`longRunSvarControl` with defaults.
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :caption: Guides
+
+ getting-started
+ getting-started-arima
+ choosing-a-var-model
+ comparison
+ textbook-mapping
+ bgr-replication
+ var-verification
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :caption: ARIMA
+
+ arimafit
+ arimaforecast
+ arimacontrolcreate
+ arimaresults
+ arimacoeftable
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :caption: VAR Estimation
+
+ varfit
+ bvarfit
+ bvarsvfit
+ varlagselect
+ bvarhyperopt
+ varcontrolcreate
+ bvarcontrolcreate
+ bvarsvcontrolcreate
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :caption: VAR Forecasting
+
+ varforecast
+ bvarforecast
+ bvarsvforecast
+ condforecast
+ svforecastcontrolcreate
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :caption: Dynamic Analysis (IRF / FEVD / HD)
+
+ irfcompute
+ irfsvcompute
+ girfcompute
+ fevdcompute
+ hdcompute
+ irfplotdata
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :caption: SVAR
+
+ longrunsvar
+ longrunsvarcontrolcreate
+ svaridentify
+ svarirfcompute
+ svarcontrolcreate
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :caption: Model Diagnostics
+
+ vardiagnostics
+ vardiagnosticsmulti
+ vardiagnosticsprint
+ grangertest
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :caption: Forecast Evaluation
+
+ fcscore
+ dmtest
+ cwtest
+ mcstest
+ pittest
+ pithistogram
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :caption: Utilities
+
+ varcompanion
+ varcoeftable
+ varresults
+ stldecompose
+ fcmetrics
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :caption: Plotting
+
+ plotforecast
+ plotirf
+ plotsvirf
+ plotresiduals
+ plotstl
diff --git a/docs/timeseries/irfcompute.rst b/docs/timeseries/irfcompute.rst
new file mode 100644
index 00000000..10131910
--- /dev/null
+++ b/docs/timeseries/irfcompute.rst
@@ -0,0 +1,245 @@
+irfCompute
+==========
+
+Purpose
+-------
+Compute orthogonalized impulse response functions using Cholesky identification.
+
+Format
+------
+
+.. function:: irf = irfCompute(result, n_ahead)
+
+ :param result: an instance of a :class:`varResult` or :class:`bvarResult` structure.
+ :type result: struct
+
+ :param n_ahead: number of horizons to compute (e.g., 20).
+ :type n_ahead: scalar
+
+ :param var_names: Optional keyword, override variable names from the estimation result.
+ :type var_names: Mx1 string array
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return irf: An instance of an :class:`irfResult` structure containing:
+
+ .. include:: include/irfresult.rst
+
+ :rtype irf: struct
+
+Examples
+--------
+
+Monetary Policy Shock
++++++++++++++++++++++
+
+Trace the effect of a federal funds rate shock on GDP and CPI:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Variable ordering: GDP (slow), CPI (medium), FFR (fast policy instrument)
+ // This ordering means: FFR shocks can affect GDP and CPI contemporaneously,
+ // but GDP shocks take one period to reach FFR.
+ result = varFit(data, 4);
+
+ irf = irfCompute(result, 20);
+
+Output:
+
+::
+
+ ================================================================================
+ Impulse Response Functions (cholesky)
+ Horizons: 0-20
+ ================================================================================
+
+ Shock to: GDP
+ h GDP CPI FFR
+ --------------------------------------------------------------------------------
+ 0 0.5280 0.0456 0.0919
+ 1 0.1859 0.0810 0.2753
+ 2 0.1600 0.0612 0.4442
+ ⋮
+ 18 0.0089 0.0031 0.0042
+ 19 0.0071 0.0025 0.0035
+ 20 0.0057 0.0020 0.0029
+ ================================================================================
+
+The impact response (h=0) shows that a 1-SD GDP shock raises GDP by 0.528,
+CPI by 0.046, and FFR by 0.092 — consistent with the central bank responding
+to output movements within the quarter.
+
+IRF from BVAR with Shrinkage
++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ br = bvarFit(data, p=4, quiet=1);
+
+ // IRF at the posterior mean of B and Sigma
+ irf = irfCompute(br, 20);
+
+For posterior IRF bands (credible intervals), use :func:`irfSvCompute` with
+an SV-BVAR result.
+
+Plotting IRFs
++++++++++++++
+
+Reshape IRF results into a plot-ready dataframe:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4, quiet=1);
+ irf = irfCompute(result, 20, quiet=1);
+
+ // Get plot data: (n_ahead+1) x (m*m) matrix with column names
+ struct DataFrame plot_data;
+ plot_data = irfPlotData(irf);
+
+ // Plot GDP response to FFR shock
+ plotXY(seqa(0, 1, 21), plot_data[., "GDP<-FFR"]);
+
+Model
+-----
+
+An impulse response function (IRF) traces the dynamic effect of a one-standard-deviation
+structural shock to variable :math:`j` on variable :math:`i` over :math:`h` periods.
+
+For a VAR(p) in companion form :math:`Y_t = F Y_{t-1} + G \varepsilon_t`, the
+reduced-form IRF at horizon :math:`h` is:
+
+.. math::
+
+ \Phi_h = J \, F^h \, J'
+
+where :math:`F` is the :math:`mp \times mp` companion matrix and :math:`J = [I_m \; 0 \; \cdots \; 0]`
+selects the first :math:`m` rows.
+
+**Cholesky identification:** To give shocks a structural interpretation, the
+reduced-form innovations are orthogonalized via the Cholesky factorization
+:math:`\Sigma = P P'` where :math:`P` is lower triangular. The structural IRF is:
+
+.. math::
+
+ \Theta_h = \Phi_h \, P
+
+Element :math:`\Theta_h[i, j]` is the response of variable :math:`i` at horizon :math:`h`
+to a one-standard-deviation shock to variable :math:`j`.
+
+**Identification assumption:** Cholesky identification imposes a recursive causal ordering.
+Variable 1 can affect all others contemporaneously; variable :math:`m` is affected by all
+others but affects none contemporaneously. This assumption is appropriate when there is a
+natural fast-to-slow ordering (e.g., financial variables respond faster than real activity).
+
+Algorithm
+---------
+
+1. **Extract companion matrix** :math:`F` and Cholesky factor :math:`P = \text{chol}(\Sigma)'` from the VAR estimates.
+
+2. **Iterate:** For :math:`h = 0, 1, \ldots, n\_ahead`:
+
+ .. math::
+
+ \Theta_h = J \, F^h \, J' \, P
+
+ The companion power :math:`F^h` is computed iteratively (matrix multiplication, not matrix exponentiation) for numerical stability.
+
+3. **Store** :math:`\Theta_0, \Theta_1, \ldots, \Theta_{n\_ahead}` as an array of :math:`m \times m` matrices.
+
+**Complexity:** :math:`O(n\_ahead \cdot m^2 p^2)` — dominated by the :math:`mp \times mp` matrix
+multiplications. Sub-millisecond for typical systems.
+
+Troubleshooting
+---------------
+
+**IRFs don't decay to zero:**
+If the VAR is near-nonstationary (max eigenvalue close to 1), IRFs can be very
+persistent. This is not a numerical error — it reflects the model's dynamics.
+Check ``result.max_eigenvalue``. For near-unit-root systems, consider:
+
+- Using longer horizons (40-60 periods instead of 20).
+- Differencing the data.
+- Adding sum-of-coefficients priors (:func:`bvarFit` with soc_tightness > 0).
+
+**IRFs are sensitive to variable ordering:**
+This is inherent to Cholesky identification — different orderings produce different
+structural shocks. If the ordering is uncertain, use :func:`girfCompute` (generalized
+IRF, ordering-invariant) or :func:`svarIdentify` (sign restrictions).
+
+**Impact response has wrong sign:**
+Check the variable ordering. In Cholesky identification, the first variable's shock
+is unrestricted; later variables' shocks are residualized. A monetary policy variable
+(FFR) should typically be ordered last so its shock is "purged" of contemporaneous
+output and price movements.
+
+Remarks
+-------
+
+**Identification:**
+The Cholesky decomposition of :math:`\Sigma` is used to orthogonalize the
+innovations. The ordering of variables in the data determines the recursive
+causal structure: variable 1 can affect all others contemporaneously, variable
+2 can affect variables 3, ..., m but not 1, and so on.
+
+**To change the identification ordering,** reorder the columns of the data
+before calling :func:`varFit` or :func:`bvarFit`.
+
+**For ordering-invariant responses,** use :func:`girfCompute` (generalized IRF,
+Pesaran & Shin 1998). For theory-based identification with sign/zero restrictions,
+see :func:`svarIdentify`.
+
+**For BVAR,** the IRF is computed at the posterior mean of B and :math:`\Sigma`.
+For posterior IRF bands, use :func:`irfSvCompute` with an :class:`bvarSvResult`.
+
+**Indexing convention:**
+``irf.irf[1, ., .]`` is the impact response (h=0). ``irf.irf[h+1, ., .]`` is the response
+at horizon h. Element ``irf.irf[h+1, i, j]`` is the response of variable i to
+a shock to variable j.
+
+Verification
+------------
+
+Verified against R ``vars::irf()`` with ``boot=FALSE`` at :math:`10^{-6}` tolerance
+on a 2-variable VAR(1) with known DGP. Tests cover impact values, decay patterns
+at h=1 and h=2, and the Cholesky lower-triangularity constraint (zero upper-off-diagonal
+at h=0).
+
+Additionally verified against ECB BEAR Cholesky IRFs on matched-prior BVAR(4),
+covering all 9 shock-response pairs at horizons 0, 10, and 20 (17 tests).
+
+References
+----------
+
+- Lutkepohl, H. (2005). *New Introduction to Multiple Time Series Analysis*. Springer. Chapter 2.3 (IRF computation), Chapter 9 (structural identification).
+- Pesaran, M.H. and Y. Shin (1998). "Generalized impulse response analysis in linear multivariate models." *Economics Letters*, 58(1), 17-29.
+- Sims, C.A. (1980). "Macroeconomics and reality." *Econometrica*, 48(1), 1-48.
+
+Library
+-------
+timeseries
+
+Source
+------
+irf.src
+
+.. seealso:: Functions :func:`irfSvCompute`, :func:`girfCompute`, :func:`fevdCompute`, :func:`hdCompute`, :func:`irfPlotData`, :func:`svarIdentify`
+
+.. seealso:: Guides :ref:`choosing-a-var-model`, :ref:`var-verification`
diff --git a/docs/timeseries/irfplotdata.rst b/docs/timeseries/irfplotdata.rst
new file mode 100644
index 00000000..509cd9d5
--- /dev/null
+++ b/docs/timeseries/irfplotdata.rst
@@ -0,0 +1,100 @@
+irfPlotData
+===========
+
+Purpose
+-------
+Reshape IRF, FEVD, or SV-BVAR IRF results into a plot-ready long-format dataframe.
+
+Format
+------
+
+.. function:: df = irfPlotData(result, shock, response)
+ df = irfPlotData(result)
+
+ :param result: an instance of an :class:`irfResult`, :class:`svIrfResult`, or :class:`fevdResult` structure.
+ :type result: struct
+
+ :param shock: Optional, shock index (1 to m). If omitted, all shocks are included.
+ :type shock: scalar
+
+ :param response: Optional, response variable index (1 to m). If omitted, all responses are included.
+ :type response: scalar
+
+ :return df: Dataframe. For :class:`irfResult`: columns horizon, shock, response, value. For :class:`svIrfResult`: columns horizon, shock, response, median, plus lower/upper columns for each credible band level. For :class:`fevdResult`: columns horizon, shock, response, share.
+ :rtype df: dataframe
+
+Examples
+--------
+
+Plot a Single Shock-Response Pair
++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4);
+ irf = irfCompute(result, 20, quiet=1);
+
+ // GDP response to FFR shock
+ df = irfPlotData(irf, 3, 1);
+ plotXY(df[., "horizon"], df[., "value"]);
+
+Plot SV-BVAR IRF with Credible Bands
++++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = bvarSvFit(data, quiet=1);
+ irf = irfSvCompute(result, 20, quiet=1);
+
+ // GDP response to FFR shock with bands
+ df = irfPlotData(irf, 3, 1);
+
+ // Plot median with 68% band
+ plotXY(df[., "horizon"],
+ df[., "median"]~df[., "bands[1].lower"]~df[., "bands[1].upper"]);
+
+Extract All Pairs
++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4, quiet=1);
+ irf = irfCompute(result, 20, quiet=1);
+
+ // All m*m pairs in long format
+ df = irfPlotData(irf);
+ print df[1:10, .];
+
+Remarks
+-------
+
+This is a convenience function for plotting. It reshapes the array-of-matrices
+representation into a long-format dataframe that can be passed directly to
+:func:`plotXY` or exported to CSV.
+
+**No Rust FFI call** — this is a pure GAUSS reshape operation.
+
+Library
+-------
+timeseries
+
+Source
+------
+irf.src
+
+.. seealso:: Functions :func:`irfCompute`, :func:`irfSvCompute`, :func:`fevdCompute`
diff --git a/docs/timeseries/irfsvcompute.rst b/docs/timeseries/irfsvcompute.rst
new file mode 100644
index 00000000..a370cd91
--- /dev/null
+++ b/docs/timeseries/irfsvcompute.rst
@@ -0,0 +1,158 @@
+irfSvCompute
+============
+
+Purpose
+-------
+Compute posterior impulse response bands from SV-BVAR draws.
+
+Format
+------
+
+.. function:: irf = irfSvCompute(result, n_ahead)
+
+ :param result: an instance of a :class:`bvarSvResult` structure returned by :func:`bvarSvFit`.
+ :type result: struct
+
+ :param n_ahead: number of horizons to compute.
+ :type n_ahead: scalar
+
+ :param var_names: Optional keyword, override variable names.
+ :type var_names: Mx1 string array
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return irf: An instance of an :class:`svIrfResult` structure containing:
+
+ .. include:: include/svirfresult.rst
+
+ :rtype irf: struct
+
+Examples
+--------
+
+SV-BVAR IRF with Credible Bands
+++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarSvFit(data, p=4, n_draws=10000, n_burn=5000, quiet=1);
+
+ irf = irfSvCompute(result, 20);
+
+Accessing Median and Bands
+++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = bvarSvFit(data, quiet=1);
+ irf = irfSvCompute(result, 20, quiet=1);
+
+ // Median response of GDP (1) to FFR shock (3) at h=5
+ print "Median:" irf.median[6, 1, 3];
+
+ // 68% credible band
+ print "68% band:" irf.lower_68[6, 1, 3] "to" irf.upper_68[6, 1, 3];
+
+ // 90% credible band
+ print "90% band:" irf.lower_90[6, 1, 3] "to" irf.upper_90[6, 1, 3];
+
+ // Full path with bands
+ print "GDP response to FFR shock:";
+ print " h Median 68%lo 68%hi 90%lo 90%hi";
+ for h (0, 20, 1);
+ print h;;
+ print irf.median[h+1, 1, 3];;
+ print irf.lower_68[h+1, 1, 3];;
+ print irf.upper_68[h+1, 1, 3];;
+ print irf.lower_90[h+1, 1, 3];;
+ print irf.upper_90[h+1, 1, 3];
+ endfor;
+
+Remarks
+-------
+
+**Posterior bands:**
+For each posterior draw :math:`(B^{(i)}, U^{(i)})`, the function computes the
+Cholesky IRF using the time-averaged :math:`U^{(i)}` for the structural rotation.
+The reported bands are pointwise quantiles across all draws:
+
+- **68% bands:** 16th and 84th percentiles (approximately :math:`\pm 1\sigma`)
+- **90% bands:** 5th and 95th percentiles
+
+**These are pointwise bands,** not simultaneous bands. They capture parameter
+uncertainty but do not control joint coverage across all horizons.
+
+**Requires full draws.** The estimation must be run with ``sv_keep = "full"``
+(the default) so that the posterior draws of B and U are available. If
+``sv_keep = "online"`` was used, an error is raised.
+
+Model
+-----
+
+For each posterior draw :math:`(B^{(s)}, U^{(s)})` from the SV-BVAR, the structural
+IRF is computed using the time-averaged Cholesky factor:
+
+.. math::
+
+ \Theta_h^{(s)} = J \, (F^{(s)})^h \, J' \, \bar{P}^{(s)}
+
+where :math:`\bar{P}^{(s)}` is derived from the draw-specific :math:`U^{(s)}` and
+the mean of the time-varying diagonal :math:`D_t`. The posterior distribution of
+:math:`\{\Theta_h^{(s)}\}` yields pointwise credible bands.
+
+Algorithm
+---------
+
+1. For each of *n_draws* posterior draws:
+
+ a. Construct companion matrix :math:`F^{(s)}` from :math:`B^{(s)}`.
+ b. Construct structural rotation :math:`\bar{P}^{(s)}` from the draw's Cholesky factor.
+ c. Compute :math:`\Theta_0^{(s)}, \ldots, \Theta_h^{(s)}` via companion powers.
+
+2. At each horizon, compute pointwise quantiles across all draws.
+
+**Complexity:** :math:`O(n\_draws \cdot h \cdot m^2 p^2)`.
+
+Troubleshooting
+---------------
+
+**"Requires full draws" error:**
+The SV-BVAR was estimated with ``sv_keep = "online"`` or ``"last"``, which does
+not store the individual :math:`(B, U)` draws needed for posterior IRF bands.
+Re-estimate with ``sv_keep = "full"`` (the default).
+
+**Bands are asymmetric:**
+This is expected — the posterior distribution of IRFs is typically skewed,
+especially at longer horizons. Asymmetric bands reflect this correctly.
+
+**Bands include zero at all horizons:**
+The shock may not have a statistically significant effect on the response variable.
+This is a finding, not a problem.
+
+References
+----------
+
+- Primiceri, G.E. (2005). "Time varying structural vector autoregressions and monetary policy." *Review of Economic Studies*, 72(3), 821-852.
+- Clark, T.E. (2011). "Real-time density forecasts from Bayesian vector autoregressions with stochastic volatility." *Journal of Business & Economic Statistics*, 29(3), 327-341.
+
+Library
+-------
+timeseries
+
+Source
+------
+irf.src
+
+.. seealso:: Functions :func:`bvarSvFit`, :func:`irfCompute`, :func:`irfPlotData`, :func:`svarIdentify`
diff --git a/docs/timeseries/longrunsvar.rst b/docs/timeseries/longrunsvar.rst
new file mode 100644
index 00000000..0cbff33d
--- /dev/null
+++ b/docs/timeseries/longrunsvar.rst
@@ -0,0 +1,204 @@
+longRunSvar
+===========
+
+Purpose
+-------
+Blanchard-Quah (1989) long-run SVAR identification. Computes structural impulse responses by imposing long-run restrictions via the Cholesky decomposition of the cumulative impact matrix.
+
+Format
+------
+
+.. function:: lr = longRunSvar(y, n_ahead)
+ lr = longRunSvar(y, n_ahead, p=4)
+ lr = longRunSvar(y, n_ahead, p=4, xreg=X)
+
+ :param y: endogenous variables. If a dataframe, column names are used as variable labels in output. If a matrix, variables are labeled "Y1", "Y2", etc.
+ :type y: TxM matrix or dataframe
+
+ :param n_ahead: number of impulse response horizons to compute (h = 0, 1, ..., n_ahead).
+ :type n_ahead: scalar
+
+ :param p: Optional keyword, lag order. Default = 1.
+ :type p: scalar
+
+ :param xreg: Optional keyword, TxK exogenous regressors. Default = {} (none).
+ :type xreg: matrix or dataframe
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :param ctl: Optional keyword, an instance of a :class:`longRunSvarControl` structure. When provided, struct values are used and keywords are ignored. An instance is initialized by calling :func:`longRunSvarControlCreate` and the following members can be set:
+
+ .. include:: include/longrunsvarcontrol.rst
+
+ :type adv: struct
+
+ :return lr: An instance of a :class:`longRunSvarResult` structure containing:
+
+ .. include:: include/longrunsvarresult.rst
+
+ :rtype lr: struct
+
+Examples
+--------
+
+Blanchard-Quah Supply and Demand Shocks
+++++++++++++++++++++++++++++++++++++++++
+
+The classic Blanchard and Quah (1989) decomposition with GDP growth and unemployment. The first shock (supply) has a permanent effect on GDP; the second shock (demand) has zero long-run effect on GDP:
+
+::
+
+ new;
+ library timeseries;
+
+ // Load US macro quarterly data
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + unemployment");
+
+ // Long-run SVAR with 4 lags and 20-step IRF
+ lr = longRunSvar(y, 20, p=4);
+
+Output:
+
+::
+
+ ================================================================================
+ Long-Run SVAR (Blanchard & Quah 1989)
+ Variables: 2, Lags: 4, Horizons: 0-20
+ ================================================================================
+ Structural Impact Matrix (B0):
+ Supply Demand
+ GDP 0.0083 0.0071
+ UNEMP -0.0512 0.1243
+ ================================================================================
+
+The impact matrix shows that a supply shock raises GDP and lowers unemployment on impact, while a demand shock raises both.
+
+Technology Shock Identification (Gali 1999)
++++++++++++++++++++++++++++++++++++++++++++
+
+Identify technology shocks using labor productivity and hours worked. Only the technology shock (first variable) has a permanent effect on productivity:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "productivity_growth + hours_growth");
+
+ // Ordering: productivity first, hours second
+ // Technology shock = permanent productivity effect
+ // Non-technology shock = zero long-run productivity effect
+ lr = longRunSvar(y, 40, p=8);
+
+ // Access IRF at horizon 10: response of hours to technology shock
+ print "Hours response to technology shock at h=10:";
+ print lr.irf.irf[11*2, 1];
+
+With Exogenous Regressors
++++++++++++++++++++++++++
+
+Include a time trend as an exogenous regressor:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation");
+
+ lr = longRunSvar(y, 20, p=4, xreg=seqa(1, 1, rows(y)), quiet=1);
+
+ print "Structural impact matrix:";
+ print lr.impact;
+
+Model
+-----
+
+The reduced-form VAR(p) is estimated by OLS:
+
+.. math::
+
+ y_t = B_1 y_{t-1} + \cdots + B_p y_{t-p} + u + \varepsilon_t, \quad \varepsilon_t \sim N(0, \Sigma)
+
+The long-run cumulative impact matrix is:
+
+.. math::
+
+ C(1) = (I_m - B_1 - B_2 - \cdots - B_p)^{-1}
+
+This matrix captures the total (cumulative) effect of a reduced-form shock on the
+level of each variable. To identify structural shocks, compute:
+
+.. math::
+
+ C(1) \, \Sigma \, C(1)' = P \, P'
+
+where :math:`P` is the lower-triangular Cholesky factor. The structural impact matrix is:
+
+.. math::
+
+ B_0 = C(1)^{-1} \, P
+
+The identification imposes that the second shock (and higher) has zero long-run effect on the first variable, the third shock has zero long-run effect on the first two variables, and so on. The structural IRF at horizon h is:
+
+.. math::
+
+ \Theta_h = J \, F^h \, J' \, B_0
+
+where :math:`F` is the VAR companion matrix and :math:`J = [I_m \; 0 \; \cdots \; 0]`.
+
+
+Remarks
+-------
+
+**Variable ordering matters:**
+The ordering of variables in *y* determines the identification. The first variable
+is the one on which all shocks except the first have zero long-run effect. The
+second variable allows only the first two shocks to have permanent effects, and so
+on. In the Blanchard-Quah setup, GDP (or productivity) must be ordered first so that
+the demand shock has zero long-run effect on output.
+
+**Stationarity requirement:**
+The VAR must be stationary for the long-run matrix :math:`C(1) = (I - B_1 - \cdots - B_p)^{-1}`
+to exist. If the companion matrix has eigenvalues near or on the unit circle,
+:math:`C(1)` becomes ill-conditioned and the identification is unreliable. Check
+stationarity with :func:`varFit` before using this function.
+
+**Point identification only:**
+This function provides point-identified structural IRFs from a single OLS VAR
+estimate. There are no posterior uncertainty bands. For inference with uncertainty,
+bootstrap the VAR or use a Bayesian approach with :func:`bvarFit` and
+:func:`svarIrfCompute`.
+
+**Differenced vs. level data:**
+The Blanchard-Quah method is typically applied to growth rates (first differences
+of log levels). The cumulative IRF from *lr.irf* then gives the level response.
+If variables are already in levels and stationary, the IRF itself is the level
+response.
+
+**Accessing IRF values:**
+The IRF is stored in *lr.irf.irf* as an (n_ahead+1)*m x m stacked matrix. Block
+h (rows h*m+1 to (h+1)*m) is the mxm response matrix at horizon h. Element [i, j]
+of block h is the response of variable i to structural shock j at horizon h.
+
+
+References
+----------
+
+- Blanchard, O.J. and D. Quah (1989). "The dynamic effects of aggregate demand and supply disturbances." *American Economic Review*, 79(4), 655-673.
+- Gali, J. (1999). "Technology, employment, and the business cycle: Do technology shocks explain aggregate fluctuations?" *American Economic Review*, 89(1), 249-271.
+- Lutkepohl, H. (2005). *New Introduction to Multiple Time Series Analysis*. Springer, Chapter 9.
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`longRunSvarControlCreate`, :func:`svarIrfCompute`, :func:`varFit`, :func:`irfCompute`
diff --git a/docs/timeseries/longrunsvarcontrolcreate.rst b/docs/timeseries/longrunsvarcontrolcreate.rst
new file mode 100644
index 00000000..707d9ad7
--- /dev/null
+++ b/docs/timeseries/longrunsvarcontrolcreate.rst
@@ -0,0 +1,44 @@
+longRunSvarControlCreate
+=========================
+
+Purpose
+-------
+Create a :class:`longRunSvarControl` structure with default values.
+
+Format
+------
+
+.. function:: adv = longRunSvarControlCreate()
+
+ :return adv: An instance of a :class:`longRunSvarControl` structure with the following default values:
+
+ .. include:: include/longrunsvarcontrol.rst
+
+ :rtype adv: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation");
+
+ // Remove the constant — use struct for non-keyword settings
+ adv = longRunSvarControlCreate();
+ adv.const = 0;
+
+ lr = longRunSvar(y, 20, p=4, quiet=1, ctl=adv);
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`longRunSvar`
diff --git a/docs/timeseries/mcstest.rst b/docs/timeseries/mcstest.rst
new file mode 100644
index 00000000..af1c7be9
--- /dev/null
+++ b/docs/timeseries/mcstest.rst
@@ -0,0 +1,92 @@
+mcsTest
+=======
+
+Purpose
+-------
+Model Confidence Set: identify the set of models with equal predictive ability.
+
+Format
+------
+
+.. function:: mcs = mcsTest(losses)
+ mcs = mcsTest(losses, alpha=0.10)
+
+ :param losses: loss series for M models. Each column is one model's loss series.
+ :type losses: NxM matrix
+
+ :param alpha: Optional keyword, significance level. Default = 0.15.
+ :type alpha: scalar
+
+ :param n_boot: Optional keyword, bootstrap replications. Default = 5000.
+ :type n_boot: scalar
+
+ :param block: Optional keyword, block length for block bootstrap. Default = auto.
+ :type block: scalar
+
+ :param seed: Optional keyword, RNG seed. Default = 42.
+ :type seed: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :return mcs: An instance of a :class:`mcsResult` structure containing surviving model indices, p-values, and elimination order.
+ :rtype mcs: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ // Squared errors from 5 models
+ losses = e1^2 ~ e2^2 ~ e3^2 ~ e4^2 ~ e5^2;
+
+ mcs = mcsTest(losses);
+
+ print "Surviving models:" mcs.surviving;
+ print "MCS p-values:" mcs.p_values;
+ print "Elimination order:" mcs.elimination_order;
+
+Remarks
+-------
+
+Implements Hansen, Lunde & Nason (2011). The MCS is the smallest set of
+models that contains the best model with probability 1-alpha. Models are
+sequentially eliminated until the null of equal predictive ability cannot
+be rejected for the remaining set.
+
+The surviving set includes all models whose MCS p-value exceeds *alpha*.
+
+Model
+-----
+
+The MCS procedure iteratively tests equal predictive ability across a set of models.
+At each step, the worst-performing model is identified and tested for elimination:
+
+.. math::
+
+ t_{\max,M} = \max_{i \in M} \frac{\bar{d}_{i\cdot}}{\sqrt{\widehat{\text{var}}(\bar{d}_{i\cdot})}}
+
+where :math:`\bar{d}_{i\cdot} = \frac{1}{|M|} \sum_{j \in M} \bar{d}_{ij}` is model
+i's average loss relative to all surviving models. The p-value is computed via
+stationary bootstrap (Politis & Romano 1994).
+
+
+References
+----------
+
+- Hansen, P.R., A. Lunde, and J.M. Nason (2011). "The Model Confidence Set." *Econometrica*, 79(2), 453-497.
+- Politis, D.N. and J.P. Romano (1994). "The stationary bootstrap." *Journal of the American Statistical Association*, 89(428), 1303-1313.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+scoring.src
+
+.. seealso:: Functions :func:`dmTest`, :func:`cwTest`
diff --git a/docs/timeseries/pithistogram.rst b/docs/timeseries/pithistogram.rst
new file mode 100644
index 00000000..ea691f48
--- /dev/null
+++ b/docs/timeseries/pithistogram.rst
@@ -0,0 +1,70 @@
+pitHistogram
+============
+
+Purpose
+-------
+Compute and display a PIT histogram for visual calibration assessment.
+
+Format
+------
+
+.. function:: counts = pitHistogram(pit_values)
+ counts = pitHistogram(pit_values, n_bins)
+
+ :param pit_values: PIT values from :func:`pitTest`.
+ :type pit_values: Nx1 vector
+
+ :param n_bins: Optional, number of bins. Default = 10.
+ :type n_bins: scalar
+
+ :return counts: bin counts.
+ :rtype counts: n_bins x 1 vector
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ pt = pitTest(sorted_draws, actual, quiet=1);
+ counts = pitHistogram(pt.pit_values);
+
+ // A uniform histogram indicates good calibration
+ print counts;
+
+Remarks
+-------
+
+A well-calibrated density forecast produces a uniform PIT histogram.
+Humps indicate underdispersion (too narrow intervals); U-shapes indicate
+overdispersion. Skewness indicates bias.
+
+Model
+-----
+
+The PIT histogram bins the empirical CDF values :math:`u_t = \hat{F}_t(y_t)` into
+equal-width bins on [0, 1]. Under correct calibration, all bins should have
+approximately equal height (:math:`T / n_{\text{bins}}`). Deviations indicate:
+
+- **Hump in center:** Underdispersion (intervals too narrow — overconfident).
+- **U-shape (high at edges):** Overdispersion (intervals too wide — underconfident).
+- **Skewed:** Systematic bias in the predictive mean.
+
+
+References
+----------
+
+- Diebold, F.X., T.A. Gunther, and A.S. Tay (1998). "Evaluating density forecasts." *International Economic Review*, 39(4), 863-883.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+scoring.src
+
+.. seealso:: Functions :func:`pitTest`, :func:`fcScore`
diff --git a/docs/timeseries/pittest.rst b/docs/timeseries/pittest.rst
new file mode 100644
index 00000000..c009c2fe
--- /dev/null
+++ b/docs/timeseries/pittest.rst
@@ -0,0 +1,91 @@
+pitTest
+=======
+
+Purpose
+-------
+Density forecast calibration tests via the Probability Integral Transform.
+
+Format
+------
+
+.. function:: pt = pitTest(sorted_draws, actual)
+ pt = pitTest(sorted_draws, actual, n_bins=20)
+
+ :param sorted_draws: sorted forecast draws. Each column is the sorted draws for one observation.
+ :type sorted_draws: (n_draws)xN matrix
+
+ :param actual: realized values.
+ :type actual: Nx1 vector
+
+ :param n_bins: Optional keyword, number of bins for chi-squared test. Default = 10.
+ :type n_bins: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :return pt: An instance of a :class:`pitResult` structure containing KS test, chi-squared test, Berkowitz test, and raw PIT values.
+ :rtype pt: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ // PIT calibration check
+ pt = pitTest(sorted_draws, actual);
+
+ print "KS test: stat=" pt.ks_stat "p=" pt.ks_pval;
+ print "Berkowitz: stat=" pt.berk_stat "p=" pt.berk_pval;
+
+ // PIT histogram (should be uniform if calibrated)
+ counts = pitHistogram(pt.pit_values);
+
+Remarks
+-------
+
+If the density forecast is correctly calibrated, the PIT values are
+uniformly distributed on [0, 1]. Three tests are applied:
+
+- **KS test:** Kolmogorov-Smirnov test against U(0,1).
+- **Chi-squared test:** Binned goodness-of-fit against uniform.
+- **Berkowitz test:** Tests both uniformity and serial independence of
+ PITs via a likelihood ratio test on the probit-transformed values.
+
+A well-calibrated forecast should have non-significant p-values for all
+three tests.
+
+Model
+-----
+
+The PIT value for observation :math:`t` is:
+
+.. math::
+
+ u_t = \hat{F}_t(y_t) = \frac{1}{S} \sum_{s=1}^{S} \mathbf{1}(\hat{y}_t^{(s)} \leq y_t)
+
+where :math:`\hat{y}_t^{(s)}` are posterior predictive draws. If the density forecast is
+correctly specified, :math:`u_t \sim U(0,1)` (Diebold, Gunther & Tay 1998).
+
+**Berkowitz test** additionally tests serial independence by fitting an AR(1) to the
+probit-transformed PITs :math:`z_t = \Phi^{-1}(u_t)` and testing :math:`H_0: \mu = 0, \sigma = 1, \rho = 0`.
+
+
+References
+----------
+
+- Diebold, F.X., T.A. Gunther, and A.S. Tay (1998). "Evaluating density forecasts with applications to financial risk management." *International Economic Review*, 39(4), 863-883.
+- Berkowitz, J. (2001). "Testing density forecasts, with applications to risk management." *Journal of Business & Economic Statistics*, 19(4), 465-474.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+scoring.src
+
+.. seealso:: Functions :func:`pitHistogram`, :func:`fcScore`
diff --git a/docs/timeseries/plotforecast.rst b/docs/timeseries/plotforecast.rst
new file mode 100644
index 00000000..9c830b15
--- /dev/null
+++ b/docs/timeseries/plotforecast.rst
@@ -0,0 +1,64 @@
+plotForecast
+============
+
+Purpose
+-------
+Plot forecast with fan chart — observed data leading into forecast horizon
+with shaded prediction bands.
+
+Format
+------
+
+.. function:: plotForecast(result, fc)
+
+ :param result: Estimation result containing historical data.
+ :type result: struct bvarResult
+
+ :param fc: Forecast result from :func:`bvarForecast`.
+ :type fc: struct forecastResult
+
+Examples
+--------
+
+Basic Forecast Plot
++++++++++++++++++++
+
+::
+
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ result = bvarFit(data, p=4, ar=0);
+ fc = bvarForecast(result, 8);
+
+ // One line — produces m stacked panels with fan charts
+ plotForecast(result, fc);
+
+Save to File
+++++++++++++
+
+::
+
+ plotForecast(result, fc);
+ plotSave("forecast_fan_chart.png", "px", 800 | 600);
+
+Remarks
+-------
+
+**Layout:** For multivariate models, each variable gets its own panel in a
+vertical stack. Panels are auto-titled with variable names from the result struct.
+
+**Historical context:** The plot shows the last 20% of the training data (or 40
+observations, whichever is larger) leading into the forecast horizon. This lets
+you see how the forecast extends from the observed data.
+
+**Layering:** Historical data is plotted as a solid black line. The forecast band
+is a shaded gray area between the lower and upper bounds. The forecast median is
+a solid blue line.
+
+**Band level:** The band corresponds to the *level* used in the :func:`bvarForecast`
+call (default 68%). To show 90% bands, use ``bvarForecast(result, h, 0.90)``.
+
+.. seealso:: Functions :func:`bvarForecast`, :func:`bvarFit`
diff --git a/docs/timeseries/plotirf.rst b/docs/timeseries/plotirf.rst
new file mode 100644
index 00000000..8f293b36
--- /dev/null
+++ b/docs/timeseries/plotirf.rst
@@ -0,0 +1,62 @@
+plotIrf
+=======
+
+Purpose
+-------
+Plot impulse response functions in an m × m grid. Each cell shows the
+response of one variable to a one-standard-deviation shock to another.
+
+Format
+------
+
+.. function:: plotIrf(irf)
+
+ :param irf: IRF result from :func:`irfCompute` or :func:`girfCompute`.
+ :type irf: struct irfResult
+
+Examples
+--------
+
+Cholesky IRF Grid
++++++++++++++++++
+
+::
+
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ rv = varFit(data, p=4, quiet=1);
+ irf = irfCompute(rv, 20);
+
+ // 3×3 grid of impulse responses
+ plotIrf(irf);
+
+Save to File
+++++++++++++
+
+::
+
+ plotIrf(irf);
+ plotSave("irf_grid.png", "px", 900 | 900);
+
+Remarks
+-------
+
+**Grid layout:** Row *i*, column *j* shows the response of variable *i* to a
+shock to variable *j*. Each cell is titled "response ← shock" using the
+variable names from the estimation result.
+
+**Zero line:** A horizontal dashed gray line at zero is drawn in every cell.
+If the IRF stays above (or below) zero at all horizons, the effect is
+consistently positive (or negative).
+
+**Diagonal cells:** These show each variable's response to its own shock. For
+Cholesky identification, the impact response (h=0) on the diagonal equals
+the Cholesky factor of :math:`\Sigma`.
+
+**For credible bands:** Use :func:`plotSvIrf` with an :class:`svIrfResult` from
+:func:`irfSvCompute`. The point-estimate :func:`plotIrf` does not show bands.
+
+.. seealso:: Functions :func:`irfCompute`, :func:`girfCompute`, :func:`plotSvIrf`
diff --git a/docs/timeseries/plotresiduals.rst b/docs/timeseries/plotresiduals.rst
new file mode 100644
index 00000000..9a8367f4
--- /dev/null
+++ b/docs/timeseries/plotresiduals.rst
@@ -0,0 +1,60 @@
+plotResiduals
+=============
+
+Purpose
+-------
+Plot residual diagnostics: time series plot, autocorrelation function (ACF),
+and histogram. Three panels per variable.
+
+Format
+------
+
+.. function:: plotResiduals(result)
+
+ :param result: Estimation result containing residuals.
+ :type result: struct varResult
+
+Examples
+--------
+
+VAR Residual Diagnostics
+++++++++++++++++++++++++
+
+::
+
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ rv = varFit(data, p=4, quiet=1);
+
+ // 3 diagnostic panels per variable
+ plotResiduals(rv);
+
+Remarks
+-------
+
+**Three panels per variable:**
+
+1. **Time plot** — residuals over time with a zero line. Look for patterns,
+ structural breaks, or volatility clustering. If the residuals look random,
+ the model captures the serial dependence.
+
+2. **ACF** — autocorrelation at lags 1 through 20. The red dashed lines show
+ the 95% significance bounds (:math:`\pm 1.96 / \sqrt{T}`). Spikes beyond
+ these bounds indicate remaining autocorrelation that the model didn't capture.
+
+3. **Histogram** — distribution of residuals. Should look approximately normal
+ and centered at zero. Heavy tails suggest outliers or non-normality.
+
+**Multivariate:** For models with m > 1 variables, each variable opens a
+separate plot window with its own 3-panel diagnostic display.
+
+**What to look for:**
+
+- ACF spikes at seasonal lags (12, 24 for monthly data) → add seasonal terms
+- Volatility clustering in the time plot → consider :func:`bvarSvFit`
+- Skewed histogram → model may be misspecified for extreme observations
+
+.. seealso:: Functions :func:`varFit`, :func:`varDiagnostics`
diff --git a/docs/timeseries/plotstl.rst b/docs/timeseries/plotstl.rst
new file mode 100644
index 00000000..832c1f55
--- /dev/null
+++ b/docs/timeseries/plotstl.rst
@@ -0,0 +1,68 @@
+plotStl
+=======
+
+Purpose
+-------
+Plot STL decomposition in four panels: original data, trend, seasonal pattern,
+and remainder.
+
+Format
+------
+
+.. function:: plotStl(y, stl)
+
+ :param y: Original time series.
+ :type y: Nx1 matrix
+
+ :param stl: STL decomposition result from :func:`stlDecompose`.
+ :type stl: struct stlResult
+
+Examples
+--------
+
+Airline Passengers Decomposition
++++++++++++++++++++++++++++++++++
+
+::
+
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline_passengers.csv");
+ y = loadd(fname, "passengers");
+
+ stl = stlDecompose(y, 12);
+
+ // 4 stacked panels
+ plotStl(y, stl);
+
+Save to File
+++++++++++++
+
+::
+
+ plotStl(y, stl);
+ plotSave("stl_decomposition.png", "px", 800 | 800);
+
+Remarks
+-------
+
+**Four panels:**
+
+1. **Data** — the original series (black line)
+2. **Trend** — long-run level extracted by LOESS (blue line)
+3. **Seasonal** — repeating periodic pattern with zero line (green line)
+4. **Remainder** — what's left after removing trend and seasonal (red line, with zero line)
+
+The decomposition is additive: Data = Trend + Seasonal + Remainder.
+
+**Reading the plot:**
+
+- If the **trend** is smooth and captures the long-run movement, the seasonal
+ period is correctly specified.
+- If the **seasonal** pattern changes amplitude over time, consider a
+ multiplicative decomposition (take logs first).
+- If the **remainder** shows patterns or autocorrelation, the decomposition
+ didn't capture all the structure — the ARIMA model on the remainder should
+ handle it.
+
+.. seealso:: Functions :func:`stlDecompose`, :func:`arimaFit`
diff --git a/docs/timeseries/plotsvirf.rst b/docs/timeseries/plotsvirf.rst
new file mode 100644
index 00000000..bc8cff60
--- /dev/null
+++ b/docs/timeseries/plotsvirf.rst
@@ -0,0 +1,50 @@
+plotSvIrf
+=========
+
+Purpose
+-------
+Plot SV-BVAR impulse responses with credible bands in an m × m grid.
+Shows median IRF with shaded 68% and 90% posterior bands.
+
+Format
+------
+
+.. function:: plotSvIrf(irf)
+
+ :param irf: Posterior IRF result from :func:`irfSvCompute`.
+ :type irf: struct svIrfResult
+
+Examples
+--------
+
+Posterior IRF with Bands
+++++++++++++++++++++++++
+
+::
+
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ svr = bvarSvFit(data, p=4, ar=0, n_draws=5000, n_burn=2000, quiet=1);
+ irf = irfSvCompute(svr, 20);
+
+ // 3×3 grid with shaded credible bands
+ plotSvIrf(irf);
+
+Remarks
+-------
+
+**Band shading:** The inner band (68%) is drawn with darker shading, the outer
+band (90%) with lighter shading. The median IRF is a solid blue line.
+
+**Grid layout:** Same as :func:`plotIrf` — row *i* = response variable,
+column *j* = shock source.
+
+**Significance:** If both the 68% and 90% bands exclude zero at a given horizon,
+the response is significant at that horizon with high posterior probability.
+
+**Zero line:** A horizontal dashed gray line at zero is drawn in every cell.
+
+.. seealso:: Functions :func:`irfSvCompute`, :func:`plotIrf`, :func:`bvarSvFit`
diff --git a/docs/timeseries/stldecompose.rst b/docs/timeseries/stldecompose.rst
new file mode 100644
index 00000000..b6dae544
--- /dev/null
+++ b/docs/timeseries/stldecompose.rst
@@ -0,0 +1,161 @@
+stlDecompose
+============
+
+Purpose
+-------
+Seasonal-Trend decomposition via LOESS (STL).
+
+Format
+------
+
+.. function:: stl = stlDecompose(y, period)
+ stl = stlDecompose(y, period, s_window=7)
+
+ :param y: time series data.
+ :type y: Nx1 vector
+
+ :param period: seasonal period (e.g., 12 for monthly, 4 for quarterly, 52 for weekly).
+ :type period: scalar
+
+ :param s_window: Optional keyword, seasonal smoothing window (must be odd, >= 7). Default = auto.
+ :type s_window: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :return stl: An instance of a :class:`stlResult` structure containing:
+
+ .. list-table::
+ :widths: auto
+
+ * - stl.seasonal
+ - Nx1 vector, seasonal component.
+
+ * - stl.trend
+ - Nx1 vector, trend component.
+
+ * - stl.remainder
+ - Nx1 vector, remainder (y - seasonal - trend).
+
+ :rtype stl: struct
+
+Examples
+--------
+
+Monthly Data
+++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+
+ stl = stlDecompose(y, 12);
+
+ print "Seasonal component (first year):";
+ print stl.seasonal[1:12];
+
+ print "Trend (first 5):";
+ print stl.trend[1:5];
+
+Deseasonalize then Fit ARIMA
++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline.dat");
+ y = loadd(fname, "passengers");
+
+ stl = stlDecompose(y, 12, quiet=1);
+
+ // Fit ARIMA on seasonally adjusted series
+ y_adj = y - stl.seasonal;
+ result = arimaFit(y_adj);
+
+Weekly Data
++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/weekly.dat");
+ y = loadd(fname, "sales");
+
+ stl = stlDecompose(y, 52, s_window=15);
+
+Remarks
+-------
+
+STL decomposes a time series into three additive components:
+
+.. math::
+
+ y_t = S_t + T_t + R_t
+
+where :math:`S_t` is the seasonal component, :math:`T_t` is the trend, and
+:math:`R_t` is the remainder.
+
+**The seasonal smoothing window** (*s_window*) controls how rapidly the seasonal
+pattern can change. Larger values produce a more stable seasonal pattern.
+Must be odd and >= 7. The default is typically ``period + 1`` (rounded to odd).
+
+Algorithm
+---------
+
+STL uses an inner loop of iterative LOESS (locally weighted regression) smoothing:
+
+1. **Detrend:** Subtract the current trend estimate from the series.
+2. **Seasonal smoothing:** Apply LOESS to each subseries (e.g., all Januaries) with window *s_window*.
+3. **Low-pass filter:** Remove high-frequency artifacts from the seasonal estimate.
+4. **Deseasonalize:** Subtract the seasonal estimate from the original series.
+5. **Trend smoothing:** Apply LOESS to the deseasonalized series.
+6. **Iterate** steps 1-5 (typically 2 inner iterations, 1 outer iteration for robustness weights).
+
+See Cleveland et al. (1990) for the complete specification.
+
+
+Troubleshooting
+---------------
+
+**Seasonal component is too smooth / not smooth enough:**
+Increase *s_window* for smoother seasonal patterns; decrease for more adaptive patterns.
+The default is typically ``period + 1``.
+
+**Remainder has visible seasonal pattern:**
+*s_window* is too large — the seasonal smoother can't track changes in the seasonal
+pattern. Reduce *s_window* or use a multiplicative decomposition (take logs first,
+decompose, exponentiate).
+
+
+Verification
+------------
+
+STL decomposition verified against R ``stats::stl()`` with ``s.window=13`` on the
+AirPassengers dataset. Seasonal, trend, and remainder components match at :math:`10^{-4}`
+tolerance.
+
+
+
+References
+----------
+
+- Cleveland, R.B., W.S. Cleveland, J.E. McRae, and I. Terpenning (1990). "STL: A seasonal-trend decomposition procedure based on Loess." *Journal of Official Statistics*, 6(1), 3-73.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+stl.src
+
+.. seealso:: Functions :func:`arimaFit`
diff --git a/docs/timeseries/svarcontrolcreate.rst b/docs/timeseries/svarcontrolcreate.rst
new file mode 100644
index 00000000..e19af144
--- /dev/null
+++ b/docs/timeseries/svarcontrolcreate.rst
@@ -0,0 +1,78 @@
+svarControlCreate
+==================
+
+Purpose
+-------
+Initialize an :class:`svarControl` structure with default values for use with :func:`svarIrfCompute`.
+
+Format
+------
+
+.. function:: adv = svarControlCreate()
+
+ :return adv: An instance of an :class:`svarControl` structure with the following members:
+
+ .. include:: include/svarcontrol.rst
+
+ :rtype adv: struct
+
+Examples
+--------
+
+Default Settings
+++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ struct svarControl adv;
+ adv = svarControlCreate();
+
+Adding Zero Restrictions
+++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ struct svarControl adv;
+ adv = svarControlCreate();
+
+ // Zero restriction: shock 1 has no contemporaneous
+ // effect on variable 3
+ adv.zero_restr = { 3 1 0 };
+
+Adding Narrative Restrictions
++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ struct svarControl adv;
+ adv = svarControlCreate();
+
+ // Narrative restriction: shock 3 was positive at obs 84
+ // [type, variable, shock, date1, date2, sign]
+ adv.narrative_restr = { 1 3 3 84 0 1 };
+
+Remarks
+-------
+
+The :class:`svarControl` structure is optional. When only sign restrictions
+are needed, :func:`svarIrfCompute` can be called without it. The advanced structure
+is required when using zero restrictions, or when overriding default algorithm settings.
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`svarIrfCompute`
diff --git a/docs/timeseries/svaridentify.rst b/docs/timeseries/svaridentify.rst
new file mode 100644
index 00000000..f6ccc5c4
--- /dev/null
+++ b/docs/timeseries/svaridentify.rst
@@ -0,0 +1,167 @@
+svarIdentify
+============
+
+Purpose
+-------
+Find a structural rotation satisfying sign restrictions for a single VAR or BVAR estimate.
+
+Format
+------
+
+.. function:: sr = svarIdentify(result, sign_restr)
+ sr = svarIdentify(result, sign_restr, n_ahead=20, max_tries=10000, seed=42, quiet=0)
+
+ :param result: an instance of a :class:`varResult` or :class:`bvarResult` structure.
+ :type result: struct
+
+ :param sign_restr: Nx4 matrix of sign restrictions on impulse responses. Each row specifies one restriction:
+
+ === ==================================================================
+ 1 Variable index (1 to m) -- the responding variable.
+ 2 Shock index (1 to m) -- the structural shock.
+ 3 Horizon (0 = impact, 1 = one step ahead, etc.).
+ 4 Sign: 1 for positive response, -1 for negative response.
+ === ==================================================================
+
+ :type sign_restr: Nx4 matrix
+
+ :param n_ahead: Optional keyword, number of IRF horizons to compute. Default = 20.
+ :type n_ahead: scalar
+
+ :param max_tries: Optional keyword, maximum number of rotation attempts before giving up. Default = 10000.
+ :type max_tries: scalar
+
+ :param seed: Optional keyword, RNG seed for reproducible rotation draws. Default = 42.
+ :type seed: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return sr: An instance of an :class:`svarResult` structure containing:
+
+ .. list-table::
+ :widths: auto
+
+ * - sr.p
+ - mxm matrix, structural impact matrix P such that :math:`\Sigma = PP'`.
+
+ * - sr.irf
+ - :class:`irfResult` struct, identified impulse responses under this rotation.
+
+ * - sr.n_tries
+ - Scalar, number of rotation attempts needed to find a valid rotation.
+
+ * - sr.m
+ - Scalar, number of variables.
+
+ * - sr.var_names
+ - Mx1 string array, variable names.
+
+ * - sr.shock_names
+ - Mx1 string array, shock labels.
+
+ :rtype sr: struct
+
+Examples
+--------
+
+Monetary Policy SVAR
+++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ // Load data — ordering determines Cholesky structure
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ result = varFit(y, 4);
+
+ // Sign restrictions: [variable, shock, horizon, sign]
+ // Monetary shock (shock 3): FFR up, GDP down, CPI down at impact
+ sign_restr = { 3 3 0 1, // FFR positive
+ 1 3 0 -1, // GDP negative
+ 2 3 0 -1 }; // CPI negative
+
+ sr = svarIdentify(result, sign_restr);
+
+ print "Structural impact matrix P:";
+ print sr.p;
+ print "Rotations tried:" sr.n_tries;
+
+Remarks
+-------
+
+**Algorithm:**
+Draws random orthogonal matrices Q from the Haar measure on O(m) via QR
+decomposition of N(0,1) matrices with sign correction (Mezzadri 2007). For
+each candidate Q, forms :math:`P = \text{chol}(\Sigma) \cdot Q` and checks
+all sign restrictions on the implied IRFs. Returns the first accepted rotation.
+
+**This function finds a single rotation,** which is useful for point estimation
+(e.g., from an OLS VAR). For posterior inference with credible bands, use
+:func:`svarIrfCompute` with a :class:`bvarResult` or :class:`bvarSvResult`.
+
+**Zero restrictions** are not currently supported in :func:`svarIdentify`.
+Zero restrictions require the ARW2018 null-space algorithm; use
+:func:`svarIrfCompute` with an :class:`svarControl` struct for zero restrictions.
+
+Model
+-----
+
+Sign-restricted SVAR decomposes the error covariance as :math:`\Sigma = PP'` where
+:math:`P` is not unique. The set of valid decompositions is :math:`\{PQ : Q \in O(m),\; PQ \text{ satisfies sign restrictions}\}` where :math:`O(m)` is the group of orthogonal matrices.
+
+Given a set of sign restrictions :math:`\Theta_h[i,j] \gtrless 0` (the IRF of variable
+:math:`i` to shock :math:`j` at horizon :math:`h` is positive or negative), the
+function finds a :math:`Q^*` such that :math:`P^* = \text{chol}(\Sigma)' \cdot Q^*`
+produces IRFs satisfying all restrictions.
+
+Algorithm
+---------
+
+1. Compute :math:`L = \text{chol}(\Sigma)'`.
+2. Draw :math:`Z \sim N(0, I_{m \times m})` and compute :math:`Q, R = \text{QR}(Z)` with sign correction (Mezzadri 2007 algorithm for Haar-uniform orthogonal matrices).
+3. Form candidate :math:`P = L \cdot Q`.
+4. Compute IRFs :math:`\Theta_h = J F^h J' P` at all restricted horizons.
+5. Check all sign restrictions. If satisfied, return :math:`P`. Otherwise, go to step 2.
+6. Repeat up to *max_tries* times.
+
+**Complexity:** :math:`O(\text{max\_tries} \cdot h_{\max} \cdot m^2 p^2)` worst case. Acceptance rates depend on how restrictive the sign constraints are.
+
+Troubleshooting
+---------------
+
+**No valid rotation found (max_tries exceeded):**
+The sign restrictions may be too numerous, contradictory, or implausible for this data.
+Relax some restrictions or increase *max_tries*.
+
+**Low acceptance rate (< 1%):**
+Many restrictions at long horizons are hard to satisfy. Start with impact-only
+restrictions and add horizons incrementally.
+
+Verification
+------------
+
+Sign restriction algorithm verified against the Rubio-Ramirez, Waggoner & Zha (2010)
+analytical examples for 2-variable and 3-variable systems.
+
+
+References
+----------
+
+- Mezzadri, F. (2007). "How to generate random matrices from the classical compact groups." *Notices of the AMS*, 54(5), 592-604.
+- Rubio-Ramirez, J.F., D.F. Waggoner, and T. Zha (2010). "Structural vector autoregressions: Theory of identification and algorithms for inference." *Review of Economic Studies*, 77(2), 665-696.
+- Uhlig, H. (2005). "What are the effects of monetary policy on output? Results from an agnostic identification procedure." *Journal of Monetary Economics*, 52(2), 381-419.
+
+Library
+-------
+timeseries
+
+Source
+------
+svar.src
+
+.. seealso:: Functions :func:`svarIrfCompute`, :func:`svarControlCreate`, :func:`irfCompute`
diff --git a/docs/timeseries/svarirfcompute.rst b/docs/timeseries/svarirfcompute.rst
new file mode 100644
index 00000000..6e2cd857
--- /dev/null
+++ b/docs/timeseries/svarirfcompute.rst
@@ -0,0 +1,345 @@
+svarIrfCompute
+==============
+
+Purpose
+-------
+Compute posterior sign-restricted, zero-restricted, and narrative-restricted IRF, cumulative IRF, and FEVD bands from SV-BVAR draws.
+
+Format
+------
+
+.. function:: sir = svarIrfCompute(result, sign_restr)
+ sir = svarIrfCompute(result, sign_restr, n_ahead=20, narr_restr={}, max_tries=10000, seed=42, quiet=0, ctl={})
+
+ :param result: an instance of a :class:`bvarSvResult` structure with posterior draws from :func:`bvarSvFit`.
+ :type result: struct
+
+ :param sign_restr: Nx4 matrix of sign restrictions on impulse responses. Each row specifies one restriction:
+
+ === ==================================================================
+ 1 Variable index (1 to m) -- the responding variable.
+ 2 Shock index (1 to m) -- the structural shock.
+ 3 Horizon (0 = impact, 1 = one step ahead, etc.).
+ 4 Sign: 1 for positive response, -1 for negative response.
+ === ==================================================================
+
+ :type sign_restr: Nx4 matrix
+
+ :param n_ahead: Optional keyword, number of IRF horizons to compute. Default = 20.
+ :type n_ahead: scalar
+
+ :param narr_restr: Optional keyword, Nx6 matrix of narrative restrictions. Each row specifies one restriction:
+
+ === ==================================================================
+ 1 Type: narrative restriction type (see table below).
+ 2 Variable index (1 to m).
+ 3 Shock index (1 to m).
+ 4 Date 1: observation index (1-indexed) for point restrictions, or start of range.
+ 5 Date 2: end observation index for range restrictions (0 if unused).
+ 6 Sign: 1 for positive, -1 for negative.
+ === ==================================================================
+
+ Narrative restriction types:
+
+ .. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Type
+ - Name
+ - Meaning
+ * - 1
+ - ``shock_sign``
+ - The structural shock *j* at date *t* has the specified sign.
+ * - 2
+ - ``shock_dominance``
+ - Shock *j* is the dominant contributor to variable *i* at date *t* (its contribution exceeds all others).
+ * - 3
+ - ``decomposition_sign``
+ - The historical decomposition contribution of shock *j* to variable *i* at date *t* has the specified sign.
+
+ :type narr_restr: Nx6 matrix
+
+ :param max_tries: Optional keyword, maximum number of rotation attempts per posterior draw before giving up. Default = 10000.
+ :type max_tries: scalar
+
+ :param seed: Optional keyword, RNG seed for reproducible rotation draws. Default = 42.
+ :type seed: scalar
+
+ :param ctl: Optional keyword, an instance of an :class:`svarControl` structure for zero restrictions and advanced settings. An instance is initialized by calling :func:`svarControlCreate` and the following members can be set:
+
+ .. include:: include/svarcontrol.rst
+
+ :type ctl: struct
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return sir: An instance of an :class:`svarPosteriorResult` structure containing:
+
+ .. include:: include/svarposteriorresult.rst
+
+ :rtype sir: struct
+
+Examples
+--------
+
+Basic Monetary Policy SVAR
+++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ // Estimate SV-BVAR
+ result = bvarSvFit(y, p=4, n_draws=10000, n_burn=5000, quiet=1);
+
+ // Sign restrictions for monetary policy shock
+ // [variable, shock, horizon, sign]
+ // variable and shock: 1-indexed (GAUSS convention)
+ // horizon: 0 = impact, 1 = one step ahead, etc.
+ // sign: 1 = positive, -1 = negative
+ sign_restr = { 3 3 0 1, // FFR up on impact
+ 1 3 0 -1, // GDP down on impact
+ 2 3 0 -1 }; // CPI down on impact
+
+ sir = svarIrfCompute(result, sign_restr);
+
+ print "Acceptance rate:" sir.accept_rate;
+
+Sign + Zero Restrictions
+++++++++++++++++++++++++
+
+Combine sign restrictions with zero (exclusion) restrictions. The algorithm automatically switches to ARW2018 when zero restrictions are present:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ result = bvarSvFit(y, quiet=1);
+
+ // Sign restrictions
+ sign_restr = { 3 3 0 1, // FFR up at impact
+ 1 3 0 -1 }; // GDP down at impact
+
+ // Zero restrictions: monetary shock has no
+ // contemporaneous effect on CPI
+ struct svarControl adv;
+ adv = svarControlCreate();
+ adv.zero_restr = { 2 3 0 }; // [variable, shock, horizon]
+
+ sir = svarIrfCompute(result, sign_restr, n_ahead=20, ctl=adv);
+
+With Narrative Restrictions
++++++++++++++++++++++++++++
+
+Add narrative restrictions to sharpen identification. The algorithm automatically dispatches to the v3 narrative engine:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ result = bvarSvFit(y, quiet=1);
+
+ // Sign restrictions
+ sign_restr = { 3 3 0 1,
+ 1 3 0 -1,
+ 2 3 0 -1 };
+
+ // Narrative restriction: Volcker disinflation
+ // Monetary shock (shock 3) was positive in 1980:Q4 (obs 84)
+ narr_restr = { 1 3 3 84 0 1 };
+ // type=1 (shock_sign), var=3, shock=3,
+ // date1=84, date2=0, sign=+1
+
+ sir = svarIrfCompute(result, sign_restr, narr_restr=narr_restr);
+
+Oil Market SVAR with Narrative Restrictions
++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/oil_market.csv");
+ y = loadd(fname, "oil_production + real_activity + real_oil_price");
+
+ // Estimate SV-BVAR
+ result = bvarSvFit(y, p=12, n_draws=10000, n_burn=5000, quiet=1);
+
+ // Sign restrictions: oil supply shock
+ sign_restr = { 1 1 0 -1, // Production falls
+ 3 1 0 1 }; // Oil price rises
+
+ // Narrative restrictions:
+ // 1990:M8 (obs 200): supply shock was negative (Gulf War)
+ // 2008:M7 (obs 415): demand shock dominated oil price
+ narr_restr = { 1 1 1 200 0 -1, // shock_sign: supply shock negative
+ 2 3 2 415 0 1 }; // shock_dominance: demand shock
+ // dominated oil price
+
+ sir = svarIrfCompute(result, sign_restr, narr_restr=narr_restr);
+
+ print "Acceptance rate:" sir.accept_rate;
+
+Accessing Results and Plotting
+++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ // ... (estimate and identify as above) ...
+
+ // Median response of GDP to monetary shock at h=5
+ print sir.irf_median[6, 1, 3];
+
+ // 68% band
+ print sir.irf_bands[1].lower[6, 1, 3] "to" sir.irf_bands[1].upper[6, 1, 3];
+
+ // Cumulative response (for differenced VARs)
+ print "Cumulative GDP response to monetary shock at h=20:";
+ print sir.cirf_median[21, 1, 3];
+
+ // FEVD: GDP variance from monetary shock at h=20
+ print "GDP variance share from monetary shock:";
+ print sir.fevd_median[21, 1, 3];
+
+ // Plot using irfPlotData
+ df = irfPlotData(sir, 3, 1); // Monetary shock -> GDP
+ plotXY(df[., "horizon"], df[., "median"]~df[., "bands_1_lower"]~df[., "bands_1_upper"]);
+
+Remarks
+-------
+
+**Sign restriction format:**
+Each row of *sign_restr* is ``{variable, shock, horizon, sign}`` where
+indices are 1-based (GAUSS convention). Multiple restrictions are stacked
+as rows:
+
+::
+
+ sign_restr = { 3 3 0 1,
+ 1 3 0 -1,
+ 2 3 0 -1 };
+
+**Algorithm auto-dispatch:**
+The function automatically selects the appropriate backend algorithm:
+
+- **Pure sign restrictions:** RRW2010 accept-reject (fast, Haar-uniform draws).
+- **Sign + zero restrictions:** ARW2018 null-space construction (exact zeros by construction).
+- **Narrative restrictions present:** v3 narrative engine (ADRR2018 importance-weighted accept-reject).
+
+Override with ``ctl.algorithm``: 0 = auto (default), 1 = accept-reject, 2 = ARW2018.
+
+**Acceptance rate:**
+The acceptance rate (*sir.accept_rate*) indicates what fraction of posterior
+draws yielded a valid rotation. Rates below 10% suggest the restrictions may
+be too tight, contradictory, or implausible for the data.
+
+**SV-BVAR draws:**
+The time-T covariance :math:`\Sigma_T` is reconstructed from U and
+:math:`h_T` for each draw, giving identification at the current volatility
+state rather than a time-averaged covariance.
+
+**Sign vs zero vs narrative restrictions:**
+
+- **Sign restrictions** constrain the *direction* of impulse responses (positive or negative). They are set-identifying: many rotations satisfy the same signs, producing wide credible bands.
+- **Zero restrictions** constrain specific impulse responses to be *exactly zero* at a given horizon. They tighten identification and are enforced by algebraic construction, not accept-reject.
+- **Narrative restrictions** constrain the *historical decomposition* at specific dates, using known historical events to discipline identification. They are the most informative and produce the tightest bands.
+
+**Narrative restriction types:**
+
+- **Type 1 (shock_sign):** The most basic narrative restriction. It constrains the sign of a specific structural shock at a known date. Example: the monetary policy shock was contractionary in 1979:Q4.
+- **Type 2 (shock_dominance):** Constrains a specific shock to be the single largest contributor to the forecast error of a given variable at the specified date. Stronger than shock_sign.
+- **Type 3 (decomposition_sign):** Constrains the sign of the historical decomposition contribution of a specific shock to a given variable. Useful when the event is known to have moved a variable in a particular direction.
+
+**Observation indexing:**
+The *date1* and *date2* columns use 1-based observation indices matching the
+estimation sample. For quarterly data starting in 1960:Q1, observation 84
+corresponds to 1980:Q4.
+
+Model
+-----
+
+For each posterior draw :math:`(B^{(s)}, \Sigma^{(s)})`, the function searches for a
+sign-satisfying rotation :math:`Q^{(s)}` and computes:
+
+- **IRF:** :math:`\Theta_h^{(s)} = J (F^{(s)})^h J' P^{(s)} Q^{(s)}`
+- **Cumulative IRF:** :math:`C_h^{(s)} = \sum_{\ell=0}^{h} \Theta_\ell^{(s)}`
+- **FEVD:** Variance share from each shock, with posterior uncertainty
+
+The resulting bands integrate over both parameter uncertainty (different draws) and
+set identification uncertainty (different valid rotations within each draw).
+
+Algorithm
+---------
+
+1. For each of *n_draws* posterior draws :math:`(B^{(s)}, \Sigma^{(s)})`:
+
+ a. Form :math:`L^{(s)} = \text{chol}(\Sigma^{(s)})'`.
+ b. Draw random rotations :math:`Q` until one satisfies all sign restrictions (accept-reject), or construct :math:`Q` in the null space of zero restrictions (ARW2018).
+ c. If narrative restrictions are present, apply importance-weighted accept-reject (ADRR2018).
+ d. Compute IRF, cumulative IRF, and FEVD under the accepted rotation.
+
+2. Compute pointwise quantiles across accepted draws (median, 68%, 90% bands).
+
+**Complexity:** :math:`O(n\_accepted \cdot h \cdot m^2 p^2 + n\_total\_tries \cdot m^3)`.
+
+Troubleshooting
+---------------
+
+**Very low acceptance rate (< 5%):**
+Too many restrictions for this model. Options:
+
+- Remove restrictions at longer horizons (keep impact only).
+- Remove restrictions on variables weakly related to the shock.
+- Use a wider credible level to see if the posterior spans both signs.
+
+**Bands are very wide:**
+Sign restrictions are set-identifying (not point-identifying). Wide bands reflect
+genuine identification uncertainty. Consider adding zero or narrative restrictions
+to tighten identification.
+
+**Cumulative IRF is needed for differenced data:**
+If your VAR is estimated on growth rates, the cumulative IRF gives the level response.
+Use ``sir.cirf_median`` instead of ``sir.irf_median``.
+
+Verification
+------------
+
+Sign-restricted posterior IRFs cross-validated against ECB BEAR ``bear.irfres()``
+output and the Rubio-Ramirez, Waggoner & Zha (2010) analytical examples.
+Narrative restrictions verified against Antolin-Diaz & Rubio-Ramirez (2018) replication files.
+
+References
+----------
+
+- Antolin-Diaz, J. and J.F. Rubio-Ramirez (2018). "Narrative sign restrictions for SVARs." *American Economic Review*, 108(10), 2802-2829.
+- Arias, J.E., J.F. Rubio-Ramirez, and D.F. Waggoner (2018). "Inference based on structural vector autoregressions identified with sign and zero restrictions: Theory and applications." *Econometrica*, 86(2), 685-720.
+- Fry, R. and A. Pagan (2011). "Sign restrictions in structural vector autoregressions: A critical review." *Journal of Economic Literature*, 49(4), 938-960.
+- Rubio-Ramirez, J.F., D.F. Waggoner, and T. Zha (2010). "Structural vector autoregressions: Theory of identification and algorithms for inference." *Review of Economic Studies*, 77(2), 665-696.
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`svarControlCreate`, :func:`svarIdentify`, :func:`bvarSvFit`, :func:`irfPlotData`
diff --git a/docs/timeseries/svforecastcontrolcreate.rst b/docs/timeseries/svforecastcontrolcreate.rst
new file mode 100644
index 00000000..57a054dc
--- /dev/null
+++ b/docs/timeseries/svforecastcontrolcreate.rst
@@ -0,0 +1,47 @@
+svForecastControlCreate
+=======================
+
+Purpose
+-------
+Create an :class:`svForecastControl` structure with default values for SV-BVAR density forecasting.
+
+Format
+------
+
+.. function:: ctl = svForecastControlCreate()
+
+ :return ctl: An instance of an :class:`svForecastControl` structure with the following default values:
+
+ .. include:: include/svforecastcontrol.rst
+
+ :rtype ctl: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ fctl = svForecastControlCreate();
+
+ // Switch to simulation mode for proper density
+ fctl.mode = "simulate";
+ fctl.n_paths = 500;
+
+ // Custom quantiles for risk management
+ fctl.quantile_levels = 0.01|0.05|0.50|0.95|0.99;
+
+ // Use with bvarSvForecast
+ dfc = bvarSvForecast(result, 12, fctl);
+
+Library
+-------
+timeseries
+
+Source
+------
+forecast.src
+
+.. seealso:: Functions :func:`bvarSvForecast`
diff --git a/docs/timeseries/textbook-mapping.rst b/docs/timeseries/textbook-mapping.rst
new file mode 100644
index 00000000..c7edcf8d
--- /dev/null
+++ b/docs/timeseries/textbook-mapping.rst
@@ -0,0 +1,300 @@
+.. _textbook-mapping:
+
+Teaching with GAUSS Time Series
+===============================
+
+This page maps GAUSS Time Series functions to chapters in four textbooks
+commonly used in PhD econometrics and time series courses. Each exercise
+below includes runnable GAUSS code alongside the relevant textbook reference.
+
+Hamilton (1994) — *Time Series Analysis*
+----------------------------------------
+
+The standard reference for PhD time series econometrics. Covers ARMA, VAR, Kalman
+filter, spectral analysis, unit roots, cointegration, and regime switching.
+
+.. list-table::
+ :widths: 10 40 25 25
+ :header-rows: 1
+
+ * - Ch.
+ - Topic
+ - GAUSS function
+ - Exercise idea
+ * - 3-4
+ - ARMA processes, forecasting
+ - :func:`arimaFit`, :func:`arimaForecast`
+ - Fit ARIMA to Nile river data. Compare auto-selected vs fixed order.
+ * - 5
+ - Maximum likelihood estimation
+ - :func:`arimaFit` (``method="ml"``)
+ - Compare CSS vs ML estimation on AirPassengers. Examine log-likelihood surface.
+ * - 11
+ - Vector autoregressions
+ - :func:`varFit`, :func:`varLagSelect`
+ - Replicate a 3-variable monetary policy VAR. Select lag order by AIC/BIC.
+ * - 11.4
+ - Granger causality
+ - :func:`grangerTest`
+ - Test whether FFR Granger-causes GDP in the monetary policy VAR.
+ * - 11.6
+ - Impulse response functions
+ - :func:`irfCompute`, :func:`fevdCompute`
+ - Compute Cholesky IRFs. Discuss ordering sensitivity.
+ * - 11.7
+ - VAR forecasting
+ - :func:`varForecast`, :func:`bvarForecast`
+ - Compare frequentist vs Bayesian forecast intervals.
+ * - 12
+ - Bayesian analysis
+ - :func:`bvarFit`, :func:`bvarHyperopt`
+ - Estimate Minnesota BVAR. Compare log marginal likelihood across priors.
+ * - 13
+ - Kalman filter
+ - :func:`arimaFit` (state-space backend)
+ - GAUSS ARIMA uses Kalman filter internally. Show equivalence with Hamilton Ch. 13 formulas.
+ * - 21
+ - ARCH / heteroskedasticity
+ - :func:`bvarSvFit`
+ - Estimate SV-BVAR and show time-varying volatility captures ARCH effects.
+
+Lutkepohl (2005) — *New Introduction to Multiple Time Series Analysis*
+----------------------------------------------------------------------
+
+The definitive VAR reference. Covers estimation, specification, structural analysis,
+cointegration, and state-space models for multivariate systems.
+
+.. list-table::
+ :widths: 10 40 25 25
+ :header-rows: 1
+
+ * - Ch.
+ - Topic
+ - GAUSS function
+ - Exercise idea
+ * - 2.1
+ - VAR(p) processes and stability
+ - :func:`varFit`, :func:`varCompanion`
+ - Estimate VAR(4). Check companion eigenvalues for stationarity.
+ * - 2.3
+ - Impulse responses and FEVD
+ - :func:`irfCompute`, :func:`fevdCompute`
+ - Compute IRFs at posterior mean. Verify FEVD rows sum to 1.
+ * - 2.3.4
+ - Historical decomposition
+ - :func:`hdCompute`
+ - Decompose GDP into shock contributions. Verify reconstruction equals observed.
+ * - 3.2
+ - OLS estimation
+ - :func:`varFit`
+ - Estimate VAR by OLS. Examine coefficient layout. Match Eq. 3.2.1.
+ * - 3.5
+ - Forecasting from estimated VAR
+ - :func:`varForecast`
+ - Generate h-step forecasts with MSE-based confidence intervals.
+ * - 3.6
+ - Granger causality
+ - :func:`grangerTest`
+ - Test all pairwise Granger causality in a 3-variable system.
+ * - 4.3
+ - Model selection criteria
+ - :func:`varLagSelect`
+ - Compare AIC, BIC, HQ across lag orders 1-8. Discuss disagreements.
+ * - 5
+ - Bayesian estimation
+ - :func:`bvarFit`
+ - Minnesota prior BVAR. Compare posterior with OLS to visualize shrinkage.
+ * - 9
+ - Structural VARs
+ - :func:`irfCompute`, :func:`svarIdentify`
+ - Cholesky vs sign-restricted identification. Compare IRFs.
+
+Kilian & Lutkepohl (2017) — *Structural Vector Autoregressive Analysis*
+------------------------------------------------------------------------
+
+The modern SVAR textbook. Covers identification (short-run, long-run, sign restrictions),
+estimation, inference, and applications to oil markets and monetary policy.
+
+.. list-table::
+ :widths: 10 40 25 25
+ :header-rows: 1
+
+ * - Ch.
+ - Topic
+ - GAUSS function
+ - Exercise idea
+ * - 2
+ - VAR models
+ - :func:`varFit`, :func:`bvarFit`
+ - Estimate reduced-form VAR. Compare OLS and Bayesian.
+ * - 4
+ - Structural VAR tools
+ - :func:`irfCompute`, :func:`fevdCompute`, :func:`hdCompute`
+ - Full structural analysis pipeline: IRF → FEVD → HD.
+ * - 5
+ - Bayesian VAR analysis
+ - :func:`bvarFit`, :func:`bvarHyperopt`
+ - Minnesota prior with GLP hyperparameter optimization. Compare marginal likelihoods.
+ * - 8
+ - Short-run restrictions
+ - :func:`irfCompute`
+ - Cholesky (recursive) identification. Replicate Christiano, Eichenbaum & Evans (1999).
+ * - 10-11
+ - Long-run restrictions
+ - (planned)
+ - Blanchard-Quah decomposition. *Zero restrictions planned for future release.*
+ * - 13
+ - Sign restrictions
+ - :func:`svarIdentify`, :func:`svarIrfCompute`
+ - Replicate Uhlig (2005) monetary policy identification. Examine acceptance rates.
+ * - 13.5
+ - Sign-restricted FEVD
+ - :func:`svarIrfCompute`
+ - Posterior FEVD bands under sign restrictions.
+ * - 16
+ - Large BVARs
+ - :func:`bvarFit`, :func:`bvarSvFit`
+ - Scale to 20 variables. Compare conjugate BVAR (3s) vs SV-BVAR (8s) on large system.
+
+Hyndman & Athanasopoulos (2021) — *Forecasting: Principles and Practice* (3rd ed.)
+-----------------------------------------------------------------------------------
+
+The modern forecasting textbook. Free online at `otexts.com/fpp3 `_.
+Covers ARIMA, exponential smoothing, regression, decomposition, and forecast evaluation.
+Uses R in the text — the table below shows the GAUSS equivalents.
+
+.. list-table::
+ :widths: 10 40 25 25
+ :header-rows: 1
+
+ * - Ch.
+ - Topic
+ - GAUSS function
+ - R equivalent
+ * - 3
+ - STL decomposition
+ - :func:`stlDecompose`
+ - ``stl()``
+ * - 5.8
+ - Forecast accuracy (RMSE, MASE)
+ - :func:`fcMetrics`, :func:`fcScore`
+ - ``accuracy()``
+ * - 9
+ - ARIMA models
+ - :func:`arimaFit`
+ - ``auto.arima()``
+ * - 9.5
+ - Auto ARIMA selection
+ - :func:`arimaFit` (order omitted)
+ - ``auto.arima()``
+ * - 9.7
+ - Seasonal ARIMA
+ - :func:`arimaFit` (``period=12``)
+ - ``auto.arima()`` with seasonal
+ * - 9.9
+ - ARIMA forecasting
+ - :func:`arimaForecast`
+ - ``forecast()``
+ * - 10
+ - Dynamic regression (ARIMAX)
+ - :func:`arimaFit` (``xreg=X``)
+ - ``auto.arima(xreg=X)``
+ * - 12.3
+ - VAR models
+ - :func:`varFit`, :func:`bvarFit`
+ - ``vars::VAR()``
+ * - 12.3
+ - VAR forecasting
+ - :func:`varForecast`, :func:`bvarForecast`
+ - ``predict()``
+
+Replication Exercises
+---------------------
+
+These self-contained exercises use shipped data or live FRED data and can be
+assigned as homework.
+
+**Exercise 1: The Box-Jenkins Airline Model** (Hamilton Ch. 3-5, FPP3 Ch. 9)
+
+This exercise fits SARIMA(0,1,1)(0,1,1)[12] to the AirPassengers data and forecasts 24 months ahead::
+
+ library timeseries;
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/airline_passengers.csv");
+ y = loadd(fname, "passengers");
+
+ // arimaFit(y, p, d, q, sp, sd, sq, period)
+ result = arimaFit(y, p=0, d=1, q=1, sp=0, sd=1, sq=1, period=12);
+
+ fc = arimaForecast(result, 24);
+
+**Exercise 2: Monetary Policy VAR** (Hamilton Ch. 11, Lutkepohl Ch. 2-4, K&L Ch. 8)
+
+This exercise estimates a 3-variable VAR on GDP, CPI, and FFR, then computes and interprets IRFs::
+
+ library timeseries;
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = varFit(data, p=4);
+
+ irf = irfCompute(result, 20);
+
+ fevd = fevdCompute(irf);
+
+**Exercise 3: Bayesian Shrinkage** (Lutkepohl Ch. 5, K&L Ch. 5)
+
+This exercise compares OLS and BVAR out-of-sample forecast accuracy using a train/test split::
+
+ library timeseries;
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Split: first 160 obs for estimation, last 40 for evaluation
+ y_train = data[1:160, .];
+ y_test = asMatrix(data[161:200, .]);
+
+ // OLS forecast
+ rv = varFit(y_train, p=4, quiet=1);
+
+ fc_ols = varForecast(rv, 40);
+
+ // BVAR forecast
+ br = bvarFit(y_train, p=4, ar=0, quiet=1);
+
+ fc_bvar = bvarForecast(br, 40);
+
+ // Compare RMSE
+ { rmse_ols, mase_ols, smape_ols } = fcMetrics(y_test, fc_ols.forecasts);
+ { rmse_bvar, mase_bvar, smape_bvar } = fcMetrics(y_test, fc_bvar.forecasts);
+ print "RMSE OLS:" rmse_ols;
+ print "RMSE BVAR:" rmse_bvar;
+
+**Exercise 4: Kilian (2009) Oil Market SVAR** (K&L Ch. 8, 13)
+
+This exercise replicates the Kilian (2009) oil market structural analysis using live FRED data::
+
+ // See pkgs/timeseries/examples/fred_oil_market_svar.e for the complete script
+
+**Exercise 5: Model Comparison with Bayes Factors** (K&L Ch. 5)
+
+This exercise uses the log marginal likelihood to compare models with different hyperparameter settings::
+
+ library timeseries;
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Optimize hyperparameters
+ ho = bvarHyperopt(data);
+ print "Optimal overall_tightness:" ho.overall_tightness;
+ print "Maximized log ML:" ho.log_ml;
+
+ // Compare with fixed hyperparameters
+ r_tight = bvarFit(data, overall_tightness=0.01, quiet=1);
+ r_loose = bvarFit(data, overall_tightness=1.0, quiet=1);
+
+ r_opt = bvarFit(data, ctl=ho.ctl);
+
+ print "Log ML (tight):" r_tight.log_ml;
+ print "Log ML (loose):" r_loose.log_ml;
+ print "Log ML (optimal):" r_opt.log_ml;
+.. seealso:: Guides :ref:`getting-started`, :ref:`choosing-a-var-model`, :ref:`var-comparison`
diff --git a/docs/timeseries/tvpsvcontrolcreate.rst b/docs/timeseries/tvpsvcontrolcreate.rst
new file mode 100644
index 00000000..8fa832c2
--- /dev/null
+++ b/docs/timeseries/tvpsvcontrolcreate.rst
@@ -0,0 +1,50 @@
+tvpSvControlCreate
+===================
+
+Purpose
+-------
+Create a :class:`tvpSvControl` structure with default values.
+
+Format
+------
+
+.. function:: adv = tvpSvControlCreate()
+
+ :return adv: An instance of a :class:`tvpSvControl` structure with the following default values:
+
+ .. include:: include/tvpsvcontrol.rst
+
+ :rtype adv: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ struct tvpSvControl adv;
+ adv = tvpSvControlCreate();
+
+ // Tighter drift priors (less time variation in coefficients)
+ adv.q_b_shape = 10.0;
+ adv.q_b_scale = 0.001;
+
+ // Band-limited U for a larger system
+ adv.u_bandwidth = 3;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ result = tvpSvFit(y, p=2, n_draws=10000, n_burn=10000, ctl=adv);
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`tvpSvFit`
diff --git a/docs/timeseries/tvpsvfit.rst b/docs/timeseries/tvpsvfit.rst
new file mode 100644
index 00000000..2684997a
--- /dev/null
+++ b/docs/timeseries/tvpsvfit.rst
@@ -0,0 +1,203 @@
+tvpSvFit
+========
+
+Purpose
+-------
+Estimate a Time-Varying Parameter VAR with Stochastic Volatility (Primiceri 2005).
+
+Format
+------
+
+.. function:: result = tvpSvFit(y)
+ result = tvpSvFit(y, p=2, n_draws=10000)
+ result = tvpSvFit(y, p=2, n_draws=10000, n_burn=10000, seed=123)
+ result = tvpSvFit(y, ctl=adv)
+
+ :param y: endogenous variables. If a dataframe, column names are used as variable names.
+ :type y: TxM matrix or dataframe
+
+ :param p: Optional keyword, lag order. Default = 1.
+ :type p: scalar
+
+ :param n_draws: Optional keyword, number of posterior draws to keep. Default = 5000.
+ :type n_draws: scalar
+
+ :param n_burn: Optional keyword, number of burn-in iterations to discard. Default = 5000.
+ :type n_burn: scalar
+
+ :param seed: Optional keyword, RNG seed. Default = 42.
+ :type seed: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :param ctl: Optional keyword, an instance of a :class:`tvpSvControl` structure. When provided, struct values are used and keywords are ignored. An instance is initialized by calling :func:`tvpSvControlCreate` and the following members can be set:
+
+ .. include:: include/tvpsvcontrol.rst
+
+ :type adv: struct
+
+ :return result: An instance of a :class:`tvpSvResult` structure containing:
+
+ .. include:: include/tvpsvresult.rst
+
+ :rtype result: struct
+
+Examples
+--------
+
+Default TVP-SV-VAR
++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ // Default TVP-SV-VAR(1) with 5000 draws
+ result = tvpSvFit(y);
+
+The summary includes SV acceptance diagnostics:
+
+::
+
+ ================================================================================
+ TVP-VAR-SV (Primiceri 2005)
+ Variables: 3, Lags: 1, T: 199
+ Draws: 5000, Burn-in: 5000
+ ================================================================================
+ Phi acceptance rates:
+ 0.47 0.41 0.52
+ ================================================================================
+
+Custom Draws and Lags
++++++++++++++++++++++
+
+Increase the lag order and posterior draws directly:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ // TVP-SV-VAR(2) with 10000 draws and 10000 burn-in
+ result = tvpSvFit(y, p=2, n_draws=10000, n_burn=10000);
+
+ // Terminal B_T (coefficients at the last observation)
+ print "Terminal B_T posterior mean:";
+ print result.b_mean;
+
+Advanced Settings
++++++++++++++++++
+
+Use the :class:`tvpSvControl` structure for fine-grained prior control:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ struct tvpSvControl adv;
+ adv = tvpSvControlCreate();
+
+ // Tighter drift priors (less time variation)
+ adv.q_b_shape = 10.0;
+ adv.q_b_scale = 0.001;
+
+ // Wider diffuse initialization
+ adv.p0_b_kappa = 25.0;
+
+ result = tvpSvFit(y, p=4, n_draws=10000, n_burn=10000, ctl=adv);
+
+ // SV parameters
+ print "SV persistence (phi):";
+ print result.sv_phi;
+
+ print "Phi acceptance rates:";
+ print result.phi_accept_rate;
+
+Model
+-----
+
+The full Primiceri (2005) TVP-VAR-SV with three time-varying components:
+
+.. math::
+
+ y_t &= X_t B_t + \varepsilon_t, \quad \varepsilon_t \sim N(0, \Sigma_t) \\
+ \Sigma_t &= U_t'^{-1} D_t U_t^{-1}, \quad D_t = \text{diag}(e^{h_{1,t}}, \ldots, e^{h_{m,t}}) \\
+ B_t &= B_{t-1} + \eta_t, \quad \eta_t \sim N(0, Q_B) \\
+ u_t &= u_{t-1} + \zeta_t, \quad \zeta_t \sim N(0, Q_U) \\
+ h_{i,t} &= \mu_i + \phi_i(h_{i,t-1} - \mu_i) + \nu_{i,t}, \quad \nu_{i,t} \sim N(0, \sigma^2_i)
+
+where:
+
+- :math:`B_t` are the VAR coefficients, following a random walk.
+- :math:`U_t` are the lower-triangular Cholesky off-diagonals of the error covariance, following a random walk.
+- :math:`h_{i,t}` are the log-volatilities, following independent AR(1) processes.
+- :math:`Q_B` and :math:`Q_U` are diagonal drift covariance matrices with Inverse-Gamma priors.
+
+Remarks
+-------
+
+**Sampler details:**
+The sampler uses equation-by-equation Carter-Kohn forward-filtering backward-sampling
+(FFBS) for :math:`B_t`, following Primiceri's original approach. This reduces the
+state dimension from :math:`K \times m` to :math:`K` per equation. The observation
+variance for each equation comes from the stochastic volatility :math:`h_{i,t}`.
+
+**Priors:**
+:math:`Q_B` and :math:`Q_U` have conjugate diagonal Inverse-Gamma posteriors
+controlled by ``adv.q_b_shape``, ``adv.q_b_scale``, ``adv.q_u_shape``, and
+``adv.q_u_scale``. Smaller scale values (e.g., 0.001) produce tighter drift
+priors, favoring slower parameter evolution. Larger scale values (e.g., 0.1)
+allow more rapid time variation.
+
+**Initialization:**
+:math:`B_0` is initialized from OLS and redrawn each iteration from its full
+conditional. The initial state covariance is :math:`P_0 = \kappa I` where
+:math:`\kappa` is controlled by ``adv.p0_b_kappa``.
+
+**ASIS interweaving:**
+By default, the SV sampler uses the Ancillarity-Sufficiency Interweaving Strategy
+(Kastner & Fruhwirth-Schnatter 2014) which alternates between centered and
+non-centered parameterizations. This dramatically improves mixing when persistence
+:math:`\phi_i` is near 1. Disable with ``adv.use_asis = 0``.
+
+**Band-limited U for large systems:**
+For systems with :math:`m > 15`, set ``adv.u_bandwidth`` > 0 to estimate only the
+first :math:`k` off-diagonals per column of :math:`U_t`, reducing parameters from
+:math:`m(m-1)/2` to :math:`m \cdot k`. This is an approximation that assumes
+distant variables have negligible contemporaneous correlation.
+
+**Acceptance rates:**
+The persistence parameter :math:`\phi_i` is drawn via Metropolis-Hastings. The
+acceptance rate is reported in *result.phi_accept_rate*. Rates between 0.2 and
+0.6 indicate good mixing. If rates are outside this range, increase *n_burn*
+or adjust the SV prior.
+
+References
+----------
+
+- Primiceri, G. E. (2005). "Time varying structural vector autoregressions and monetary policy." *Review of Economic Studies*, 72(3), 821-852.
+- Del Negro, M. & G. E. Primiceri (2015). "Time varying structural vector autoregressions and monetary policy: A corrigendum." *Review of Economic Studies*, 82(4), 1342-1345.
+- Carter, C. K. & R. Kohn (1994). "On Gibbs sampling for state space models." *Biometrika*, 81(3), 541-553.
+- Kastner, G. & S. Fruhwirth-Schnatter (2014). "Ancillarity-sufficiency interweaving strategy (ASIS) for boosting MCMC estimation of stochastic volatility models." *Computational Statistics & Data Analysis*, 76, 408-423.
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`tvpSvControlCreate`, :func:`tvpSvForecast`, :func:`bvarSvFit`, :func:`varFit`
diff --git a/docs/timeseries/tvpsvforecast.rst b/docs/timeseries/tvpsvforecast.rst
new file mode 100644
index 00000000..38bfbe29
--- /dev/null
+++ b/docs/timeseries/tvpsvforecast.rst
@@ -0,0 +1,146 @@
+tvpSvForecast
+=============
+
+Purpose
+-------
+Generate density forecasts from a fitted TVP-SV-VAR model with time-varying volatility propagation.
+
+Format
+------
+
+.. function:: dfc = tvpSvForecast(result, h)
+ dfc = tvpSvForecast(result, h, mode="simulate", n_paths=500)
+ dfc = tvpSvForecast(result, h, ctl=fctl)
+
+ :param result: an instance of a :class:`tvpSvResult` structure returned by :func:`tvpSvFit`.
+ :type result: struct
+
+ :param h: forecast horizon (number of steps ahead).
+ :type h: scalar
+
+ :param mode: Optional keyword, forecast mode: ``"mean_path"`` (default) or ``"simulate"``.
+ :type mode: string
+
+ :param n_paths: Optional keyword, simulation paths per draw (simulate mode only). Default = 100.
+ :type n_paths: scalar
+
+ :param seed: Optional keyword, RNG seed for simulation. Default = 42.
+ :type seed: scalar
+
+ :param level: Optional keyword, credible band level(s). Scalar or vector. Default = 0.68|0.90.
+ :type level: scalar or vector
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :param ctl: Optional keyword, an instance of an :class:`svForecastControl` structure. When provided, struct values are used and keywords are ignored. An instance is initialized by calling :func:`svForecastControlCreate` and the following members can be set:
+
+ .. include:: include/svforecastcontrol.rst
+
+ :type fctl: struct
+
+ :return dfc: An instance of a :class:`densityForecastResult` structure containing:
+
+ .. include:: include/densityforecastresult.rst
+
+ :rtype dfc: struct
+
+Examples
+--------
+
+Basic Forecast
+++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ result = tvpSvFit(y, p=2, n_draws=5000, n_burn=5000);
+
+ // 12-step-ahead density forecast
+ dfc = tvpSvForecast(result, 12);
+
+ print "Median forecast:";
+ print dfc.fc_median;
+
+The printed output shows median forecasts with 68% and 90% credible bands:
+
+::
+
+ ================================================================================
+ TVP-SV Density Forecast: 12 steps
+ Draws: 5000
+ ================================================================================
+
+ gdp_growth
+ h Median [16% 84%] [5% 95%]
+ ------------------------------------------------------------
+ 1 2.145 1.203 3.087 0.541 3.749
+ 2 2.038 0.892 3.184 0.134 3.942
+ ...
+
+Custom Credible Level
++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+
+ result = tvpSvFit(y);
+
+ // 80% credible bands
+ dfc = tvpSvForecast(result, 8, level=0.80);
+
+ // Access bands
+ print "80% lower:";
+ print dfc.bands[1].lower;
+ print "80% upper:";
+ print dfc.bands[1].upper;
+
+Remarks
+-------
+
+**Forecast with time-varying parameters:**
+Unlike constant-parameter BVAR forecasts, the TVP-SV-VAR forecast uses the terminal
+(last-period) parameter estimates :math:`B_T` and :math:`U_T` from each posterior
+draw. This means the forecast reflects the most recent structural relationships
+in the data, which is critical for policy analysis during regime changes.
+
+**Credible bands:**
+The forecast returns 68% and 90% credible bands by default, computed as pointwise
+quantiles across posterior draws. When a scalar *level* is provided instead of
+*fctl*, it replaces the outer band level (the 68% inner band is always included).
+
+**Point forecasts:**
+The median forecast (*dfc.fc_median*) is generally preferred over the mean forecast
+(*dfc.fc_mean*) for asymmetric predictive distributions, which are common with
+stochastic volatility. Both are computed across posterior draws.
+
+**Volatility propagation:**
+The log-volatility :math:`h_{i,t}` is propagated forward using the estimated AR(1)
+dynamics:
+
+.. math::
+
+ h_{i,T+s} = \mu_i + \phi_i (h_{i,T+s-1} - \mu_i) + \sigma_i \eta_{i,T+s}
+
+When persistence :math:`\phi_i` is near 1, volatility shocks at the forecast origin
+decay slowly, producing wider forecast bands at longer horizons.
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`tvpSvFit`, :func:`svForecastControlCreate`, :func:`bvarSvForecast`, :func:`bvarForecast`
diff --git a/docs/timeseries/var-verification.rst b/docs/timeseries/var-verification.rst
new file mode 100644
index 00000000..d67f37e0
--- /dev/null
+++ b/docs/timeseries/var-verification.rst
@@ -0,0 +1,144 @@
+.. _var-verification:
+
+Verification and Cross-Validation
+=================================
+
+GAUSS Time Series is verified against two independent reference implementations
+(R and MATLAB/BEAR) at multiple levels: exact numerical match for deterministic
+computations, structural property validation for stochastic samplers.
+
+Test Summary
+------------
+
+.. list-table::
+ :widths: 35 15 20 30
+ :header-rows: 1
+
+ * - Test Suite
+ - Tests
+ - Tolerance
+ - What it verifies
+ * - OLS VAR vs R ``vars``
+ - 22
+ - :math:`10^{-6}`
+ - Coefficients, :math:`\Sigma`, IRF, FEVD, Granger, forecasts
+ * - BVAR Gibbs vs R ``BVAR`` 200K
+ - 7
+ - Structural
+ - Posterior mean RMSE ordering, :math:`\Sigma` magnitude, shrinkage behavior
+ * - SV-BVAR vs R ``stochvol`` + ``bayesianVARs``
+ - 30
+ - Structural
+ - KSC sampler, SV parameters, canonical DGPs (Clark, CCM, GLP), FRED-MD
+ * - BVAR matched-prior vs ECB BEAR
+ - 45
+ - 0.06
+ - All 39 B coefficients + 6 :math:`\Sigma` elements, identical hyperparameters
+ * - IRF matched-prior vs BEAR
+ - 17
+ - 0.04-0.25
+ - Cholesky IRF at h=0, 10, 20 for all shock-response pairs
+ * - OLS exact vs BEAR
+ - 14
+ - :math:`10^{-8}`
+ - B, :math:`\Sigma`, eigenvalues, Cholesky factors
+ * - **Total**
+ - **135**
+ -
+ -
+
+
+Chain of Trust
+--------------
+
+Each level validates against an independent source:
+
+::
+
+ R vars 1.6-1 / R 4.5.2
+ │
+ ├── OLS: 22 tests, exact match (1e-6)
+ │
+ └── BVAR: 7 tests, structural properties vs R BVAR 200K reference
+ │
+ └── Conjugate RMSE < Gibbs RMSE < 1.0
+ Sigma within 50% relative error
+ Shrinkage > 60%
+
+ R stochvol / bayesianVARs
+ │
+ └── SV-BVAR: 30 tests
+ ├── KSC mixture sampler vs stochvol (same algorithm)
+ ├── Canonical DGPs: Clark (2011), CCM (2019), GLP (2015)
+ ├── Real FRED-MD data
+ └── ASIS interweaving, permutation correctness
+
+ ECB BEAR Toolbox v5.0 (MATLAB)
+ │
+ ├── OLS: exact match (1e-8) on same data (T_eff=195)
+ ├── BVAR: matched hyperparameters (overall_tightness=0.1, ar=0.8)
+ │ max coefficient difference: 0.051 / 39 coefficients
+ └── IRF: Cholesky at h=0,10,20 across 9 shock-response pairs
+
+
+Methodology Notes
+-----------------
+
+**Why different tolerances?**
+
+- **OLS (1e-6 to 1e-8):** Deterministic — the same linear algebra on the same data
+ should produce the same answer to floating point precision.
+
+- **BVAR posteriors (0.06):** Different RNG streams and slightly different prior
+ forms (conjugate vs independent Normal-Wishart) produce Monte Carlo variation.
+ The tolerance is calibrated to 2 posterior standard deviations.
+
+- **SV-BVAR (structural):** Different R packages use different samplers, priors,
+ and parameterizations. We validate structural properties (convergence, shrinkage,
+ parameter recovery on known DGPs) rather than expecting exact draws to match.
+
+**The conjugate vs independent NW prior-form difference:**
+
+GAUSS uses the conjugate Normal-Inverse-Wishart prior (exact posterior draws).
+BEAR uses the independent Normal-Wishart prior (Gibbs sampling required). With
+matched hyperparameters (overall_tightness=0.1, ar=0.8), posterior means agree within 0.06
+on all 39 B coefficients. The largest difference (0.051 on YER lag 2) occurs on a
+non-own-lag coefficient where the two prior forms shrink differently:
+
+- OLS: 0.172
+- Conjugate NW posterior: 0.036
+- Independent NW posterior: -0.015
+
+Both are shrunk toward the prior mean of zero; the conjugate form preserves more
+of the OLS signal. This is expected and well-documented behavior.
+
+
+Running the Tests
+-----------------
+
+**Rust-level tests** (R cross-validation):
+
+::
+
+ cd gausslib/crates/gausslib-var
+ cargo test --test r_benchmark # 22 OLS tests
+ cargo test --test gibbs_crossval # 7 BVAR tests
+ cargo test --test sv_crossval # 30 SV-BVAR tests
+
+**GAUSS-level tests** (BEAR cross-validation):
+
+::
+
+ library timeseries;
+ run verify_vs_bear.e; // 14 OLS exact + timing
+ run bear_matched_prior.e; // 45 matched-prior BVAR
+ run bear_matched_irf.e; // 17 matched-prior IRF
+
+
+References
+----------
+
+- Kadiyala, K.R. and S. Karlsson (1997). "Numerical methods for estimation and inference in Bayesian VAR-models." *Journal of Applied Econometrics*, 12(2), 99-132.
+- Kastner, G. (2016). "Dealing with stochastic volatility in time series using the R package stochvol." *Journal of Statistical Software*, 69(5).
+- Kuschnig, N. and L. Vashold (2021). "BVAR: Bayesian vector autoregressions with hierarchical prior selection in R." *Journal of Statistical Software*, 100(14).
+- Dieppe, A., R. Legrand, and B. van Roye (2016). "The BEAR Toolbox." ECB Working Paper No. 1934.
diff --git a/docs/timeseries/varcoeftable.rst b/docs/timeseries/varcoeftable.rst
new file mode 100644
index 00000000..9f86ebe5
--- /dev/null
+++ b/docs/timeseries/varcoeftable.rst
@@ -0,0 +1,51 @@
+varCoefTable
+============
+
+Purpose
+-------
+Return the coefficient table from a fitted VAR or BVAR model as a dataframe.
+
+Format
+------
+
+.. function:: tab = varCoefTable(result)
+ tab = varCoefTable(result, equation=2)
+
+ :param result: an instance of a :class:`varResult`, :class:`bvarResult`, or :class:`bvarSvResult` structure.
+ :type result: struct
+
+ :param equation: Optional keyword, equation number (1 to m) to extract. Default = 0 (all equations stacked).
+ :type equation: scalar
+
+ :return tab: Dataframe. For frequentist: columns Name, Coef, SE, t-stat, p-value. For Bayesian: columns Name, Mean, SD, 16%, 84%.
+ :rtype tab: dataframe
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4, quiet=1);
+
+ // Full table (all equations)
+ tab = varCoefTable(result);
+ print tab;
+
+ // Single equation
+ tab_gdp = varCoefTable(result, equation=1);
+ print tab_gdp;
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`varFit`, :func:`bvarFit`, :func:`bvarSvFit`, :func:`varResults`
diff --git a/docs/timeseries/varcompanion.rst b/docs/timeseries/varcompanion.rst
new file mode 100644
index 00000000..961b0b1b
--- /dev/null
+++ b/docs/timeseries/varcompanion.rst
@@ -0,0 +1,59 @@
+varCompanion
+============
+
+Purpose
+-------
+Extract the companion matrix and stability diagnostics from a fitted VAR or BVAR model.
+
+Format
+------
+
+.. function:: { companion, eigenvalues, is_stable } = varCompanion(result)
+
+ :param result: an instance of a :class:`varResult` or :class:`bvarResult` structure.
+ :type result: struct
+
+ :return companion: (mp)x(mp) companion matrix.
+ :rtype companion: matrix
+
+ :return eigenvalues: (mp)x2 matrix with columns [real, imaginary] for each eigenvalue.
+ :rtype eigenvalues: matrix
+
+ :return is_stable: 1 if all eigenvalues are inside the unit circle, 0 otherwise.
+ :rtype is_stable: scalar
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4, quiet=1);
+
+ // Extract companion matrix and eigenvalues
+ { companion, eigenvalues, is_stable } = varCompanion(result);
+
+ if is_stable;
+ print "VAR is stable.";
+ else;
+ print "WARNING: VAR is not stable.";
+ endif;
+
+ // Eigenvalue moduli
+ moduli = sqrt(eigenvalues[., 1]^2 + eigenvalues[., 2]^2);
+ print "Eigenvalue moduli:";
+ print moduli;
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`varFit`, :func:`bvarFit`
diff --git a/docs/timeseries/varcontrolcreate.rst b/docs/timeseries/varcontrolcreate.rst
new file mode 100644
index 00000000..0a637c2a
--- /dev/null
+++ b/docs/timeseries/varcontrolcreate.rst
@@ -0,0 +1,44 @@
+varControlCreate
+================
+
+Purpose
+-------
+Create a :class:`varControl` structure with default values.
+
+Format
+------
+
+.. function:: ctl = varControlCreate()
+
+ :return ctl: An instance of a :class:`varControl` structure with the following default values:
+
+ .. include:: include/varcontrol.rst
+
+ :rtype ctl: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ ctl = varControlCreate();
+
+ // Remove the constant
+ ctl.const = 0;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, p=4, ctl=ctl);
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`varFit`
diff --git a/docs/timeseries/vardiagnostics.rst b/docs/timeseries/vardiagnostics.rst
new file mode 100644
index 00000000..342838f0
--- /dev/null
+++ b/docs/timeseries/vardiagnostics.rst
@@ -0,0 +1,160 @@
+varDiagnostics
+==============
+
+Purpose
+-------
+Run convergence diagnostics on a Bayesian VAR or SV-BVAR result.
+
+Format
+------
+
+.. function:: diag = varDiagnostics(result)
+ diag = varDiagnostics(result, rhat_threshold=1.01)
+
+ :param result: an instance of a :class:`bvarResult` or :class:`bvarSvResult` structure.
+ :type result: struct
+
+ :param rhat_threshold: Optional keyword, R-hat threshold for convergence warnings. Default = 1.05.
+ :type rhat_threshold: scalar
+
+ :param min_ess: Optional keyword, minimum ESS threshold for convergence warnings. Default = 400.
+ :type min_ess: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return diag: An instance of a :class:`diagResult` structure containing:
+
+ .. include:: include/diagresult.rst
+
+ :rtype diag: struct
+
+Examples
+--------
+
+Basic Convergence Check
++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarSvFit(data, p=4, n_draws=10000, n_burn=5000, quiet=1);
+
+ diag = varDiagnostics(result);
+
+ // One-bit convergence check
+ if diag.converged;
+ print "All checks passed.";
+ else;
+ print diag.n_warnings "issues found:";
+ print diag.warnings;
+ endif;
+
+SV-BVAR with SSVS Diagnostics
+++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ result = bvarSvFit(data, p=4, ssvs=1, n_draws=10000, n_burn=5000, quiet=1);
+
+ diag = varDiagnostics(result);
+
+ // SSVS diagnostics
+ print "Inclusion probabilities:";
+ print diag.ssvs_pip;
+
+ print "Switching rates:";
+ print diag.ssvs_switch_rate;
+
+ // MH acceptance rates for SV persistence
+ print "Phi acceptance rates:";
+ print diag.phi_accept_rate;
+
+Stricter Thresholds
++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = bvarSvFit(data, quiet=1);
+
+ // Publication-quality thresholds
+ diag = varDiagnostics(result, rhat_threshold=1.01, min_ess=1000);
+
+Remarks
+-------
+
+**Diagnostics computed:**
+
+- **Split-R-hat** (Vehtari et al. 2021): Splits the chain in half and computes
+ the ratio of between-half to within-half variance. Values > 1.05 indicate
+ incomplete convergence.
+- **Bulk ESS**: Effective sample size for the bulk of the posterior. Low values
+ (< 400) indicate high autocorrelation.
+- **Tail ESS**: Effective sample size for the tails (5th/95th quantiles). Can
+ be lower than bulk ESS for heavy-tailed posteriors.
+- **Geweke z-test**: Compares the mean of the first 10% and last 50% of the
+ chain. Values outside [-2, 2] suggest non-stationarity. Only computed for
+ single-chain results.
+- **SSVS diagnostics**: Posterior inclusion probabilities and indicator switching
+ rates. A switching rate of 0 means the indicator never moved.
+- **SV acceptance rates**: MH acceptance rates for SV persistence phi. Rates
+ outside [0.15, 0.70] suggest tuning issues.
+
+**Warnings include corrective suggestions:**
+
+- R-hat > threshold: ``"Consider increasing n_draws or running more chains."``
+- ESS < threshold: ``"Consider increasing n_draws or n_burn."``
+- phi_accept < 0.15: ``"SV persistence MH acceptance rate too low. Consider adjusting sv_phi_std."``
+
+Model
+-----
+
+**Split-R-hat** (Vehtari et al. 2021) assesses convergence by comparing within-chain
+and between-chain variance on rank-normalized draws:
+
+.. math::
+
+ \hat{R} = \sqrt{\frac{\hat{\text{var}}^+(\theta | y)}{W}}
+
+where :math:`\hat{\text{var}}^+` is the pooled variance estimate and :math:`W` is
+the within-chain variance. Values near 1 indicate convergence; :math:`\hat{R} > 1.01`
+is the recommended threshold for concern.
+
+**Bulk ESS** estimates the number of independent draws the chain is worth for
+central tendency (posterior mean, median). Computed via Geyer's initial monotone
+sequence estimator with rank normalization.
+
+**Tail ESS** estimates independent draws for tail quantiles (5th, 95th percentiles)
+by applying the ESS estimator to folded draws :math:`|x - \text{median}(x)|`.
+
+References
+----------
+
+- Vehtari, A., A. Gelman, D. Simpson, B. Carpenter, and P.C. Burkner (2021). "Rank-normalization, folding, and localization: An improved R-hat for assessing convergence of MCMC." *Bayesian Analysis*, 16(2), 667-718.
+- Geweke, J. (1992). "Evaluating the accuracy of sampling-based approaches to the calculation of posterior moments." In *Bayesian Statistics 4*, 169-193.
+
+Library
+-------
+timeseries
+
+Source
+------
+diagnostics.src
+
+.. seealso:: Functions :func:`varDiagnosticsMulti`, :func:`varDiagnosticsPrint`, :func:`bvarSvFit`
diff --git a/docs/timeseries/vardiagnosticsmulti.rst b/docs/timeseries/vardiagnosticsmulti.rst
new file mode 100644
index 00000000..818626e0
--- /dev/null
+++ b/docs/timeseries/vardiagnosticsmulti.rst
@@ -0,0 +1,75 @@
+varDiagnosticsMulti
+===================
+
+Purpose
+-------
+Run multi-chain convergence diagnostics with cross-chain R-hat.
+
+Format
+------
+
+.. function:: diag = varDiagnosticsMulti(result)
+ diag = varDiagnosticsMulti(results)
+
+ :param result: a :class:`bvarSvResult` from :func:`bvarSvFit` with ``n_chains > 1``.
+ :type result: struct
+
+ :param results: alternatively, an array of :class:`bvarResult` structs from separate chains.
+ :type results: array of structs
+
+ :param rhat_threshold: Optional keyword, R-hat threshold. Default = 1.05.
+ :type rhat_threshold: scalar
+
+ :param min_ess: Optional keyword, minimum ESS threshold. Default = 400.
+ :type min_ess: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress output. Default = 0.
+ :type quiet: scalar
+
+ :return diag: An instance of a :class:`diagResult` structure containing cross-chain diagnostics.
+
+ .. include:: include/diagresult.rst
+
+ :rtype diag: struct
+
+Examples
+--------
+
+Multi-Chain SV-BVAR
++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ ctl = bvarSvControlCreate();
+ ctl.n_chains = 4;
+ ctl.parallel = 1;
+
+ result = bvarSvFit(data, p=4, n_draws=10000, n_burn=5000, ctl=ctl, quiet=1);
+
+ // Multi-chain diagnostics (cross-chain R-hat)
+ diag = varDiagnosticsMulti(result);
+
+Remarks
+-------
+
+Cross-chain R-hat is more reliable than single-chain split-R-hat because it
+detects chains that converge to different modes. Requires at least 2 chains.
+
+The Geweke z-test is not computed for multi-chain diagnostics — cross-chain
+R-hat supersedes it.
+
+Library
+-------
+timeseries
+
+Source
+------
+diagnostics.src
+
+.. seealso:: Functions :func:`varDiagnostics`, :func:`varDiagnosticsPrint`
diff --git a/docs/timeseries/vardiagnosticsprint.rst b/docs/timeseries/vardiagnosticsprint.rst
new file mode 100644
index 00000000..44e151ee
--- /dev/null
+++ b/docs/timeseries/vardiagnosticsprint.rst
@@ -0,0 +1,42 @@
+varDiagnosticsPrint
+===================
+
+Purpose
+-------
+Reprint the diagnostics summary table.
+
+Format
+------
+
+.. function:: varDiagnosticsPrint(diag)
+
+ :param diag: an instance of a :class:`diagResult` structure from :func:`varDiagnostics` or :func:`varDiagnosticsMulti`.
+ :type diag: struct
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = bvarSvFit(data, quiet=1);
+
+ // Suppress initial output, print later
+ diag = varDiagnostics(result, quiet=1);
+
+ // Reprint
+ call varDiagnosticsPrint(diag);
+
+Library
+-------
+timeseries
+
+Source
+------
+diagnostics.src
+
+.. seealso:: Functions :func:`varDiagnostics`, :func:`varDiagnosticsMulti`
diff --git a/docs/timeseries/varfit.rst b/docs/timeseries/varfit.rst
new file mode 100644
index 00000000..58d92155
--- /dev/null
+++ b/docs/timeseries/varfit.rst
@@ -0,0 +1,271 @@
+varFit
+======
+
+Purpose
+-------
+Fit a VAR(p) model by ordinary least squares.
+
+Format
+------
+
+.. function:: result = varFit(y)
+ result = varFit(y, p=1, const=1, xreg={}, quiet=0, ctl={})
+
+ :param y: endogenous variables. If a dataframe, column names are used as variable labels in output. If a matrix, variables are labeled "Y1", "Y2", etc.
+ :type y: TxM matrix or dataframe
+
+ :param p: Optional keyword, lag order. Default = 1.
+ :type p: scalar
+
+ :param const: Optional keyword, 1 to include a constant, 0 to exclude. Default = 1.
+ :type const: scalar
+
+ :param xreg: Optional keyword, exogenous regressors.
+ :type xreg: TxK matrix
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :param ctl: Optional keyword, an instance of a :class:`varControl` structure. An instance is initialized by calling :func:`varControlCreate` and the following members can be set:
+
+ .. include:: include/varcontrol.rst
+
+ :type ctl: struct
+
+ :return result: An instance of a :class:`varResult` structure containing:
+
+ .. include:: include/varresult.rst
+
+ :rtype result: struct
+
+Examples
+--------
+
+Monetary Policy VAR
++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ // Load US macro quarterly data
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Fit VAR(4)
+ result = varFit(data, 4);
+
+Output:
+
+::
+
+ ================================================================================
+ VAR(4) Variables: 3
+ Method: OLS Observations: 200
+ Constant: Yes Effective obs: 196
+ ================================================================================
+ AIC: -12.384 BIC: -11.927 HQ: -12.198
+ Log-Lik: 1232.86 |Sigma|: 2.41e-08
+ ================================================================================
+ Companion eigenvalues: 0.981 0.854 0.723 (all inside unit circle)
+ ================================================================================
+
+ Equation 1: GDP
+ Coef Std.Err. t-stat p-value
+ --------------------------------------------------------------------------------
+ GDP(-1) 0.8731 0.0543 16.076 0.000
+ CPI(-1) -0.0218 0.0437 -0.499 0.618
+ FFR(-1) 0.0012 0.0089 0.135 0.893
+ Constant 0.0080 0.0012 6.588 0.000
+ ================================================================================
+ ⋮ (Equations 2-3: CPI and FFR follow the same format)
+
+Lag Order Selection
++++++++++++++++++++
+
+Compare AIC across lag orders to choose p:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Automatic selection
+ best = varLagSelect(data, 8); // Test p = 1..8
+
+ print "Selected lag order:" best.p;
+
+ // Or compare manually
+ for p (1, 8, 1);
+ result = varFit(data, p, quiet=1);
+ print "p=" p " AIC=" result.aic " BIC=" result.bic;
+ endfor;
+
+VAR with Exogenous Regressors
++++++++++++++++++++++++++++++
+
+Include unemployment as an exogenous variable:
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+ X = loadd(fname, "unemployment");
+
+ result = varFit(y, p=2, xreg=X);
+
+Model
+-----
+
+The reduced-form VAR(p) is:
+
+.. math::
+
+ y_t = B_1 y_{t-1} + B_2 y_{t-2} + \cdots + B_p y_{t-p} + \Phi x_t + u + \varepsilon_t, \quad \varepsilon_t \sim N(0, \Sigma)
+
+where :math:`y_t` is :math:`m \times 1`, each :math:`B_\ell` is :math:`m \times m`,
+:math:`x_t` are optional exogenous regressors, :math:`u` is the intercept, and
+:math:`\Sigma` is the :math:`m \times m` error covariance.
+
+Stacking the regressors into :math:`X = [Y_{-1} \; Y_{-2} \; \cdots \; Y_{-p} \; X_{\text{exo}} \; \mathbf{1}]`
+(a :math:`T_{\text{eff}} \times K` matrix where :math:`K = mp + n_{\text{exo}} + 1`), the
+system is estimated equation-by-equation by OLS:
+
+.. math::
+
+ \hat{B} = (X'X)^{-1} X'Y, \qquad \hat{\Sigma} = \frac{1}{T_{\text{eff}}} (Y - X\hat{B})'(Y - X\hat{B})
+
+Standard errors, t-statistics, and information criteria (AIC, BIC, HQ) are computed from
+the OLS residuals.
+
+
+Algorithm
+---------
+
+1. **Construct lag matrices:** Build :math:`Y` (dependent) and :math:`X` (regressors with lags, exogenous, constant) from the raw data, consuming the first :math:`p` rows as initial conditions.
+
+2. **OLS estimation:** Solve the normal equations via QR decomposition for numerical stability. Complexity: :math:`O(T K^2 m)`.
+
+3. **Residual covariance:** ML estimate :math:`\hat\Sigma = (Y - X\hat{B})'(Y - X\hat{B}) / T_{\text{eff}}`.
+
+4. **Companion form:** Construct the :math:`mp \times mp` companion matrix and compute its eigenvalues to assess stability.
+
+5. **Information criteria:**
+
+ .. math::
+
+ \text{AIC} &= \log|\hat\Sigma| + \frac{2 K m}{T_{\text{eff}}} \\
+ \text{BIC} &= \log|\hat\Sigma| + \frac{K m \log T_{\text{eff}}}{T_{\text{eff}}} \\
+ \text{HQ} &= \log|\hat\Sigma| + \frac{2 K m \log \log T_{\text{eff}}}{T_{\text{eff}}}
+
+**Complexity:** Sub-millisecond for typical macro systems (m < 10, T < 500).
+
+
+Troubleshooting
+---------------
+
+**Non-stationary VAR:**
+If the companion matrix has eigenvalues outside the unit circle, the model implies
+explosive dynamics. This does not necessarily indicate an error — it may reflect
+unit roots in the data. Consider:
+
+- Differencing the data or using growth rates.
+- Using a BVAR (:func:`bvarFit`) where the prior regularizes toward stationarity.
+- If the data is cointegrated, a VECM may be more appropriate.
+
+**Singular X'X matrix:**
+This occurs when the regressor matrix is rank-deficient, typically from collinear
+variables or too many lags relative to the sample size. Reduce p, remove collinear
+variables, or use :func:`bvarFit` where the prior regularizes the problem.
+
+**Choosing p:**
+Use :func:`varLagSelect` to compare information criteria. BIC tends to select
+parsimonious models (smaller p), AIC selects larger p. In quarterly macro data,
+p = 4 (one year of lags) is a common starting point (Lutkepohl 2005, Section 4.3).
+
+
+Remarks
+-------
+
+**Coefficient layout in result.b:**
+
+The coefficient matrix *result.b* is Kxm where K = m*p + n_exo + const
+and m is the number of endogenous variables:
+
+.. list-table::
+ :widths: auto
+ :header-rows: 1
+
+ * - Rows
+ - Content
+ * - 1 to m
+ - Lag 1 coefficients (mxm block)
+ * - m+1 to 2m
+ - Lag 2 coefficients
+ * - ...
+ - ...
+ * - (p-1)*m+1 to pm
+ - Lag p coefficients
+ * - pm+1 to pm+n_exo
+ - Exogenous coefficients (if any)
+ * - K
+ - Constant (if *const* = 1)
+
+Column j corresponds to equation j (variable j as dependent variable).
+This layout matches the standard convention in Lutkepohl (2005, Section 3.2.1).
+
+**Stability:**
+
+The companion form eigenvalues are computed automatically and printed in the
+summary. A VAR is stable (stationary) if all eigenvalues of the companion
+matrix have modulus strictly less than 1. Non-stationary models produce a
+warning but are not rejected — they may be appropriate for cointegrated systems.
+
+**When to use VAR vs BVAR:**
+For estimation and hypothesis testing with standard inference (t-stats, p-values,
+Granger causality), use ``varFit``. For forecasting, especially with m > 3 variables,
+:func:`bvarFit` dominates in out-of-sample accuracy because the Minnesota prior
+regularizes noisy cross-variable coefficients (Banbura, Giannone & Reichlin 2010).
+
+
+Verification
+------------
+
+Verified against R ``vars`` 1.6-1 (R 4.5.2) with 22 tests at :math:`10^{-6}` tolerance,
+covering coefficients, :math:`\Sigma`, residuals, log-likelihood, companion eigenvalues,
+IRF, FEVD, Granger causality, and forecasts on identical data (2-variable VAR(1),
+300 observations, known DGP).
+
+Additionally, verified against ECB BEAR Toolbox OLS output at :math:`10^{-8}` tolerance
+on the 3-variable ECB default dataset (YER, HICSA, STN), confirming all 13 coefficients,
+6 :math:`\Sigma` elements, and companion eigenvalues match.
+
+See the :ref:`var-verification` page.
+
+
+References
+----------
+
+- Banbura, M., D. Giannone, and L. Reichlin (2010). "Large Bayesian vector auto regressions." *Journal of Applied Econometrics*, 25(1), 71-92.
+- Lutkepohl, H. (2005). *New Introduction to Multiple Time Series Analysis*. Springer.
+- Sims, C.A. (1980). "Macroeconomics and reality." *Econometrica*, 48(1), 1-48.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`varLagSelect`, :func:`bvarFit`, :func:`irfCompute`, :func:`grangerTest`, :func:`varCompanion`, :func:`varCoefTable`
+
+.. seealso:: Guides :ref:`choosing-a-var-model`, :ref:`var-verification`
diff --git a/docs/timeseries/varforecast.rst b/docs/timeseries/varforecast.rst
new file mode 100644
index 00000000..23d8fed3
--- /dev/null
+++ b/docs/timeseries/varforecast.rst
@@ -0,0 +1,210 @@
+varForecast
+===========
+
+Purpose
+-------
+Generate h-step-ahead forecasts with confidence intervals from a fitted VAR model.
+
+Format
+------
+
+.. function:: fc = varForecast(result, h)
+ fc = varForecast(result, h, xreg=X_future)
+ fc = varForecast(result, h, level=0.99)
+
+ :param result: an instance of a :class:`varResult` structure returned by :func:`varFit`.
+ :type result: struct
+
+ :param h: forecast horizon (number of steps ahead).
+ :type h: scalar
+
+ :param xreg: Optional keyword, future values of exogenous regressors. Required if the model was fit with *xreg*.
+ :type xreg: hxK matrix
+
+ :param level: Optional keyword, confidence level for prediction intervals. Default = 0.95.
+ :type level: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress printed output. Default = 0.
+ :type quiet: scalar
+
+ :return fc: An instance of a :class:`forecastResult` structure containing:
+
+ .. include:: include/forecastresult.rst
+
+ :rtype fc: struct
+
+Examples
+--------
+
+Basic VAR Forecast
+++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Fit VAR(4) and forecast 12 steps
+ result = varFit(data, 4, quiet=1);
+
+ fc = varForecast(result, 12);
+
+The forecast table is printed to the **Command Window**:
+
+::
+
+ ================================================================================
+ VAR(4) Forecast: 12 steps ahead Level: 95%
+ ================================================================================
+ GDP CPI FFR
+ h Forecast [Lower Upper] Forecast [Lower Upper] Forecast [Lower Upper]
+ ----------------------------------------------------------------------------------
+ 1 2.103 [ 1.82 2.39] 3.214 [ 2.91 3.52] 4.812 [ 4.21 5.41]
+ 2 2.087 [ 1.71 2.46] 3.198 [ 2.78 3.62] 4.795 [ 3.98 5.61]
+ ⋮
+ 11 2.018 [ 1.12 2.92] 3.130 [ 2.13 4.13] 4.724 [ 2.98 6.47]
+ 12 2.011 [ 1.09 2.93] 3.122 [ 2.11 4.13] 4.718 [ 2.94 6.50]
+ ================================================================================
+
+Forecast with 99% Confidence Intervals
++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4, quiet=1);
+
+ // Wider intervals
+ fc = varForecast(result, 24, level=0.99);
+
+Forecast with Future Exogenous Regressors
++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ y = loadd(fname, "gdp_growth + cpi_inflation + fed_funds");
+ X = loadd(fname, "unemployment");
+
+ result = varFit(y, 2, xreg=X, quiet=1);
+
+ // Future unemployment values for 12 periods
+ X_future = seqa(5, 0.1, 12); // 5.0, 5.1, 5.2, ...
+ fc = varForecast(result, 12, xreg=X_future);
+
+Accessing Individual Variables
+++++++++++++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+ result = varFit(data, 4, quiet=1);
+ fc = varForecast(result, 12, quiet=1);
+
+ // GDP forecast (column 1)
+ gdp_fc = fc.forecasts[., 1];
+ gdp_lo = fc.lower[., 1];
+ gdp_hi = fc.upper[., 1];
+
+ print "GDP forecast with 95% CI:";
+ print gdp_fc~gdp_lo~gdp_hi;
+
+Remarks
+-------
+
+**Confidence intervals** are computed from the MSE matrix of the h-step-ahead
+forecast error, assuming Gaussian innovations. Intervals widen with the forecast
+horizon as uncertainty accumulates.
+
+**Exogenous regressors:** If the model was fit with *xreg*, the *xreg* keyword
+is required for forecasting. The matrix must have *h* rows and the same number
+of columns as the original regressors. An error is raised if omitted.
+
+**Non-stationary models:** Forecasts from non-stationary VARs (explosive
+eigenvalues) may diverge rapidly. Check *result.is_stationary* before forecasting.
+
+Model
+-----
+
+The h-step-ahead point forecast from a VAR(p) is:
+
+.. math::
+
+ \hat{y}_{T+h|T} = \hat{B}_1 \hat{y}_{T+h-1|T} + \cdots + \hat{B}_p \hat{y}_{T+h-p|T} + \hat{u}
+
+where :math:`\hat{y}_{T+j|T} = y_{T+j}` for :math:`j \leq 0` (observed data) and
+:math:`\hat{y}_{T+j|T}` is the forecast for :math:`j \geq 1`.
+
+The confidence interval at horizon :math:`h` is:
+
+.. math::
+
+ \hat{y}_{T+h|T} \pm z_{\alpha/2} \sqrt{\text{diag}(\text{MSE}_h)}
+
+where the mean squared error matrix is :math:`\text{MSE}_h = \sum_{j=0}^{h-1} \Phi_j \hat\Sigma \Phi_j'`
+and :math:`\Phi_j = J F^j J'` are the impulse response matrices. Intervals widen with the
+horizon as :math:`\text{MSE}_h` accumulates.
+
+
+Algorithm
+---------
+
+1. **Recursive substitution:** Iterate the estimated VAR equations forward, replacing future observations with their forecasts.
+2. **MSE computation:** Accumulate the forecast error covariance via the companion form.
+3. **Intervals:** Gaussian quantiles applied to the diagonal of :math:`\text{MSE}_h`.
+
+**Complexity:** :math:`O(h \cdot m^2 p^2)` — sub-millisecond.
+
+
+Troubleshooting
+---------------
+
+**Forecasts diverge rapidly:**
+The VAR is non-stationary (explosive eigenvalues). Check *result.is_stationary*.
+Consider differencing the data or switching to :func:`bvarFit` with regularization.
+
+**Confidence intervals are unrealistically narrow:**
+Frequentist VAR intervals do not account for parameter estimation uncertainty —
+they condition on :math:`\hat{B}` as if known. For intervals that reflect parameter
+uncertainty, use :func:`bvarForecast` (Bayesian predictive density).
+
+
+Verification
+------------
+
+VAR forecasts verified against R ``vars::predict()`` at :math:`10^{-6}` tolerance
+on a 2-variable VAR(1) with known DGP. Point forecasts and forecast standard errors
+match across 1-4 step horizons.
+
+See the :ref:`var-verification` page.
+
+
+References
+----------
+
+- Lutkepohl, H. (2005). *New Introduction to Multiple Time Series Analysis*. Springer. Section 3.5.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+forecast.src
+
+.. seealso:: Functions :func:`varFit`, :func:`bvarForecast`, :func:`bvarSvForecast`, :func:`fcScore`, :func:`dmTest`
diff --git a/docs/timeseries/varlagselect.rst b/docs/timeseries/varlagselect.rst
new file mode 100644
index 00000000..fd80303a
--- /dev/null
+++ b/docs/timeseries/varlagselect.rst
@@ -0,0 +1,153 @@
+varLagSelect
+============
+
+Purpose
+-------
+Select VAR lag order by information criteria.
+
+Format
+------
+
+.. function:: ls = varLagSelect(y, max_p)
+ ls = varLagSelect(y, max_p, ic="bic")
+
+ :param y: endogenous variables.
+ :type y: TxM matrix or dataframe
+
+ :param max_p: maximum lag order to test.
+ :type max_p: scalar
+
+ :param ic: Optional keyword, selection criterion. ``"aic"`` (default), ``"bic"``, or ``"hq"``.
+ :type ic: string
+
+ :param xreg: Optional keyword, exogenous regressors.
+ :type xreg: TxK matrix
+
+ :param const: Optional keyword, 1 to include constant (default), 0 to exclude.
+ :type const: scalar
+
+ :param quiet: Optional keyword, set to 1 to suppress the IC table. Default = 0.
+ :type quiet: scalar
+
+ :return ls: An instance of a :class:`lagSelectResult` structure containing:
+
+ .. list-table::
+ :widths: auto
+
+ * - ls.best_p
+ - Scalar, selected lag order (argmin of chosen criterion).
+
+ * - ls.criterion
+ - String, criterion used for selection (``"aic"``, ``"bic"``, or ``"hq"``).
+
+ * - ls.ic_table
+ - max_p x 3 matrix, information criterion values for each lag order. Columns: AIC, BIC, HQ.
+
+ * - ls.max_p
+ - Scalar, maximum lag tested.
+
+ * - ls.ic_names
+ - 3x1 string array, ``{"AIC", "BIC", "HQ"}``.
+
+ :rtype ls: struct
+
+Examples
+--------
+
+Basic Lag Selection
++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Test lags 1 through 8, select by AIC
+ ls = varLagSelect(data, 8);
+
+::
+
+ ================================================================================
+ VAR Lag Selection (M=3, T=200)
+ ================================================================================
+ Lag AIC BIC HQ
+ ----------------------------------------
+ 1 -12.384 -11.927* -12.198*
+ 2 -12.401* -11.689 -12.115
+ 3 -12.378 -11.410 -11.993
+ 4 -12.356 -11.133 -11.871
+ 5 -12.331 -10.853 -11.746
+ 6 -12.312 -10.578 -11.627
+ 7 -12.289 -10.300 -11.504
+ 8 -12.270 -10.026 -11.385
+ ================================================================================
+ Selected: p=2 (AIC)
+ ================================================================================
+
+Pipe into Estimation
+++++++++++++++++++++
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Select lag order, then estimate
+ ls = varLagSelect(data, 8, ic="bic", quiet=1);
+ result = varFit(data, ls.best_p);
+
+Remarks
+-------
+
+The full IC table (*ls.ic_table*) reports all three criteria (AIC, BIC, HQ)
+regardless of which criterion was used for selection. This allows comparison
+when the criteria disagree — AIC tends to select more lags than BIC.
+
+Model
+-----
+
+For each candidate lag order :math:`p = 1, \ldots, p_{\max}`, the VAR(p) is estimated
+by OLS and the information criteria are computed:
+
+.. math::
+
+ \text{AIC}(p) &= \log|\hat\Sigma_p| + \frac{2 K_p m}{T_p} \\
+ \text{BIC}(p) &= \log|\hat\Sigma_p| + \frac{K_p m \log T_p}{T_p} \\
+ \text{HQ}(p) &= \log|\hat\Sigma_p| + \frac{2 K_p m \log \log T_p}{T_p}
+
+where :math:`K_p = mp + 1` and :math:`T_p = T - p` (sample shrinks with more lags).
+
+The selected :math:`p^*` minimizes the chosen criterion. AIC tends to select larger
+models; BIC tends to select smaller models (Lutkepohl 2005, Section 4.3).
+
+
+Troubleshooting
+---------------
+
+**AIC and BIC disagree:**
+This is common. AIC optimizes forecast accuracy; BIC optimizes model consistency
+(converges to the true order as T → ∞). For forecasting, prefer AIC. For structural
+analysis, prefer BIC. When in doubt, report both.
+
+
+References
+----------
+
+- Lutkepohl, H. (2005). *New Introduction to Multiple Time Series Analysis*. Springer. Section 4.3.
+
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`varFit`, :func:`bvarFit`, :func:`bvarHyperopt`
diff --git a/docs/timeseries/varresults.rst b/docs/timeseries/varresults.rst
new file mode 100644
index 00000000..a4d949cd
--- /dev/null
+++ b/docs/timeseries/varresults.rst
@@ -0,0 +1,59 @@
+varResults
+==========
+
+Purpose
+-------
+Reprint the estimation summary table from a fitted VAR or BVAR model.
+
+Format
+------
+
+.. function:: varResults(result)
+ varResults(result, level=0.90)
+
+ :param result: an instance of a :class:`varResult`, :class:`bvarResult`, or :class:`bvarSvResult` structure.
+ :type result: struct
+
+ :param level: Optional keyword, credible interval level for Bayesian models. Default = 0.68 (68% bands, standard in macro). For frequentist :class:`varResult`, controls the confidence level.
+ :type level: scalar
+
+Examples
+--------
+
+::
+
+ new;
+ library timeseries;
+
+ fname = getGAUSSHome("pkgs/timeseries/examples/data/us_macro_quarterly.csv");
+ data = loadd(fname);
+
+ // Fit with output suppressed
+ result = bvarFit(data, quiet=1);
+
+ // Print with default 68% credible bands
+ call varResults(result);
+
+ // Reprint with 90% credible bands
+ call varResults(result, level=0.90);
+
+Remarks
+-------
+
+Accepts any of the three VAR result struct types (:class:`varResult`,
+:class:`bvarResult`, :class:`bvarSvResult`). The printed format adapts
+automatically:
+
+- **varResult:** frequentist table with Coef, SE, t-stat, p-value
+- **bvarResult:** Bayesian table with Mean, SD, lower/upper credible bands
+- **bvarSvResult:** Bayesian table + SV parameters + acceptance rates + PIPs (if SSVS)
+
+Library
+-------
+timeseries
+
+Source
+------
+var.src
+
+.. seealso:: Functions :func:`varFit`, :func:`bvarFit`, :func:`bvarSvFit`, :func:`varCoefTable`
diff --git a/docs/tkf2eps.rst b/docs/tkf2eps.rst
index 48f894d8..286947ca 100644
--- a/docs/tkf2eps.rst
+++ b/docs/tkf2eps.rst
@@ -38,3 +38,19 @@ them in your program before calling :func:`tkf2eps`.
See the header of the output Encapsulated PostScript file and a
PostScript manual if you want to modify these parameters.
+Examples
+--------
+
+::
+
+ // Convert a TKF graphics file to EPS format
+ ret = tkf2eps("myplot.tkf", "myplot.eps");
+
+.. NOTE:: This function is deprecated. For modern :file:`.plot` files, use :func:`plotSave` instead:
+
+::
+
+ // Preferred modern approach
+ plotSave("myplot.eps");
+
+.. seealso:: Functions :func:`plotSave`, :func:`tkf2ps`
diff --git a/docs/tkf2ps.rst b/docs/tkf2ps.rst
index 18b4a3c9..84522b6c 100644
--- a/docs/tkf2ps.rst
+++ b/docs/tkf2ps.rst
@@ -38,3 +38,19 @@ them in your program before calling :func:`tkf2ps`.
See the header of the output PostScript file and a PostScript manual if
you want to modify these parameters.
+Examples
+--------
+
+::
+
+ // Convert a TKF graphics file to PostScript format
+ ret = tkf2ps("myplot.tkf", "myplot.ps");
+
+.. NOTE:: This function is deprecated. For modern :file:`.plot` files, use :func:`plotSave` instead:
+
+::
+
+ // Preferred modern approach
+ plotSave("myplot.ps");
+
+.. seealso:: Functions :func:`plotSave`, :func:`tkf2eps`
diff --git a/docs/tocart.rst b/docs/tocart.rst
index f7423ce7..ba1fef61 100644
--- a/docs/tocart.rst
+++ b/docs/tocart.rst
@@ -23,8 +23,29 @@ Format
:rtype xy: max(N,L) by max(K,M) complex matrix
+Examples
+----------------
+
+::
+
+ // Convert polar coordinates (r=5, theta=pi/4)
+ // to Cartesian coordinates
+ r = 5;
+ theta = pi / 4;
+ xy = tocart(r, theta);
+ print xy;
+
+The code above produces the following output:
+
+::
+
+ 3.5355339 + 3.5355339i
+
+The real part is the *x* coordinate and the imaginary part is the *y* coordinate.
+
Source
------
coord.src
+.. seealso:: Functions :func:`topolar`
diff --git a/docs/todaydt.rst b/docs/todaydt.rst
index f894da28..643da1ca 100644
--- a/docs/todaydt.rst
+++ b/docs/todaydt.rst
@@ -28,6 +28,22 @@ and time. In the DT scalar format, the number:
represents 13:05:25 or 1:05:25 PM on September 6, 2012.
+Examples
+--------
+
+::
+
+ // Get today's date in DT scalar format
+ format /rd 16,0;
+ dt = todaydt();
+ print dt;
+
+Example output (run on September 6, 2012):
+
+::
+
+ 20120906000000
+
Source
------
diff --git a/docs/toeplitz.rst b/docs/toeplitz.rst
index d6fce727..843c0a89 100644
--- a/docs/toeplitz.rst
+++ b/docs/toeplitz.rst
@@ -36,9 +36,11 @@ After the code above, *y* is equal to:
2 1 2 3 4
3 2 1 2 3
4 3 2 1 2
- 5 4 2 2 3
+ 5 4 3 2 1
Source
------
toeplitz.src
+
+.. seealso:: Functions :func:`ones`, :func:`eye`, :func:`diagrv`
diff --git a/docs/topolar.rst b/docs/topolar.rst
index 994801c4..c28fe667 100644
--- a/docs/topolar.rst
+++ b/docs/topolar.rst
@@ -21,8 +21,29 @@ Format
:rtype theta: NxK real matrix
+Examples
+----------------
+
+::
+
+ // Create a Cartesian point (x=3, y=4)
+ // as a complex number
+ xy = complex(3, 4);
+
+ { r, theta } = topolar(xy);
+ print r;
+ print theta;
+
+The code above produces the following output:
+
+::
+
+ 5.0000000
+ 0.92729522
+
Source
------
coord.src
+.. seealso:: Functions :func:`tocart`
diff --git a/docs/trapchk.rst b/docs/trapchk.rst
index f120fd45..fa666a7d 100644
--- a/docs/trapchk.rst
+++ b/docs/trapchk.rst
@@ -81,5 +81,20 @@ values that will be returned for:
GAUSS functions that test the trap flag currently test only bits 0 and 1.
+Examples
+--------
+
+::
+
+ // Set trap bit 0 and check it
+ trap 1;
+ y = trapchk(1);
+ print (y != 0); // 1 (true), bit 0 is set
+
+ // Turn off trap and check again
+ trap 0;
+ y = trapchk(1);
+ print (y != 0); // 0 (false), bit 0 is not set
+
.. seealso:: Functions :func:`scalerr`, `trap`, :func:`error`
diff --git a/docs/trigamma.rst b/docs/trigamma.rst
index 5b5b3f78..e1a96a6f 100644
--- a/docs/trigamma.rst
+++ b/docs/trigamma.rst
@@ -5,21 +5,74 @@ trigamma
Purpose
----------------
-Computes trigamma function.
+Computes the trigamma function, which is the second derivative of the log of the gamma function. Commonly used in Newton-Raphson iterations for maximum likelihood estimation of gamma and Dirichlet distribution parameters.
Format
----------------
.. function:: y = trigamma(x)
- :param x: data
+ :param x: values at which to evaluate the trigamma function. All elements must be positive.
:type x: MxN matrix or N-dimensional array
- :return y: trigamma.
+ :return y: the trigamma function evaluated element-wise at each value of *x*.
:rtype y: MxN matrix or N-dimensional array
Remarks
-------
-The :func:`trigamma` function is the second derivative of the log of the gamma function with respect to its argument.
+The :func:`trigamma` function is the second derivative of the log of the gamma function with respect to its argument:
+.. math::
+
+ \psi_1(x) = \frac{d^2}{dx^2} \ln \Gamma(x)
+
+It is the derivative of the :func:`digamma` function. The trigamma function is defined for positive real numbers and approaches zero as *x* increases.
+
+Examples
+----------------
+
+Example 1: Basic evaluation
+++++++++++++++++++++++++++++
+
+::
+
+ // Evaluate trigamma at several points
+ x = { 0.5, 1, 2, 5, 10 };
+ y = trigamma(x);
+ print (x~y);
+
+produces:
+
+::
+
+ 0.50000000 4.9348022
+ 1.0000000 1.6449341
+ 2.0000000 0.64493407
+ 5.0000000 0.22132296
+ 10.000000 0.10516634
+
+Note that ``trigamma(1)`` equals :math:`\pi^2/6 \approx 1.6449`, and the values decrease toward zero for larger *x*.
+
+Example 2: Use in Fisher information
+++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // For a Gamma(alpha, beta) distribution, the Fisher information
+ // for alpha involves the trigamma function:
+ // I(alpha) = trigamma(alpha)
+
+ alpha = 3;
+ fisher_info = trigamma(alpha);
+ print "Fisher information for alpha = " alpha;
+ print "I(alpha) = " fisher_info;
+
+produces:
+
+::
+
+ Fisher information for alpha = 3.0000000
+ I(alpha) = 0.39493407
+
+.. seealso:: Functions :func:`digamma`, :func:`gamma`, :func:`lnfact`
diff --git a/docs/tsmt/nwmt.rst b/docs/tsmt/nwmt.rst
index 3ddaac1e..792c4666 100644
--- a/docs/tsmt/nwmt.rst
+++ b/docs/tsmt/nwmt.rst
@@ -15,14 +15,15 @@ tsmt
Format
------
-x = nwmt( covb, resid, nwtrunc );
+x = nwmt( x, resid, nwtrunc );
Input
-----
+---------+-----------------------------------------------------------+
- | covb | QxQ matrix, covariance matrix for the AR parameters. |
+ | x | TxQ matrix, regressor matrix used in the original |
+ | | regression (including constant column if applicable). |
+---------+-----------------------------------------------------------+
- | resid | TxL matrix of residuals. |
+ | resid | Tx1 vector of residuals. |
+---------+-----------------------------------------------------------+
| nwtrunc | scalar, the number of autocorrelations to use in |
| | calculating the Newey-West correction (*q* in the Remarks |
diff --git a/docs/tsmt/permutate.rst b/docs/tsmt/permutate.rst
deleted file mode 100644
index 1ce1c587..00000000
--- a/docs/tsmt/permutate.rst
+++ /dev/null
@@ -1,36 +0,0 @@
-=========
-permutate
-=========
-
-10.0.42permutate
-================
-
-Purpose
--------
-Lists all possible permutations without replacement for n number of
- items, chosen k times.
-
-Library
--------
-tsmt
-
-Format
-------
-y = permutate(n, k);
-
-Input
------
-= =================================
- n number of items.
- k number of times items are chosen.
- = =================================
-
-Output
-------
-= ===========================================
- y a matrix listing all possible permutations.
- = ===========================================
-
-Source
-------
-permutate.src
diff --git a/docs/tsmt/simarmamt.rst b/docs/tsmt/simarmamt.rst
index 4bbfb21f..a78e2848 100644
--- a/docs/tsmt/simarmamt.rst
+++ b/docs/tsmt/simarmamt.rst
@@ -21,11 +21,12 @@ Input
-----
+-------+-------------------------------------------------------------+
| b | (p + q)x1 vector, coefficient values for theoretical ARMA |
- | | process. |
+ | | process. The first *p* elements are AR coefficients and the |
+ | | last *q* elements are MA coefficients. |
+-------+-------------------------------------------------------------+
- | p | scalar, number of moving average (MA) parameters. |
+ | p | scalar, number of autoregressive (AR) parameters. |
+-------+-------------------------------------------------------------+
- | q | scalar, number of autoregressive (AR) parameters. |
+ | q | scalar, number of moving average (MA) parameters. |
+-------+-------------------------------------------------------------+
| const | scalar, if a constant, or NxM matrix, if constant includes |
| | time trends or constants with structural breaks. |
@@ -96,7 +97,7 @@ n = 100;
// Number of replications
k = 1;
-// Stanadard deviation of error process
+// Standard deviation of error process
std = 0.5;
// Generate data
diff --git a/docs/ttest.rst b/docs/ttest.rst
index 931c2014..f8c23b5a 100644
--- a/docs/ttest.rst
+++ b/docs/ttest.rst
@@ -112,18 +112,34 @@ Example 1: Two-sample t-test with vectors
// Perform t-test
out = ttest(y1, y2);
-Example 2: Using dataframe with formula
-+++++++++++++++++++++++++++++++++++++++
-
::
- // Load data
- data = loadd("experiment.csv");
+ Two-Sample t-test
+
+ Descriptive Statistics
+ ------------------------------------------------------------
+ Group N Mean Std Dev
+ Group 1 5 24.4000 2.3022
+ Group 2 5 31.4000 2.3022
+
+ Mean Difference: -7.0000
- // Test if score differs by treatment group
- out = ttest(data, "score ~ treatment");
+ Test of Means
+ ------------------------------------------------------------
+ Method t df p-value
+ Welch (unequal var) -4.8076 8.0 0.0013
+ Pooled (equal var) -4.8076 8 0.0013
-Example 3: Paired t-test
+ Test of Variances
+ ------------------------------------------------------------
+ F df p-value
+ F-test 1.0000 4, 4 1.0000
+
+ 95% Confidence Interval: [ -10.3576, -3.6424]
+
+The small p-value (0.0013) indicates a statistically significant difference between the two groups.
+
+Example 2: Paired t-test
++++++++++++++++++++++++
::
@@ -138,17 +154,82 @@ Example 3: Paired t-test
out = ttest(before, after, ctl);
-Example 4: One-sided test
+::
+
+ Paired Samples t-test
+
+ Descriptive Statistics
+ ------------------------------------------------------------
+ Group N Mean Std Dev
+ Group 1 5 123.0000 4.6904
+ Group 2 5 118.0000 4.9497
+
+ Mean Difference: 5.0000
+
+ Paired t-test
+ ------------------------------------------------------------
+ t df p-value
+ Paired 15.8114 4 0.0001
+
+ 95% Confidence Interval: [ 4.1220, 5.8780]
+
+Example 3: One-sided test
+++++++++++++++++++++++++
::
+ y1 = { 23, 25, 28, 22, 24 };
+ y2 = { 30, 32, 29, 35, 31 };
+
struct ttestControl ctl;
ctl = ttestControlCreate();
ctl.alternative = 1; // test if group1 > group2
out = ttest(y1, y2, ctl);
+The one-sided p-value (0.9993) is large because group 1's mean (24.4) is actually *less than* group 2's mean (31.4), contradicting the alternative hypothesis that group 1 > group 2.
+
+Example 4: Using dataframe with formula
++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Load data
+ data = loadd(getGAUSSHome("examples/auto2.dta"), "mpg + foreign");
+
+ // Test if mpg differs by origin
+ struct ttestControl ctl;
+ ctl = ttestControlCreate();
+
+ out = ttest(data, "mpg ~ foreign", ctl);
+
+::
+
+ Two-Sample t-test
+
+ Descriptive Statistics
+ ------------------------------------------------------------
+ Group N Mean Std Dev
+ Group 1 52 19.8269 4.7433
+ Group 2 22 24.7727 6.6112
+
+ Mean Difference: -4.9458
+
+ Test of Means
+ ------------------------------------------------------------
+ Method t df p-value
+ Welch (unequal var) -3.1797 30.5 0.0034
+ Pooled (equal var) -3.6308 72 0.0005
+
+ Test of Variances
+ ------------------------------------------------------------
+ F df p-value
+ F-test 1.9427 21, 51 0.0549
+
+ 95% Confidence Interval: [ -8.1201, -1.7716]
+
+Foreign cars average 4.9 more mpg than domestic. The Welch test (p = 0.0034) confirms the difference is statistically significant.
+
Remarks
----------------
@@ -160,5 +241,5 @@ Remarks
- For paired tests, both samples must have the same length.
-.. seealso:: Functions :func:`ttestControlCreate`
+.. seealso:: Functions :func:`ttestControlCreate`, :func:`contingency`, :func:`mvnTest`, :func:`shapiroWilk`
diff --git a/docs/unique.rst b/docs/unique.rst
index e74b0b75..f2750df8 100644
--- a/docs/unique.rst
+++ b/docs/unique.rst
@@ -206,4 +206,9 @@ The code above will produce the following output:
banana
watermelon
+Remarks
+-------
+
+.. note:: :func:`unique` operates element-wise: it extracts unique scalar values from the entire matrix, regardless of shape. It does NOT return unique rows. To find unique rows of a matrix, use :func:`uniqrows` instead.
+
.. seealso:: Functions :func:`sortc`, :func:`uniquesa`, :func:`uniqindx`
diff --git a/docs/use.rst b/docs/use.rst
index 217f22ae..59a504dc 100644
--- a/docs/use.rst
+++ b/docs/use.rst
@@ -78,5 +78,20 @@ unnecessary to execute a `new` before `use`'ing a compiled file.
`use` can appear only ONCE at the TOP of a program.
+Examples
+--------
+
+::
+
+ // Load a previously saved compiled file at the top of a program
+ use pgraph;
+ xy(x, sin(x));
+
+::
+
+ // use must appear ONCE at the TOP of a program
+ use mylib;
+ // All procedures and data from mylib.gcg are now available
+
.. seealso:: Functions `compile`, `run`, `saveall`
diff --git a/docs/user-guide/advanced/arrays.rst b/docs/user-guide/advanced/arrays.rst
new file mode 100644
index 00000000..c8ed027b
--- /dev/null
+++ b/docs/user-guide/advanced/arrays.rst
@@ -0,0 +1,771 @@
+.. _arrays:
+
+N-Dimensional Arrays
+===============================================
+
+GAUSS supports N-dimensional arrays as a data type separate from
+matrices. While a matrix is always 2-dimensional (rows x columns), an
+array can have 3, 4, or more dimensions. Arrays are useful for panel
+data, multivariate time series, and any computation that operates on
+collections of matrices.
+
+.. note::
+
+ If you are coming from Python, a GAUSS array is similar to a NumPy
+ ``ndarray`` with 3+ dimensions. **However, GAUSS dimension numbering
+ is reversed relative to NumPy:** GAUSS dimension 1 is the innermost
+ (columns), while NumPy ``axis=0`` is the outermost. See
+ :ref:`dimension-numbering` below.
+
+ If you are coming from MATLAB, a GAUSS array is similar to a
+ multidimensional array (e.g., ``A(:,:,k)``). **Dimension numbering
+ is reversed:** MATLAB ``size(A,1)`` is rows, but GAUSS dimension 1
+ is columns (innermost). See :ref:`dimension-numbering` below.
+
+.. warning::
+
+ Arrays and matrices are **distinct types** in GAUSS, even if they
+ contain identical data. A 2x3 array is not the same as a 2x3
+ matrix. Use :func:`arraytomat` and :func:`areshape` to convert
+ between them.
+
+
+Creating Arrays
+--------------------------------------------
+
+GAUSS provides several functions for creating arrays:
+
+.. list-table::
+ :widths: 25 75
+ :header-rows: 1
+
+ * - Function
+ - Description
+
+ * - :func:`areshape`
+ - Create an array from a matrix, recycling elements to fill the
+ specified dimensions
+
+ * - :func:`aconcat`
+ - Concatenate matrices or arrays along a specified dimension
+
+ * - :func:`aeye`
+ - Create an array of identity matrices
+
+ * - :func:`arrayinit`
+ - Create an array filled with a single scalar value
+
+ * - :func:`arrayalloc`
+ - Allocate an array without initializing its contents
+
+ * - :func:`squeeze`
+ - Remove singleton dimensions from an array
+
+Example: areshape
+++++++++++++++++++++++++++++++++++++
+
+:func:`areshape` is the most common way to create an array. It takes a
+matrix and reshapes it into the specified dimensions, recycling elements
+if needed:
+
+::
+
+ // Create a 2x2 matrix
+ x = { 1 2, 3 4 };
+
+ // Reshape into a 3x2x2 array (3 copies of the matrix)
+ a = areshape(x, 3|2|2);
+ print a;
+
+This prints::
+
+ Plane [1,.,.]
+
+ 1.0000000 2.0000000
+ 3.0000000 4.0000000
+
+ Plane [2,.,.]
+
+ 1.0000000 2.0000000
+ 3.0000000 4.0000000
+
+ Plane [3,.,.]
+
+ 1.0000000 2.0000000
+ 3.0000000 4.0000000
+
+The **orders vector** (``3|2|2``) specifies the size of each dimension.
+The first element of the orders vector is the outermost dimension (3
+"planes"), and the last two elements define the rows and columns of
+each plane (2x2).
+
+When GAUSS prints an array, ``Plane [k,.,.]`` means the *k*-th slice
+along the outermost dimension. The ``.`` symbols represent "all
+elements" along the remaining dimensions (rows and columns).
+
+.. _dimension-numbering:
+
+Dimension numbering
+++++++++++++++++++++++++++++++++++++
+
+Many array functions take a *dimension* argument (e.g., :func:`amean`,
+:func:`aconcat`). GAUSS numbers dimensions from the **innermost out**:
+
+- **Dimension 1** — columns (innermost / last element of the orders
+ vector)
+- **Dimension 2** — rows (second-to-last element)
+- **Dimension 3** — planes (third-to-last element)
+- Higher dimensions follow the same pattern
+
+For a ``2|3|4`` array (2 planes of 3 rows by 4 columns):
+
+- ``amean(a, 1)`` averages across the 4 **columns**, returning a
+ ``2|3|1`` array
+- ``amean(a, 2)`` averages across the 3 **rows**, returning a
+ ``2|1|4`` array
+- ``amean(a, 3)`` averages across the 2 **planes**, returning a
+ ``1|3|4`` array
+
+.. warning::
+
+ The dimension numbers are the **reverse** of the orders vector
+ position. The orders vector lists the outermost dimension first
+ (``2|3|4``), but dimension 1 refers to the innermost (4 columns).
+ This also differs from NumPy, where ``axis=0`` is the outermost
+ dimension.
+
+Example: aconcat
+++++++++++++++++++++++++++++++++++++
+
+:func:`aconcat` joins two matrices or arrays along a specified
+dimension:
+
+::
+
+ x1 = { 1 2, 3 4 };
+ x2 = { 5 6, 7 8 };
+
+ // Concatenate along the 3rd dimension
+ a = aconcat(x1, x2, 3);
+ print a;
+
+This prints::
+
+ Plane [1,.,.]
+
+ 1.0000000 2.0000000
+ 3.0000000 4.0000000
+
+ Plane [2,.,.]
+
+ 5.0000000 6.0000000
+ 7.0000000 8.0000000
+
+The third argument specifies which dimension to concatenate along.
+Starting from two 2x2 matrices:
+
+- ``aconcat(x1, x2, 1)`` — join along **columns** (dimension 1):
+ result is 2x4
+- ``aconcat(x1, x2, 2)`` — join along **rows** (dimension 2): result
+ is 4x2
+- ``aconcat(x1, x2, 3)`` — join along **planes** (dimension 3):
+ result is 2x2x2 (creates a 3-D array)
+
+Example: arrayinit and aeye
+++++++++++++++++++++++++++++++++++++
+
+::
+
+ // 2x3x3 array of zeros
+ a = arrayinit(2|3|3, 0);
+
+ // 2x3x3 array of identity matrices
+ b = aeye(2|3|3);
+ print b;
+
+This prints::
+
+ Plane [1,.,.]
+
+ 1.0000000 0.0000000 0.0000000
+ 0.0000000 1.0000000 0.0000000
+ 0.0000000 0.0000000 1.0000000
+
+ Plane [2,.,.]
+
+ 1.0000000 0.0000000 0.0000000
+ 0.0000000 1.0000000 0.0000000
+ 0.0000000 0.0000000 1.0000000
+
+:func:`aeye` sets the principal diagonal of the **last two dimensions**
+to 1.
+
+Example: Random arrays
+++++++++++++++++++++++++++++++++++++
+
+Create a random array by reshaping a random vector:
+
+::
+
+ // 4x3x2 array of standard normal random numbers
+ ord = 4|3|2;
+ a = areshape(rndn(prodc(ord), 1), ord);
+
+
+Indexing and Extracting
+--------------------------------------------
+
+GAUSS provides several ways to access elements and sub-arrays.
+
+Index operator
+++++++++++++++++++++++++++++++++++++
+
+The bracket index operator works like matrix indexing, extended to
+N dimensions. Use ``.`` to select all elements along a dimension:
+
+::
+
+ a = areshape(seqa(1, 1, 12), 3|2|2);
+
+ // Extract plane 2 (a sub-array)
+ b = a[2,.,.];
+ print b;
+
+This prints::
+
+ Plane [1,.,.]
+
+ 5.0000000 6.0000000
+ 7.0000000 8.0000000
+
+.. warning::
+
+ The index operator **always returns an array**, even for a single
+ scalar::
+
+ c = a[1,1,1];
+ print c;
+
+ Prints::
+
+ Plane [1,.,.]
+
+ 1.0000000
+
+ Use :func:`getscalar3D` to extract a single element as a scalar,
+ or :func:`getmatrix` / :func:`arraytomat` to get a matrix result.
+
+getarray and getmatrix
+++++++++++++++++++++++++++++++++++++
+
+These functions extract contiguous sub-arrays and are faster than the
+index operator:
+
+::
+
+ a = areshape(seqa(1, 1, 12), 3|2|2);
+
+ // getarray returns an array (type 21)
+ b = getarray(a, 2);
+ print b;
+
+This prints::
+
+ 5.0000000 6.0000000
+ 7.0000000 8.0000000
+
+:func:`getarray` extracts a sub-array along the outermost dimension.
+The second argument (*loc*) is an Mx1 vector that indexes into the
+leading dimensions. For a 3-D array, a scalar selects a plane; for a
+4-D array, a 2x1 vector selects a plane within a block::
+
+ // 4-D array: 2 blocks x 3 planes x 2 rows x 2 columns
+ a4 = areshape(seqa(1, 1, 24), 2|3|2|2);
+
+ // Extract plane 2 of block 1
+ b4 = getarray(a4, 1|2);
+
+:func:`getmatrix` works the same way but guarantees the result is a
+**matrix** (type 6) instead of an array (type 21)::
+
+ c = getmatrix(a, 2);
+ print type(c);
+
+This prints::
+
+ 6.0000000
+
+Use :func:`getmatrix` when you need to pass the result to a function
+that requires a matrix.
+
+For 3-D and 4-D arrays, GAUSS also provides convenience functions that
+accept separate scalar indices:
+
+- :func:`getscalar3D` — extract a single element from a 3-D array as
+ a scalar (type 6)
+- :func:`getmatrix4D` — extract a 2-D slice from a 4-D array as a
+ matrix (type 6)
+- :func:`getscalar4D` — extract a single element from a 4-D array as
+ a scalar (type 6)
+
+.. tip::
+
+ For large arrays accessed in loops, :func:`getarray`,
+ :func:`getmatrix`, and their 3D/4D variants are significantly
+ faster than the index operator.
+
+putarray and setarray
+++++++++++++++++++++++++++++++++++++
+
+These functions insert data into an array:
+
+::
+
+ a = arrayinit(3|2|2, 0);
+
+ // putarray returns a new array (does not modify a)
+ b = putarray(a, 2, eye(2));
+ print b;
+
+This prints::
+
+ Plane [1,.,.]
+
+ 0.0000000 0.0000000
+ 0.0000000 0.0000000
+
+ Plane [2,.,.]
+
+ 1.0000000 0.0000000
+ 0.0000000 1.0000000
+
+ Plane [3,.,.]
+
+ 0.0000000 0.0000000
+ 0.0000000 0.0000000
+
+:func:`putarray` returns a new array with the insertion applied.
+:func:`setarray` modifies the array **in place**:
+
+::
+
+ a = arrayinit(3|2|2, 0);
+ setarray a, 2, eye(2); // modifies a directly
+
+
+Array Operations
+--------------------------------------------
+
+Querying dimensions
+++++++++++++++++++++++++++++++++++++
+
+:func:`getorders` returns a vector containing the size of each
+dimension. The length of the vector equals the number of dimensions:
+
+::
+
+ a = arrayinit(4|3|5|2, 0);
+ print getorders(a);
+
+This prints::
+
+ 4.0000000
+ 3.0000000
+ 5.0000000
+ 2.0000000
+
+Use :func:`type` to check whether a variable is an array (type 21) or
+matrix (type 6):
+
+::
+
+ a = arrayinit(2|3, 0);
+ m = zeros(2, 3);
+ print "array type:" type(a);
+ print "matrix type:" type(m);
+
+This prints::
+
+ array type: 21.000000
+ matrix type: 6.0000000
+
+Transposing dimensions
+++++++++++++++++++++++++++++++++++++
+
+:func:`atranspose` reorders the dimensions of an array. The second
+argument is a vector specifying the new order of dimensions:
+
+::
+
+ a = areshape(seqa(1, 1, 12), 2|3|2);
+ print a;
+
+ // Swap the 2nd and 3rd dimensions (transpose each plane)
+ b = atranspose(a, 1|3|2);
+ print b;
+
+This prints::
+
+ Plane [1,.,.]
+
+ 1.0000000 2.0000000
+ 3.0000000 4.0000000
+ 5.0000000 6.0000000
+
+ Plane [2,.,.]
+
+ 7.0000000 8.0000000
+ 9.0000000 10.000000
+ 11.000000 12.000000
+
+ Plane [1,.,.]
+
+ 1.0000000 3.0000000 5.0000000
+ 2.0000000 4.0000000 6.0000000
+
+ Plane [2,.,.]
+
+ 7.0000000 9.0000000 11.000000
+ 8.0000000 10.000000 12.000000
+
+The vector ``1|3|2`` means: keep dimension 1 in place, move dimension 3
+to position 2, and move dimension 2 to position 3. This effectively
+transposes each 2D plane within the array.
+
+Array multiplication
+++++++++++++++++++++++++++++++++++++
+
+:func:`amult` performs matrix multiplication on the **last two
+dimensions** of each array. The leading dimensions must match exactly:
+
+::
+
+ // 2x3x2 array (two 3x2 matrices)
+ a = areshape(seqa(1, 1, 12), 2|3|2);
+
+ // 2x2x2 array (two 2x2 matrices)
+ b = areshape(seqa(1, 1, 8), 2|2|2);
+
+ // Result: 2x3x2 array (two 3x2 results)
+ c = amult(a, b);
+ print c;
+
+This prints::
+
+ Plane [1,.,.]
+
+ 7.0000000 10.000000
+ 15.000000 22.000000
+ 23.000000 34.000000
+
+ Plane [2,.,.]
+
+ 91.000000 106.00000
+ 115.00000 134.00000
+ 139.00000 162.00000
+
+Each plane in ``c`` is the matrix product of the corresponding planes
+in ``a`` and ``b``.
+
+Array mean
+++++++++++++++++++++++++++++++++++++
+
+:func:`amean` computes the mean along a specified dimension, collapsing
+that dimension to size 1:
+
+::
+
+ a = areshape(seqa(1, 1, 24), 2|3|4);
+
+ // Mean across 4 columns (dimension 1) -> 2|3|1
+ b = amean(a, 1);
+ print b;
+
+ // Mean across 3 rows (dimension 2) -> 2|1|4
+ c = amean(a, 2);
+ print c;
+
+This prints::
+
+ Plane [1,.,.]
+
+ 2.5000000
+ 6.5000000
+ 10.500000
+
+ Plane [2,.,.]
+
+ 14.500000
+ 18.500000
+ 22.500000
+
+ Plane [1,.,.]
+ 5.0000000 6.0000000 7.0000000 8.0000000
+
+ Plane [2,.,.]
+ 17.000000 18.000000 19.000000 20.000000
+
+
+Looping Over Array Planes
+--------------------------------------------
+
+A common pattern is to loop over the planes of a 3-D array, extracting
+each plane as a matrix, operating on it, and storing the result back:
+
+::
+
+ a = areshape(rndn(300, 1), 3|10|10);
+ result = arrayinit(3|10|10, 0);
+
+ for i(1, 3, 1);
+ m = getmatrix(a, i); // extract plane i as a matrix
+ setarray result, i, inv(m); // store inverse back
+ endfor;
+
+.. tip::
+
+ Use :func:`getmatrix` / :func:`getarray` and :func:`setarray`
+ instead of the index operator (``a[i,.,.]``) inside loops. The
+ dedicated functions avoid creating temporary arrays on each
+ iteration and can be over **2x faster** for large arrays.
+
+
+Converting Between Arrays and Matrices
+--------------------------------------------
+
+.. list-table::
+ :widths: 25 75
+ :header-rows: 1
+
+ * - Function
+ - Description
+
+ * - :func:`arraytomat`
+ - Convert a 1-D or 2-D array to a matrix
+
+ * - :func:`areshape`
+ - Convert a matrix into an array (or reshape an existing array)
+
+ * - :func:`getmatrix`
+ - Extract a 2-D slice from an array as a matrix
+
+ * - :func:`squeeze`
+ - Remove singleton dimensions; if the result is 2-D it becomes
+ a matrix (type 6). E.g., a 1xNx1 array becomes an Nx1 matrix
+
+Example: arraytomat
+++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Create a 2-D array (same shape as a matrix, but type 21)
+ a = arrayinit(2|3, 5);
+ print "array type:" type(a);
+
+ // Convert to a matrix (type 6)
+ m = arraytomat(a);
+ print "matrix type:" type(m);
+ print m;
+
+This prints::
+
+ array type: 21.000000
+ matrix type: 6.0000000
+ 5.0000000 5.0000000 5.0000000
+ 5.0000000 5.0000000 5.0000000
+
+
+Using Arrays with GAUSS Functions
+--------------------------------------------
+
+Many built-in GAUSS functions accept arrays. There are two general
+patterns:
+
+Element-wise functions
+++++++++++++++++++++++++++++++++++++
+
+Functions like :func:`cdfnc`, :func:`ln`, :func:`exp`, :func:`abs`,
+and other element-wise operations return an array of the same size and
+shape:
+
+::
+
+ a = areshape(seqa(-2, 0.5, 12), 2|3|2);
+ b = cdfnc(a);
+ print b;
+
+This prints::
+
+ Plane [1,.,.]
+
+ 0.97724987 0.93319280
+ 0.84134475 0.69146246
+ 0.50000000 0.30853754
+
+ Plane [2,.,.]
+
+ 0.15865525 0.066807201
+ 0.022750132 0.0062096653
+ 0.0013498980 0.00023262907
+
+Matrix functions
+++++++++++++++++++++++++++++++++++++
+
+Functions like :func:`moment`, :func:`inv`, :func:`det`, and
+:func:`svds` operate on the **last two trailing dimensions**. All
+leading dimensions are treated as independent instances:
+
+- A 5x10x3 array passed to :func:`moment` returns a 5x3x3 array
+ (five 3x3 moment matrices from five 10x3 data matrices).
+- A 2x3x4x5x10x6 array passed to :func:`moment` returns a
+ 2x3x4x5x6x6 array.
+
+::
+
+ // 2x3x4 array
+ a = areshape(seqa(1, 1, 24), 2|3|4);
+
+ // amean along dim 1 collapses columns: 2|3|4 -> 2|3|1
+ b = amean(a, 1);
+
+.. note::
+
+ Not all functions follow these two patterns exactly. Check the
+ function reference if you are unsure how a particular function
+ handles array input.
+
+
+Function Reference
+--------------------------------------------
+
+.. list-table:: Creating and reshaping
+ :widths: 25 75
+ :header-rows: 1
+
+ * - Function
+ - Description
+
+ * - :func:`areshape`
+ - Create an array from a matrix or reshape an existing array
+
+ * - :func:`aconcat`
+ - Concatenate arrays along a specified dimension
+
+ * - :func:`aeye`
+ - Create an array of identity matrices
+
+ * - :func:`arrayinit`
+ - Create an array filled with a single scalar value
+
+ * - :func:`arrayalloc`
+ - Allocate an array without initializing its contents
+
+.. list-table:: Extracting and inserting
+ :widths: 25 75
+ :header-rows: 1
+
+ * - Function
+ - Description
+
+ * - :func:`getarray`
+ - Extract a sub-array along the leading dimensions (returns
+ array, type 21)
+
+ * - :func:`getmatrix`
+ - Extract a 2-D slice as a matrix (returns type 6)
+
+ * - :func:`getscalar3D`
+ - Extract a single element from a 3-D array as a scalar
+
+ * - :func:`getmatrix4D`
+ - Extract a 2-D slice from a 4-D array as a matrix
+
+ * - :func:`getscalar4D`
+ - Extract a single element from a 4-D array as a scalar
+
+ * - :func:`putarray`
+ - Insert data into an array (returns new array)
+
+ * - :func:`setarray`
+ - Insert data into an array (modifies in place)
+
+.. list-table:: Operations and queries
+ :widths: 25 75
+ :header-rows: 1
+
+ * - Function
+ - Description
+
+ * - :func:`getorders`
+ - Get the size of each dimension as a vector
+
+ * - :func:`atranspose`
+ - Reorder dimensions of an array
+
+ * - :func:`amult`
+ - Matrix multiply along trailing dimensions
+
+ * - :func:`amean`
+ - Mean along a specified dimension
+
+ * - :func:`arraytomat`
+ - Convert a 2-D array to a matrix
+
+ * - :func:`squeeze`
+ - Remove singleton dimensions (may return a matrix)
+
+ * - :func:`type`
+ - Returns 21 for arrays, 6 for matrices
+
+
+Quick Reference
+--------------------------------------------
+
+.. list-table::
+ :widths: 40 60
+ :header-rows: 1
+
+ * - Task
+ - How
+
+ * - Create array from matrix
+ - ``a = areshape(x, 3|2|2);``
+
+ * - Create array of zeros
+ - ``a = arrayinit(3|2|2, 0);``
+
+ * - Create array of identity matrices
+ - ``a = aeye(3|2|2);``
+
+ * - Stack matrices into 3-D array
+ - ``a = aconcat(x1, x2, 3);``
+
+ * - Get dimension sizes
+ - ``getorders(a)``
+
+ * - Extract a plane as matrix
+ - ``m = getmatrix(a, i);``
+
+ * - Extract a scalar from 3-D array
+ - ``s = getscalar3D(a, plane, row, col);``
+
+ * - Insert matrix into plane
+ - ``a = putarray(a, i, m);``
+
+ * - Transpose within each plane
+ - ``b = atranspose(a, 1|3|2);``
+
+ * - Multiply across planes
+ - ``c = amult(a, b);``
+
+ * - Mean along a dimension
+ - ``amean(a, dim)``
+
+ * - Convert array to matrix
+ - ``m = arraytomat(a);``
+
+ * - Check if array
+ - ``type(a)`` returns 21
+
+
+.. seealso:: :ref:`operators`, :doc:`/user-guide/advanced/structures`
diff --git a/docs/user-guide/advanced/compilation-libraries.rst b/docs/user-guide/advanced/compilation-libraries.rst
new file mode 100644
index 00000000..5059d0c9
--- /dev/null
+++ b/docs/user-guide/advanced/compilation-libraries.rst
@@ -0,0 +1,561 @@
+.. _compilation-libraries:
+
+Compilation and Libraries
+===============================================
+
+As your GAUSS projects grow beyond a single script, you need ways to
+organize code into reusable pieces and share procedures across programs.
+GAUSS provides three mechanisms for this:
+
+- **#include** — insert a source file directly into your program
+- **Libraries** — index files (``.lcg``) that tell GAUSS where to find
+ procedures and globals
+- **Compilation** — compile source to binary (``.gcg``) for faster
+ loading and code protection
+
+This page explains each mechanism and when to use it.
+
+.. note::
+
+ If you are coming from Python or C:
+
+ - ``#include`` works like C's ``#include`` — text substitution at
+ compile time.
+ - A GAUSS **library** (``.lcg``) is an index file that maps symbol
+ names to source files — a passive lookup table, not executable
+ code.
+ - A ``.gcg`` compiled file is like Python's ``.pyc`` bytecode —
+ faster to load, not human-readable, and platform-specific.
+
+
+``#include`` — Including Source Files
+--------------------------------------------
+
+The ``#include`` directive inserts the contents of another source file
+directly into your program at compile time, as if you had typed the code
+inline:
+
+::
+
+ #include myutils.src
+
+ y = addtwo(5);
+ print y;
+
+If ``myutils.src`` defines the procedure ``addtwo``, it is available
+immediately — no library setup required.
+
+How ``#include`` searches for files
+++++++++++++++++++++++++++++++++++++
+
+GAUSS searches for the included file in this order:
+
+1. The current working directory
+2. Each directory listed in the ``src_path`` configuration variable
+
+.. tip::
+
+ Use ``#include`` for small utility files or shared definitions.
+ For larger projects with many procedures, libraries provide a more
+ scalable approach.
+
+Rules for ``#include``
+++++++++++++++++++++++++++++++++++++
+
+- The filename follows ``#include`` on the same line with **no quotes
+ and no semicolon**.
+- ``#include`` directives are resolved at compile time. They can appear
+ anywhere in a source file.
+- Do not ``#include`` compiled (``.gcg``) files — include only source
+ files.
+- Nested includes are allowed: an included file can ``#include`` other
+ files.
+
+
+Libraries
+--------------------------------------------
+
+A **library** in GAUSS is a text file with the extension ``.lcg``
+(Library Catalog) that maps source file names to the symbols they
+contain. Libraries let GAUSS find and load procedures **on demand**,
+without requiring you to ``#include`` every source file.
+
+The ``library`` command
+++++++++++++++++++++++++++++++++++++
+
+The ``library`` command tells GAUSS which libraries to make available:
+
+::
+
+ // Load the TSMT time series library
+ library tsmt;
+
+ // Load multiple libraries
+ library tsmt, pgraph;
+
+Two libraries are always active:
+
+- **user.lcg** — loaded first (your personal library, if it exists)
+- **gauss.lcg** — loaded last (the built-in GAUSS library)
+
+When you issue a ``library`` command, the specified libraries are
+inserted between ``user.lcg`` and ``gauss.lcg`` in the search order.
+Any previously loaded user-specified libraries are unloaded.
+
+.. note::
+
+ ``library`` does not load any code into memory. It only tells the
+ autoloader where to *search* when it encounters an undefined symbol.
+
+Library file format (``.lcg``)
+++++++++++++++++++++++++++++++++++++
+
+A ``.lcg`` file is plain text. Each source filename appears flush left,
+followed by indented lines listing the symbols it contains:
+
+::
+
+ /*
+ ** myproject.lcg — Library catalog for my project
+ */
+
+ mathutils.src
+ onenorm : proc : 1
+ infnorm : proc : 5
+ euclidnorm : proc : 9
+
+ globals.dec
+ _my_tolerance : matrix : 1
+ _my_verbose : matrix : 2
+
+Each indented line has the format::
+
+ symbol_name : type : line_number
+
+The *line_number* field tells the autoloader which line of the source
+file defines the symbol. It is optional but improves loading speed.
+The *type* is one of:
+
+.. list-table::
+ :widths: 20 80
+ :header-rows: 1
+
+ * - Type
+ - Description
+
+ * - ``proc``
+ - Procedure
+
+ * - ``fn``
+ - Single-line function (``fn`` statement)
+
+ * - ``keyword``
+ - Keyword procedure
+
+ * - ``matrix``
+ - Matrix or scalar global variable
+
+ * - ``string``
+ - String global variable
+
+ * - ``array``
+ - N-dimensional array global variable
+
+ * - ``sparse matrix``
+ - Sparse matrix global variable
+
+ * - ``struct TypeName``
+ - Structure instance (e.g., ``struct DS``). Used for global
+ structure variables in source files.
+
+ * - ``definition``
+ - Structure type definition (in ``.sdf`` files)
+
+Comments in ``.lcg`` files recognize lines beginning with ``/*``,
+``**``, or ``*/`` as comments. Single-line ``//`` comments are not
+supported in library files.
+
+Where library files are stored
+++++++++++++++++++++++++++++++++++++
+
+.. list-table::
+ :widths: 30 70
+ :header-rows: 1
+
+ * - Library
+ - Location
+
+ * - ``gauss.lcg``
+ - ``GAUSSHOME/lib/``
+
+ * - ``user.lcg``
+ - ``GAUSSHOME/lib/`` (created by user if needed)
+
+ * - Add-on libraries
+ - ``GAUSSHOME/pkgs//lib/``
+
+Library files must be located on the ``lib_path`` configuration
+variable. Source files (``.src``, ``.dec``, ``.ext``, ``.sdf``)
+referenced by the library must be on the ``src_path``. These are
+separate configuration variables — placing a ``.lcg`` file on
+``src_path`` will not make it discoverable as a library.
+
+The Autoloader
+--------------------------------------------
+
+The **autoloader** is the mechanism that connects libraries to your
+running code. When GAUSS encounters a symbol that has not been defined
+yet, the autoloader searches for it and loads the containing source
+file automatically.
+
+How the autoloader resolves symbols
+++++++++++++++++++++++++++++++++++++
+
+When GAUSS encounters an undefined symbol on the **right-hand side** of
+a statement (used as a value, function call, etc.), it searches in this
+order:
+
+1. **user.lcg** — your personal library catalog
+2. **User-specified libraries** — libraries loaded via the ``library``
+ command, in the order specified
+3. **gauss.lcg** — the built-in GAUSS library catalog
+4. **Loose ``.g`` files** — files matching ``symbol_name.g`` in the
+ current directory, then in each ``src_path`` directory (only when
+ ``autodelete`` is ON — see below)
+
+When the autoloader finds the symbol in a ``.lcg`` file, it locates
+the source file listed above the symbol and compiles it. All symbols
+in that source file become available.
+
+.. warning::
+
+ If a symbol appears on the **left-hand side** of a statement
+ (being assigned to) and has not been defined, GAUSS creates it as
+ a new matrix variable — the autoloader is **not** invoked. This
+ means accidentally assigning to a procedure name silently creates
+ a variable instead of calling the procedure::
+
+ // WRONG: creates a matrix, does not call onenorm
+ onenorm = {1, 2, 3};
+
+ // RIGHT: right-hand side triggers the autoloader
+ result = onenorm({1, 2, 3});
+
+Example: Autoloader in action
+++++++++++++++++++++++++++++++++++++
+
+Suppose ``mathutils.src`` contains:
+
+::
+
+ // mathutils.src
+ proc (1) = onenorm(x);
+ retp(sumc(abs(x)));
+ endp;
+
+ proc (1) = infnorm(x);
+ retp(maxc(abs(x)));
+ endp;
+
+And ``myproject.lcg`` contains:
+
+::
+
+ mathutils.src
+ onenorm : proc : 1
+ infnorm : proc : 5
+
+After running ``library myproject;``, you can call ``onenorm`` or
+``infnorm`` directly. The autoloader finds the symbol in
+``myproject.lcg``, compiles ``mathutils.src``, and makes both
+procedures available.
+
+The ``autodelete`` setting
+++++++++++++++++++++++++++++++++++++
+
+By default, ``autodelete`` is ON. This means:
+
+- When the autoloader loads a source file, it marks the symbols for
+ automatic deletion.
+- If a later source file defines the same symbol, the old definition
+ is automatically replaced.
+
+With ``autodelete`` OFF, the autoloader is stricter:
+
+- The ``.g`` file search (step 4 above) is disabled. Every symbol must
+ be listed in an active library or declared with ``external``.
+- Forward references to undefined symbols within the same file require
+ ``external`` declarations.
+- Redefining a symbol that was loaded by the autoloader produces an
+ error, catching accidental name collisions.
+
+::
+
+ // Turn off automatic deletion of autoloaded symbols
+ autodelete off;
+
+
+Global Declaration Files
+--------------------------------------------
+
+Libraries often need global variables shared across procedures. GAUSS
+uses two types of declaration files to manage this: ``.dec`` files
+*define* the variable (one per library), and ``.ext`` files *reference*
+it (included in every source file that uses the variable).
+
+Declaration files (.dec)
+++++++++++++++++++++++++++++++++++++
+
+A ``.dec`` file contains ``declare`` statements that create global
+variables with default values:
+
+::
+
+ // myproject.dec
+ declare matrix _my_tolerance = 1e-8;
+ declare matrix _my_verbose = 1;
+ declare string _my_outfile = "results.txt";
+
+``declare`` creates the variable **only if it does not already exist**.
+If the variable is already in memory, ``declare`` is silently ignored.
+This makes ``.dec`` files safe to include multiple times.
+
+.. note::
+
+ Legacy code uses ``!=`` instead of ``=`` in ``declare`` statements
+ (e.g., ``declare matrix _tol != 1e-8;``). Both forms have the same
+ behavior: initialize only if the variable does not already exist.
+
+.. tip::
+
+ By convention, global variables in libraries use an underscore
+ prefix (``_my_tolerance``) to avoid name collisions with user
+ variables.
+
+External declaration files (.ext)
+++++++++++++++++++++++++++++++++++++
+
+An ``.ext`` file contains ``external`` statements that tell the
+compiler a symbol is defined elsewhere:
+
+::
+
+ // myproject.ext
+ external matrix _my_tolerance, _my_verbose;
+ external string _my_outfile;
+ external proc onenorm, infnorm;
+
+``external`` does not create the variable or assign a value — it only
+tells the compiler that the symbol exists so the program compiles
+without errors.
+
+Structure definition files (.sdf)
+++++++++++++++++++++++++++++++++++++
+
+Structure definitions are stored in ``.sdf`` (Structure Definition
+File) files. These define the fields of a structure type:
+
+::
+
+ // myresult.sdf
+ struct myResult {
+ matrix coefficients;
+ matrix stderr;
+ scalar retcode;
+ string method;
+ };
+
+Structure definition files are listed in library catalogs with the
+type ``definition``.
+
+Putting it all together
+++++++++++++++++++++++++++++++++++++
+
+A typical library project has this file structure::
+
+ myproject/
+ src/
+ myproject.dec Global variable defaults
+ myproject.ext External declarations
+ myproject.sdf Structure definitions
+ mathutils.src Procedure source code
+ ioutils.src More procedures
+ lib/
+ myproject.lcg Library catalog
+
+The ``.lcg`` file lists all the source, declaration, and definition
+files:
+
+::
+
+ myproject.dec
+ _my_tolerance : matrix : 1
+ _my_verbose : matrix : 2
+
+ myproject.sdf
+ struct myResult : definition : 1
+
+ mathutils.src
+ onenorm : proc : 1
+ infnorm : proc : 5
+
+ ioutils.src
+ loadresults : proc : 1
+ saveresults : proc : 12
+
+Users activate the library with ``library myproject;`` and can then
+call any of its procedures.
+
+
+Compiling Programs
+--------------------------------------------
+
+The ``compile`` command converts a GAUSS source file (``.e``) into a
+compiled binary file (``.gcg``):
+
+::
+
+ compile myprogram.e;
+
+This creates ``myprogram.gcg``. You can also specify an output name:
+
+::
+
+ compile myprogram.e myoutput;
+
+This creates ``myoutput.gcg``. Run a compiled file with:
+
+::
+
+ run myprogram.gcg;
+
+.. note::
+
+ The ``run`` command assumes a ``.gcg`` extension if none is given.
+ So ``run myprogram;`` is equivalent to ``run myprogram.gcg;``.
+
+When to compile
+++++++++++++++++++++++++++++++++++++
+
+Compilation is useful when you want to:
+
+- **Distribute code** without revealing source — compiled files are
+ binary and cannot be easily read.
+- **Speed up loading** — compiled files skip the parsing step.
+- **Freeze a version** — the compiled file captures library
+ dependencies at compile time.
+
+Compilation rules
+++++++++++++++++++++++++++++++++++++
+
+- **Libraries must be present at compile time.** The compiler resolves
+ ``library`` statements and autoloader references during compilation.
+ The resulting ``.gcg`` file does **not** store library references —
+ all needed code is compiled in.
+- **Libraries are not needed at run time.** Since library code is
+ compiled into the ``.gcg`` file, users can run the compiled program
+ without having the original ``.lcg`` files or source.
+- **DLLs/shared libraries must be present at run time.** If your
+ program uses ``dlibrary`` to load external shared libraries, those
+ files must be available when the compiled program runs.
+- **Compiled files are platform-specific.** A ``.gcg`` file compiled
+ on macOS will not run on Windows, and vice versa. 64-bit and 32-bit
+ builds are also incompatible.
+
+.. tip::
+
+ Place ``new;`` at the top of your source file before compiling to
+ ensure that no extraneous symbols from the current workspace are
+ included in the compiled image.
+
+Debug line numbers
+++++++++++++++++++++++++++++++++++++
+
+By default, compiled files do not include source line numbers in error
+messages. To include line number information for debugging, add
+``#lineson`` to your source file before compiling:
+
+::
+
+ #lineson
+
+ x = rndn(3, 3);
+ y = inv(x);
+ print y;
+
+
+File Type Reference
+--------------------------------------------
+
+.. list-table::
+ :widths: 15 85
+ :header-rows: 1
+
+ * - Extension
+ - Description
+
+ * - ``.e``
+ - GAUSS program source file (main entry point)
+
+ * - ``.src``
+ - Procedure source file (contains ``proc``/``endp`` definitions)
+
+ * - ``.g``
+ - Single-procedure source file (autoloader convention: one
+ procedure per file, filename matches procedure name)
+
+ * - ``.dec``
+ - Global declaration file (``declare`` statements)
+
+ * - ``.ext``
+ - External declaration file (``external`` statements)
+
+ * - ``.sdf``
+ - Structure definition file
+
+ * - ``.lcg``
+ - Library catalog file (maps source files to symbols)
+
+ * - ``.gcg``
+ - Compiled GAUSS binary (output of ``compile``)
+
+
+Quick Reference
+--------------------------------------------
+
+.. list-table::
+ :widths: 35 65
+ :header-rows: 1
+
+ * - Task
+ - How
+
+ * - Include a source file
+ - ``#include myutils.src``
+
+ * - Activate a library
+ - ``library tsmt;``
+
+ * - Activate multiple libraries
+ - ``library tsmt, pgraph;``
+
+ * - Compile a program
+ - ``compile myprogram.e;``
+
+ * - Run a compiled program
+ - ``run myprogram.gcg;``
+
+ * - Declare a global with default
+ - ``declare matrix _tol = 1e-8;``
+
+ * - Declare an external symbol
+ - ``external proc myproc;``
+
+ * - Disable autoload replacement
+ - ``autodelete off;``
+
+ * - Enable debug line numbers
+ - ``#lineson`` (at top of source file)
+
+
+.. seealso:: :doc:`/user-guide/fundamentals/procedures`, :doc:`/user-guide/advanced/structures`
diff --git a/docs/user-guide/advanced/performance.rst b/docs/user-guide/advanced/performance.rst
new file mode 100644
index 00000000..2fd17bcb
--- /dev/null
+++ b/docs/user-guide/advanced/performance.rst
@@ -0,0 +1,352 @@
+Optimizing GAUSS Code for Speed
+===============================================
+
+GAUSS is a matrix language. Code that embraces matrix operations instead
+of scalar loops can run **20-400x faster** with no extra effort. This
+guide covers the techniques that matter most, ordered by impact.
+
+
+Find Your Bottleneck First
+-----------------------------------------
+
+Before optimizing, measure where the time goes::
+
+ // Time a section of code
+ t0 = hsec;
+
+ // ... your slow code here ...
+
+ t1 = hsec;
+ print "Elapsed:" ((t1 - t0) / 100) "seconds";
+
+Wrap different sections of your program to find which part is actually
+slow. Then use this guide to fix it:
+
+1. **Loop that could be a matrix operation?** → :ref:`vectorize-section`
+2. **Loop that grows a matrix with** ``|`` **?** → :ref:`preallocate-section`
+3. **Loop with expensive independent iterations?** → :ref:`loop-section` (``threadfor``)
+4. **Loading more data than you need?** → :ref:`memory-section`
+
+
+.. _vectorize-section:
+
+Vectorize Everything
+-----------------------------------------
+
+This is the single biggest performance lever in GAUSS. Every built-in
+function and element-wise operator runs in optimized C/Fortran under the
+hood. A scalar loop doing the same work pays the interpreter overhead on
+every iteration.
+
+Counting elements that satisfy a condition
++++++++++++++++++++++++++++++++++++++++++++++
+
+**Slow** -- loop with accumulator::
+
+ // Count values where |x| > 1
+ // 1,000,000 elements: ~110 ms
+ n = rows(x);
+ count = 0;
+ for i (1, n, 1);
+ if abs(x[i, 1]) > 1;
+ count = count + 1;
+ endif;
+ endfor;
+
+**Fast** -- vectorized::
+
+ // Same result: ~6 ms (18x faster)
+ count = sumc(abs(x) .> 1);
+
+The expression ``abs(x) .> 1`` produces a column of 0s and 1s in one
+pass. :func:`sumc` totals them. Two operations, zero loop overhead.
+
+
+Element-wise math
+++++++++++++++++++++++
+
+**Slow** -- loop over every element::
+
+ // 1,000,000 rows: ~410 ms
+ z = zeros(n, 1);
+ for i (1, n, 1);
+ z[i, 1] = x[i, 1] * y[i, 1] + x[i, 1] / (abs(y[i, 1]) + 1);
+ endfor;
+
+**Fast** -- element-wise operators::
+
+ // Same result: ~12 ms (33x faster)
+ z = x .* y + x ./ (abs(y) + 1);
+
+Use ``.*``, ``./``, ``.^`` for element-wise operations and ``*``, ``/``
+for matrix operations. The dot-prefix convention applies to comparisons
+too: ``.>``, ``.<``, ``.==``, ``.!=``.
+
+
+Filtering rows
+++++++++++++++++++++
+
+**Slow** -- loop and concatenate matching rows::
+
+ // 100,000 rows x 3 cols: ~710 ms
+ result = {};
+ for i (1, rows(x), 1);
+ if x[i, 1] > 0;
+ result = result | x[i, .];
+ endif;
+ endfor;
+
+**Fast** -- use :func:`selif`::
+
+ // Same result: ~1.6 ms (440x faster)
+ result = selif(x, x[., 1] .> 0);
+
+:func:`selif` selects rows where the condition vector is non-zero.
+:func:`delif` does the opposite (deletes matching rows). Both are
+single-pass operations.
+
+
+Summary statistics
+++++++++++++++++++++
+
+Use the column-wise built-in functions instead of writing accumulator loops:
+
+========================== ========================
+Loop pattern Vectorized replacement
+========================== ========================
+Sum in a loop :func:`sumc`
+Mean in a loop :func:`meanc`
+Std dev in a loop :func:`stdc`
+Min/max in a loop :func:`minc` / :func:`maxc`
+Product in a loop :func:`prodc`
+Cumulative sum :func:`cumsumc`
+========================== ========================
+
+
+.. note::
+
+ For data that approaches available RAM, a single vectorized expression
+ can create multiple temporary matrices. If you see disk paging, break
+ the expression into steps or process data in chunks.
+
+
+.. _loop-section:
+
+Loop Optimization
+-----------------------------------------
+
+When a loop is unavoidable -- iterative algorithms, simulations with
+state, or row-by-row I/O -- these techniques keep it fast.
+
+Use ``for``, not ``do while``
+++++++++++++++++++++++++++++++++
+
+The ``for`` loop has a pre-compiled counter. A ``do while`` loop
+re-evaluates its condition expression on every iteration.
+
+::
+
+ // for loop: 1,000,000 iterations in ~62 ms
+ x = 0;
+ for i (1, 1000000, 1);
+ x = x + 1;
+ endfor;
+
+ // do while: same work in ~164 ms (2.6x slower)
+ x = 0;
+ i = 1;
+ do while i <= 1000000;
+ x = x + 1;
+ i = i + 1;
+ endo;
+
+Use ``for`` whenever the iteration count is known in advance. The
+difference matters most for tight loops with cheap bodies; with
+heavy computation per iteration, the overhead gap is negligible.
+
+
+Use ``threadfor`` for heavy independent work
+++++++++++++++++++++++++++++++++++++++++++++++++
+
+When each iteration is computationally expensive and independent of the
+others, ``threadfor`` distributes iterations across CPU cores.
+
+::
+
+ // 8 large matrix operations
+ y = zeros(8, 1);
+
+ // threadfor: ~370 ms
+ threadfor i(1, 8, 1);
+ tmp = rndn(1000, 1000);
+ y[i] = det(tmp'tmp);
+ threadendfor;
+
+ // for: ~2370 ms (6.4x slower)
+ for i (1, 8, 1);
+ tmp = rndn(1000, 1000);
+ y[i] = det(tmp'tmp);
+ endfor;
+
+``threadfor`` is most effective when each iteration does substantial
+work (matrix factorizations, simulations, optimization). For simple
+element-wise math, vectorized operations are faster than any loop.
+
+.. warning::
+
+ ``threadfor`` iterations must be independent -- no iteration can read
+ a value written by another. Each iteration should write to its own
+ location (e.g., ``y[i]``). Don't use ``threadfor`` when iterations are
+ cheap (simple arithmetic) -- the threading overhead will make it slower
+ than a plain ``for`` loop.
+
+
+Minimize work inside tight loops
+++++++++++++++++++++++++++++++++++
+
+Move invariant computations outside the loop::
+
+ // Slow: recomputes inv(X'X) every iteration
+ for i (1, n_sims, 1);
+ b[i, .] = inv(X'X) * X'y[., i];
+ endfor;
+
+ // Fast: compute the fixed part once
+ XtX_inv_Xt = inv(X'X) * X';
+ for i (1, n_sims, 1);
+ b[i, .] = XtX_inv_Xt * y[., i];
+ endfor;
+
+
+.. _preallocate-section:
+
+Preallocate, Don't Concatenate
+-----------------------------------------
+
+Appending to a matrix with ``|`` or ``~`` inside a loop copies the
+entire matrix on every iteration. For *n* iterations, this means
+*n(n+1)/2* element copies -- quadratic cost.
+
+**Slow** -- concatenation in a loop::
+
+ // 100,000 iterations: ~914 ms
+ y = {};
+ for i (1, 100000, 1);
+ y = y | i;
+ endfor;
+
+**Fast** -- preallocate and fill::
+
+ // Same result: ~15 ms (62x faster)
+ y = zeros(100000, 1);
+ for i (1, 100000, 1);
+ y[i, 1] = i;
+ endfor;
+
+The fix is simple:
+
+1. Allocate the full output matrix with :func:`zeros` before the loop.
+2. Write to ``y[i, .]`` inside the loop.
+
+If you don't know the final size in advance, estimate an upper bound,
+fill what you need, and trim at the end::
+
+ y = zeros(max_possible, k);
+ count = 0;
+ for i (1, n, 1);
+ if some_condition;
+ count = count + 1;
+ y[count, .] = result_row;
+ endif;
+ endfor;
+
+ // Trim to actual size
+ y = y[1:count, .];
+
+
+.. _memory-section:
+
+Memory-Efficient Data Access
+-----------------------------------------
+
+Load only the columns you need
++++++++++++++++++++++++++++++++++
+
+Use a formula string with :func:`loadd` to load a subset of columns
+directly from disk::
+
+ // Loads all columns into memory
+ data = loadd("big_survey.csv");
+
+ // Loads only the columns you need
+ data = loadd("big_survey.csv", "Income + Age + Education");
+
+ // Load all except a few columns
+ data = loadd("big_survey.csv", ". - RawText - Notes");
+
+When a file has dozens of columns but you only need a few, this reduces
+both load time and memory use.
+
+
+Free memory when done
+++++++++++++++++++++++++
+
+Inside a procedure, local variables are freed automatically when the
+procedure returns. At global scope, reassign large matrices once they
+are no longer needed::
+
+ // Free a large matrix
+ raw_data = 0;
+
+This replaces the large matrix with a 1x1 scalar, releasing the memory
+immediately.
+
+Inside procedures, use ``local`` to ensure intermediate matrices are
+cleaned up on return::
+
+ proc (1) = myEstimate(data);
+ local X, y, XtX;
+
+ X = data[., 2:cols(data)];
+ y = data[., 1];
+ XtX = X'X;
+
+ retp(inv(XtX) * X'y);
+ endp;
+ // X, y, XtX are all freed when myEstimate returns
+
+
+Quick Reference
+-----------------------------------------
+
+.. list-table::
+ :header-rows: 1
+ :widths: 40 40 20
+
+ * - Slow Pattern
+ - Fast Pattern
+ - Speedup
+ * - Loop with counter to count matches
+ - ``sumc(condition)``
+ - ~18x
+ * - Loop with element-wise arithmetic
+ - Vectorized ``.*``, ``./``, ``.^``
+ - ~33x
+ * - Loop and concatenate to filter rows
+ - ``selif(x, condition)``
+ - ~440x
+ * - ``do while`` with known iteration count
+ - ``for i (1, n, 1)``
+ - ~2.6x
+ * - Sequential ``for`` over heavy work
+ - ``threadfor``
+ - ~6x
+ * - Concatenation inside a loop (``y = y | row``)
+ - Preallocate with ``zeros``, fill by index
+ - ~62x
+ * - ``loadd`` all columns, subset later
+ - Formula string: ``"col1 + col2"``
+ - varies
+ * - Invariant computation inside loop
+ - Hoist computation before loop
+ - varies
diff --git a/docs/user-guide/advanced/random-numbers.rst b/docs/user-guide/advanced/random-numbers.rst
new file mode 100644
index 00000000..76408334
--- /dev/null
+++ b/docs/user-guide/advanced/random-numbers.rst
@@ -0,0 +1,496 @@
+.. _random-numbers:
+
+Random Number Generation
+===============================================
+
+GAUSS provides a powerful suite of random number generation (RNG)
+functionality for simulation, Monte Carlo studies, and statistical
+sampling. Key features include:
+
+- Multiple modern pseudo-random generators (Mersenne Twister,
+ MRG32k3a, and more)
+- Quasi-random sequences (Sobol, Niederreiter) for numerical
+ integration
+- Over 20 distribution-specific sampling functions
+- Thread-safe state-based generation for parallel computing
+- Reproducible sequences via seeding
+
+Before diving in, here are a few terms used throughout this page:
+
+- **Seed** — an integer that initializes a generator. The same seed
+ always produces the same sequence of random numbers.
+- **State** — a data vector that captures a generator's type and
+ current position in its sequence. Passing a state to a function
+ continues the sequence where the previous call left off.
+- **Stream** — an independent sequence within a multi-stream generator
+ (e.g., MT2203 has 6024 streams).
+- **Period** — the length of the full cycle before a generator repeats.
+
+.. note::
+
+ If you are coming from R, ``rndn`` is equivalent to ``rnorm`` and
+ ``rndu`` is equivalent to ``runif``. The ``rndseed`` statement is
+ analogous to ``set.seed()``. If you are coming from Python/NumPy,
+ ``rndn`` corresponds to ``numpy.random.randn`` and ``rndu`` to
+ ``numpy.random.rand``.
+
+
+Basic Random Number Functions
+--------------------------------------------
+
+GAUSS provides two fundamental functions for generating random
+numbers:
+
+::
+
+ // 3x2 matrix of standard normal random numbers
+ x = rndn(3, 2);
+
+ // 3x2 matrix of uniform random numbers on [0, 1)
+ u = rndu(3, 2);
+
+For random integers in a range, use :func:`rndi`:
+
+::
+
+ // 3x1 vector of random integers between 1 and 100
+ ri = rndi(3, 1, 1|100);
+
+These functions use a shared global state. For reproducible results,
+set the seed before generating:
+
+::
+
+ rndseed 42;
+ x = rndn(3, 2);
+
+Running the above code will always produce the same output::
+
+ 0.55850061 2.0347955
+ 0.24048153 -0.97476365
+ -0.85727785 -0.98405229
+
+.. note::
+
+ ``rndseed`` is a **language statement**, not a function — write
+ ``rndseed 42;``, not ``rndseed(42);``. It sets the global seed
+ for ``rndn``, ``rndu``, ``rndi``, and all distribution-specific
+ functions that do not take an explicit state. Setting the seed
+ again resets the sequence to the same starting point.
+
+
+Sampling from Distributions
+--------------------------------------------
+
+GAUSS includes functions for sampling from many common distributions:
+
+.. list-table::
+ :widths: 30 70
+ :header-rows: 1
+
+ * - Function
+ - Distribution
+
+ * - :func:`rndn`
+ - Standard normal (mean 0, variance 1)
+
+ * - :func:`rndu`
+ - Uniform on [0, 1)
+
+ * - :func:`rndi`
+ - Random integers in a range
+
+ * - :func:`rndBernoulli`
+ - Bernoulli (binary outcomes)
+
+ * - :func:`rndBeta`
+ - Beta
+
+ * - :func:`rndBinomial`
+ - Binomial
+
+ * - :func:`rndCauchy`
+ - Cauchy
+
+ * - :func:`rndChiSquare`
+ - Chi-square
+
+ * - :func:`rndExp`
+ - Exponential
+
+ * - :func:`rndGamma`
+ - Gamma
+
+ * - :func:`rndGeo`
+ - Geometric
+
+ * - :func:`rndGumbel`
+ - Gumbel (extreme value type I)
+
+ * - :func:`rndHyperGeo`
+ - Hypergeometric
+
+ * - :func:`rndLaplace`
+ - Laplace (double exponential)
+
+ * - :func:`rndLogNorm`
+ - Log-normal
+
+ * - :func:`rndMVn`
+ - Multivariate normal
+
+ * - :func:`rndMVt`
+ - Multivariate Student's t
+
+ * - :func:`rndNegBinomial`
+ - Negative binomial
+
+ * - :func:`rndPoisson`
+ - Poisson
+
+ * - :func:`rndRayleigh`
+ - Rayleigh
+
+ * - :func:`rndWeibull`
+ - Weibull
+
+ * - :func:`rndWishart`
+ - Wishart
+
+ * - :func:`rndWishartInv`
+ - Inverse Wishart
+
+Example: Distribution sampling
+++++++++++++++++++++++++++++++++++++
+
+::
+
+ rndseed 42;
+
+ // 1000 Gamma(shape=2, scale=1) draws
+ g = rndGamma(1000, 1, 2, 1);
+
+ // 1000 Poisson(lambda=5) draws
+ p = rndPoisson(1000, 1, 5);
+
+ // Multivariate normal with correlation
+ // { 0, 0 } is a 2x1 column vector; { 1 0.5, 0.5 1 } is a 2x2 matrix
+ // (commas separate rows, spaces separate columns)
+ mu = { 0, 0 };
+ sigma = { 1 0.5, 0.5 1 };
+ mv = rndMVn(500, mu, sigma);
+
+
+Available Generators
+--------------------------------------------
+
+GAUSS includes several pseudo-random and quasi-random number
+generators. You select a generator by creating a **state** with
+:func:`rndCreateState`:
+
+.. list-table::
+ :widths: 18 10 12 12 48
+ :header-rows: 1
+
+ * - Generator
+ - Streams
+ - Period
+ - BigCrush
+ - Notes
+
+ * - SFMT19937
+ - 1
+ - 2\ :sup:`19937`
+ - —
+ - Default for ``rndn``/``rndu``. Fastest available
+
+ * - MRG32k3a
+ - 1
+ - 2\ :sup:`191`
+ - 0 failures
+ - Supports block-skipping via :func:`rndStateSkip`
+
+ * - MT19937
+ - 1
+ - 2\ :sup:`19937`
+ - 2 failures
+ - Classic Mersenne Twister
+
+ * - MT2203
+ - 6024
+ - 2\ :sup:`2203`
+ - 4 failures
+ - Multiple independent streams for parallel work
+
+ * - Wichmann-Hill
+ - 273
+ - 2\ :sup:`42.7`
+ - 22 failures
+ - Multiple independent streams. Supports block-skipping
+
+ * - Sobol
+ - —
+ - —
+ - —
+ - Quasi-random (low discrepancy). Dimensions 1–40.
+ The seed argument to :func:`rndCreateState` sets
+ the dimension, not a random seed
+
+ * - Niederreiter
+ - —
+ - —
+ - —
+ - Quasi-random (low discrepancy). Dimensions 1–318.
+ The seed argument sets the dimension
+
+The **BigCrush** column shows the number of failures on the TestU01
+BigCrush test suite (160 tests). All generators pass DIEHARD.
+SFMT19937 was not tested because its output is not compatible with
+the scalar-at-a-time interface required by TestU01.
+
+Choosing a generator
+++++++++++++++++++++++++++++++++++++
+
+For most work, the default generator (SFMT19937 for ``rndn``/``rndu``)
+is an excellent choice. Consider switching when:
+
+- **You need parallel streams** — use MT2203 (6024 streams) or
+ Wichmann-Hill (273 streams)
+- **You need block-skipping** — use MRG32k3a or Wichmann-Hill
+ (the generators that support :func:`rndStateSkip`)
+- **You need top statistical quality** — use MRG32k3a (zero BigCrush
+ failures)
+- **You need quasi-random sequences** — use Sobol or Niederreiter for
+ numerical integration (these are deterministic, not pseudo-random)
+
+.. tip::
+
+ For simulation studies that do not require parallel generation,
+ the simplest approach is ``rndseed`` plus ``rndn``/``rndu``. You
+ only need explicit state management when working with threads or
+ when you need multiple independent sequences.
+
+
+State-Based Generation
+--------------------------------------------
+
+For full control over the random number sequence, GAUSS supports
+**state-based** generation. A state encapsulates the generator type,
+stream index, and current position in the sequence.
+
+Creating a state
+++++++++++++++++++++++++++++++++++++
+
+Use :func:`rndCreateState` to create a state for any generator:
+
+::
+
+ // MRG32k3a with seed 192938
+ state = rndCreateState("mrg32k3a", 192938);
+
+ // Generate 3 standard normal values using this state.
+ // The { x, state } syntax is a multi-return assignment:
+ // x gets the random numbers
+ // state gets the updated generator state
+ { x, state } = rndn(3, 1, state);
+ print x;
+
+This prints::
+
+ 0.20471263
+ 0.14053340
+ -1.4368991
+
+Always pass the **updated** state to the next call to continue the
+sequence where it left off — do not reuse the original seed or state.
+
+Selecting a stream
+++++++++++++++++++++++++++++++++++++
+
+For generators with multiple streams (MT2203, Wichmann-Hill), append a
+hyphen and stream number to the generator name:
+
+::
+
+ seed = 192938;
+
+ // Wichmann-Hill stream 3
+ whState3 = rndCreateState("wh-3", seed);
+
+ // MT2203 stream 21
+ mtState21 = rndCreateState("mt2203-21", seed);
+
+Each stream is an independent pseudo-random sequence with the same
+statistical properties. Two different streams seeded identically will
+produce completely different sequences.
+
+.. note::
+
+ The KISS-Monster generator and its dedicated functions
+ (``rndKMn``, ``rndKMu``, ``rndKMi``) are **deprecated**. Use
+ :func:`rndCreateState` with any supported generator instead.
+
+
+Thread Safety
+--------------------------------------------
+
+When using threads (``threadBegin`` / ``threadEnd``), the global-state
+functions (``rndn``, ``rndu``, ``rndGamma``, etc.) share a single state
+and must **not** be called concurrently:
+
+::
+
+ // WRONG — concurrent writes to global state
+ threadBegin;
+ x = rndn(500, 1);
+ threadEnd;
+ threadBegin;
+ x2 = rndn(500, 1);
+ threadEnd;
+ threadJoin;
+
+There are two safe alternatives:
+
+**Option 1: Generate before threads**
+
+::
+
+ x = rndn(500, 1);
+ x2 = rndn(500, 1);
+ threadBegin;
+ y = myFunction(x);
+ threadEnd;
+ threadBegin;
+ y2 = myFunction(x2);
+ threadEnd;
+ threadJoin;
+
+**Option 2: Use explicit states**
+
+Each thread gets its own state, so there is no shared global state to
+corrupt. This example uses MRG32k3a, but any generator works:
+
+::
+
+ state1 = rndCreateState("mrg32k3a", 723193);
+ state2 = rndCreateState("mrg32k3a", 94493);
+ threadBegin;
+ { x1, state1 } = rndn(500, 1, state1);
+ y1 = myFunction(x1);
+ threadEnd;
+ threadBegin;
+ { x2, state2 } = rndn(500, 1, state2);
+ y2 = myFunction(x2);
+ threadEnd;
+ threadJoin;
+
+
+Parallel Generation with Block-Skipping
+--------------------------------------------
+
+When you need a single contiguous pseudo-random sequence split across
+multiple threads, use **block-skipping**. The :func:`rndStateSkip`
+function advances a state by a specified number of values without
+generating them:
+
+::
+
+ // Create initial state
+ seed = 2342343;
+ state1 = rndCreateState("mrg32k3a", seed);
+
+ // Create 3 additional states, each starting 1e8 values forward
+ state2 = rndStateSkip(1e8, state1);
+ state3 = rndStateSkip(1e8, state2);
+ state4 = rndStateSkip(1e8, state3);
+
+ // Process each block in a separate thread
+ threadBegin;
+ { x1, state1 } = rndGamma(1e8, 1, 2, 2, state1);
+ y1 = myfunc(x1);
+ threadEnd;
+ threadBegin;
+ { x2, state2 } = rndGamma(1e8, 1, 2, 2, state2);
+ y2 = myfunc(x2);
+ threadEnd;
+ threadBegin;
+ { x3, state3 } = rndGamma(1e8, 1, 2, 2, state3);
+ y3 = myfunc(x3);
+ threadEnd;
+ threadBegin;
+ { x4, state4 } = rndGamma(1e8, 1, 2, 2, state4);
+ y4 = myfunc(x4);
+ threadEnd;
+ threadJoin;
+
+The four threads together produce the same sequence as a single call
+generating 4 x 10\ :sup:`8` values — just processed in parallel.
+
+.. note::
+
+ Block-skipping via :func:`rndStateSkip` is available with the
+ **MRG32k3a** and **Wichmann-Hill** generators. For other
+ generators, use multiple independent streams (MT2203) or
+ separate seeds instead.
+
+
+Performance Tips
+--------------------------------------------
+
+- **Generate in bulk.** Creating one million numbers in a single call
+ is much faster than 100,000 calls of 10 numbers each. Avoid
+ generating random numbers one at a time inside loops.
+
+- **Use SFMT19937 for speed.** The optimized Mersenne Twister is the
+ fastest generator available. The default generator for
+ ``rndn``/``rndu`` is already very fast.
+
+- **Use multiple threads.** For large-scale simulations, distribute
+ work across threads using state-based generation (see above).
+
+- **Watch memory.** Generating a very large matrix in one call can
+ exhaust available RAM. Balance batch size against available memory.
+
+
+Quick Reference
+--------------------------------------------
+
+.. list-table::
+ :widths: 45 55
+ :header-rows: 1
+
+ * - Task
+ - How
+
+ * - Set seed for reproducibility
+ - ``rndseed 42;``
+
+ * - Standard normal matrix
+ - ``x = rndn(n, k);``
+
+ * - Uniform matrix
+ - ``u = rndu(n, k);``
+
+ * - Random integers in [a, b]
+ - ``ri = rndi(n, k, a|b);``
+
+ * - Gamma draws
+ - ``g = rndGamma(n, 1, shape, scale);``
+
+ * - Multivariate normal
+ - ``mv = rndMVn(n, mu, sigma);``
+
+ * - Create generator state
+ - ``state = rndCreateState("mrg32k3a", seed);``
+
+ * - Generate with state
+ - ``{ x, state } = rndn(n, k, state);``
+
+ * - Select a stream
+ - ``state = rndCreateState("mt2203-9", seed);``
+
+ * - Skip ahead in sequence
+ - ``state2 = rndStateSkip(1e6, state1);``
+
+
+.. seealso:: :doc:`/user-guide/advanced/structures`
diff --git a/docs/user-guide/advanced/structures.rst b/docs/user-guide/advanced/structures.rst
new file mode 100644
index 00000000..2d899b6f
--- /dev/null
+++ b/docs/user-guide/advanced/structures.rst
@@ -0,0 +1,719 @@
+Structures
+===============================================
+
+When a function has many settings — convergence tolerance, output
+verbosity, covariance method — passing each one as a separate argument
+would be unwieldy. Structures solve this by bundling related data into a
+single variable. In GAUSS, they serve two primary purposes: bundling
+configuration options for a function call (a *control structure*), and
+bundling the results that a function returns (an *output structure*).
+Nearly every estimation function in GAUSS follows this pattern.
+
+::
+
+ // 1. Create a control structure with default settings
+ struct olsmtControl ctl;
+ ctl = olsmtControlCreate();
+
+ // 2. Change the settings you need
+ ctl.output = 1;
+
+ // 3. Call the estimation function
+ struct olsmtOut out;
+ out = olsmt(getGAUSSHome("examples/credit.dat"), "Limit ~ Income + Rating", ctl);
+
+ // 4. Examine the results in the output structure
+ print "Coefficients:";
+ print out.b;
+
+ print "Standard errors:";
+ print out.stderr;
+
+ print "R-squared:";
+ print out.rsq;
+
+If you have used :func:`olsmt`, :func:`glm`, :func:`quantileFit`, or
+any of the time series functions, you have already used structures.
+This page explains how structures work, how to define your own, and how
+to get the most out of the control/output pattern.
+
+
+The Control Structure Pattern
+-----------------------------------------
+
+The most important thing to understand about structures in GAUSS is the
+**control-in, output-out** pattern. This is how almost all estimation
+and modeling functions work:
+
+1. Create a control structure filled with sensible defaults.
+2. Override only the members you want to change.
+3. Pass the control structure to the estimation function.
+4. Receive an output structure containing the results.
+
+The following example demonstrates this workflow with :func:`olsmt`.
+
+Example: OLS with control and output structures
++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Load data
+ fname = getGAUSSHome("examples/credit.dat");
+
+ // Step 1: Create a control structure with defaults
+ struct olsmtControl ctl;
+ ctl = olsmtControlCreate();
+
+ // Step 2: Override only the settings you need
+ ctl.cov = "hac"; // HAC (Newey-West) standard errors
+
+ // Step 3: Call olsmt with the control structure
+ struct olsmtOut out;
+ out = olsmt(fname, "Balance ~ Income + Rating + Cards", ctl);
+
+ // Step 4: Examine output members
+ print "Coefficient estimates:";
+ print out.b;
+
+ print "Standard errors:";
+ print out.stderr;
+
+ print "R-squared = " out.rsq;
+ print "Durbin-Watson = " out.dwstat;
+
+.. tip::
+
+ You do not have to set every member of the control structure. The
+ ``Create`` function fills every member with a sensible default. Only
+ override the settings you need.
+
+Common control and output structures
++++++++++++++++++++++++++++++++++++++++
+
+Many GAUSS functions follow the same naming convention:
+
+.. list-table::
+ :widths: 25 25 25 25
+ :header-rows: 1
+
+ * - Function
+ - Control Structure
+ - Create Function
+ - Output Structure
+
+ * - :func:`olsmt`
+ - :class:`olsmtControl`
+ - :func:`olsmtControlCreate`
+ - :class:`olsmtOut`
+
+ * - :func:`glm`
+ - :class:`glmControl`
+ - :func:`glmControlCreate`
+ - :class:`glmOut`
+
+ * - :func:`quantileFit`
+ - :class:`qfitControl`
+ - :func:`qfitControlCreate`
+ - :class:`qfitOut`
+
+ * - :func:`gmmFit`
+ - :class:`gmmControl`
+ - :func:`gmmControlCreate`
+ - :class:`gmmOut`
+
+ * - :func:`plotXY`
+ - :class:`plotControl`
+ - :func:`plotGetDefaults`
+ - (none)
+
+
+Defining Structures
+-----------------------------------------
+
+A structure definition lists the name and type of each member. The
+syntax is:
+
+::
+
+ struct my_struct {
+ scalar count;
+ matrix data;
+ string label;
+ string array names;
+ };
+
+Member types
+++++++++++++++++++++++++++++++
+
+A structure can contain members of the following types:
+
+.. list-table::
+ :widths: 20 40 40
+ :header-rows: 1
+
+ * - Type
+ - Description
+ - Default Value
+
+ * - ``scalar``
+ - A single numeric value. This type is unique to structures.
+ - ``0``
+
+ * - ``matrix``
+ - A matrix of any size.
+ - ``{}`` (empty matrix)
+
+ * - ``array``
+ - An N-dimensional array.
+ - 1-element, 1-dimensional array containing ``0``
+
+ * - ``string``
+ - A single string.
+ - ``""`` (empty string)
+
+ * - ``string array``
+ - An array of strings.
+ - ``""`` (1x1 string array set to empty)
+
+ * - ``struct``
+ - A nested structure of another type.
+ - (members initialized to their defaults)
+
+Nested structures
+++++++++++++++++++++++++++++++
+
+Structures can contain other structures as members:
+
+::
+
+ struct point {
+ scalar x;
+ scalar y;
+ };
+
+ struct rectangle {
+ struct point upper_left;
+ struct point lower_right;
+ };
+
+
+Creating and Initializing
+-----------------------------------------
+
+Declaring an instance
+++++++++++++++++++++++++++++++
+
+To use a structure, declare an instance with the ``struct`` keyword:
+
+::
+
+ struct olsmtControl ctl;
+
+If the structure type is defined in the GAUSS Run-Time Library (such as
+:class:`olsmtControl`, :class:`plotControl`, or :class:`glmControl`), no ``#include``
+is needed. For custom structure types defined in a separate file, use
+``#include``:
+
+::
+
+ #include mystruct.sdf
+
+ struct my_struct s;
+
+Initializing members
+++++++++++++++++++++++++++++++
+
+Members are accessed using dot notation:
+
+::
+
+ struct olsmtControl ctl;
+ ctl = olsmtControlCreate();
+
+ // Set individual members
+ ctl.output = 1;
+ ctl.cov = "hac";
+ ctl.con = 0;
+
+When a structure is first declared, all members are set to their type
+defaults (scalars to ``0``, matrices to ``{}``, strings to ``""``).
+However, for built-in structures you should always call the
+corresponding ``Create`` function, which sets members to the correct
+application defaults:
+
+::
+
+ // Correct: use the Create function
+ struct olsmtControl ctl;
+ ctl = olsmtControlCreate();
+
+ // Also correct for plotControl
+ struct plotControl plt;
+ plt = plotGetDefaults("xy");
+
+
+Accessing Members
+-----------------------------------------
+
+Use dot notation to read or write any member of a structure:
+
+::
+
+ // Write
+ ctl.output = 1;
+ ctl.cov = "robust";
+
+ // Read
+ print ctl.output;
+ print ctl.cov;
+
+For nested structures, chain the dots:
+
+::
+
+ struct rectangle r;
+ r.upper_left.x = 0;
+ r.upper_left.y = 10;
+ r.lower_right.x = 5;
+ r.lower_right.y = 0;
+
+For arrays of structures, use indexing before the dot:
+
+::
+
+ struct olsmtControl ctl;
+ ctl = reshape(olsmtControlCreate(), 3, 1);
+
+ // Access the second element's 'output' member
+ ctl[2].output = 1;
+
+
+Structures in Procedures
+-----------------------------------------
+
+Structures can be passed to and returned from procedures, just like
+matrices and strings.
+
+Passing a structure as an argument
+++++++++++++++++++++++++++++++++++++
+
+Declare the structure type in the procedure signature:
+
+::
+
+ proc (1) = computeArea(struct rectangle rect);
+ local width, height;
+ width = rect.lower_right.x - rect.upper_left.x;
+ height = rect.upper_left.y - rect.lower_right.y;
+ retp(width * height);
+ endp;
+
+Structures are passed **by value**. The procedure receives a local copy
+of the structure. Modifications inside the procedure do not affect the
+caller's original structure.
+
+Returning a structure
+++++++++++++++++++++++++++++++
+
+A procedure can return a structure:
+
+::
+
+ proc (1) = centerRectangle(struct rectangle rect);
+ local width, height;
+ struct rectangle centered;
+
+ width = rect.lower_right.x - rect.upper_left.x;
+ height = rect.upper_left.y - rect.lower_right.y;
+
+ centered.upper_left.x = -width / 2;
+ centered.upper_left.y = height / 2;
+ centered.lower_right.x = width / 2;
+ centered.lower_right.y = -height / 2;
+
+ retp(centered);
+ endp;
+
+This is the pattern used by every GAUSS estimation function: the
+function accepts a control structure and returns an output structure.
+
+
+Complete Examples
+-----------------------------------------
+
+Example 1: OLS regression with robust standard errors
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Building on the introductory example above, this version requests
+heteroskedasticity-robust standard errors:
+
+::
+
+ fname = getGAUSSHome("examples/credit.dat");
+
+ struct olsmtControl ctl;
+ ctl = olsmtControlCreate();
+ ctl.output = 1; // Print report
+ ctl.cov = "robust"; // Heteroskedasticity-robust SEs
+
+ struct olsmtOut out;
+ out = olsmt(fname, "Balance ~ Income + Rating", ctl);
+
+ print "Robust standard errors:";
+ print out.stderr;
+
+Example 2: GLM with output structure
++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Load data and remove missing values
+ fname = getGAUSSHome("examples/auto2.dta");
+ df = loadd(fname, "mpg + weight + rep78");
+ df = packr(df);
+
+ // Create GLM control structure
+ struct glmControl gc;
+ gc = glmControlCreate();
+
+ // Run GLM
+ struct glmOut out;
+ out = glm(df, "mpg ~ weight + factor(rep78)", "normal", gc);
+
+ // Examine output -- glmOut uses nested structures
+ print "Coefficients:";
+ print out.coef.estimates;
+
+ print "Standard errors:";
+ print out.coef.se;
+
+Example 3: Plotting with plotControl
++++++++++++++++++++++++++++++++++++++++
+
+The :func:`plotControl` structure controls all visual aspects of GAUSS
+plots. This is another example of the control structure pattern:
+
+::
+
+ // Load data
+ df = loadd(getGAUSSHome("examples/auto2.dta"));
+
+ // Create a plotControl structure with XY defaults
+ struct plotControl plt;
+ plt = plotGetDefaults("scatter");
+
+ // Customize the plot
+ plotSetTitle(&plt, "Fuel Economy vs. Weight");
+ plotSetXLabel(&plt, "Weight (lbs)");
+ plotSetYLabel(&plt, "Miles per Gallon");
+
+ // Draw the scatter plot
+ plotScatter(plt, df, "mpg ~ weight");
+
+.. note::
+
+ Plot control functions like :func:`plotSetTitle` take a *pointer* to
+ the structure (``&plt``) rather than the structure itself. This allows
+ them to modify the structure in place. See the
+ `Structure Pointers`_ section below.
+
+
+Defining Your Own Structures
+-----------------------------------------
+
+While most users will work with the built-in control and output
+structures, you can define your own for custom procedures. The typical
+pattern is:
+
+1. Define the structure in a ``.sdf`` file.
+2. Write a ``Create`` function that returns an initialized instance.
+3. Write procedures that accept and return the structure.
+
+::
+
+ // --- mymodel.sdf ---
+ struct myModelControl {
+ scalar maxIters;
+ scalar tol;
+ scalar verbose;
+ };
+
+ struct myModelOut {
+ matrix coefficients;
+ matrix standardErrors;
+ scalar converged;
+ };
+
+::
+
+ // --- mymodel.src ---
+ #include mymodel.sdf
+
+ proc (1) = myModelControlCreate();
+ struct myModelControl ctl;
+ ctl.maxIters = 100;
+ ctl.tol = 1e-8;
+ ctl.verbose = 1;
+ retp(ctl);
+ endp;
+
+ proc (1) = myModelEstimate(x, y, struct myModelControl ctl);
+ local b, se, iter;
+ struct myModelOut out;
+
+ // ... estimation logic ...
+
+ out.coefficients = b;
+ out.standardErrors = se;
+ out.converged = (iter < ctl.maxIters);
+ retp(out);
+ endp;
+
+
+Arrays of Structures
+-----------------------------------------
+
+You can create arrays (vectors) of structures using vertical
+concatenation or :func:`reshape`:
+
+::
+
+ struct olsmtControl ctl1, ctl2, ctl_array;
+ ctl1 = olsmtControlCreate();
+ ctl2 = olsmtControlCreate();
+
+ // Vertical concatenation with |
+ ctl_array = ctl1 | ctl2;
+
+ // Set different options for each
+ ctl_array[1].con = 0;
+ ctl_array[2].con = 1;
+
+Use :func:`reshape` to create larger arrays. The following example uses
+the ``DS`` structure described in :ref:`ds-and-pv-structures` below:
+
+::
+
+ // Create a 5x1 vector of DS structures
+ struct DS d;
+ d = reshape(dsCreate(), 5, 1);
+
+ // Access members of individual elements
+ d[1].dataMatrix = rndn(100, 3);
+ d[2].dataMatrix = rndn(200, 5);
+
+
+Structure Pointers
+-----------------------------------------
+
+A structure pointer holds the address of a structure rather than a copy
+of it. Pointers are useful when you want a procedure to modify a
+structure in place, avoiding the overhead of copying large structures.
+
+Creating a pointer
+++++++++++++++++++++++++++++++
+
+::
+
+ struct olsmtControl ctl;
+ ctl = olsmtControlCreate();
+
+ // Create a pointer to 'ctl'
+ struct olsmtControl *p;
+ p = &ctl;
+
+Accessing members through a pointer
++++++++++++++++++++++++++++++++++++++
+
+Use the arrow syntax (``->``) instead of dot notation:
+
+::
+
+ // These two lines have the same effect
+ ctl.output = 1;
+ p->output = 1;
+
+Modifying the structure through the pointer modifies the original
+structure, not a copy.
+
+Using pointers in procedures
+++++++++++++++++++++++++++++++
+
+When a procedure takes a structure pointer, it can modify the caller's
+structure directly without returning it:
+
+::
+
+ proc (0) = setDefaults(struct myModelControl *p);
+ p->maxIters = 100;
+ p->tol = 1e-8;
+ p->verbose = 1;
+ endp;
+
+ struct myModelControl ctl;
+ struct myModelControl *cp;
+ cp = &ctl;
+ setDefaults(cp);
+
+ // 'ctl' has now been modified
+ print ctl.maxIters;
+
+This is exactly how the ``plotSet*`` functions work: they take a pointer
+to a :class:`plotControl` structure and modify it in place.
+
+.. note::
+
+ Structure pointers cannot be members of a structure. They are
+ primarily used as procedure arguments to allow in-place modification.
+
+
+Saving and Loading Structures
+-----------------------------------------
+
+Structures can be saved to disk and loaded back later using
+:func:`saveStruct` and :func:`loadStruct`. The file is saved with an
+``.fsr`` extension.
+
+::
+
+ // Save a structure to disk
+ struct olsmtOut out;
+ // ... (populate 'out' from an estimation) ...
+ ret = saveStruct(out, "my_results");
+
+ // Load it back later
+ struct olsmtOut loaded;
+ { loaded, ret } = loadStruct("my_results", "olsmtOut");
+
+
+.. _ds-and-pv-structures:
+
+DS and PV Structures
+-----------------------------------------
+
+The ``DS`` (data set) and ``PV`` (parameter vector) structures are
+specialized structures used primarily by the lower-level optimization
+functions such as :func:`sqpSolveMT`.
+
+DS structure
+++++++++++++++++++++++++++++++
+
+The ``DS`` structure is a container for passing data to optimization
+functions. The most commonly used members are shown below:
+
+::
+
+ struct DS {
+ scalar type;
+ matrix dataMatrix;
+ array dataArray;
+ string dname;
+ string array vnames;
+ };
+
+.. note::
+
+ The full ``DS`` structure contains additional members
+ (``endoMatrix``, ``exoMatrix``, etc.) used by specific optimization
+ functions. See the :func:`dsCreate` reference page for the complete
+ definition.
+
+Create an instance with :func:`dsCreate`:
+
+::
+
+ struct DS d0;
+ d0 = dsCreate();
+ d0.dataMatrix = loadd(getGAUSSHome("examples/credit.dat"));
+
+.. note::
+
+ In modern GAUSS (version 16+), you can pass data matrices directly
+ to optimization functions instead of wrapping them in a ``DS``
+ structure. The ``DS`` structure is still supported for backward
+ compatibility.
+
+PV structure
+++++++++++++++++++++++++++++++
+
+The ``PV`` structure manages a parameter vector for optimization. It
+lets you "pack" named parameter matrices into a single vector, and
+"unpack" them back into their original shapes during optimization.
+
+::
+
+ struct PV p0;
+ p0 = pvCreate();
+
+ // Pack parameters with names
+ garch_start = { 0.1, 0.1 };
+ arch_start = { 0.1, 0.1 };
+
+ p0 = pvPack(p0, 1.0, "constant");
+ p0 = pvPack(p0, garch_start, "garch");
+ p0 = pvPack(p0, arch_start, "arch");
+ p0 = pvPack(p0, 0.1, "omega");
+
+ // Later, unpack by name
+ b0 = pvUnpack(p0, "constant");
+ garch = pvUnpack(p0, "garch");
+
+The ``PV`` structure also supports masked matrices (where only some
+elements are free parameters) and symmetric matrices. See the reference
+pages for :func:`pvPack`, :func:`pvPackm`, :func:`pvPacks`,
+:func:`pvUnpack`, and :func:`pvCreate` for details.
+
+
+Rules and Tips
+-----------------------------------------
+
+- **Always use the Create function.** For built-in structures, call
+ the corresponding ``Create`` function (e.g.,
+ :func:`olsmtControlCreate`, :func:`glmControlCreate`) to get correct
+ defaults. Do not rely on the zero-initialization of a bare
+ declaration.
+
+- **Structures are passed by value.** When you pass a structure to a
+ procedure, the procedure gets a local copy. Modifications inside the
+ procedure do not affect the original. Use structure pointers if you
+ need in-place modification.
+
+- **Structures inside procedures.** Inside a procedure, declare a
+ structure with ``struct MyType varname;`` — it is automatically
+ local. The ``local`` keyword is not used with structure variables.
+
+- **Structure definitions go in** ``.sdf`` **files.** By convention,
+ structure definitions are saved in files with a ``.sdf`` extension
+ and included with ``#include``. If the structure is part of a loaded
+ library, no ``#include`` is needed.
+
+- **Member names are case sensitive.** ``ctl.output`` and
+ ``ctl.Output`` refer to different members.
+
+- **The** ``scalar`` **type is unique to structures.** Outside of a
+ structure definition, there is no ``scalar`` type in GAUSS. Inside a
+ structure, ``scalar`` restricts a member to a single numeric value,
+ which is more efficient than a 1x1 matrix.
+
+.. tip::
+
+ **How to discover structure members:** To see what members an output
+ structure contains, check the function's command reference page (e.g.,
+ the :func:`olsmt` page lists every member of :class:`olsmtOut`). You can
+ also explore interactively by printing individual members:
+ ``print out.b;`` for coefficients, ``print out.stderr;`` for standard
+ errors, ``print out.rsq;`` for R-squared.
+
+
+What's Next
+-----------------------------------------
+
+- Run :func:`olsmt` with a control structure and explore the members
+ of the output structure.
+- Try :func:`glm` for generalized linear models, which follows the same
+ control-in, output-out pattern.
+- Use :class:`plotControl` structures to customize your plots with functions
+ like :func:`plotSetTitle`, :func:`plotSetXLabel`, and
+ :func:`plotSetLineColor`.
+
+.. seealso:: Functions :func:`olsmt`, :func:`olsmtControlCreate`, :func:`glm`, :func:`glmControlCreate`, :func:`quantileFit`, :func:`pvPack`, :func:`pvUnpack`, :func:`pvCreate`, :func:`dsCreate`, :func:`saveStruct`, :func:`loadStruct`, :func:`plotGetDefaults`
diff --git a/docs/user-guide/advanced/time-and-date-OUTLINE.md b/docs/user-guide/advanced/time-and-date-OUTLINE.md
new file mode 100644
index 00000000..3dd07db4
--- /dev/null
+++ b/docs/user-guide/advanced/time-and-date-OUTLINE.md
@@ -0,0 +1,151 @@
+# Time and Date — Chapter Outline
+
+## Design Principles
+
+1. **Dataframe-first.** Lead with `loadd` auto-detection and date columns.
+ The reader's first experience should be: load a CSV, dates just work.
+2. **Workflow-driven** (pandas approach). Follow the natural sequence:
+ load → inspect → extract components → filter → compute → plot → aggregate.
+3. **Conceptual anchor** (Stata approach). Early section: "dates are POSIX
+ numbers under the hood." This explains why arithmetic works and why
+ `selif(data, data[., "Date"] .< "2018")` is valid.
+4. **Legacy clearly labeled** (MATLAB approach). DT scalars, DTV vectors,
+ 4x1 date vectors go in a final reference section, not mixed in.
+5. **Econometric connection.** Show dates in the context of time series
+ analysis — the actual reason our users need dates.
+
+## Target Audience
+
+Econometricians and financial analysts who:
+- Have CSV/Excel data with date columns
+- Need to load, filter, transform, and plot time series
+- May be coming from Stata (`%td`, `tsset`), R/pandas (`as.Date`, `DatetimeIndex`), or MATLAB (`datetime`)
+
+---
+
+## Outline
+
+### 1. Introduction (short)
+- What this page covers
+- R/Python/Stata equivalence note (like other pages)
+- Key idea: GAUSS stores dates as POSIX seconds internally; display
+ format controls how they appear
+
+### 2. Loading Data with Dates
+- `loadd("file.csv")` — auto-detection (the happy path, ~30 formats)
+- Verifying date detection: `print head(data)`, `getColTypes`
+- When auto-detection fails: the `date()` formula keyword
+ - `loadd("file.csv", "date(mydate) + x1 + x2")`
+ - Specifying format explicitly: `date($mydate, '%d/%m/%Y')`
+- Loading from Excel (same `loadd` behavior)
+- Example: load a real-world dataset, show dates display correctly
+
+### 3. How Dates Work Internally
+- All date columns store POSIX seconds (seconds since Jan 1, 1970 UTC)
+- Display format is separate from storage (the Stata insight)
+- `asDate` — mark a numeric column as date, or change display format
+- `setColDateFormats` — set display format for existing date columns
+- `getColDateFormats` — query current display format
+- Default display: `%Y-%m-%d`; quarterly: `%Y-Q%q`; monthly: `%Y-%m`
+- Table of common format specifiers (compact — just the top 10-15 most
+ used, not the full BSD strftime dump)
+
+### 4. Creating Dates
+- From strings: `asDate("2024-03-15")`, `strctoposix("2024-03-15", "%Y-%m-%d")`
+- Date sequences: `seqaPosix("2020-01-01", 1, "months", 24)` — monthly
+ sequence starting Jan 2020, 24 periods
+- Building a date column for a dataframe: create sequence, combine with data
+- From components: (brief mention of `dtdate`, `dtday` for legacy code)
+
+### 5. Extracting Date Components
+- The `dt*` family — present as a single scannable table:
+ `dtYear`, `dtMonth`, `dtQuarter`, `dtDayofMonth`, `dtDayofWeek`,
+ `dtDayofYear`, `dtWeek`, `dtHour`, `dtMinute`, `dtSecond`,
+ `dtMonthName`, `dtDayName`
+- Example: add a "Quarter" column to a dataframe
+ `data = dfaddcol(data, "Quarter", dtQuarter(data, "Date"))`
+- Example: filter to weekdays only
+ `data = selif(data, dtDayofWeek(data, "Date") .> 0 .and dtDayofWeek(data, "Date") .< 6)`
+
+### 6. Filtering and Subsetting by Date
+- String comparison on date columns:
+ `selif(data, data[., "Date"] .>= "2020-01-01" .and data[., "Date"] .< "2021-01-01")`
+- The `between` function (date-aware):
+ `mask = between(data[., "Date"], "2020-01-01", "2020-12-31")`
+- Partial date strings work: `.< "2020"` means before Jan 1, 2020
+
+### 7. Date Arithmetic
+- Adding time: `timeDeltaPosix(date, 3, "months")` — add 3 months
+- Subtracting time: `timeDeltaPosix(date, -7, "days")` — go back a week
+- Differences: `timeDiffPosix(date1, date2, "days")` — days between dates
+- Supported units table: years, months, days, hours, seconds
+ (note: "months" for delta but not for diff)
+- Example: compute holding period in days between buy and sell dates
+
+### 8. Plotting Time Series
+- The simple case: `plotXY(data, "Date ~ Price")` — auto-detects dates,
+ auto-routes to time series plot
+- `plotTS` for evenly-spaced data (frequency-based: 1=yearly, 4=quarterly,
+ 12=monthly)
+- `plotTSHF` for irregularly-spaced or high-frequency data
+- Customizing date axes: `plotSetXTicLabel`, `plotSetXTicInterval`
+- Example: load stock prices, plot with custom date formatting
+
+### 9. Frequency Conversion
+- `tsAggregate` — downsample time series data
+ - Frequencies: "D", "M", "Q", "Y" (and "H", "N", "S" for intraday)
+ - Methods: "last", "mean", "sum", "lastBD", etc.
+- Example: convert daily stock data to monthly (last trading day)
+- Example: convert monthly GDP to quarterly (sum or mean)
+
+### 10. Converting Between Formats
+- String ↔ POSIX: `strctoposix` / `posixtostrc`
+- String ↔ DT: `strctodt` / `dttostrc`
+- DT → POSIX: `dttoposix`
+- When you need each (brief guidance, not exhaustive)
+
+### 11. Format Specifier Reference
+- Compact table of BSD strftime specifiers (the important ones)
+- Note the GAUSS extension: `%q` for quarter
+- GAUSS legacy format codes (YYYY, MO, DD, etc.) — used by `plotSetXTicLabel`
+
+### 12. Legacy Date Representations
+- Brief section clearly marked as legacy
+- DT scalars: what they are, when you'll encounter them
+- DTV vectors: what they are
+- 4x1 date/time vectors: what they are
+- Migration guidance: use `dttoposix` to convert DT → POSIX
+- Trading day functions: `elapsedTradingDays`, `getNextTradingDay`,
+ `getNextWeekDay` (note: DT scalar input, NYSE calendar through 2004)
+
+### 13. Quick Reference
+- Task → Function table (same format as other pages)
+- Load with dates, create sequence, extract year/month/quarter,
+ filter by date range, add months, compute difference, plot,
+ change display format, aggregate to monthly
+
+---
+
+## What We're Deliberately NOT Covering
+
+- **Time zones** — GAUSS has no built-in TZ conversion. Don't document
+ what doesn't exist; would be misleading.
+- **Business calendars beyond NYSE** — the existing functions are
+ limited and somewhat outdated. Mention them in legacy section,
+ don't promote as a feature.
+- **Full BSD strftime table** — the legacy docs dump all 30+ specifiers.
+ We'll include the top 15 and link to a reference for the rest.
+- **DTV vector internals** — almost nobody uses these. Brief mention only.
+- **Timed iterations with `hsec`** — this is a benchmarking pattern,
+ not really a "dates" topic. Could go in a future performance page.
+
+## Open Questions
+
+1. Should `tsAggregate` go here or in data-management? It's deeply
+ date-related but also a data transformation. (Leaning: here, since
+ frequency conversion is core to time series dates.)
+2. Should we include a "Coming from Stata/R" migration sidebar that
+ maps their date concepts to GAUSS? (Leaning: yes, brief note box.)
+3. The `plotXY` auto-routing to `plotTSHF` is a great feature — should
+ we lead the plotting section with it? (Leaning: yes, it's the
+ simplest path.)
diff --git a/docs/user-guide/advanced/time-and-date.rst b/docs/user-guide/advanced/time-and-date.rst
new file mode 100644
index 00000000..d9dfd1a8
--- /dev/null
+++ b/docs/user-guide/advanced/time-and-date.rst
@@ -0,0 +1,960 @@
+.. _time-and-date:
+
+Time and Date
+===============================================
+
+GAUSS provides a modern date system built around dataframes. Date
+columns are auto-detected when loading data, display in human-readable
+formats, and support filtering, arithmetic, and plotting.
+
+.. note::
+
+ If you are coming from **Stata**: ``loadd`` is like ``import
+ delimited`` plus ``generate date = daily(...)`` plus ``format %td``
+ in one step. GAUSS does **not** require a ``tsset`` declaration —
+ functions like :func:`lagn` and :func:`plotXY` operate on columns
+ directly. If you are coming from **R/pandas**: :func:`loadd`
+ combines ``read.csv`` + ``as.Date``; :func:`asDate` is similar to
+ ``as.Date()`` or ``pd.to_datetime()``.
+
+.. list-table::
+ :widths: 30 35 35
+ :header-rows: 1
+
+ * - Task
+ - Stata
+ - GAUSS
+
+ * - Load with dates
+ - ``import delimited`` + ``gen date = daily(...)``
+ - ``loadd("file.csv")`` (auto-detects)
+
+ * - Set date format
+ - ``format date %tq``
+ - ``asDate(data, "%Y-Q%q", "Date")``
+
+ * - Extract year
+ - ``gen yr = year(date)``
+ - ``dtYear(data, "Date")``
+
+ * - Lag
+ - ``tsset date`` then ``L.x``
+ - ``lagn(data[., "x"], 1)``
+
+ * - Plot time series
+ - ``tsline gdp``
+ - ``plotXY(data, "GDP ~ Date")``
+
+ * - Aggregate frequency
+ - ``collapse (mean) x, by(qdate)``
+ - ``tsAggregate(data, "Q", "mean")``
+
+
+Under the hood, GAUSS stores all dates as **POSIX seconds** — the
+number of seconds since January 1, 1970 UTC. This is similar to
+Stata's internal date numbers (days since January 1, 1960), but using
+seconds from 1970 as the epoch. The **display format** is separate
+from the stored value — changing a display format from ``%Y-%m-%d`` to
+``%Y-Q%q`` does not alter the underlying number, only how it prints.
+
+
+Loading Data with Dates
+--------------------------------------------
+
+The most common way to get dates into GAUSS is through :func:`loadd`,
+which auto-detects approximately 30 date formats in CSV and Excel
+files:
+
+::
+
+ data = loadd("stock_prices.csv");
+ print head(data);
+
+::
+
+ Date Close
+ 2024-01-02 472.65
+ 2024-01-03 468.38
+ 2024-01-04 467.77
+ 2024-01-05 473.48
+ 2024-01-08 479.18
+
+To verify that a column was recognized as a date, check its type:
+
+::
+
+ print getColTypes(data);
+
+::
+
+ type
+ date
+ number
+
+When auto-detection fails
+++++++++++++++++++++++++++++++++++++
+
+If a date column loads as a string instead of a date (check with
+:func:`getColTypes` — a failed detection shows ``string`` rather
+than ``date``), use the ``date()`` keyword in a formula string to
+force conversion:
+
+::
+
+ // Tell GAUSS that "mydate" is a date column
+ data = loadd("file.csv", "date(mydate) + x1 + x2");
+
+ // Specify the format explicitly when auto-detection cannot guess it
+ data = loadd("file.csv", "date(mydate, '%d/%m/%Y') + x1 + x2");
+
+.. tip::
+
+ If your data has the common quarterly format ``2020Q1``,
+ ``2020-Q3``, etc., use the ``%q`` specifier (a GAUSS extension):
+
+ ::
+
+ data = loadd("macro.csv", "date(quarter, '%YQ%q') + gdp + cpi");
+
+ This converts ``2020Q1`` to January 1, 2020, ``2020Q3`` to July 1,
+ 2020, and so on.
+
+
+Handling missing or unparseable dates
++++++++++++++++++++++++++++++++++++++++
+
+When a date column contains blank cells or values that cannot be
+parsed, GAUSS inserts a missing value (``.``). Use :func:`packr` to
+drop rows with missing dates, or compare against :func:`miss` to
+find them (:func:`ismiss` returns a scalar, not a row-by-row mask):
+
+::
+
+ // Find rows with missing dates (element-wise)
+ mask = data[., "Date"] .== miss();
+
+ // Get row indices of missing dates
+ idx = findIdx(mask);
+
+ // Drop rows where date is missing
+ data = packr(data);
+
+
+Displaying and Formatting Dates
+--------------------------------------------
+
+The default display format is ``%Y-%m-%d`` (e.g., ``2024-03-15``).
+Use :func:`asDate` to change how dates are displayed and return
+the updated dataframe, or :func:`setColDateFormats` to set the
+format metadata directly. Neither alters the stored POSIX values:
+
+::
+
+ // Display as month/day/year
+ data = asDate(data, "%m/%d/%Y", "Date");
+
+ // Display as quarterly
+ data = asDate(data, "%Y-Q%q", "Date");
+
+ // Display with time
+ data = asDate(data, "%Y-%m-%d %H:%M", "Date");
+
+To check the current display format:
+
+::
+
+ print getColDateFormats(data, "Date");
+
+.. _date-format-specifiers:
+
+Common format specifiers
+++++++++++++++++++++++++++++++++++++
+
+If your dates look like this, use this format string:
+
+.. list-table::
+ :widths: 35 25 40
+ :header-rows: 1
+
+ * - Example
+ - Format string
+ - Used by
+
+ * - ``2024-03-15``
+ - ``%Y-%m-%d``
+ - :func:`asDate`, :func:`strctoposix`
+
+ * - ``03/15/2024``
+ - ``%m/%d/%Y``
+ - :func:`asDate`, :func:`strctoposix`
+
+ * - ``15-Mar-2024``
+ - ``%d-%b-%Y``
+ - :func:`asDate`, :func:`strctoposix`
+
+ * - ``2024-Q1``
+ - ``%Y-Q%q``
+ - :func:`asDate`, :func:`strctoposix`
+
+ * - ``2024Q3``
+ - ``%YQ%q``
+ - :func:`asDate`, :func:`strctoposix`
+
+ * - ``March 15, 2024``
+ - ``%B %d, %Y``
+ - :func:`asDate`, :func:`strctoposix`
+
+ * - ``2024-03-15 14:30``
+ - ``%Y-%m-%d %H:%M``
+ - :func:`asDate`, :func:`strctoposix`
+
+ * - ``2024``
+ - ``%Y``
+ - :func:`asDate`, :func:`strctoposix`
+
+ * - ``2024-03``
+ - ``%Y-%m``
+ - :func:`asDate`, :func:`strctoposix`
+
+The ``%q`` specifier for quarters is a GAUSS extension — it is not
+part of standard BSD strftime. See :ref:`format-reference` for the
+full list.
+
+.. warning::
+
+ GAUSS has **two separate format systems**. Modern functions
+ (:func:`strctoposix`, :func:`posixtostrc`, :func:`asDate`,
+ :func:`setColDateFormats`) use **BSD strftime** specifiers like
+ ``%Y-%m-%d``. Legacy functions (:func:`strtodt`, :func:`dttostr`)
+ and plot axis labels (:func:`plotSetXTicLabel`) use **GAUSS format
+ codes** like ``YYYY-MO-DD``. These are **not interchangeable**.
+
+
+Extracting Date Components
+--------------------------------------------
+
+The ``dt*`` family of functions extracts components from date columns:
+
+.. list-table::
+ :widths: 30 35 35
+ :header-rows: 1
+
+ * - Function
+ - Returns
+ - Example output
+
+ * - :func:`dtYear`
+ - Year
+ - ``2024``
+
+ * - :func:`dtMonth`
+ - Month (1–12)
+ - ``3``
+
+ * - :func:`dtQuarter`
+ - Quarter (1–4)
+ - ``1``
+
+ * - :func:`dtDayofMonth`
+ - Day of month (1–31)
+ - ``15``
+
+ * - :func:`dtDayofWeek`
+ - Day of week. Default: 0=Sun … 6=Sat. With ``start_Monday=1``: 1=Mon … 7=Sun
+ - ``5`` (Friday, default)
+
+ * - :func:`dtDayofYear`
+ - Day of year (1–366)
+ - ``75``
+
+ * - :func:`dtWeek`
+ - Week of year (0–53; 0 = before first Monday)
+ - ``11``
+
+ * - :func:`dtHour`
+ - Hour. Default: 1–12. With ``twenty_four=1``: 0–23
+ - ``2`` (default) or ``14`` (24-hr)
+
+ * - :func:`dtMinute`
+ - Minute (0–59)
+ - ``30``
+
+ * - :func:`dtSecond`
+ - Second (0–59)
+ - ``0``
+
+ * - :func:`dtMonthName`
+ - Month name
+ - ``"March"``
+
+ * - :func:`dtDayName`
+ - Day name
+ - ``"Friday"``
+
+All ``dt*`` functions take a dataframe and an optional column name:
+
+::
+
+ // Add a quarter column
+ data = dfaddcol(data, "Quarter", dtQuarter(data, "Date"));
+
+ // Filter to weekdays only
+ // Monday-start mode: Mon=1, Tue=2, ..., Fri=5, Sat=6, Sun=7
+ dow = dtDayofWeek(data, "Date", 1);
+ data = selif(data, dow .>= 1 .and dow .<= 5);
+
+
+Filtering by Date
+--------------------------------------------
+
+The simplest way to filter by date range is :func:`between`:
+
+::
+
+ // Keep only 2020 data
+ mask = between(data[., "Date"], "2020-01-01", "2020-12-31");
+ data_2020 = selif(data, mask);
+
+.. note::
+
+ :func:`between` is **inclusive** on both endpoints by default. A
+ partial string like ``"2021"`` is interpreted as January 1, 2021 at
+ midnight, so ``between(dates, "2020", "2021")`` includes
+ January 1, 2021. Use the optional fourth argument to control this:
+
+ ::
+
+ // Exclude the right endpoint
+ mask = between(data[., "Date"], "2020", "2021", "left");
+
+ Options: ``"both"`` (default), ``"left"``, ``"right"``,
+ ``"neither"``.
+
+For more complex conditions, use relational operators on date
+columns — GAUSS automatically compares the string against the stored
+POSIX value:
+
+::
+
+ // Keep data from 2018 through 2022
+ data = selif(data, data[., "Date"] .>= "2018-01-01"
+ .and data[., "Date"] .< "2023-01-01");
+
+Partial date strings work: ``"2020"`` means January 1, 2020 at
+midnight, so ``.< "2021"`` selects all of 2020.
+
+
+Creating Dates
+--------------------------------------------
+
+From strings
+++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Single date (auto-detects format, returns a date-typed dataframe)
+ dt = asDate("2024-03-15");
+
+ // With explicit format (when auto-detection cannot guess)
+ dt = strctoposix("15-Mar-2024", "%d-%b-%Y");
+
+Date sequences
+++++++++++++++++++++++++++++++++++++
+
+Use :func:`seqaPosix` to generate evenly-spaced date sequences:
+
+::
+
+ // Monthly: 24 months starting January 2020
+ monthly = seqaPosix("2020-01-01", 1, "months", 24);
+
+ // Quarterly: use 3-month increments
+ quarterly = seqaPosix("2020-01-01", 3, "months", 20);
+
+ // Daily: 365 days
+ daily = seqaPosix("2024-01-01", 1, "days", 365);
+
+Supported units: ``"years"``, ``"months"``, ``"days"``, ``"hours"``,
+``"minutes"``, ``"seconds"``.
+
+To build a new dataframe from scratch, use ``~`` to combine columns
+horizontally. Use :func:`dfaddcol` to append a computed column to an
+existing dataframe (as in the growth rate example later):
+
+::
+
+ dates = asDate(seqaPosix("2020-01-01", 1, "months", 24), "%Y-%m");
+ values = rndn(24, 1);
+ data = dates ~ dfname(values, "GDP");
+
+
+Date Arithmetic
+--------------------------------------------
+
+Adding and subtracting time
+++++++++++++++++++++++++++++++++++++
+
+:func:`timeDeltaPosix` adds (or subtracts) a duration to a date:
+
+::
+
+ dt = strctoposix("2024-01-15", "%Y-%m-%d");
+
+ // Add 3 months
+ dt_plus3m = timeDeltaPosix(dt, 3, "months");
+
+ // Subtract 7 days
+ dt_minus7d = timeDeltaPosix(dt, -7, "days");
+
+Supported units: ``"years"``, ``"months"``, ``"days"``, ``"hours"``,
+``"minutes"``, ``"seconds"``.
+
+.. warning::
+
+ ``"months"`` adds calendar months, but does **not** clip to
+ month-end. January 31 + 1 month = **March 2**, not February 28
+ or 29. If you need month-end dates, generate a sequence of 1st-of-
+ month dates and subtract one day, or use :func:`tsAggregate` with
+ ``"lastBD"`` on daily data.
+
+Computing differences
+++++++++++++++++++++++++++++++++++++
+
+:func:`timeDiffPosix` computes the difference between two dates:
+
+::
+
+ d1 = strctoposix("2024-06-15", "%Y-%m-%d");
+ d2 = strctoposix("2024-01-01", "%Y-%m-%d");
+
+ print timeDiffPosix(d1, d2, "days"); // 166
+
+Supported units for :func:`timeDiffPosix`: ``"days"``, ``"hours"``,
+``"minutes"``, ``"seconds"``. The result is ``d1 - d2`` in the
+requested unit. Note that ``"months"`` and ``"years"`` are **not**
+available as difference units — compute them manually from the day
+count or use :func:`dtYear` / :func:`dtMonth` to compare
+components.
+
+
+Lags, Differences, and Growth Rates
+--------------------------------------------
+
+For time series work, dates matter most when computing lags and
+growth rates. GAUSS provides :func:`lagn` for shifting data by
+position:
+
+::
+
+ // Lag GDP by one period (missing value fills the first row)
+ gdp_lag = lagn(data[., "GDP"], 1);
+
+ // Lead GDP by one period (missing fills the last row)
+ gdp_lead = lagn(data[., "GDP"], -1);
+
+Computing percentage change:
+
+::
+
+ gdp = data[., "GDP"];
+ growth = (gdp - lagn(gdp, 1)) ./ lagn(gdp, 1);
+
+Computing log returns from a price series:
+
+::
+
+ price = data[., "Close"];
+ log_returns = ln(price) - ln(lagn(price, 1));
+
+.. note::
+
+ :func:`lagn` shifts by **position**, not by calendar time. If
+ your data is not already sorted, sort it first:
+
+ ::
+
+ data = sortc(data, "Date");
+
+ This is the step that Stata's ``tsset`` handles automatically.
+ The first row after a lag (or last row after a lead) will contain
+ a missing value (``.``). Estimation functions in TSMT, CML, and
+ built-ins like :func:`olsmt` handle missing values by listwise
+ deletion. Low-level matrix operations do not — use :func:`packr`
+ to drop incomplete rows when needed.
+
+Using ``lag()`` in formula strings
+++++++++++++++++++++++++++++++++++++
+
+The ``lag()`` keyword in formula strings lets you specify lags
+directly in model estimation — no need to create lagged columns
+manually:
+
+::
+
+ // Regress inflation on lagged GDP growth
+ call olsmt(data, "inflation ~ lag(gdp_growth)");
+
+ // Two lags
+ call olsmt(data, "inflation ~ lag(gdp_growth, 1) + lag(gdp_growth, 2)");
+
+This is similar to Stata's ``L.x`` and ``L2.x`` operators, but does
+not require a ``tsset`` declaration first.
+
+.. warning::
+
+ If your data has a **panel structure** (multiple entities observed
+ over time), :func:`lagn` will lag across entity boundaries
+ unless you group the data first — this is a silent error that
+ produces wrong results. For panel-aware lags, see the
+ :doc:`/data-management/index` section on panel data operations.
+ :func:`lagTrim` is a performance variant of :func:`lagn` that
+ removes leading missing rows, but it is **not** panel-aware.
+
+
+Plotting Time Series
+--------------------------------------------
+
+When a dataframe column is typed as a date, :func:`plotXY` and
+:func:`plotScatter` automatically format the X axis with date labels:
+
+::
+
+ // Simplest case — auto-detects date axis
+ plotXY(data, "Close ~ Date");
+
+For more control over date-axis plots:
+
+::
+
+ // plotTSHF — explicit date vector and label unit
+ plotTSHF(data[., "Date"], "months", data[., "Close"]);
+
+ // plotTS — for evenly-spaced data (frequency-based)
+ // dtstart is a DT scalar: use strctodt to create one
+ dtstart = strctodt("20200101", "%Y%m%d");
+ plotTS(dtstart, 4, data[., "Close"]); // 4 = quarterly
+
+:func:`plotTS` frequency codes:
+
+.. list-table::
+ :widths: 30 20 50
+ :header-rows: 1
+
+ * - Frequency
+ - Code
+ - Date axis labels
+
+ * - Yearly
+ - 1
+ - ``YYYY``
+
+ * - Quarterly
+ - 4
+ - ``YYYY-QQ``
+
+ * - Monthly
+ - 12
+ - ``YYYY-MO``
+
+ * - Weekly
+ - 52
+ - ``MO-DD``
+
+ * - Daily
+ - 365
+ - ``MO-DD``
+
+The axis label formats above (``YYYY-QQ``, ``YYYY-MO``, etc.) are
+**GAUSS legacy format codes**, not BSD strftime specifiers — see
+:ref:`format-reference`.
+
+Customizing date axis labels:
+
+::
+
+ struct plotControl myPlot;
+ myPlot = plotGetDefaults("xy");
+
+ // Set date format for X-axis labels (uses GAUSS format codes)
+ plotSetXTicLabel(&myPlot, "YYYY-QQ");
+
+ plotXY(myPlot, data, "Close ~ Date");
+
+
+Frequency Conversion
+--------------------------------------------
+
+:func:`tsAggregate` converts time series data between frequencies:
+
+::
+
+ // Daily to monthly (last observation of each month)
+ monthly = tsAggregate(daily_data, "M", "last");
+
+ // Daily to quarterly (mean)
+ quarterly = tsAggregate(daily_data, "Q", "mean");
+
+ // Monthly to yearly (sum)
+ yearly = tsAggregate(monthly_data, "Y", "sum");
+
+Frequency codes: ``"S"`` (second), ``"N"`` (minute), ``"H"``
+(hourly), ``"D"`` (daily), ``"M"`` (monthly), ``"Q"`` (quarterly),
+``"Y"`` (yearly).
+
+Aggregation methods: ``"last"``, ``"first"``, ``"lastBD"`` (last
+business day), ``"mean"``, ``"sum"``, ``"max"``, ``"min"``,
+``"median"``, ``"sd"``, ``"count"``, ``"mode"``.
+
+::
+
+ // Get end-of-month last business day prices
+ monthly_bd = tsAggregate(daily_data, "M", "lastBD");
+
+.. note::
+
+ ``"lastBD"`` uses weekdays (Monday–Friday) only. It does **not**
+ consult a holiday calendar.
+
+
+Putting It All Together
+--------------------------------------------
+
+Here is a complete workflow: load quarterly macro data, compute GDP
+growth, and run a regression of CPI inflation on lagged GDP growth.
+
+::
+
+ // Load data — dates auto-detected
+ data = loadd("macro_quarterly.csv");
+
+ // Verify date column (should show "date", not "string")
+ print head(data);
+ print getColTypes(data);
+
+ // If the date loaded as "string", reload with explicit format:
+ // data = loadd("macro_quarterly.csv", "date(Date, '%YQ%q') + GDP + CPI");
+
+ // Sort by date before computing lags
+ data = sortc(data, "Date");
+
+ // Compute GDP growth rate
+ gdp = data[., "GDP"];
+ growth = (gdp - lagn(gdp, 1)) ./ lagn(gdp, 1);
+ data = dfaddcol(data, "GDP_Growth", growth);
+
+ // Compute CPI inflation rate
+ cpi = data[., "CPI"];
+ inflation = (cpi - lagn(cpi, 1)) ./ lagn(cpi, 1);
+ data = dfaddcol(data, "Inflation", inflation);
+
+ // Plot GDP growth over time
+ plotXY(data, "GDP_Growth ~ Date");
+
+ // Regress inflation on lagged GDP growth
+ call olsmt(data, "Inflation ~ lag(GDP_Growth)");
+
+
+Trading Day Functions
+--------------------------------------------
+
+GAUSS includes functions for working with NYSE trading days:
+
+.. list-table::
+ :widths: 35 65
+ :header-rows: 1
+
+ * - Function
+ - Description
+
+ * - :func:`getNextTradingDay`
+ - Next NYSE trading day
+
+ * - :func:`getPreviousTradingDay`
+ - Previous NYSE trading day
+
+ * - :func:`getNextWeekDay`
+ - Next weekday (Mon–Fri)
+
+ * - :func:`getPreviousWeekDay`
+ - Previous weekday (Mon–Fri)
+
+ * - :func:`elapsedTradingDays`
+ - Trading days between two dates
+
+ * - :func:`annualTradingDays`
+ - Trading days in a given year
+
+These functions take **DT scalar** input (not POSIX dates). There
+is no direct POSIX-to-DT conversion function; a string intermediate
+is required. To use them with modern date columns:
+
+::
+
+ // Convert a POSIX date to DT scalar for trading day functions
+ posix_date = data[1, "Date"];
+ dt_str = posixtostrc(posix_date, "%Y%m%d%H%M%S");
+ dt_scalar = strctodt(dt_str, "%Y%m%d%H%M%S");
+
+ next_td = getNextTradingDay(dt_scalar);
+ print dttostrc(next_td, "%Y-%m-%d");
+
+.. warning::
+
+ The built-in NYSE holiday calendar covers **1888–2020**. For
+ dates after 2020, these functions treat all holidays as regular
+ trading days (only weekends are excluded). The calendar file
+ ``holidays.asc`` in your GAUSS home directory is user-editable —
+ you can extend it with additional holidays.
+
+ :func:`tsAggregate` with ``"lastBD"`` is a simpler alternative
+ for many use cases and does not depend on the holiday calendar.
+
+
+.. _format-reference:
+
+Format Reference
+--------------------------------------------
+
+BSD strftime specifiers
+++++++++++++++++++++++++++++++++++++
+
+Used by :func:`strctoposix`, :func:`posixtostrc`, :func:`asDate`,
+:func:`setColDateFormats`, and the DT-scalar bridge functions
+:func:`strctodt` and :func:`dttostrc` (which use BSD specifiers
+but produce/consume DT scalar values):
+
+.. list-table::
+ :widths: 15 85
+ :header-rows: 1
+
+ * - Code
+ - Meaning
+
+ * - ``%Y``
+ - Four-digit year (2024)
+
+ * - ``%y``
+ - Two-digit year (24)
+
+ * - ``%m``
+ - Month 01–12
+
+ * - ``%d``
+ - Day of month 01–31
+
+ * - ``%H``
+ - Hour 00–23
+
+ * - ``%I``
+ - Hour 01–12
+
+ * - ``%M``
+ - Minute 00–59
+
+ * - ``%S``
+ - Second 00–59
+
+ * - ``%B``
+ - Full month name (March)
+
+ * - ``%b``
+ - Abbreviated month name (Mar)
+
+ * - ``%A``
+ - Full day name (Friday)
+
+ * - ``%a``
+ - Abbreviated day name (Fri)
+
+ * - ``%p``
+ - AM/PM
+
+ * - ``%q``
+ - Quarter 1–4 (**GAUSS extension**)
+
+ * - ``%j``
+ - Day of year 001–366
+
+ * - ``%F``
+ - Shorthand for ``%Y-%m-%d``
+
+ * - ``%T``
+ - Shorthand for ``%H:%M:%S``
+
+GAUSS legacy format codes
+++++++++++++++++++++++++++++++++++++
+
+Used by :func:`strtodt`, :func:`dttostr`, :func:`plotSetXTicLabel`:
+
+.. list-table::
+ :widths: 15 85
+ :header-rows: 1
+
+ * - Code
+ - Meaning
+
+ * - ``YYYY``
+ - Four-digit year
+
+ * - ``YR``
+ - Two-digit year
+
+ * - ``MO``
+ - Month
+
+ * - ``DD``
+ - Day
+
+ * - ``HH``
+ - Hour
+
+ * - ``MI``
+ - Minute
+
+ * - ``SS``
+ - Second
+
+ * - ``QQ``
+ - Quarter
+
+
+Legacy Date Representations
+--------------------------------------------
+
+Modern GAUSS code should use POSIX dates (dataframe date columns).
+**You can skip this section if you are writing new code from scratch.**
+You will need it if you are reading older GAUSS programs, using the
+trading day functions above, or working with pre-GAUSS 22 code.
+Older code may use these legacy formats:
+
+**DT Scalars** — a double-precision number encoding ``YYYYMMDDHHmmSS``.
+For example, ``20150910110231`` means September 10, 2015, 11:02:31 AM.
+Functions like :func:`dtday`, :func:`dtdate`, and :func:`todaydt`
+create DT scalars. The trading day functions above also use DT scalar
+input.
+
+**DTV Vectors** — an Nx8 matrix where each row contains: year,
+month (1–12), day (1–31), hour (0–23), minute (0–59), second
+(0–59), day-of-week (0–6, 0=Sunday), and day-of-year (0–365).
+Used by :func:`dtvnormal` and :func:`utctodtv`. Convert from DT
+scalar using :func:`dttodtv`.
+
+**4x1 Date/Time Vectors** — a separate legacy format returned by
+the :func:`date` and :func:`time` functions (not interchangeable
+with DTV). Contains year, month, day, and hundredths-of-second-
+since-midnight. Used with :func:`ethsec`, :func:`etdays`, and
+:func:`datestr`.
+
+Converting between legacy and modern formats
++++++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // DT scalar → POSIX (one step)
+ posix = dttoposix(dt_scalar);
+
+ // POSIX → DT scalar (two steps — no direct conversion exists)
+ dt_str = posixtostrc(posix_date, "%Y%m%d%H%M%S");
+ dt_scalar = strctodt(dt_str, "%Y%m%d%H%M%S");
+
+Conversion functions:
+
+.. list-table::
+ :widths: 30 20 20 30
+ :header-rows: 1
+
+ * - Function
+ - From
+ - To
+ - Format system
+
+ * - :func:`dttoposix`
+ - DT scalar
+ - POSIX
+ - —
+
+ * - :func:`strctoposix`
+ - String
+ - POSIX
+ - BSD strftime
+
+ * - :func:`posixtostrc`
+ - POSIX
+ - String
+ - BSD strftime
+
+ * - :func:`strctodt`
+ - String
+ - DT scalar
+ - BSD strftime
+
+ * - :func:`dttostrc`
+ - DT scalar
+ - String
+ - BSD strftime
+
+ * - :func:`strtodt`
+ - String
+ - DT scalar
+ - GAUSS legacy
+
+ * - :func:`dttostr`
+ - DT scalar
+ - String
+ - GAUSS legacy
+
+
+Quick Reference
+--------------------------------------------
+
+.. list-table::
+ :widths: 45 55
+ :header-rows: 1
+
+ * - Task
+ - How
+
+ * - Load CSV with dates
+ - ``data = loadd("file.csv");``
+
+ * - Force date detection
+ - ``loadd("f.csv", "date(col, '%YQ%q') + x")``
+
+ * - Change display format
+ - ``asDate(data, "%Y-Q%q", "Date")``
+
+ * - Create monthly sequence
+ - ``seqaPosix("2020-01-01", 1, "months", 24)``
+
+ * - Extract year
+ - ``dtYear(data, "Date")``
+
+ * - Extract quarter
+ - ``dtQuarter(data, "Date")``
+
+ * - Filter by date range
+ - ``selif(data, between(data[.,"Date"], "2020-01-01", "2020-12-31"))``
+
+ * - Add 3 months
+ - ``timeDeltaPosix(date, 3, "months")``
+
+ * - Days between dates
+ - ``timeDiffPosix(d1, d2, "days")``
+
+ * - Lag by 1 period
+ - ``lagn(data[., "x"], 1)``
+
+ * - Growth rate
+ - ``(x - lagn(x,1)) ./ lagn(x,1)``
+
+ * - Plot time series
+ - ``plotXY(data, "Close ~ Date")``
+
+ * - Aggregate to monthly
+ - ``tsAggregate(data, "M", "last")``
+
+ * - DT scalar → POSIX
+ - ``dttoposix(dt_scalar)``
+
+
+.. seealso:: :doc:`/data-management/index`, :doc:`/user-guide/formula-strings`
diff --git a/docs/user-guide/formula-strings.rst b/docs/user-guide/formula-strings.rst
new file mode 100644
index 00000000..c30dbac0
--- /dev/null
+++ b/docs/user-guide/formula-strings.rst
@@ -0,0 +1,579 @@
+
+Formula Strings
+===============================================
+
+Formula strings allow you to represent a model or a collection of variables
+in a compact, readable way, using the variable names in the dataset. They
+are used throughout GAUSS for loading data, specifying regression models,
+computing descriptive statistics, and controlling plot layouts.
+
+.. admonition:: Prerequisites
+
+ This page assumes you can load data with :func:`loadd`. If you are new
+ to GAUSS, see :doc:`/getting-started/quickstart` first.
+
+::
+
+ // Load two variables by name
+ x = loadd(getGAUSSHome("examples/cancer.dat"), "stage + count");
+
+ // Specify a regression model (call discards the return value
+ // and prints the report directly)
+ call olsmt(getGAUSSHome("examples/credit.dat"), "Limit ~ Income + Rating");
+
+ // Compute descriptive statistics for selected variables
+ call dstatmt(getGAUSSHome("examples/auto2.dta"), "mpg + weight + price");
+
+Formula strings work with **dataframes** — matrices that carry column names
+and types, returned by :func:`loadd`. Because each column has a name,
+formula strings can reference those names directly for subsetting,
+estimation, and plotting.
+
+
+Basic Syntax
+-----------------------------------------
+
+A formula string is a quoted string containing variable names and operators.
+
+**Selecting variables for loading or statistics:**
+
+::
+
+ // Load all variables
+ df = loadd(fname, ".");
+
+ // Load specific variables
+ df = loadd(fname, "Income + Rating + Cards");
+
+ // Load all variables except one
+ df = loadd(fname, ". - Cards");
+
+**Specifying a model with dependent and independent variables:**
+
+The tilde ``~`` separates the dependent (response) variable on the left
+from the independent (explanatory) variables on the right:
+
+::
+
+ // Limit = alpha + beta_1 * Income + beta_2 * Rating + epsilon
+ call olsmt(fname, "Limit ~ Income + Rating");
+
+ // Use all remaining variables as predictors
+ call olsmt(fname, "Limit ~ .");
+
+
+Operators
+-----------------------------------------
+
+The following operators are available in formula strings. The examples
+assume a dataset containing three variables: **Limit**, **Income**, and
+**Rating**.
+
+.. list-table::
+ :widths: 15 85
+ :header-rows: 1
+
+ * - Operator
+ - Description
+
+ * - ``.`` (dot)
+ - Include all variables. When used after ``~``, includes everything
+ except the dependent variable.
+
+ ::
+
+ // These two are equivalent
+ "Limit ~ Income + Rating"
+ "Limit ~ ."
+
+ * - ``+`` (plus)
+ - Add a variable.
+
+ ::
+
+ "Income + Rating"
+
+ * - ``-`` (minus)
+ - Remove a variable.
+
+ ::
+
+ // These two are equivalent
+ "Limit ~ Rating"
+ "Limit ~ . - Income"
+
+ * - ``:`` (colon)
+ - Create a pure interaction term between two variables (no main effects).
+
+ ::
+
+ "Limit ~ Income:Rating"
+
+ * - ``*`` (asterisk)
+ - Include both main effects and the interaction term.
+
+ ::
+
+ // These two are equivalent
+ "Limit ~ Income * Rating"
+ "Limit ~ Income + Rating + Income:Rating"
+
+ * - ``1`` (one)
+ - Represents the intercept. Estimation functions such as :func:`olsmt`
+ and :func:`glm` include an intercept by default. Data-loading
+ functions such as :func:`loadd` and statistics functions such as
+ :func:`dstatmt` do not.
+
+ ::
+
+ // Remove the intercept
+ "Limit ~ -1 + Income + Rating"
+
+ * - ``$`` (dollar sign)
+ - Indicates that a variable should be loaded as a string. Typically
+ used with the ``date`` keyword.
+
+ ::
+
+ // Load 'order_time' as a string and interpret as a date
+ "date($order_time)"
+
+
+Keywords
+-----------------------------------------
+
+factor
++++++++++++++++++++++++
+
+The ``factor`` keyword tells GAUSS that a numeric variable represents
+categories. In estimation functions such as :func:`olsmt` and :func:`glm`,
+GAUSS will automatically create dummy variables for each level, using
+the first level as the base case.
+
+::
+
+ // Load data
+ fname = getGAUSSHome("examples/auto2.dta");
+
+ // Create dummy variables from 'rep78'
+ call olsmt(fname, "mpg ~ weight + factor(rep78)");
+
+The above code prints a regression report with separate coefficient
+estimates for each non-base-case level of ``rep78``:
+
+::
+
+ Ordinary Least Squares
+ =========================================================================================
+ Valid cases: 69 Dependent variable: mpg
+ Missing cases: 5 Deletion method: Listwise
+ Total SS: 2.34e+03 Degrees of freedom: 63
+ R-squared: 0.672 Rbar-squared: 0.646
+ Residual SS: 768 Std. err of est: 3.49
+ F(5,63): 25.8 Probability of F: 4.6e-14
+ =========================================================================================
+ Standard Prob Lower Upper
+ Variable Estimate Error t-value >|t| Bound Bound
+ -----------------------------------------------------------------------------------------
+
+ CONSTANT 38.059 3.0934 12.304 2.0913e-18 31.996 44.122
+ weight -0.005503 0.000601 -9.1564 3.4748e-13 -0.006681 -0.0043251
+ rep78: Fair -0.4786 2.765 -0.17309 0.86313 -5.8981 4.9409
+ rep78: Average -0.47156 2.5531 -0.1847 0.85406 -5.4757 4.5326
+ rep78: Good -0.59903 2.6066 -0.22981 0.81898 -5.708 4.5099
+ rep78: Excellent 2.0863 2.7248 0.76566 0.44674 -3.2544 7.4269
+ =========================================================================================
+
+
+cat
++++++++++++++++++++++++
+
+The ``cat`` keyword tells GAUSS that a string variable in a file (such as
+CSV or XLSX) should be reclassified to integer categories. This is useful
+for file types that do not store variable type information.
+
+``cat`` can be combined with ``factor`` to load string data, convert it to
+integer categories, and create dummy variables in a single step. Read the
+nesting from the inside out: ``cat(load)`` converts the strings to integers
+first, then ``factor(...)`` creates dummy variables from those integers:
+
+::
+
+ fname = getGAUSSHome("examples/yarn.xlsx");
+
+ // cat(load): 'high, med, low' → integers
+ // factor(cat(load)): integers → dummy variables for OLS
+ call olsmt(fname, "cycles ~ factor(cat(load))");
+
+The output:
+
+::
+
+ Ordinary Least Squares
+ ====================================================================================
+ Valid cases: 27 Dependent variable: cycles
+ Missing cases: 0 Deletion method: None
+ Total SS: 2.02e+07 Degrees of freedom: 24
+ R-squared: 0.0866 Rbar-squared: 0.0105
+ Residual SS: 1.85e+07 Std. err of est: 877
+ F(2,24): 1.14 Probability of F: 0.337
+ ====================================================================================
+ Standard Prob Lower Upper
+ Variable Estimate Error t-value >|t| Bound Bound
+ ------------------------------------------------------------------------------------
+
+ CONSTANT 534.44 292.47 1.8273 0.080113 -38.806 1107.7
+ load: low 621.56 413.62 1.5027 0.14596 -189.14 1432.3
+ load: med 359.11 413.62 0.86821 0.39388 -451.59 1169.8
+ ====================================================================================
+
+You can specify a base case explicitly when loading with ``cat``:
+
+::
+
+ fname = getGAUSSHome("examples/yarn.xlsx");
+
+ // Load with 'med' as the base case
+ df = loadd(fname, "cycles + cat(load, 'med')");
+
+ // Now 'med' is the reference level in the regression
+ call olsmt(df, "cycles ~ factor(load)");
+
+
+date
++++++++++++++++++++++++
+
+The ``date`` keyword tells GAUSS that a column contains date information.
+GAUSS will try to match one of approximately 30 recognized date patterns
+and convert the values to POSIX date/time format (seconds since
+January 1, 1970).
+
+.. note::
+
+ :func:`loadd` auto-detects dates for most common formats. The ``date``
+ keyword is an override for cases where auto-detection fails or you need
+ to force a specific interpretation.
+
+::
+
+ fname = getGAUSSHome("examples/yellowstone.csv");
+
+ // The $ tells GAUSS that 'Date' is stored as a string.
+ // The date() keyword tells GAUSS to interpret it as a date.
+ dates = loadd(fname, "date($Date)");
+
+ // Preview the first 4 dates
+ print dates[1:4];
+
+This prints:
+
+::
+
+ Date
+ 2016/01/01
+ 2015/01/01
+ 2014/01/01
+ 2013/01/01
+
+Dates are stored internally as POSIX date/time values (seconds since
+January 1, 1970), but GAUSS displays them in human-readable format
+automatically. Use :func:`dtYear`, :func:`dtMonth`, and
+:func:`dtDayofWeek` to extract date components.
+
+You can also specify a date format explicitly when GAUSS cannot
+auto-detect the pattern:
+
+::
+
+ // Specify the format directly
+ dates = loadd(fname, "date($Date, '%Y-%m-%d')");
+
+
+by
++++++++++++++++++++++++
+
+The ``by`` keyword groups data by the values of a variable. It is
+supported by descriptive statistics functions such as :func:`dstatmt`
+and plotting functions such as :func:`plotScatter` and :func:`plotXY`.
+
+::
+
+ // Load data as a dataframe
+ df = loadd(getGAUSSHome("examples/auto2.dta"));
+
+ // Compute descriptive statistics for 'mpg', grouped by 'foreign'
+ call dstatmt(df, "mpg + by(foreign)");
+
+In plotting functions, ``by`` creates separate series for each group:
+
+::
+
+ // Load the data
+ df = loadd(getGAUSSHome("examples/auto2.dta"));
+
+ // Scatter plot of mpg vs weight, colored by 'foreign'
+ plotScatter(df, "mpg ~ weight + by(foreign)");
+
+
+Data Transformations
+-----------------------------------------
+
+You can apply any GAUSS function to a variable inside a formula string.
+The function must accept a single column vector as input and return a
+column vector of the same length.
+
+::
+
+ // Use the natural log of height
+ "weight ~ ln(height)"
+
+ // Square root transformation
+ "y ~ sqrt(x1) + x2"
+
+ // Lag a variable (for time series)
+ "y ~ lag(x)"
+
+You may use any built-in or user-defined GAUSS procedure. Because the
+formula string is not parsed until runtime, procedures that are not
+referenced elsewhere in the code may not be compiled. If you get the error
+``"Undefined proc"``, add an ``external proc`` declaration:
+
+::
+
+ // Declare the procedure so the compiler includes it
+ external proc myTransform;
+
+ call olsmt(fname, "y ~ myTransform(x1) + x2");
+
+
+Model Specification
+-----------------------------------------
+
+Multiple variable regression
+++++++++++++++++++++++++++++++
+
+For the following examples, assume a dataset containing: **admit**,
+**gre**, **gpa**, and **rank**.
+
+.. list-table::
+ :widths: 50 50
+ :header-rows: 1
+
+ * - Model
+ - Formula string
+
+ * - :math:`\text{admit} = \alpha + \beta_1 \text{gre} + \beta_2 \text{gpa} + \beta_3 \text{rank} + \varepsilon`
+ - ``"admit ~ ."`` or ``"admit ~ gre + gpa + rank"``
+
+ * - :math:`\text{admit} = \alpha + \beta_1 \text{gre} + \beta_2 \text{gpa} + \varepsilon`
+ - ``"admit ~ . - rank"`` or ``"admit ~ gre + gpa"``
+
+
+Keywords and transformations
+++++++++++++++++++++++++++++++
+
+.. list-table::
+ :widths: 50 50
+ :header-rows: 1
+
+ * - Model
+ - Formula string
+
+ * - :math:`\text{admit} = \alpha + \beta_1 \ln(\text{gre}) + \beta_2 D_{\text{rank}=2} + \beta_3 D_{\text{rank}=3} + \beta_4 D_{\text{rank}=4} + \varepsilon`
+
+ Log-transform ``gre`` and create dummy variables from ``rank``
+ (level 1 is the base case).
+ - ``"admit ~ ln(gre) + factor(rank)"``
+
+ * - :math:`\text{admit} = \alpha + \beta_1 \text{gre} + \beta_2 \text{gpa} + \beta_3 (\text{gre} \times \text{gpa}) + \varepsilon`
+
+ Include main effects and their interaction.
+ - ``"admit ~ gre * gpa"``
+
+
+Controlling the intercept
+++++++++++++++++++++++++++++++
+
+Estimation functions include an intercept by default. Remove it with
+``-1``:
+
+.. list-table::
+ :widths: 50 50
+ :header-rows: 1
+
+ * - Model
+ - Formula string
+
+ * - :math:`\text{admit} = \beta_1 \text{gre} + \beta_2 \text{gpa} + \beta_3 \text{rank} + \varepsilon`
+ - ``"admit ~ . - 1"`` or ``"admit ~ -1 + gre + gpa + rank"``
+
+ * - :math:`\text{admit} = \beta_1 \text{gre} + \beta_2 \text{gpa} + \varepsilon`
+ - ``"admit ~ . - 1 - rank"`` or ``"admit ~ -1 + gre + gpa"``
+
+
+Multiple dependent variables
+++++++++++++++++++++++++++++++
+
+Some functions use additional tildes to separate groups of variables.
+The first tilde always separates the primary dependent variable from the
+independent variables, and a second tilde introduces a secondary
+dependent variable or grouping variable. Functions that accept this
+syntax include :func:`quantileFit` (endogenous variables) and
+:func:`clusterSE` (cluster identifier):
+
+::
+
+ // Primary dependent ~ secondary dependent ~ regressors
+ "y1 ~ y2 ~ x1 + x2"
+
+
+Formulas without a dependent variable
+++++++++++++++++++++++++++++++++++++++++
+
+Some operations, such as computing descriptive statistics or loading data,
+do not have a dependent variable. In these cases, omit the tilde:
+
+.. list-table::
+ :widths: 40 60
+ :header-rows: 1
+
+ * - Variables to include
+ - Formula string
+
+ * - All variables
+ - ``"."`` or ``"admit + gre + gpa + rank"``
+
+ * - gre and rank only
+ - ``". - admit - gpa"`` or ``"gre + rank"``
+
+
+Complete Examples
+-----------------------------------------
+
+The following examples show complete, runnable code combining formula
+strings with common GAUSS workflows. Each uses a built-in dataset.
+
+Example 1: OLS with formula strings
+++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Load data as a dataframe
+ fname = getGAUSSHome("examples/credit.dat");
+ df = loadd(fname);
+
+ // Preview the data
+ head(df);
+
+ // Estimate: Limit = alpha + beta_1 * Income + beta_2 * Rating + epsilon
+ call olsmt(df, "Limit ~ Income + Rating");
+
+.. note::
+
+ The legacy function :func:`ols` still works and accepts the same formula
+ string syntax, but :func:`olsmt` is recommended for new code.
+
+
+Example 2: GLM with categorical variables
++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Load data and remove missing values
+ df = loadd(getGAUSSHome("examples/auto2.dta"), "mpg + weight + rep78");
+ df = packr(df);
+
+ // Fit a GLM: mpg depends on weight and categorical rep78
+ struct glmOut out;
+ out = glm(df, "mpg ~ weight + factor(rep78)", "normal");
+
+
+Example 3: Loading and transforming data
++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ fname = getGAUSSHome("examples/credit.dat");
+
+ // Load selected variables with a transformation
+ df = loadd(fname, "Limit + ln(Income) + Rating");
+
+ // View the first few rows
+ head(df);
+
+
+Example 4: Descriptive statistics by group
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Load data as a dataframe
+ df = loadd(getGAUSSHome("examples/auto2.dta"));
+
+ // Descriptive statistics for mpg and weight, grouped by foreign
+ call dstatmt(df, "mpg + weight + by(foreign)");
+
+
+Example 5: Scatter plot with grouping
+++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // Load data
+ df = loadd(getGAUSSHome("examples/auto2.dta"));
+
+ // Scatter plot with groups
+ plotScatter(df, "mpg ~ weight + by(foreign)");
+
+
+Example 6: Quantile regression
+++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ fname = getGAUSSHome("examples/credit.dat");
+
+ // Quantile regression at the median
+ struct qfitOut out;
+ out = quantileFit(fname, "Balance ~ Income + Rating", 0.5);
+
+
+Rules and Tips
+-----------------------------------------
+
+- **Case sensitivity:** Variable names in formula strings are case
+ sensitive. ``"Income"`` and ``"income"`` refer to different variables.
+
+- **Transformation requirements:** Any procedure used as a data
+ transformation must accept a single column vector and return a column
+ vector of the same length.
+
+- **Intercept defaults:** Estimation functions (:func:`olsmt`, :func:`glm`,
+ :func:`quantileFit`) add an intercept automatically. Data functions
+ (:func:`loadd`) and statistics functions (:func:`dstatmt`) do not.
+
+- **Whitespace:** Spaces around operators are optional but recommended
+ for readability. ``"y~x1+x2"`` and ``"y ~ x1 + x2"`` are equivalent.
+
+- **Dataframe column names:** Formula strings use the column names stored
+ in the dataframe. Use :func:`getHeaders` to see available names.
+
+- **Files without variable names:** Some data files, such as GAUSS matrix
+ files (``.fmt``), do not have column names. Refer to columns by position
+ using ``X1``, ``X2``, ``X3``, and so on: ``loadd("mydata.fmt", "X1 + X3")``.
+
+.. tip::
+
+ Use :func:`head` to preview a dataframe after loading. This helps you
+ confirm the variable names and types before writing a formula string.
+
+
+What's Next
+-----------------------------------------
+
+- Load your own data with :func:`loadd` and explore the available
+ column names with :func:`getHeaders`.
+- Run a regression with :func:`olsmt` and examine the output structure.
+- Create grouped plots with :func:`plotScatter` and the ``by`` keyword.
+
+.. seealso:: Functions :func:`loadd`, :func:`olsmt`, :func:`glm`, :func:`dstatmt`, :func:`quantileFit`, :func:`plotScatter`, :func:`plotXY`, :func:`plotBar`
diff --git a/docs/user-guide/fundamentals/control-flow.rst b/docs/user-guide/fundamentals/control-flow.rst
new file mode 100644
index 00000000..35e7eeea
--- /dev/null
+++ b/docs/user-guide/fundamentals/control-flow.rst
@@ -0,0 +1,614 @@
+.. _control-flow:
+
+Control Flow
+===============================================
+
+GAUSS provides several control-flow constructs:
+``if``/``elseif``/``else`` for conditional branching, ``for`` for
+counted loops, ``do while``/``do until`` for condition-based loops,
+and ``threadfor`` for parallel execution. Two helper statements —
+``break`` and ``continue`` — give you finer control inside any loop.
+
+.. note::
+
+ In GAUSS, **every statement ends with a semicolon** — including
+ ``else;``, ``endif;``, ``endfor;``, and ``endo;``. This is different
+ from Python, R, and MATLAB where semicolons are optional or absent.
+
+The examples on this page use common GAUSS functions like
+:func:`zeros`, :func:`rows`, :func:`cols`, and :func:`abs`. See the
+:doc:`/command-reference` for details on any unfamiliar function.
+
++-------------------------------+-------------------------------------------------------------+
+| Statement | Description |
++===============================+=============================================================+
+| ``if`` / ``elseif`` / ``else``| Conditional branching based on scalar expressions. |
++-------------------------------+-------------------------------------------------------------+
+| ``for`` / ``endfor`` | Counted loop with start, stop, and step values. |
++-------------------------------+-------------------------------------------------------------+
+| ``do while`` / ``do until`` | Condition-based loop that runs while (or until) an |
+| | expression is true. |
++-------------------------------+-------------------------------------------------------------+
+| ``break`` | Exits the innermost loop immediately. |
++-------------------------------+-------------------------------------------------------------+
+| ``continue`` | Skips to the next iteration of the innermost loop. |
++-------------------------------+-------------------------------------------------------------+
+| ``threadfor`` | Parallel ``for`` loop — iterations may run on |
+| | different threads. |
++-------------------------------+-------------------------------------------------------------+
+| ``goto`` | Unconditional jump to a label. Rarely needed; |
+| | prefer structured constructs. |
++-------------------------------+-------------------------------------------------------------+
+
+
+Conditional Branching: if / elseif / else
+--------------------------------------------
+
+::
+
+ if scalar_expression;
+ // runs when expression is nonzero (TRUE)
+ elseif scalar_expression;
+ // runs when this expression is TRUE
+ else;
+ // runs when no expression above was TRUE
+ endif;
+
+- The expression must evaluate to a **scalar**. It is TRUE if nonzero,
+ FALSE if zero. Passing a matrix or vector produces the error
+ ``Argument must be scalar``.
+- ``elseif`` and ``else`` are optional. You can have as many
+ ``elseif`` branches as you need, but at most one ``else``.
+- One ``endif`` is required per ``if``.
+
+Example: Sign function
++++++++++++++++++++++++++++++++++
+
+::
+
+ x = -3;
+
+ if x < 0;
+ y = -1;
+ elseif x > 0;
+ y = 1;
+ else;
+ y = 0;
+ endif;
+
+ print y;
+
+This prints:
+
+::
+
+ -1.0000000
+
+.. note::
+
+ The ``print`` statement displays one or more expressions separated
+ by spaces: ``print "label" x;`` prints the string, then the value
+ of *x*. A double semicolon ``;;`` at the end suppresses the newline
+ so the next ``print`` continues on the same line.
+
+Example: Classify a numeric grade
++++++++++++++++++++++++++++++++++++++
+
+::
+
+ score = 82;
+
+ if score >= 90;
+ grade = "A";
+ elseif score >= 80;
+ grade = "B";
+ elseif score >= 70;
+ grade = "C";
+ else;
+ grade = "F";
+ endif;
+
+ print grade;
+
+This prints:
+
+::
+
+ B
+
+GAUSS tests each ``elseif`` in order and executes the **first** branch
+whose expression is TRUE, then jumps to ``endif``.
+
+
+Counted Loops: for
+--------------------------------------------
+
+The ``for`` loop runs a counter from a start value to a stop value,
+incrementing by a step each iteration:
+
+::
+
+ for i (start, stop, step);
+ // body
+ endfor;
+
+- *i* — counter variable name, **strictly local** to the loop. It does
+ not affect any global variable with the same name, and it is not
+ accessible after the loop ends. If you need the final counter value,
+ save it to another variable inside the loop.
+- *start*, *stop*, *step* — scalar expressions, evaluated **once** when
+ the loop initializes.
+- The loop terminates when *i* exceeds *stop* (for positive *step*) or
+ falls below *stop* (for negative *step*). If *start* already exceeds
+ *stop* (or is already below *stop* for negative *step*), the loop body
+ never executes.
+
+.. warning::
+
+ Unlike Python and R, the ``for`` counter does not exist outside
+ the loop. ``for i (1, 5, 1); endfor; print i;`` will print
+ whatever value ``i`` had *before* the loop, not 5.
+
+Example: Basic counting
++++++++++++++++++++++++++++++++++
+
+::
+
+ for i (1, 4, 1);
+ print i;
+ endfor;
+
+This prints:
+
+::
+
+ 1.0000000
+ 2.0000000
+ 3.0000000
+ 4.0000000
+
+Example: Step by 2
++++++++++++++++++++++++++++++++++
+
+::
+
+ for i (1, 10, 2);
+ print i;;
+ endfor;
+
+This prints:
+
+::
+
+ 1.0000000 3.0000000 5.0000000 7.0000000 9.0000000
+
+Example: Counting down
++++++++++++++++++++++++++++++++++
+
+Use a negative step to count backward:
+
+::
+
+ for i (5, 1, -1);
+ print i;;
+ endfor;
+
+This prints:
+
+::
+
+ 5.0000000 4.0000000 3.0000000 2.0000000 1.0000000
+
+Example: Nested loops — building a matrix
+++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ x = zeros(3, 4);
+
+ for i (1, rows(x), 1);
+ for j (1, cols(x), 1);
+ x[i,j] = i * j;
+ endfor;
+ endfor;
+
+ print x;
+
+This prints:
+
+::
+
+ 1.0000000 2.0000000 3.0000000 4.0000000
+ 2.0000000 4.0000000 6.0000000 8.0000000
+ 3.0000000 6.0000000 9.0000000 12.000000
+
+.. tip::
+
+ The same result can often be computed without loops using
+ element-wise operators::
+
+ // seqa(start, step, n) creates a sequence: {1, 2, 3}
+ // ' transposes it to a row: {1, 2, 3, 4}
+ // .* is element-wise multiply (broadcasts 3x1 .* 1x4 → 3x4)
+ x = seqa(1, 1, 3) .* seqa(1, 1, 4)';
+
+ Vectorized operations are typically much faster than explicit loops.
+ See :ref:`when-to-use-loops` below.
+
+
+Condition-Based Loops: do while / do until
+--------------------------------------------
+
+A ``do while`` loop repeats as long as its expression is TRUE (nonzero).
+A ``do until`` loop repeats until its expression becomes TRUE — that is,
+it continues while the expression is FALSE (zero).
+
+Note that ``do`` loops end with ``endo`` (not ``enddo``).
+``for`` loops use ``endfor``, and ``if`` blocks use ``endif``.
+
+::
+
+ // Runs while expression is TRUE
+ do while expression;
+ // body
+ endo;
+
+ // Runs until expression becomes TRUE
+ do until expression;
+ // body
+ endo;
+
+- The condition is checked **at the top** of the loop, before each
+ iteration. If the condition is not met on entry, the body never
+ executes.
+- You must update the loop variable yourself — ``do`` loops do not
+ auto-increment a counter.
+
+Example: do while
++++++++++++++++++++++++++++++++++
+
+::
+
+ x = 1;
+
+ do while x <= 5;
+ print x;;
+ x = x + 1;
+ endo;
+
+This prints:
+
+::
+
+ 1.0000000 2.0000000 3.0000000 4.0000000 5.0000000
+
+Example: do until
++++++++++++++++++++++++++++++++++
+
+The same result, with the condition inverted:
+
+::
+
+ x = 1;
+
+ do until x > 5;
+ print x;;
+ x = x + 1;
+ endo;
+
+This prints:
+
+::
+
+ 1.0000000 2.0000000 3.0000000 4.0000000 5.0000000
+
+Example: Convergence check
++++++++++++++++++++++++++++++++++
+
+``do while`` is especially useful when you don't know the number of
+iterations in advance — for example, iterating until convergence:
+
+::
+
+ x = 10;
+ tol = 1e-6;
+ diff = 1;
+
+ do while diff > tol;
+ x_new = (x + 2 / x) / 2; // Babylonian method for sqrt(2)
+ diff = abs(x_new - x);
+ x = x_new;
+ endo;
+
+ print "sqrt(2) =" x;
+
+This prints:
+
+::
+
+ sqrt(2) = 1.4142136
+
+break and continue
+--------------------------------------------
+
+``break`` and ``continue`` work inside both ``for`` and ``do`` loops.
+
+- ``break`` — exits the **innermost** loop immediately. Execution
+ continues at the statement after ``endfor`` or ``endo``.
+- ``continue`` — skips the rest of the current iteration. In a ``for``
+ loop, the counter is incremented and the loop resumes at the top. In a
+ ``do`` loop, execution returns to the condition check.
+
+Example: break — find the first negative value
++++++++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ x = { 3.1, 2.7, 1.2, -0.8, 4.5 };
+ found = 0;
+
+ for i (1, rows(x), 1);
+ if x[i] < 0;
+ found = i;
+ break;
+ endif;
+ endfor;
+
+ print "First negative at row:" found;
+
+This prints:
+
+::
+
+ First negative at row: 4.0000000
+
+Example: continue — skip missing values
+++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // A bare . denotes a missing value (like NA in R or NaN in Python)
+ x = { 1.2, ., 3.4, ., 5.6, 7.8 };
+ total = 0;
+ count = 0;
+
+ for i (1, rows(x), 1);
+ if ismiss(x[i]);
+ continue;
+ endif;
+ total = total + x[i];
+ count = count + 1;
+ endfor;
+
+ print "Sum:" total;
+ print "Count:" count;
+ print "Mean:" (total / count);
+
+This prints:
+
+::
+
+ Sum: 18.000000
+ Count: 4.0000000
+ Mean: 4.5000000
+
+
+Parallel Loops: threadfor
+--------------------------------------------
+
+The ``threadfor`` loop has the same syntax as ``for`` but distributes
+iterations across CPU threads:
+
+::
+
+ threadfor i (start, stop, step);
+ // body — iterations may run in any order
+ threadendfor;
+
+Key rules:
+
+1. **Iterations may execute in any order.** Do not rely on sequential
+ execution.
+2. **Indexed assignments** to global variables (e.g., ``x[i] = ...``)
+ behave the same as in a standard ``for`` loop — the variable persists
+ after the loop.
+3. **Non-indexed assignments** inside the loop create temporary
+ variables that exist only for the current iteration.
+4. ``threadfor`` loops **cannot be nested**.
+5. ``break`` and ``continue`` are **not supported** in ``threadfor``.
+
+Example: Fill a vector in parallel
++++++++++++++++++++++++++++++++++++++
+
+::
+
+ x = zeros(5, 1);
+
+ threadfor i (1, 5, 1);
+ x[i] = i^2;
+ threadendfor;
+
+ print x;
+
+This prints:
+
+::
+
+ 1.0000000
+ 4.0000000
+ 9.0000000
+ 16.000000
+ 25.000000
+
+Example: Parallel bootstrap
++++++++++++++++++++++++++++++++++++++
+
+::
+
+ // loadd loads a dataset; x[., 2] selects all rows of column 2
+ fname = getGAUSSHome("examples/fueleconomy.dat");
+ x = loadd(fname);
+ engine_disp = x[., 2];
+
+ iters = 500;
+ nobs = rows(engine_disp); // number of observations
+
+ // zeros(r, c) creates an r x c matrix of zeros
+ sample_means = zeros(iters, 1);
+
+ threadfor i (1, iters, 1);
+ // rndu draws uniform random numbers; ceil rounds up
+ // idx contains random row indices for resampling
+ idx = ceil(nobs * rndu(nobs, 1));
+ sample = engine_disp[idx];
+
+ // Indexed assignment — persists after the loop
+ // meanc computes the column mean
+ sample_means[i] = meanc(sample);
+ threadendfor;
+
+ print "Bootstrap mean:" meanc(sample_means);
+ print "Bootstrap std: " stdc(sample_means);
+
+
+.. _when-to-use-loops:
+
+When to Use Loops (and When Not To)
+--------------------------------------------
+
+GAUSS is a matrix language. Many operations that require loops in
+general-purpose languages can be written as a single matrix expression
+in GAUSS. Vectorized expressions are almost always **faster** than
+equivalent loops because they run in optimized compiled code.
+
+**Prefer vectorized operations when you can:**
+
+::
+
+ // SLOW: element-wise loop
+ y = zeros(rows(x), 1);
+ for i (1, rows(x), 1);
+ y[i] = x[i]^2;
+ endfor;
+
+ // FAST: vectorized equivalent
+ y = x .^ 2;
+
+**Loops are appropriate when:**
+
+- Each iteration depends on the previous result (e.g., convergence,
+ recursive calculations).
+- You need to accumulate results conditionally (e.g., skip rows, early
+ exit with ``break``).
+- You are iterating over model specifications or file names, not over
+ data elements.
+
+.. list-table::
+ :widths: 25 35 40
+ :header-rows: 1
+
+ * - Task
+ - Loop approach
+ - Vectorized approach
+
+ * - Square each element
+ - ``for`` loop over rows
+ - ``x .^ 2``
+
+ * - Column sums
+ - ``for`` loop accumulating
+ - :func:`sumc` (sum of each column)
+
+ * - Element-wise multiply
+ - Nested ``for`` loops
+ - ``x .* y``
+
+ * - Find rows matching a condition
+ - ``for`` with ``if``
+ - :func:`selif` (select rows where condition is true)
+
+Choosing the right loop
++++++++++++++++++++++++++++++++++
+
+.. list-table::
+ :widths: 30 20 50
+ :header-rows: 1
+
+ * - Situation
+ - Use
+ - Why
+
+ * - Known number of iterations
+ - ``for``
+ - Fastest loop; counter is automatic and local
+
+ * - Unknown iterations (convergence, EOF)
+ - ``do while``
+ - Flexible termination condition
+
+ * - Large independent iterations (CPU-bound)
+ - ``threadfor``
+ - Distributes work across CPU cores
+
+ * - Small loops, or iterations with dependencies
+ - ``for``
+ - Threading overhead exceeds benefit for small loops
+
+The ``for`` loop has lower per-iteration overhead than ``do`` and should
+be preferred when either could be used.
+
+
+Unconditional Jump: goto
+--------------------------------------------
+
+The ``goto`` statement jumps to a labeled location in the program:
+
+::
+
+ goto label;
+ // ... skipped code ...
+
+ label:
+ // execution continues here
+
+- A label is any valid GAUSS name followed immediately by a colon.
+- Labels do not need to be declared before use.
+
+``goto`` is rarely needed in modern GAUSS code — ``if``/``else``,
+``break``, and ``continue`` handle nearly all branching. It is
+documented here for completeness and for reading legacy code.
+
+
+Quick Reference
+--------------------------------------------
+
+.. list-table::
+ :widths: 25 35 40
+ :header-rows: 1
+
+ * - Construct
+ - Syntax
+ - Terminates with
+
+ * - ``if``
+ - ``if expr; ... elseif expr; ... else; ... endif;``
+ - ``endif``
+
+ * - ``for``
+ - ``for i (start, stop, step); ... endfor;``
+ - ``endfor``
+
+ * - ``do while``
+ - ``do while expr; ... endo;``
+ - ``endo``
+
+ * - ``do until``
+ - ``do until expr; ... endo;``
+ - ``endo``
+
+ * - ``threadfor``
+ - ``threadfor i (start, stop, step); ... threadendfor;``
+ - ``threadendfor``
+
+
+.. seealso:: :doc:`/user-guide/fundamentals/procedures`, :func:`selif`, :func:`delif`, :func:`ismiss`, :func:`sumc`, :func:`meanc`
diff --git a/docs/user-guide/fundamentals/operators.rst b/docs/user-guide/fundamentals/operators.rst
new file mode 100644
index 00000000..22983d9a
--- /dev/null
+++ b/docs/user-guide/fundamentals/operators.rst
@@ -0,0 +1,667 @@
+.. _operators:
+
+Operators and Expressions
+===============================================
+
+GAUSS is a matrix language, and most of its operators work on matrices
+as well as scalars. The key distinction to learn is between **matrix**
+operators (which follow linear-algebra rules) and **element-wise**
+operators (which apply independently to each element). Element-wise
+operators are prefixed with a dot: ``.*``, ``./``, ``.^``, ``.==``, etc.
+
+This page covers arithmetic, concatenation, comparison, logical, and
+indexing operators, plus broadcasting rules and operator precedence.
+For complete specifications of each operator, see the
+:doc:`/cc/operators` reference.
+
+.. note::
+
+ In GAUSS, curly braces create matrix literals. Spaces separate
+ columns, commas separate rows: ``{ 1 2, 3 4 }`` creates a 2x2
+ matrix with rows [1 2] and [3 4].
+
+.. note::
+
+ If you are coming from MATLAB, the dot-prefix convention is similar,
+ but not identical — GAUSS ``^`` is element-wise (same as ``.^``),
+ unlike MATLAB where ``^`` is matrix power.
+ If you are coming from Python/NumPy, GAUSS ``*`` is ``@`` (matrix
+ multiply), and GAUSS ``.*`` is ``*`` (element-wise).
+
+.. note::
+
+ In GAUSS, any nonzero value is TRUE and zero is FALSE. Comparison
+ operators return 1 for true and 0 for false.
+
+
+Arithmetic Operators
+--------------------------------------------
+
+.. list-table::
+ :widths: 10 25 65
+ :header-rows: 1
+
+ * - Operator
+ - Name
+ - Description
+
+ * - ``+``
+ - Addition
+ - Element-wise addition (supports :ref:`broadcasting `)
+
+ * - ``-``
+ - Subtraction
+ - Element-wise subtraction (supports :ref:`broadcasting `)
+
+ * - ``*``
+ - Matrix multiply
+ - Standard matrix product (NxK \* KxM = NxM). If either operand is
+ a scalar, performs element-wise multiplication instead.
+
+ * - ``.*``
+ - Element-wise multiply
+ - Multiplies corresponding elements
+
+ * - ``/``
+ - Matrix division
+ - ``A / B`` is equivalent to ``inv(B) * A``. If either operand is
+ a scalar, performs element-wise division instead.
+
+ * - ``./``
+ - Element-wise division
+ - Divides corresponding elements
+
+ * - ``^`` ``.^``
+ - Element-wise power
+ - Raises each element independently. Both forms are identical —
+ GAUSS has no matrix power operator.
+
+ * - ``.*.``
+ - Kronecker product
+ - Tensor product of two matrices. See :func:`kronecker`.
+
+ * - ``%``
+ - Modulo (element-wise)
+ - Remainder after division for each element
+
+ * - ``'``
+ - Transpose
+ - Transposes rows and columns
+
+ * - ``!``
+ - Factorial
+ - ``n!`` computes n factorial
+
+Example: Matrix vs. element-wise multiply
++++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ A = { 1 2, 3 4 };
+ B = { 5 6, 7 8 };
+
+ // Matrix multiply: linear algebra product
+ print "A * B:";
+ print A * B;
+
+ // Element-wise multiply: each element independently
+ print "A .* B:";
+ print A .* B;
+
+This prints:
+
+::
+
+ A * B:
+
+ 19.000000 22.000000
+ 43.000000 50.000000
+ A .* B:
+
+ 5.0000000 12.000000
+ 21.000000 32.000000
+
+Matrix multiply produces a 2x2 result using dot products of rows and
+columns. Element-wise multiply simply multiplies each pair of
+corresponding elements: 1*5, 2*6, 3*7, 4*8.
+
+Example: Element-wise power
++++++++++++++++++++++++++++++++++
+
+::
+
+ x = { 1, 2, 3, 4, 5 };
+
+ // Square each element
+ print x .^ 2;
+
+This prints:
+
+::
+
+ 1.0000000
+ 4.0000000
+ 9.0000000
+ 16.000000
+ 25.000000
+
+
+Concatenation Operators
+--------------------------------------------
+
+.. list-table::
+ :widths: 10 25 65
+ :header-rows: 1
+
+ * - Operator
+ - Name
+ - Description
+
+ * - ``~``
+ - Horizontal concatenation
+ - Joins matrices side by side (same row count)
+
+ * - ``|``
+ - Vertical concatenation
+ - Stacks matrices top to bottom (same col count)
+
+ * - ``$+``
+ - String concatenation
+ - Joins two strings end to end
+
+Example: Building matrices with ~ and |
+++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ a = { 1 2, 3 4 };
+ b = { 5 6, 7 8 };
+
+ // Side by side (horizontal): same number of rows required
+ print a ~ b;
+
+ // Stacked (vertical): same number of columns required
+ print a | b;
+
+This prints:
+
+::
+
+ 1.0000000 2.0000000 5.0000000 6.0000000
+ 3.0000000 4.0000000 7.0000000 8.0000000
+
+ 1.0000000 2.0000000
+ 3.0000000 4.0000000
+ 5.0000000 6.0000000
+ 7.0000000 8.0000000
+
+These operators are used throughout GAUSS to assemble data. For example,
+``1|rows(x)`` creates the 2x1 column vector ``{ 1, rows(x) }`` — this
+idiom appears frequently with functions like :func:`rndi` that take
+range vectors.
+
+
+Comparison Operators
+--------------------------------------------
+
+GAUSS has two sets of comparison operators: **element-wise** (dot-prefix)
+and **matrix** (no prefix).
+
+.. list-table::
+ :widths: 20 20 60
+ :header-rows: 1
+
+ * - Element-wise
+ - Matrix
+ - Description
+
+ * - ``.==``
+ - ``==``
+ - Equal
+
+ * - ``./=`` (or ``.!=``)
+ - ``/=`` (or ``!=``)
+ - Not equal
+
+ * - ``.<``
+ - ``<``
+ - Less than
+
+ * - ``.<=``
+ - ``<=``
+ - Less than or equal
+
+ * - ``.>``
+ - ``>``
+ - Greater than
+
+ * - ``.>=``
+ - ``>=``
+ - Greater than or equal
+
+- **Element-wise** (e.g., ``.==``) — compares each pair of elements and
+ returns a matrix of 1s and 0s the same size as the inputs.
+- **Matrix** (e.g., ``==``) — returns a single scalar: 1 if the
+ condition holds for **every** element, 0 otherwise.
+
+Example: Element-wise vs. matrix comparison
+++++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ x = { 1 5, 3 2 };
+ y = { 2 4, 3 3 };
+
+ // Element-wise: returns a matrix of 0s and 1s
+ print "x .== y:";
+ print x .== y;
+
+ // Matrix: returns a single scalar (1 only if ALL elements match)
+ print "x == y:";
+ print x == y;
+
+This prints:
+
+::
+
+ x .== y:
+
+ 0.0000000 0.0000000
+ 1.0000000 0.0000000
+ x == y:
+ 0.0000000
+
+Element-wise ``.==`` shows that only position [2,1] is equal (both 3).
+Matrix ``==`` returns 0 because the matrices are not identical everywhere.
+
+.. tip::
+
+ Use element-wise comparisons (``.==``, ``.<``, etc.) when you want
+ to find *which* elements meet a condition. Use matrix comparisons
+ (``==``, ``<``, etc.) when you need a single yes/no answer — for
+ example, in an ``if`` statement, which requires a scalar.
+
+
+Logical Operators
+--------------------------------------------
+
+.. list-table::
+ :widths: 20 20 60
+ :header-rows: 1
+
+ * - Element-wise
+ - Matrix
+ - Description
+
+ * - ``.and``
+ - ``and``
+ - Logical AND
+
+ * - ``.or``
+ - ``or``
+ - Logical OR
+
+ * - ``.not``
+ - ``not``
+ - Logical NOT
+
+ * - ``.xor``
+ - ``xor``
+ - Logical exclusive OR
+
+ * - ``.eqv``
+ - ``eqv``
+ - Logical equivalence
+
+The same element-wise vs. matrix distinction applies: ``.and`` returns a
+matrix of results; ``and`` returns a single scalar.
+
+Example: Logical operators
++++++++++++++++++++++++++++++++++
+
+::
+
+ a = { 1 0, 1 1 };
+ b = { 1 1, 0 0 };
+
+ print "a .and b:";
+ print a .and b;
+
+ print ".not a:";
+ print .not a;
+
+This prints:
+
+::
+
+ a .and b:
+
+ 1.0000000 0.0000000
+ 0.0000000 0.0000000
+ .not a:
+
+ 0.0000000 1.0000000
+ 0.0000000 0.0000000
+
+
+Indexing
+--------------------------------------------
+
+Square brackets ``[ ]`` are used to extract or assign submatrices.
+
+.. note::
+
+ GAUSS indices start at 1 (like R and MATLAB), not 0 (like Python).
+ The first element of a vector is ``v[1]``, not ``v[0]``.
+
+::
+
+ x = { 1 2 3 4,
+ 5 6 7 8,
+ 9 10 11 12 };
+
+**Single element:**
+
+::
+
+ x[2, 3] // 7 — row 2, column 3
+
+**Entire row or column** — use a dot ``.`` for "all":
+
+::
+
+ x[., 1] // { 1, 5, 9 } — all rows of column 1
+ x[2, .] // { 5 6 7 8 } — row 2, all columns
+
+**Range** — use a colon ``:`` for consecutive indices:
+
+::
+
+ x[1:2, .] // rows 1 through 2, all columns
+
+**Specific rows/columns** — list indices separated by spaces:
+
+::
+
+ x[1 3, 2 4] // rows 1 and 3, columns 2 and 4
+
+Example: Indexing a matrix
++++++++++++++++++++++++++++++++++
+
+::
+
+ x = { 1 2 3 4,
+ 5 6 7 8,
+ 9 10 11 12 };
+
+ print "x[2, 3] =" x[2, 3];
+ print "x[., 1] (all rows, col 1):";
+ print x[., 1];
+ print "x[1:2, .] (rows 1-2, all cols):";
+ print x[1:2, .];
+ print "x[1 3, 2 4] (rows 1,3 cols 2,4):";
+ print x[1 3, 2 4];
+
+This prints:
+
+::
+
+ x[2, 3] = 7.0000000
+ x[., 1] (all rows, col 1):
+
+ 1.0000000
+ 5.0000000
+ 9.0000000
+ x[1:2, .] (rows 1-2, all cols):
+
+ 1.0000000 2.0000000 3.0000000 4.0000000
+ 5.0000000 6.0000000 7.0000000 8.0000000
+ x[1 3, 2 4] (rows 1,3 cols 2,4):
+
+ 2.0000000 4.0000000
+ 10.000000 12.000000
+
+.. note::
+
+ Vectors can be indexed with a single index: ``v[3]`` returns the
+ third element regardless of whether *v* is a row or column vector.
+
+
+.. _exe-conformability:
+
+ExE Conformability (Broadcasting)
+--------------------------------------------
+
+Element-wise operators do not require the operands to have exactly the
+same dimensions. GAUSS automatically **broadcasts** smaller operands to
+match larger ones, following these rules:
+
+- A **scalar** is conformable with any matrix — the scalar is applied
+ to every element.
+- A **column vector** (Nx1) is conformable with an NxK matrix — the
+ vector is applied to each column.
+- A **row vector** (1xK) is conformable with an NxK matrix — the
+ vector is applied to each row.
+
+This is called **ExE conformability** and works with all element-wise
+operators (``.*``, ``.^``, ``.==``, etc.) as well as ``+`` and ``-``.
+
+If the dimensions do not match any of these rules, GAUSS raises the
+error: ``Matrix dimensions are incompatible``.
+
+Example: Broadcasting in action
++++++++++++++++++++++++++++++++++
+
+::
+
+ x = { 1, 2, 3 }; // 3x1 column vector
+ y = { 10 20 30 40 }; // 1x4 row vector
+
+ // 3x1 .* 1x4 broadcasts to 3x4
+ print x .* y;
+
+This prints:
+
+::
+
+ 10.000000 20.000000 30.000000 40.000000
+ 20.000000 40.000000 60.000000 80.000000
+ 30.000000 60.000000 90.000000 120.00000
+
+Each element of *x* is multiplied by every element of *y*, producing a
+3x4 result. This is the GAUSS equivalent of NumPy broadcasting or
+MATLAB's implicit expansion.
+
+
+The Transpose Shorthand: X'Y
+--------------------------------------------
+
+GAUSS provides a shorthand for the common expression ``X' * Y``:
+
+::
+
+ // These are equivalent:
+ result1 = X' * Y;
+ result2 = X'Y;
+
+When the transpose operator ``'`` is immediately followed by a variable
+name (no space or operator between them), GAUSS interprets it as
+"transpose *X*, then matrix-multiply by *Y*."
+
+Example: Transpose-multiply shorthand
++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ X = { 1 2, 3 4, 5 6 }; // 3x2
+ Y = { 7, 8, 9 }; // 3x1
+
+ // Transpose X (2x3) then multiply by Y (3x1) = 2x1
+ print X'Y;
+
+This prints:
+
+::
+
+ 76.000000
+ 100.00000
+
+.. warning::
+
+ The shorthand only works for the simple form ``X'Y``. For
+ compound expressions, use explicit parentheses::
+
+ // WRONG: ambiguous
+ z = X'Y / W'X;
+
+ // RIGHT: explicit grouping
+ z = (X'Y) / (W'X);
+
+
+Operator Precedence
+--------------------------------------------
+
+Operators are evaluated from **highest to lowest** precedence. Within
+the same precedence level, evaluation is left to right. This table lists
+the most commonly used operators:
+
+.. list-table::
+ :widths: 15 50 15
+ :header-rows: 1
+
+ * - Precedence
+ - Operators
+ - Category
+
+ * - 90
+ - ``'`` ``.'`` (transpose)
+ - Unary
+
+ * - 89
+ - ``!`` (factorial)
+ - Unary
+
+ * - 85
+ - ``^`` ``.^`` (power)
+ - Arithmetic
+
+ * - 83
+ - unary ``-`` (negation)
+ - Unary
+
+ * - 80
+ - ``*`` ``.*`` ``.*.`` ``/`` ``./``
+ - Arithmetic
+
+ * - 75
+ - ``%`` (modulo)
+ - Arithmetic
+
+ * - 70
+ - ``+`` ``-`` ``$+``
+ - Arithmetic / String
+
+ * - 68
+ - ``~`` (horizontal concat)
+ - Concatenation
+
+ * - 67
+ - ``|`` (vertical concat)
+ - Concatenation
+
+ * - 65
+ - ``.==`` ``./=`` ``.<`` ``.<=`` ``.>`` ``.>=``
+ - Element-wise comparison
+
+ * - 64–60
+ - ``.not`` ``.and`` ``.or`` ``.xor`` ``.eqv``
+ - Element-wise logical
+
+ * - 55
+ - ``==`` ``/=`` ``<`` ``<=`` ``>`` ``>=``
+ - Matrix comparison
+
+ * - 49–45
+ - ``not`` ``and`` ``or`` ``xor`` ``eqv``
+ - Matrix logical
+
+ * - 10
+ - ``=`` (assignment)
+ - Assignment
+
+Key takeaways:
+
+- **Power before multiply before add** — same as standard math.
+- **Dot-comparisons bind more tightly than non-dot** — ``.==`` (65) is
+ evaluated before ``==`` (55).
+- **Concatenation sits between arithmetic and comparisons** — so
+ ``a + b ~ c + d`` means ``(a + b) ~ (c + d)``.
+- When in doubt, **use parentheses** to make evaluation order explicit.
+
+Example: Precedence in practice
++++++++++++++++++++++++++++++++++
+
+::
+
+ // This expression:
+ print -5 + 3/4 + 6*3;
+
+ // Is evaluated as:
+ print (-5) + (3/4) + (6*3);
+
+Both print:
+
+::
+
+ 13.750000
+
+
+Quick Reference
+--------------------------------------------
+
+.. list-table::
+ :widths: 25 25 50
+ :header-rows: 1
+
+ * - Category
+ - Matrix form
+ - Element-wise form
+
+ * - Multiply
+ - ``*``
+ - ``.*``
+
+ * - Divide
+ - ``/``
+ - ``./``
+
+ * - Power
+ - ``^`` or ``.^`` (both element-wise)
+ -
+
+ * - Equal
+ - ``==`` (scalar result)
+ - ``.==`` (matrix result)
+
+ * - Not equal
+ - ``/=``
+ - ``./=``
+
+ * - Less than
+ - ``<``
+ - ``.<``
+
+ * - AND
+ - ``and``
+ - ``.and``
+
+ * - OR
+ - ``or``
+ - ``.or``
+
+ * - NOT
+ - ``not``
+ - ``.not``
+
+
+.. seealso:: :doc:`/cc/operators`, :ref:`control-flow`, :doc:`/user-guide/fundamentals/procedures`, :func:`inv`, :func:`selif`
diff --git a/docs/user-guide/fundamentals/procedures.rst b/docs/user-guide/fundamentals/procedures.rst
new file mode 100644
index 00000000..79dfa78e
--- /dev/null
+++ b/docs/user-guide/fundamentals/procedures.rst
@@ -0,0 +1,804 @@
+
+Procedures and Keywords
+===============================================
+
+As your GAUSS programs grow, you will find yourself repeating the same
+calculations — standardizing columns, computing test statistics, or
+formatting output. Procedures let you package a computation into a
+reusable, self-contained unit that you write once and call wherever you
+need it. They keep programs organized, make code easier to test, and let
+you build on your own (and others') previous work.
+
+::
+
+ // Define a procedure that standardizes a column vector
+ proc (1) = standardize(x);
+ local mu, sd;
+
+ mu = meanc(x);
+ sd = stdc(x);
+
+ retp((x - mu) ./ sd);
+ endp;
+
+ // Use it like a built-in function
+ income = loadd(getGAUSSHome("examples/credit.dat"), "Income");
+ income_std = standardize(income);
+
+ head(income_std);
+
+This page covers everything you need to write, call, and compose
+procedures in GAUSS, including the function pointer pattern used
+throughout the GAUSS runtime library and the related ``keyword``
+construct.
+
+
+Defining Procedures
+-----------------------------------------
+
+A procedure definition has four parts:
+
+1. **Declaration** -- the ``proc`` statement that names the procedure,
+ its return count, and its parameters.
+2. **Local variables** -- optional ``local`` statements that create
+ variables visible only inside the procedure.
+3. **Body** -- any GAUSS statements needed to do the work.
+4. **Return** -- the :func:`retp` statement that sends results back to
+ the caller, followed by ``endp`` to close the definition.
+
+The simplest possible procedure
++++++++++++++++++++++++++++++++++
+
+::
+
+ proc (1) = square(a);
+ retp(a .* a);
+ endp;
+
+ // Call it
+ print square(5);
+
+::
+
+ 25.000000
+
+The ``(1)`` after ``proc`` tells GAUSS this procedure returns one value.
+The name follows the ``=`` sign, and the parameter list is in
+parentheses.
+
+The proc statement
++++++++++++++++++++++++++++++++++
+
+The general form is:
+
+::
+
+ proc (rets) = name(arg1, arg2, ..., argN);
+
+- **rets** -- number of values returned (0 to 1023). Default is 1.
+ Use ``(0)`` for side-effect-only procedures.
+- **name** -- up to 32 characters, starting with a letter or underscore.
+- **arg1 ... argN** -- parameter names, local to this procedure. Up to
+ 1023 parameters are allowed.
+
+.. note::
+
+ Procedure definitions cannot be nested. You cannot define a ``proc``
+ inside another ``proc``.
+
+
+Local Variables
+-----------------------------------------
+
+The ``local`` statement declares variables that exist only while the
+procedure is executing. Once the procedure returns, its locals disappear.
+
+::
+
+ proc (1) = hypotenuse(a, b);
+ local c;
+
+ c = sqrt(a^2 + b^2);
+
+ retp(c);
+ endp;
+
+ print hypotenuse(3, 4);
+
+::
+
+ 5.0000000
+
+Why local variables matter
++++++++++++++++++++++++++++++++++
+
+Without ``local``, any variable you assign inside a procedure becomes
+a **global** variable, visible everywhere. This leads to subtle bugs
+when two procedures accidentally share the same variable name. Always
+declare intermediates as ``local``:
+
+::
+
+ proc (1) = ols_beta(x, y);
+ local xpx_inv, b;
+
+ xpx_inv = invpd(x'x);
+ b = xpx_inv * (x'y);
+
+ retp(b);
+ endp;
+
+.. warning::
+
+ ``local`` can only be used inside a procedure. It is not valid at
+ global scope.
+
+Key rules for locals
++++++++++++++++++++++++++++++++++
+
+- The ``local`` statement does **not** initialize variables. You must
+ assign a value before reading them, or GAUSS will raise a
+ ``Variable not initialized`` error.
+- Parameters listed in the ``proc`` statement are automatically local.
+ You do not need to redeclare them.
+- Local variables are dynamically sized. They can change dimensions
+ during execution.
+- You can have multiple ``local`` statements in the same procedure.
+
+
+Returning Values
+-----------------------------------------
+
+The :func:`retp` statement sends results back to the caller. The number
+of values in the :func:`retp` must match the return count declared in
+the ``proc`` statement.
+
+Single return
++++++++++++++++++++++++++++++++++
+
+::
+
+ proc (1) = cube(x);
+ retp(x .* x .* x);
+ endp;
+
+ y = cube(3);
+ print y;
+
+::
+
+ 27.000000
+
+Multiple returns
++++++++++++++++++++++++++++++++++
+
+Procedures can return up to 1023 values. Declare the count in
+``proc (N)`` and return all values in a single :func:`retp`:
+
+::
+
+ proc (3) = summary_stats(x);
+ local mu, sd, n;
+
+ mu = meanc(x);
+ sd = stdc(x);
+ n = rows(x);
+
+ retp(mu, sd, n);
+ endp;
+
+ // Capture all three returns with braces
+ { mu, sd, n } = summary_stats(rndn(100, 1));
+
+ print "Mean:" mu;
+ print "Std Dev:" sd;
+ print "N:" n;
+
+The caller uses curly braces ``{ ... }`` to capture multiple returns.
+
+.. tip::
+
+ The return values of one procedure can be passed directly as
+ arguments to another procedure. For example, if ``procA`` returns
+ two values and ``procB`` takes two arguments:
+
+ ::
+
+ y = procB(procA(x));
+
+No return value
++++++++++++++++++++++++++++++++++
+
+If the procedure performs only side effects (printing, writing files),
+declare ``(0)`` returns. The ``endp`` statement generates an implicit
+:func:`retp` with no arguments, so you can omit the :func:`retp`
+entirely:
+
+::
+
+ proc (0) = print_header(title);
+ print "============================";
+ print title;
+ print "============================";
+ endp;
+
+ print_header("Regression Results");
+
+Multiple retp statements
++++++++++++++++++++++++++++++++++
+
+A procedure can have more than one :func:`retp`, for example inside
+conditional branches. Every :func:`retp` must return the same number
+of items declared in the ``proc`` statement:
+
+::
+
+ proc (1) = safe_log(x);
+ if x <= 0;
+ retp(miss());
+ endif;
+
+ retp(ln(x));
+ endp;
+
+
+Calling Procedures
+-----------------------------------------
+
+Procedures are called exactly like built-in functions:
+
+::
+
+ // No return -- side-effect only
+ print_header("My Report");
+
+ // One return
+ y = square(5);
+
+ // Multiple returns
+ { mu, sd, n } = summary_stats(x);
+
+Arguments can be expressions of any complexity, including calls to
+other procedures:
+
+::
+
+ y = cube(square(2) + 1); // cube(4 + 1) = 125
+
+The call statement
++++++++++++++++++++++++++++++++++
+
+If a procedure returns values but you want to discard them, use
+``call``:
+
+::
+
+ // Run a regression but discard the output structure
+ call olsmt(getGAUSSHome("examples/credit.dat"), "Limit ~ Income + Rating");
+
+This works for any procedure, including those that return multiple
+values.
+
+
+Optional Arguments
+-----------------------------------------
+
+GAUSS supports optional arguments through the ``...`` (ellipsis) syntax
+and the :func:`dynargsGet` function. This is the standard pattern for
+writing procedures that accept both required and optional inputs with
+sensible defaults.
+
+Basic pattern
++++++++++++++++++++++++++++++++++
+
+Add ``...`` as the last parameter. Inside the procedure, call
+:func:`dynargsGet` with an index range and default values:
+
+::
+
+ proc (1) = compute_area(length, ...);
+ local width;
+
+ // If a second argument was passed, use it.
+ // Otherwise, default to 'length' (a square).
+ width = dynargsGet(1, length);
+
+ retp(length * width);
+ endp;
+
+ print compute_area(5); // Square: 25
+ print compute_area(5, 3); // Rectangle: 15
+
+::
+
+ 25.000000
+ 15.000000
+
+Multiple optional arguments
++++++++++++++++++++++++++++++++++
+
+Use a 2x1 index vector in :func:`dynargsGet` to request a range of
+optional arguments. The expression ``1|2`` creates a 2x1 column vector
+``{ 1, 2 }`` using the vertical concatenation operator ``|``. Provide
+one default for each:
+
+::
+
+ proc (1) = weighted_mean(x, ...);
+ local w, trim_pct;
+
+ // Dynamic arguments 1 and 2, with defaults
+ { w, trim_pct } = dynargsGet(1|2, ones(rows(x), 1), 0);
+
+ if trim_pct > 0;
+ // Trim extreme values
+ local lo, hi, mask;
+ lo = quantile(x, trim_pct / 2);
+ hi = quantile(x, 1 - trim_pct / 2);
+ mask = (x .>= lo) .and (x .<= hi);
+ x = selif(x, mask);
+ w = selif(w, mask);
+ endif;
+
+ retp(sumc(w .* x) / sumc(w));
+ endp;
+
+ data = rndn(100, 1);
+
+ // Use all defaults
+ m1 = weighted_mean(data);
+
+ // Custom weights, default trim
+ m2 = weighted_mean(data, ones(100, 1) * 2);
+
+ // Custom weights and 10% trim
+ m3 = weighted_mean(data, ones(100, 1), 0.10);
+
+Real-world example from the GAUSS runtime library
+++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+The built-in :func:`lag` function uses this pattern:
+
+::
+
+ proc lag(x, ...);
+ local n_lags, fill;
+
+ { n_lags, fill } = dynargsGet(1|2, 1, miss());
+
+ retp(shiftc(x, n_lags, fill));
+ endp;
+
+This lets users call ``lag(x)`` (lag by 1, fill with missing),
+``lag(x, 3)`` (lag by 3, fill with missing), or
+``lag(x, 3, 0)`` (lag by 3, fill with zero).
+
+Checking the argument count
++++++++++++++++++++++++++++++++++
+
+Use :func:`dynargsCount` when you need to branch based on how many
+optional arguments were provided, rather than using defaults:
+
+::
+
+ proc (1) = flexible_stat(x, ...);
+ local n_args;
+
+ n_args = dynargsCount();
+
+ if n_args == 1;
+ // One optional arg: interpret as quantile level
+ local q;
+ q = dynargsGet(1);
+ retp(quantile(x, q));
+ endif;
+
+ // Default: return the mean
+ retp(meanc(x));
+ endp;
+
+
+Function Pointers
+-----------------------------------------
+
+GAUSS lets you pass procedures as arguments to other procedures. This
+is essential for optimization, numerical integration, and any routine
+that needs to call a user-supplied function.
+
+The pattern has three steps:
+
+1. Prefix the procedure name with ``&`` when passing it.
+2. Inside the receiving procedure, declare the local variable first
+ as a plain local (to receive the pointer), then redeclare it with
+ ``:proc`` (to call it as a procedure).
+3. Call the local as if it were a regular procedure.
+
+Basic example
++++++++++++++++++++++++++++++++++
+
+::
+
+ // A procedure that applies any function to data, then sums
+ proc (1) = apply_and_sum(&f, x);
+ local f:proc;
+
+ retp(sumc(f(x)));
+ endp;
+
+ // Wrap a built-in function so it can be passed with &
+ proc (1) = mySqrt(x);
+ retp(sqrt(x));
+ endp;
+
+ x = { 4, 9, 16, 25 };
+ result = apply_and_sum(&mySqrt, x);
+ print result;
+
+::
+
+ 14.000000
+
+.. warning::
+
+ The ``&`` operator only works with **user-defined GAUSS procedures**.
+ It does not work with built-in C-level functions such as ``sqrt``,
+ ``ln``, or ``abs``. To pass a built-in, wrap it in a one-line
+ procedure as shown in the ``mySqrt`` example above.
+
+.. note::
+
+ **Why** ``local f:proc;`` **is needed:** GAUSS compiles code before
+ running it. When the compiler sees ``f(x)`` inside the procedure, it
+ needs to know that ``f`` is a callable procedure, not a matrix. The
+ ``:proc`` declaration provides that information.
+
+ When a procedure receives a function pointer through its ``&``
+ parameter, you only need ``local f:proc;``. The two-step pattern
+ is needed when loading a pointer from a variable or array at runtime:
+
+ ::
+
+ // Case 1: & parameter -- just declare :proc
+ proc (1) = my_func(&f, x);
+ local f:proc;
+ retp(f(x));
+ endp;
+
+ // Case 2: pointer from a variable or array
+ proc (1) = dispatch(func_array, i, x);
+ local f;
+ f = func_array[i];
+ local f:proc;
+ retp(f(x));
+ endp;
+
+Passing user-defined procedures
++++++++++++++++++++++++++++++++++
+
+You can pass any procedure, not just built-ins:
+
+::
+
+ proc (1) = myMax(x, y);
+ if x > y;
+ retp(x);
+ else;
+ retp(y);
+ endif;
+ endp;
+
+ proc (1) = myMin(x, y);
+ if x < y;
+ retp(x);
+ else;
+ retp(y);
+ endif;
+ endp;
+
+ // A procedure that takes a comparison function
+ proc (1) = reduce(&op, x);
+ local op:proc;
+
+ local result, i;
+ result = x[1];
+
+ for i(2, rows(x), 1);
+ result = op(result, x[i]);
+ endfor;
+
+ retp(result);
+ endp;
+
+ data = { 3, 7, 2, 9, 1 };
+
+ print "Max:" reduce(&myMax, data);
+ print "Min:" reduce(&myMin, data);
+
+::
+
+ Max: 9.0000000
+ Min: 1.0000000
+
+Indexing into a vector of function pointers
+++++++++++++++++++++++++++++++++++++++++++++++
+
+You can store multiple function pointers in a vector and select one
+at runtime:
+
+::
+
+ // Define a few simple functions
+ proc (1) = double(x); retp(2 * x); endp;
+ proc (1) = triple(x); retp(3 * x); endp;
+ proc (1) = negate(x); retp(-x); endp;
+
+ // Store pointers in a row vector with ~
+ procVec = &double ~ &triple ~ &negate;
+
+ proc (1) = dispatch(x, i);
+ local f;
+ f = procVec[i];
+ local f:proc;
+
+ retp(f(x));
+ endp;
+
+ print dispatch(5, 1); // 10 (double)
+ print dispatch(5, 2); // 15 (triple)
+ print dispatch(5, 3); // -5 (negate)
+
+The double ``local`` pattern -- first as a matrix to do the indexing,
+then as ``:proc`` to make it callable -- is the key to this technique.
+
+
+Keywords
+-----------------------------------------
+
+A **keyword** is a special type of subroutine that takes exactly one
+string argument and returns nothing. Keywords are defined with the
+``keyword`` statement instead of ``proc``.
+
+::
+
+ keyword show_file(s);
+ local fname;
+
+ if s $== "";
+ print "Usage: show_file ";
+ retp;
+ endif;
+
+ fname = strtriml(strtrimr(s));
+ print "Showing: " fname;
+
+ // Load and preview the file
+ print head(loadd(fname));
+ endp;
+
+Calling a keyword
++++++++++++++++++++++++++++++++++
+
+Keywords are called without parentheses. Everything after the keyword
+name up to the semicolon is passed as one string:
+
+::
+
+ show_file mydata.csv;
+
+If called with nothing, the argument is a null string:
+
+::
+
+ show_file;
+
+Keywords vs. procedures
++++++++++++++++++++++++++++++++++
+
+.. list-table::
+ :widths: 30 35 35
+ :header-rows: 1
+
+ * - Feature
+ - ``proc``
+ - ``keyword``
+
+ * - Arguments
+ - 0 to 1023, typed
+ - Exactly 1, always a string
+
+ * - Return values
+ - 0 to 1023
+ - None
+
+ * - Call syntax
+ - ``name(arg1, arg2)``
+ - ``name text here;``
+
+ * - Typical use
+ - Computation, transformations
+ - Interactive commands, utilities
+
+.. note::
+
+ Keywords are uncommon in modern GAUSS code. For most new work,
+ procedures with ``...`` optional arguments are more flexible.
+
+
+Practical Examples
+-----------------------------------------
+
+Example 1: Descriptive statistics procedure
++++++++++++++++++++++++++++++++++++++++++++++
+
+A complete procedure that computes descriptive statistics for a
+dataframe column:
+
+::
+
+ proc (1) = describe(x);
+ local n, mu, sd, lo, hi;
+
+ n = rows(x);
+ mu = meanc(x);
+ sd = stdc(x);
+ lo = minc(x);
+ hi = maxc(x);
+
+ print " N: " n;
+ print " Mean: " mu;
+ print " Std: " sd;
+ print " Min: " lo;
+ print " Max: " hi;
+
+ retp(mu);
+ endp;
+
+ // Use with real data
+ df = loadd(getGAUSSHome("examples/credit.dat"), "Income");
+ mu = describe(df);
+
+Example 2: Procedure with optional arguments
++++++++++++++++++++++++++++++++++++++++++++++
+
+A moving average function with configurable window size:
+
+::
+
+ proc (1) = moving_avg(x, ...);
+ local window;
+
+ window = dynargsGet(1, 5); // Default window = 5
+
+ local n, result, i, start_idx;
+ n = rows(x);
+ result = zeros(n, 1);
+
+ for i(1, n, 1);
+ start_idx = maxc(1 | (i - window + 1));
+ result[i] = meanc(x[start_idx:i]);
+ endfor;
+
+ retp(result);
+ endp;
+
+ // Use defaults
+ data = rndn(20, 1);
+ ma5 = moving_avg(data);
+
+ // Custom 10-period window
+ ma10 = moving_avg(data, 10);
+
+Example 3: Function pointers with optional arguments
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+A procedure that applies a user-supplied function element-by-element,
+with an optional scaling factor:
+
+::
+
+ proc (1) = apply_scaled(&f, x, ...);
+ local f:proc;
+
+ local scale;
+ scale = dynargsGet(1, 1); // Default scale = 1
+
+ retp(scale * f(x));
+ endp;
+
+ // Wrappers for built-in functions (& requires user-defined procs)
+ proc (1) = mySqrt(x); retp(sqrt(x)); endp;
+ proc (1) = myLn(x); retp(ln(x)); endp;
+
+ x = { 1, 4, 9, 16 };
+
+ result = apply_scaled(&mySqrt, x);
+ print "sqrt:" result';
+
+ result = apply_scaled(&myLn, x, 100);
+ print "100*ln:" result';
+
+Example 4: Multiple returns with real data
++++++++++++++++++++++++++++++++++++++++++++++
+
+This example uses the :class:`olsmtOut` structure returned by
+:func:`olsmt`. For details on structures, see
+:doc:`/user-guide/advanced/structures`.
+
+::
+
+ proc (2) = regression_summary(fname, formula);
+ struct olsmtOut result;
+ result = olsmt(fname, formula);
+
+ retp(result.b, result.stderr);
+ endp;
+
+ fname = getGAUSSHome("examples/credit.dat");
+
+ { b, se } = regression_summary(fname, "Limit ~ Income + Rating");
+
+ print "Coefficients:";
+ print b;
+ print "Standard errors:";
+ print se;
+
+
+Rules and Tips
+-----------------------------------------
+
+- **Always declare locals.** Without ``local``, any variable you assign
+ inside a procedure becomes global and can collide with variables in
+ other procedures or at the top level.
+
+- **local is only valid inside proc/keyword.** You cannot use ``local``
+ at global scope. It will produce a compile error.
+
+- **Parameter names are local by default.** The names in the ``proc``
+ argument list do not need to be redeclared with ``local``.
+
+- **The return count must match.** If ``proc (2)`` is declared, every
+ :func:`retp` must provide exactly 2 values.
+
+- **Procedures are recursive.** A procedure can call itself, but make
+ sure there is a base case to prevent infinite recursion.
+
+- **Naming conventions.** GAUSS procedure names are case-insensitive.
+ ``MyProc`` and ``myproc`` refer to the same procedure. Use descriptive
+ names: ``compute_returns`` is clearer than ``cr``.
+
+- **Procedure definitions cannot be nested.** You cannot define a
+ ``proc`` inside another ``proc``.
+
+- **Use dynargsGet for optional arguments.** Rather than checking
+ argument counts manually, use :func:`dynargsGet` with defaults. This
+ is the standard pattern in the GAUSS runtime library.
+
+- **Use call to discard returns.** If you call a procedure for its
+ side effects and want to ignore the return value, prefix the call
+ with ``call``.
+
+- **Function pointer order.** When using the ``local fn; fn = &proc;
+ local fn:proc;`` pattern, the assignment must come **before** the
+ ``:proc`` declaration.
+
+.. tip::
+
+ If you are writing a procedure that might be used inside a formula
+ string (for example, as a data transformation in :func:`olsmt`),
+ it must accept a single column vector and return a column vector
+ of the same length. If GAUSS reports ``Undefined proc``, add
+ ``external proc myProc;`` before the formula string call so the
+ compiler includes it.
+
+
+What's Next
+-----------------------------------------
+
+- Learn how to organize procedures into reusable library files
+ with ``#include``.
+- Explore :func:`olsmt`, :func:`glm`, and other estimation functions
+ that accept formula strings referencing user-defined procedures.
+- Use :func:`dynargsGet` and :func:`dynargsCount` to write flexible
+ interfaces.
+
+.. seealso:: Functions :func:`retp`, :func:`dynargsGet`, :func:`dynargsCount`, :func:`dynargsTypes`, :func:`local`, :func:`call`, :func:`olsmt`, :func:`loadd`, :func:`head`
diff --git a/docs/user-guide/fundamentals/strings.rst b/docs/user-guide/fundamentals/strings.rst
new file mode 100644
index 00000000..4215dd45
--- /dev/null
+++ b/docs/user-guide/fundamentals/strings.rst
@@ -0,0 +1,559 @@
+.. _strings:
+
+Strings and String Arrays
+===============================================
+
+GAUSS has two text data types: **strings** and **string arrays**. A
+string holds a single text value of any length. A string array is an
+NxK matrix of strings — each element is a separate string.
+
+This page covers creating strings, string operators, string arrays,
+common string functions, and converting between strings and numbers.
+
+.. note::
+
+ If you are coming from Python, a GAUSS string is like a Python
+ ``str``. A GAUSS string array is like a NumPy array of strings
+ (``np.array(["a", "b", "c"])``).
+ If you are coming from R, a GAUSS string array is like a character
+ vector (``c("a", "b", "c")``).
+
+
+Creating Strings
+--------------------------------------------
+
+Strings are created with double quotes:
+
+::
+
+ s = "Hello World";
+ print s;
+
+This prints:
+
+::
+
+ Hello World
+
+Strings can contain any characters, including newlines and special
+characters inserted with **escape sequences**:
+
+.. list-table::
+ :widths: 15 45 40
+ :header-rows: 1
+
+ * - Escape
+ - Character
+ - ASCII code
+
+ * - ``\n``
+ - Newline
+ - 10
+
+ * - ``\t``
+ - Tab
+ - 9
+
+ * - ``\r``
+ - Carriage return
+ - 13
+
+ * - ``\"``
+ - Double quote
+ - 34
+
+ * - ``\\``
+ - Literal backslash
+ - 92
+
+Example: Escape sequences
++++++++++++++++++++++++++++++++++
+
+::
+
+ s = "Line 1\nLine 2";
+ print s;
+
+ t = "col1\tcol2\tcol3";
+ print t;
+
+ p = "C:\\gauss\\data";
+ print p;
+
+This prints:
+
+::
+
+ Line 1
+ Line 2
+ col1 col2 col3
+ C:\gauss\data
+
+.. tip::
+
+ On macOS and Linux, forward slashes work in file paths, so escape
+ sequences are rarely needed: ``"/home/user/data"``.
+
+
+String Operators
+--------------------------------------------
+
+.. list-table::
+ :widths: 10 25 65
+ :header-rows: 1
+
+ * - Operator
+ - Name
+ - Description
+
+ * - ``$+``
+ - String concatenation
+ - Joins strings end-to-end. Works element-wise on string arrays.
+
+ * - ``$~``
+ - Horizontal string array concatenation
+ - Creates or extends a string array (side by side)
+
+ * - ``$|``
+ - Vertical string array concatenation
+ - Creates or extends a string array (stacked)
+
+ * - ``$==``
+ - String equality
+ - Returns 1 if strings match, 0 otherwise
+
+ * - ``$/=``
+ - String inequality
+ - Returns 1 if strings differ, 0 otherwise
+
+ * - ``$<`` ``$>`` ``$<=`` ``$>=``
+ - String ordering
+ - Lexicographic (alphabetical) comparison
+
+The key distinction: ``$+`` produces a **single string** (text glued
+together); ``$~`` and ``$|`` produce a **string array** (a collection
+of separate strings). All string comparison operators (``$==``, ``$<``,
+etc.) are **case-sensitive**.
+
+Example: $+ vs. $~
++++++++++++++++++++++++++++++++++
+
+::
+
+ x = "age";
+ y = "pay";
+ z = "sex";
+
+ // $+ joins into one string
+ s = x $+ y $+ z;
+ print s;
+ print strlen(s);
+
+ // $~ creates a 1x3 string array
+ sa = x $~ y $~ z;
+ print sa;
+ print rows(sa) cols(sa);
+
+This prints:
+
+::
+
+ agepaysex
+ 9.0000000
+
+ age pay sex
+ 1.0000000 3.0000000
+
+With ``$+``, the three words are glued into one 9-character string.
+With ``$~``, they become three separate elements in a 1x3 string array.
+
+Example: String comparison
++++++++++++++++++++++++++++++++++
+
+::
+
+ print "abc" $== "abc";
+ print "abc" $== "xyz";
+ print "abc" $/= "xyz";
+
+This prints:
+
+::
+
+ 1.0000000
+ 0.0000000
+ 1.0000000
+
+
+String Arrays
+--------------------------------------------
+
+A string array is an NxK matrix where each element is a string. String
+arrays are the standard way to work with collections of text in GAUSS —
+column names, variable labels, file lists, categorical values, and more.
+
+Creating string arrays
++++++++++++++++++++++++++++++++++
+
+Use ``$~`` (horizontal) and ``$|`` (vertical) to build string arrays:
+
+::
+
+ // 1x3 row: horizontal concatenation
+ row = "alpha" $~ "beta" $~ "gamma";
+ print row;
+
+ // 3x1 column: vertical concatenation
+ col = "one" $| "two" $| "three";
+ print col;
+
+This prints:
+
+::
+
+ alpha beta gamma
+
+ one
+ two
+ three
+
+Build a 2D string array by combining both operators:
+
+::
+
+ m = ("a" $~ "b" $~ "c") $| ("x" $~ "y" $~ "z");
+ print m;
+
+This prints:
+
+::
+
+ a b c
+ x y z
+
+Indexing string arrays
++++++++++++++++++++++++++++++++++
+
+String arrays use the same indexing syntax as numeric matrices
+(see :ref:`operators`):
+
+::
+
+ sa = "alpha" $~ "beta" $~ "gamma";
+ print sa[1, 2]; // "beta"
+
+ sv = "one" $| "two" $| "three";
+ print sv[2]; // "two"
+
+ m = ("a" $~ "b" $~ "c") $| ("x" $~ "y" $~ "z");
+ print m[2, 3]; // "z"
+
+This prints:
+
+::
+
+ beta
+ two
+ z
+
+
+Common String Functions
+--------------------------------------------
+
+GAUSS provides many functions for working with strings. Here are the
+most commonly used ones, grouped by task.
+
+.. list-table::
+ :widths: 25 75
+ :header-rows: 1
+
+ * - Function
+ - Description
+
+ * - :func:`strlen`
+ - Returns the length (number of characters) of a string
+
+ * - :func:`strsect`
+ - Extracts a substring: ``strsect(s, start, len)``
+
+ * - :func:`strindx`
+ - Finds the position of a substring: ``strindx(s, target, start)``
+
+ * - :func:`strreplace`
+ - Replaces all occurrences of a substring
+
+ * - :func:`strsplit`
+ - Splits a string into a string array by delimiter
+
+ * - :func:`strjoin`
+ - Joins a string array into a single string with a separator
+
+ * - :func:`upper`
+ - Converts to uppercase
+
+ * - :func:`lower`
+ - Converts to lowercase
+
+ * - :func:`strtrim`
+ - Removes leading and trailing whitespace
+
+ * - :func:`contains`
+ - Tests whether a string array contains a value (returns 1 or 0)
+
+ * - :func:`sprintf`
+ - Formats values into a string: ``sprintf("x = %6.3f", 3.14)``
+
+.. note::
+
+ String positions are 1-based: the first character is at position 1,
+ not 0.
+
+Example: Extracting and searching
+++++++++++++++++++++++++++++++++++++
+
+::
+
+ s = "Hello World";
+
+ // Extract substring: start at position 1, length 5
+ print strsect(s, 1, 5);
+
+ // Extract substring: start at position 7, length 5
+ print strsect(s, 7, 5);
+
+ // Find position of "World" starting from position 1
+ print strindx(s, "World", 1);
+
+This prints:
+
+::
+
+ Hello
+ World
+ 7.0000000
+
+Example: Replacing and splitting
+++++++++++++++++++++++++++++++++++++
+
+::
+
+ s = "Hello World";
+ print strreplace(s, "World", "GAUSS");
+
+ // Split a delimited string into a string array
+ parts = strsplit("one,two,three", ",");
+ print parts;
+
+ // Join a string array back into one string
+ print strjoin(parts, " - ");
+
+This prints:
+
+::
+
+ Hello GAUSS
+ one two three
+ one - two - three
+
+Example: Case conversion
++++++++++++++++++++++++++++++++++
+
+::
+
+ s = "Hello World";
+ print upper(s);
+ print lower(s);
+
+This prints:
+
+::
+
+ HELLO WORLD
+ hello world
+
+
+Converting Between Strings and Numbers
+--------------------------------------------
+
+GAUSS provides functions to convert between numeric values and their
+string representations.
+
+.. list-table::
+ :widths: 25 75
+ :header-rows: 1
+
+ * - Function
+ - Description
+
+ * - :func:`ntos`
+ - Number to string: ``ntos(x)`` or ``ntos(x, prec)`` where *prec*
+ is the number of significant digits (default 6)
+
+ * - :func:`strtof`
+ - String or string array to numeric value(s)
+
+ * - :func:`stof`
+ - Single string to number
+
+ * - :func:`ftocv`
+ - Matrix to character vector (legacy, for formatted display)
+
+ * - :func:`ftostrC`
+ - Matrix to string array using C format specifiers
+
+Example: Numeric to string
++++++++++++++++++++++++++++++++++
+
+::
+
+ x = 3.14159;
+
+ // Default: 6 significant digits
+ print ntos(x);
+
+ // Specify number of significant digits
+ print ntos(x, 2);
+
+This prints:
+
+::
+
+ 3.14159
+ 3.1
+
+Example: String to numeric
++++++++++++++++++++++++++++++++++
+
+::
+
+ // String array to numeric matrix
+ sa = "1.5" $| "2.7" $| "3.9";
+ y = strtof(sa);
+ print y;
+
+This prints:
+
+::
+
+ 1.5000000
+ 2.7000000
+ 3.9000000
+
+
+Data Types: String vs. String Array vs. Character Matrix
+-------------------------------------------------------------
+
+GAUSS has three text-related types. Understanding the differences helps
+you choose the right one:
+
+.. list-table::
+ :widths: 20 20 60
+ :header-rows: 1
+
+ * - Type
+ - ``type()``
+ - Description
+
+ * - Matrix
+ - 6
+ - An NxK numeric matrix (scalars, vectors, and matrices).
+
+ * - String
+ - 13
+ - A single text value of any length.
+
+ * - String array
+ - 15
+ - An NxK matrix of strings. Each element can be any length.
+
+ * - Character matrix
+ - 6
+ - A numeric matrix where each element stores up to 8 characters.
+ Reports the same ``type()`` value as a regular matrix.
+ Legacy type — prefer string arrays for new code.
+
+.. warning::
+
+ **Character matrices** are a legacy feature. Each element is stored
+ in 8 bytes (the size of a double-precision number), so each element
+ is limited to 8 characters. String arrays have no such limit and
+ should be used for all new code.
+
+You can check a variable's type with the :func:`type` function:
+
+::
+
+ x = 42;
+ s = "hello";
+ sa = "a" $~ "b";
+
+ print "matrix type:" type(x);
+ print "string type:" type(s);
+ print "string array type:" type(sa);
+
+This prints:
+
+::
+
+ matrix type: 6.0000000
+ string type: 13.000000
+ string array type: 15.000000
+
+
+Quick Reference
+--------------------------------------------
+
+.. list-table::
+ :widths: 30 70
+ :header-rows: 1
+
+ * - Task
+ - How
+
+ * - Create a string
+ - ``s = "text";``
+
+ * - Concatenate strings
+ - ``s = a $+ b;``
+
+ * - Build a string array (row)
+ - ``sa = "a" $~ "b" $~ "c";``
+
+ * - Build a string array (column)
+ - ``sa = "a" $| "b" $| "c";``
+
+ * - Index a string array
+ - ``sa[2, 3]`` or ``sv[i]``
+
+ * - String length
+ - :func:`strlen`
+
+ * - Substring extraction
+ - :func:`strsect`
+
+ * - Find substring
+ - :func:`strindx`
+
+ * - Replace substring
+ - :func:`strreplace`
+
+ * - Split by delimiter
+ - :func:`strsplit`
+
+ * - Join with separator
+ - :func:`strjoin`
+
+ * - Number to string
+ - :func:`ntos`
+
+ * - String to number
+ - :func:`strtof`
+
+ * - Compare strings
+ - ``$==``, ``$/=``, ``$<``, ``$>``, ``$<=``, ``$>=``
+
+ * - Format a string
+ - :func:`sprintf`
+
+
+.. seealso:: :ref:`operators`, :ref:`control-flow`, :doc:`/user-guide/formula-strings`, :func:`strcombine`, :func:`strtrim`
diff --git a/docs/user-guide/index.rst b/docs/user-guide/index.rst
new file mode 100644
index 00000000..574175e2
--- /dev/null
+++ b/docs/user-guide/index.rst
@@ -0,0 +1,38 @@
+
+User Guide
+===============
+
+Learn the GAUSS programming language — from core syntax to advanced features.
+
+Fundamentals
+-----------------------------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ fundamentals/operators
+ fundamentals/strings
+ fundamentals/control-flow
+ formula-strings
+ fundamentals/procedures
+
+Data Management
+-----------------------------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ /data-management
+
+Advanced
+-----------------------------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ advanced/time-and-date
+ advanced/random-numbers
+ advanced/arrays
+ advanced/structures
+ advanced/compilation-libraries
+ advanced/performance
diff --git a/docs/util/GAUSSDomain.py b/docs/util/GAUSSDomain.py
index 08e7b5a3..0ad6c72c 100644
--- a/docs/util/GAUSSDomain.py
+++ b/docs/util/GAUSSDomain.py
@@ -12,13 +12,10 @@
from docutils import nodes
from docutils.parsers.rst import directives
-from six import iteritems
from GAUSSHTMLTranslator import desc_returnlist, desc_return
from sphinx import addnodes, locale
from sphinx.addnodes import desc_signature
-from sphinx.domains.python import pairindextypes
-#from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning
from sphinx.directives import ObjectDescription
from sphinx.domains import Domain, ObjType, Index
from sphinx.locale import _, __
@@ -51,22 +48,15 @@
''', re.VERBOSE)
-#pairindextypes = {
-# 'module': _('module'),
-# 'keyword': _('keyword'),
-# 'operator': _('operator'),
-# 'object': _('object'),
-# 'exception': _('exception'),
-# 'statement': _('statement'),
-# 'builtin': _('built-in function'),
-#} # Dict[unicode, unicode]
-#
-#locale.pairindextypes = DeprecatedDict(
-# pairindextypes,
-# 'sphinx.locale.pairindextypes is deprecated. '
-# 'Please use sphinx.domains.python.pairindextypes instead.',
-# RemovedInSphinx30Warning
-#)
+pairindextypes = {
+ 'module': _('module'),
+ 'keyword': _('keyword'),
+ 'operator': _('operator'),
+ 'object': _('object'),
+ 'exception': _('exception'),
+ 'statement': _('statement'),
+ 'builtin': _('built-in function'),
+}
def _pseudo_parse_generic(signode, arglist, desc_listtype, desc_type):
@@ -135,6 +125,7 @@ def make_xref(self,
innernode=nodes.emphasis, # type: nodes.Node
contnode=None, # type: nodes.Node
env=None, # type: BuildEnvironment
+ **kwargs,
):
# type: (...) -> nodes.Node
result = super(PyXrefMixin, self).make_xref(rolename, domain, target, # type: ignore
@@ -158,6 +149,8 @@ def make_xrefs(self,
innernode=nodes.emphasis, # type: nodes.Node
contnode=None, # type: nodes.Node
env=None, # type: BuildEnvironment
+ inliner=None,
+ location=None,
):
# type: (...) -> List[nodes.Node]
delims = r'(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+)'
@@ -182,7 +175,7 @@ def make_xrefs(self,
class PyField(PyXrefMixin, Field):
def make_xref(self, rolename, domain, target,
- innernode=nodes.emphasis, contnode=None, env=None):
+ innernode=nodes.emphasis, contnode=None, env=None, **kwargs):
# type: (unicode, unicode, unicode, nodes.Node, nodes.Node, BuildEnvironment) -> nodes.Node # NOQA
if rolename == 'class' and target == 'None':
# None is not a type, so use obj role instead.
@@ -198,7 +191,7 @@ class PyGroupedField(PyXrefMixin, GroupedField):
class PyTypedField(PyXrefMixin, TypedField):
def make_xref(self, rolename, domain, target,
- innernode=nodes.emphasis, contnode=None, env=None):
+ innernode=nodes.emphasis, contnode=None, env=None, **kwargs):
# type: (unicode, unicode, unicode, nodes.Node, nodes.Node, BuildEnvironment) -> nodes.Node # NOQA
if rolename == 'class' and target == 'None':
# None is not a type, so use obj role instead.
@@ -734,7 +727,7 @@ def generate(self, docnames=None):
ignores = self.domain.env.config['modindex_common_prefix'] # type: ignore
ignores = sorted(ignores, key=len, reverse=True)
# list of all modules, sorted by module name
- modules = sorted(iteritems(self.domain.data['modules']),
+ modules = sorted(self.domain.data['modules'].items(),
key=lambda x: x[0].lower())
# sort out collapsable modules
prev_modname = ''
@@ -784,7 +777,7 @@ def generate(self, docnames=None):
collapse = len(modules) - num_toplevels < num_toplevels
# sort by first letter
- sorted_content = sorted(iteritems(content))
+ sorted_content = sorted(content.items())
return sorted_content, collapse
@@ -1000,9 +993,9 @@ def _make_module_refnode(self, builder, fromdocname, name, contnode):
def get_objects(self):
# type: () -> Iterator[Tuple[unicode, unicode, unicode, unicode, unicode, int]]
- for modname, info in iteritems(self.data['modules']):
+ for modname, info in self.data['modules'].items():
yield (modname, modname, 'module', info[0], 'module-' + modname, 0)
- for refname, (docname, type) in iteritems(self.data['objects']):
+ for refname, (docname, type) in self.data['objects'].items():
if type != 'module': # modules are already handled
yield (refname, refname, type, docname, refname, 1)
diff --git a/docs/util/GAUSSLexer.py b/docs/util/GAUSSLexer.py
index f521b07c..e341c544 100644
--- a/docs/util/GAUSSLexer.py
+++ b/docs/util/GAUSSLexer.py
@@ -156,7 +156,7 @@ class GAUSSLexer(RegexLexer):
tokens = {
'whitespace': [
# preprocessor directives: without whitespace
- ('^#if\s+0', Comment.Preproc, 'if0'),
+ (r'^#if\s+0', Comment.Preproc, 'if0'),
('^#', Comment.Preproc, 'macro'),
# or with whitespace
('^(' + _ws1 + r')(#if\s+0)',
@@ -239,9 +239,9 @@ class GAUSSLexer(RegexLexer):
}
def analyse_text(text):
- if re.search('^\s*(?:endp|endfor)\s*;', text, re.MULTILINE): # end of proc
+ if re.search(r'^\s*(?:endp|endfor)\s*;', text, re.MULTILINE): # end of proc
return 0.2
- elif re.search('^\s*proc ', text, re.MULTILINE): # system cmd
+ elif re.search(r'^\s*proc ', text, re.MULTILINE): # system cmd
return 0.2
diff --git a/docs/util/GAUSSRoles.py b/docs/util/GAUSSRoles.py
index bf079a7e..2d6c36b7 100644
--- a/docs/util/GAUSSRoles.py
+++ b/docs/util/GAUSSRoles.py
@@ -1,7 +1,6 @@
import re
from docutils import nodes, utils
-from six import iteritems
_amp_re = re.compile(r'(? Dict[unicode, Any]
from docutils.parsers.rst import roles
- for rolename, func in iteritems(specific_docroles):
+ for rolename, func in specific_docroles.items():
roles.register_local_role(rolename, func)
return {
diff --git a/docs/v.rst b/docs/v.rst
index bc0f95d1..734018e5 100644
--- a/docs/v.rst
+++ b/docs/v.rst
@@ -7,6 +7,7 @@ V
vals
varcovmsvarcovxs
+ vertical-concatenation
varcovmvarcovx
vargetl
varget
diff --git a/docs/varmall.rst b/docs/varmall.rst
index f2bb0ff5..55f5ceac 100644
--- a/docs/varmall.rst
+++ b/docs/varmall.rst
@@ -46,7 +46,25 @@ Format
Remarks
-------
+Examples
+--------
+
+::
+
+ // Compute log-likelihood for a VAR(1) model with 2 variables
+ w = rndn(100, 2);
+ phi = 0.5 * eye(2); // AR(1) coefficient matrix
+ theta = zeros(2, 2); // No MA terms
+ vc = eye(2); // Identity covariance
+ ll = varmall(w, phi, theta, vc);
+ print "Log-likelihood:" ll;
+
+Remarks
+-------
+
:func:`varmall` is adapted from code developed by Jose Alberto Mauricio of the
Universidad Complutense de Madrid. It was published as Algorithm AS311
in Applied Statistics. Also described in "Exact Maximum Likelihood
Estimation of Stationary Vector ARMA Models," JASA, 90:282-264.
+
+.. seealso:: Functions :func:`varmares`
diff --git a/docs/varmares.rst b/docs/varmares.rst
index 568f8a67..20e6edd5 100644
--- a/docs/varmares.rst
+++ b/docs/varmares.rst
@@ -42,8 +42,24 @@ Format
Remarks
-------
+Examples
+--------
+
+::
+
+ // Compute residuals for a VAR(1) model with 2 variables
+ w = rndn(100, 2);
+ phi = 0.5 * eye(2); // AR(1) coefficient matrix
+ theta = zeros(2, 2); // No MA terms
+ res = varmares(w, phi, theta);
+ print "Residual rows:" (rows(res));
+
+Remarks
+-------
+
:func:`varmares` is adapted from code developed by Jose Alberto Mauricio of the
Universidad Complutense de Madrid. It was published as Algorithm AS311
in Applied Statistics. Also described in "Exact Maximum Likelihood
Estimation of Stationary Vector ARMA Models," JASA, 90:282-264.
+.. seealso:: Functions :func:`varmall`
diff --git a/docs/vartypef.rst b/docs/vartypef.rst
index 08fb7f4b..ad7b92d0 100644
--- a/docs/vartypef.rst
+++ b/docs/vartypef.rst
@@ -23,3 +23,18 @@ Remarks
This function should be used in place of older functions that are based
on the case of the variable names. You should also use the v96 dataset format.
+Examples
+----------------
+
+::
+
+ // Open a dataset
+ open f = mydata.dat;
+
+ // Get variable types: 1=numeric, 0=character
+ y = vartypef(f);
+ print y;
+
+ f = close(f);
+
+.. seealso:: Functions :func:`colsf`, :func:`rowsf`
diff --git a/docs/vcmsvcxs.rst b/docs/vcmsvcxs.rst
index 0a1f55bc..358689f1 100644
--- a/docs/vcmsvcxs.rst
+++ b/docs/vcmsvcxs.rst
@@ -33,6 +33,24 @@ computed as the moment matrix of deviations about the mean divided by
the number of observations :math:`N`. For an unbiased estimator covariance
matrix which uses :math:`N - 1` rather than :math:`N` see :func:`vcm` or :func:`vcx`.
+Examples
+--------
+
+::
+
+ // Compute observed variance-covariance matrix from data
+ x = rndn(100, 3);
+ vc = vcxs(x);
+ print vc;
+
+::
+
+ // Compute from a moment matrix (constant term must be first column)
+ x = rndn(100, 3);
+ m = (ones(100, 1) ~ x)'(ones(100, 1) ~ x);
+ vc = vcms(m);
+ print vc;
+
Source
------
diff --git a/docs/vecvecr.rst b/docs/vecvecr.rst
index d00f1bb7..fc3696f0 100644
--- a/docs/vecvecr.rst
+++ b/docs/vecvecr.rst
@@ -47,3 +47,4 @@ Remarks
:func:`vecr` is much faster.
+.. seealso:: Functions :func:`reshape`, :func:`areshape`
diff --git a/docs/vget.rst b/docs/vget.rst
index 7e2dc92c..c950edec 100644
--- a/docs/vget.rst
+++ b/docs/vget.rst
@@ -24,6 +24,19 @@ Format
:rtype dbufnew: Kx1 vector
+Examples
+--------
+
+::
+
+ // Build a data buffer and extract an item
+ dbuf = vput(0, rndn(2, 3), "X");
+ dbuf = vput(dbuf, "hello", "msg");
+
+ // Extract "X", removing it from the buffer
+ { x, dbuf } = vget(dbuf, "X");
+ print x;
+
Source
------
diff --git a/docs/view.rst b/docs/view.rst
index 5a0bb447..3f32daf3 100644
--- a/docs/view.rst
+++ b/docs/view.rst
@@ -39,6 +39,19 @@ If :func:`view` is not called, a default position will be calculated.
Use :func:`viewxyz` to locate the observer in plot coordinates.
+Examples
+--------
+
+.. NOTE:: This function is for use with the deprecated PQG graphics.
+
+::
+
+ library pgraph;
+
+ // Set observer position in workbox units for a 3-D plot
+ view(5, 5, 5); // isometric view
+ // ... followed by a surface or contour call
+
Source
------
diff --git a/docs/viewxyz.rst b/docs/viewxyz.rst
index c9035592..dc3908b2 100644
--- a/docs/viewxyz.rst
+++ b/docs/viewxyz.rst
@@ -36,6 +36,19 @@ If :func:`viewxyz` is not called, a default position will be calculated.
Use :func:`view` to locate the observer in workbox units.
+Examples
+--------
+
+.. NOTE:: This function is for use with the deprecated PQG graphics.
+
+::
+
+ library pgraph;
+
+ // Set observer position in plot coordinates for a 3-D plot
+ viewxyz(10, 10, 5);
+ // ... followed by a surface or contour call
+
Source
------
diff --git a/docs/vlist.rst b/docs/vlist.rst
index 7cb771fc..a394997f 100644
--- a/docs/vlist.rst
+++ b/docs/vlist.rst
@@ -18,6 +18,16 @@ Remarks
:func:`vlist` lists the names of all the strings and matrices stored in *dbuf*.
+Examples
+--------
+
+::
+
+ // Create a data buffer and list its contents
+ dbuf = vput(0, rndn(3, 3), "myMatrix");
+ dbuf = vput(dbuf, "test", "myString");
+ vlist(dbuf);
+
Source
------
diff --git a/docs/vnamecv.rst b/docs/vnamecv.rst
index e54428a3..3443654d 100644
--- a/docs/vnamecv.rst
+++ b/docs/vnamecv.rst
@@ -17,5 +17,16 @@ Format
:rtype cv: Kx1 character vector
+Examples
+--------
+
+::
+
+ // Get the names of items stored in a data buffer
+ dbuf = vput(0, rndn(2, 2), "alpha");
+ dbuf = vput(dbuf, "hello", "beta");
+ cv = vnamecv(dbuf);
+ print cv;
+
.. seealso:: Functions :func:`vget`, :func:`vput`, :func:`vread`, :func:`vtypecv`
diff --git a/docs/volume.rst b/docs/volume.rst
index 2d01b30c..bedbdc6e 100644
--- a/docs/volume.rst
+++ b/docs/volume.rst
@@ -32,6 +32,19 @@ Remarks
The ratio between these values is what is important. If :func:`volume` is not
called, a default workbox will be calculated.
+Examples
+--------
+
+.. NOTE:: This function is for use with the deprecated PQG graphics.
+
+::
+
+ library pgraph;
+
+ // Set the 3-D workbox to a 2:1:1 ratio (wider in X)
+ volume(2, 1, 1);
+ // ... followed by a surface or contour call
+
Source
------
diff --git a/docs/vput.rst b/docs/vput.rst
index 72e395cd..f2d61d5b 100644
--- a/docs/vput.rst
+++ b/docs/vput.rst
@@ -29,6 +29,18 @@ Remarks
If *dbuf* already contains *x*, the new value of *x* will replace the old one.
+Examples
+--------
+
+::
+
+ // Create a new data buffer and add items
+ dbuf = vput(0, rndn(3, 2), "X");
+ dbuf = vput(dbuf, "hello world", "msg");
+
+ // Replace an existing item in the buffer
+ dbuf = vput(dbuf, eye(3), "X");
+
Source
------
diff --git a/docs/vread.rst b/docs/vread.rst
index a1f3e863..b6a7c7bb 100644
--- a/docs/vread.rst
+++ b/docs/vread.rst
@@ -26,6 +26,19 @@ Remarks
:func:`vread`, unlike :func:`vget`, does not change the contents of *dbuf*. Reading *x* from
*dbuf* does not remove it from *dbuf*.
+Examples
+--------
+
+::
+
+ // Read an item from a data buffer without removing it
+ dbuf = vput(0, rndn(2, 2), "mymat");
+ dbuf = vput(dbuf, "test", "mystr");
+
+ x = vread(dbuf, "mymat");
+ print x;
+ // dbuf still contains "mymat" and "mystr"
+
Source
------
diff --git a/docs/vtypecv.rst b/docs/vtypecv.rst
index 74533771..7a22e0b0 100644
--- a/docs/vtypecv.rst
+++ b/docs/vtypecv.rst
@@ -17,5 +17,17 @@ Format
:rtype cv: Kx1 character vector
+Examples
+--------
+
+::
+
+ // Get the types of items in a data buffer
+ dbuf = vput(0, rndn(2, 2), "X");
+ dbuf = vput(dbuf, "hello", "msg");
+ cv = vtypecv(dbuf);
+ print cv;
+ // Types: 6 = matrix, 13 = string
+
.. seealso:: Functions :func:`vget`, :func:`vput`, :func:`vread`, :func:`vnamecv`
diff --git a/docs/waitwaitc.rst b/docs/waitwaitc.rst
index 826a533d..55a748e8 100644
--- a/docs/waitwaitc.rst
+++ b/docs/waitwaitc.rst
@@ -25,10 +25,25 @@ If you are working in terminal mode, these commands do not "see" any
keystrokes until :kbd:`ENTER` is pressed. `waitc` clears any pending keystrokes
before waiting until another key is pressed.
+Examples
+--------
+
+::
+
+ // Pause until a key is pressed
+ print "Press any key to continue...";
+ wait;
+
+::
+
+ // Clear pending keystrokes, then wait for a new one
+ print "Press a key to start...";
+ waitc;
+
Source
------
wait.src, waitc.src
-.. seealso:: Functions :func:`pause`
+.. seealso:: Functions :func:`sleep`, :func:`pause`, :func:`keyav`
diff --git a/docs/zeta.rst b/docs/zeta.rst
index 91acb675..8e48ade2 100644
--- a/docs/zeta.rst
+++ b/docs/zeta.rst
@@ -48,3 +48,4 @@ References
#. Jon Breslaw, 2009
+.. seealso:: Functions :func:`gamma`, :func:`beta`
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 00000000..7c84926c
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,7 @@
+# Sphinx documentation build dependencies
+# Install: pip install -r requirements.txt
+sphinx==7.4.7
+sphinx-rtd-theme==3.0.2
+docutils>=0.20,<0.22
+pygments>=2.17
+sphinx-design==0.7.0