自 MATLAB® 环境调用 NAG 函数

虽然 NAG 算法库是用 Fortran 语言所编写的,但是您可以在 MATLAB 环境中调用它,如同是 MATLAB 本身提供的函数。在 MATLAB 工具箱中的函数会将数据传递到 Fortran 函数中,并将算法计算的成功后的结果转化成 MATLAB 的对象传回。

一个简单的例子

这里有一个例子显示如何使用 NAG 函数计算线性方程组 AX = B 的结果,其中 A 是一个 nn 的矩阵,X 与 B 都为 n 向量。
a = [ 1.80,  2.88,  2.05, -0.89;
      5.25, -2.95, -0.95, -3.80;
      1.58, -2.69, -2.90, -1.04;
     -1.11, -0.66, -0.59,  0.80];
b = [ 9.52;
     24.35;
      0.77;
     -6.22];
[aOut, ipiv, bOut, info] = f07aa(a, b);
bOut
bOut =

    1.0000
   -1.0000
    3.0000
   -5.0000
在这里我们可以看到 NAG 的 f07aa 函数有两个参数;分别为系数矩阵 A 与 方程式后侧的 B 向量 (实际上 f07aa 可以处理多个右侧的 B 值,所以 B 实际上是一个矩阵)。计算后会传回四个结果:
aOut
A 矩阵的 LU 分解
ipiv
用来表示输入矩阵的排列位置
bOut
结果矩阵
info
诊断参数,表示算法是否执行成功
如果 info=0 表示算法计算结果成功。若遇到输出为非零的数值,表示会有错误与警告的讯息会被显示出 (请参考 错误与警告)。 在个别的章节函数介绍中,都会有完整的例子提供您参考。

可选参数

许多 NAG 的函数皆有可选参数。在此情况下,函数可以藉由输入适合的值或者在大部分的情况下采用默认值。 有一个非常普遍的例子,在 Fortran 函数中,会需要用户提供参数说明矩阵的大小,这在 MATLAB 中可以很简单的推论出来。 例如在前面提到的例子,很明显的矩阵 A 的 rank 是 n。当然,我们也可以在调用时告诉 MATLAB 它的 rank 是 3,那么它将会求解 A 矩阵左上部的 3 乘 3 部分的矩阵,同时与 B 向量的前 3 个数据进行计算 (可参考 型态 了解在这里使用的 int32 命令的含义):
[aOut, ipiv, bOut, info] = f07aa(a, b, 'n', int32(3));
bOut

bOut =

    4.1631
   -2.1249
    3.9737
   -6.2200
The last element of bOut can be ignored. Since b was a 4x1 matrix on input, it will be a 4x1 matrix on output, even though the last element is not being used. A similar outcome can be achieved by:
[aOut, ipiv, bOut, info] = f07aa(a(1:3,1:3), b(1:3));
bOut

bOut =

    4.1631
   -2.1249
    3.9737
总结:
  1. 可选参数在强制性参数输入后加入
  2. 可选参数需要成对的输入:先提供一个参数名称,紧接着再加入数值
  3. 可选参数没有顺序性
另一种常见用可选参数的例子是取代默认值。例如 g01hb 是计算多变量分布的机率值,它的相对精度默认值是 0.0001:
tail = 'c';
a = [-2; -2; -2; -2];
b = [2; 2; 2; 2];
xmu = [0; 0; 0; 0];
sig = [1.0, 0.9, 0.9, 0.9;
       0.9, 1.0, 0.9, 0.9;
       0.9, 0.9, 1.0, 0.9;
       0.9, 0.9, 0.9, 1.0];

g01hb(tail, a, b, xmu, sig)

ans =

    0.9142

我们可以改变 tol 参数,调整所需要的精确度:
g01hb(tail, a, b, xmu, sig,'tol',0.1)

ans =

    0.9182
最后,我们注意到有些 NAG 函数使用使用不同的机制设置参数,其中包含调用函数的默认化工作、使用单独的参数设置函数再加上算法的运算函数。您可以参考 f12fe 范例。

错误与警告

在 NAG 的函数中会抛出一许多的错误数值,这些错误数值与名称,大略整理如下:
NAG:licenceError
并未发现本产品的合法 Licnese。
NAG:arrayBoundError
提供函数的矩阵太小。.
NAG:callBackError
当执行提供 M-File 的参数档时发生错误。
NAG:missingInputParameters
至少缺少一个或以上的强制性输入参数。
NAG:optionalParameterError
有可能是可选参数没有成对 参数名/数值 输入,或者提供错误的参数名称。请注意此错误有可能是因为一些强制性的参数被省略了。
NAG:tooManyOutputParameters
使用者要求输出太多的参数。
NAG:typeError
提供给函数的 M-File 或者子程序的型态不正确。请参考 型态
NAG:valueError
参数输入不正确的数值。
在大多数情况下,错误讯息会提供更具体的引发错误的细节。例如 NAG:arrayBoundError 可能显示以下的讯息:

??? The dimension of parameter 2 (A) should be at least 4

NAG 函数也会抛出以下的两种警告类型:
NAG:truncationWarning
从 Fortran 的数据结构中传回时,字符串内容被截断。
NAG:warning
NAG 函数传回错误或警告讯息。
第二个错误讯息是较为重要的,它表示函数调用完后的 ifail (或者在 f07 与 f08 的 info 参数)传回非零值。 如何解释这项数值,请您参考详细的使用手册,如果您不希望看到这样的警告讯息,也可以透过以下方式禁止它显示:
warning('off', 'NAG:warning')
在此情况下,使用者最需注意的就是检查函数调用完后传回来的 ifail 参数值。

型态

在 MATLAB 中的 NAG 函数对于参数的型态要求是相当精确的。因为 MATLAB 默认会假设每一个数值是双精度的,除非有另行指定,这表示使用者需要特别去指定输入的数据型态,例如:整数、复数或布尔值。 同样的,在 NAG 函数调用的 M-Files 中,使用者也必须确认传回结果的型态一致性。这样才能确保 MATLAB 与 Fortran 之间的数据型态一致。 通常,使用者会使用 int32 定义整数,complex 定义复数值以及 logical 指定布尔型态。在我们的函数说明文件中有许多这样的例子。 如果数据的型态不正确,那么便会产生 NAG:typeError 的错误讯息:
s01ea(0)

??? Parameter number 1 is not a complex scalar of class double.

提供 M-Files 做为参数输入

许多的 NAG 函数会要求使用这提供 M 档案来目标函数。例如积分或优化函数中的目标函数等。以下是一个求解积分的例子:
d01ah(0, 1, 1e-5, 'd01ah_f', int32(0))
ans =

    3.1416
被积函数是置 'd01ah_f.m' 档案中,如以下的内如::
function [result] = d01ah_f(x)
        result=4.0/(1.0+x^2);
使用者可以参考 MATLAB 的手册有关于 Working with M-FilesEditing and Debugging M-Files 部分。 我们每一个需要 M-File 的函数皆提供完整的范例说明。