欢迎访问 Lu程序设计 下载 OpenLu 的64位版本

工程计算助手

1 概述 | 3 基本计算 | 4 软件组成与结构
2 基础知识 | 3.1 表达式计算 | 4.1 文件及文件夹
2.1 启动界面及工作模式 | 3.2 求和与求积 | 4.2 开放式软件系统
2.2 代码格式 | 3.3 解方程 | 5 更详细的帮助 >> OpenLu使用说明
2.3 整数、实数、复数和三维向量计算 | 3.4 微积分 | 6 问题及建议
2.4 常用数学函数 | 3.5 微分方程求解 |
2.5 运算符 | 3.6 优化拟合 |
2.6 函数及模块 | 3.7 矩阵运算 |
2.7 使用命名空间 | 3.8 函数图形 |
2.8 流程控制 | 3.9 使用常量文件 |
2.9 结果输出 | 3.10 自定义函数库 |
2.10 代码重用 | 3.11 创建命令菜单 |

1 概述 [返回页首]

本程序内部名称为“开放式计算软件OpenLu”，本说明称之为“工程计算助手”，旨在以工程计算助手的方式实现开放式计算。

本软件力求方便快捷地进行各种工程数值计算。无需专门学习，通过看实例做计算是本软件的基本特点。基本计算内容包括表达式计算、解方程、解非线性方程（组）、多元积分、微分方程求解、参数优化拟合 、矩阵运算等等。

2 基础知识 [返回页首]

2.1 启动界面及工作模式 [返回页首]

OpenLu启动时界面上有2个窗口，上面是代码窗口，下面是运算结果输出窗口。

OpenLu工作模式有三种，可通过命令菜单进行切换：

（1）普通编译模式：在代码窗口写好代码后，通过菜单、工具栏或快捷键F8进行编译计算。

（2）即时编译模式：在代码窗口写代码时，即时给出代码中的错误。

（3）即时编译计算模式：在代码窗口写代码时，即时给出代码中的错误，若没有错误，将进行计算给出结果。

为了更好地使用OpenLu时，建议进行以下操作：
（1）给OpenLu创建一个快捷方式，然后把该快捷方式放在桌面上或“开始”菜单中。
（2）用OpenLu打开文件夹“Ini”中的文件“OpenLu.ini”（通常会提示该文件已经打开），或者其他自定义的工作区文件。
a、执行菜单命令：设置 -> 设置当前文件为工作区。
b、执行菜单命令：设置 -> 设置当前文件为缺省工作区。
2.2 代码格式 [返回页首]

OpenLu由Lu脚本支持，采用Lu脚本源代码格式。简单地，即：源代码文件由若干函数（或表达式）组成，函数（或表达式）由分号分隔，函数 （或表达式）由语句组成，语句由逗号、冒号或分号分隔，函数（或表达式）中可使用三对等价的括号( )、[ ]和{ }，源代码中可使用C++风格的注释。如下例：

> //每行中两个反斜杠后的内容为注释

> /*

> 这是多行注释。

> 这是多行注释。

> */

> 2.5+sin[1.2-cos(0.8)];

> sin[2.3-5i]; //i表示一个虚数

2.3 整数、实数、复数和三维向量计算 [返回页首]

> 2+20/3; //数字中不带小数点时进行整数运算。例如：20/3=6

> 2+20./3; //数字中带小数点时进行实数运算。例如：20./3=6.666666666666667，本例中3虽然是整数，但自动转换为实数进行计算

> 2+3i; //数字后的i表示该数是一个虚数

> 2$3; //运算符并“$”将2个实数（包含整数）转换为一个复数

> 2$3$5; //运算符并“$”将1个复数和一个实数（包含整数）合并为一个三维向量

> (2+3i)$5; //运算符并“$”将1个复数和一个实数（包含整数）合并为一个三维向量

可以看出，Lu脚本可自动为数学混合算式进行数据类型转换，低一级数据类型将自动转换为高一级数据类型，即：整数→实数→复数→三维向量。

2.4 常用数学函数 [返回页首]

函 数 | 参数类型 | 说 明
sin(x) | 实数、复数 | 正弦函数
cos(x) | 实数、复数 | 余弦函数
tan(x) | 实数、复数 | 正切函数
asin(x) | 实数、复数 | 反正弦函数
acos(x) | 实数、复数 | 反余弦函数
atan(x) | 实数、复数 | 反正切函数
sqrt(x) | 实数、复数 | 平方根函数
exp(x) | 实数、复数 | 指数函数
ln(x) | 实数、复数 | 自然对数函数
lg(x) | 实数、复数 | 常用对数函数
sinh(x) | 实数、复数 | 双曲正弦函数，[exp(x)-exp(-x)]/2
cosh(x) | 实数、复数 | 双曲余弦函数，[exp(x)+exp(-x)]/2
tanh(x) | 实数、复数 | 双曲正切函数，[exp(x)-exp(-x)]/[exp(x)+exp(-x)]
abs(x) | 实数、复数 | 绝对值函数
floor(x) | 实数 | 返回不大于x的最大整数
ceil(x) | 实数 | 返回不小于x的最小整数
itor(x) | 整数 | 将整数转换成实数，大数转换时有精度损失
rtoi(x) | 实数 | 将实数转换成整数，大数转换时有误差
con(x) | 复数 | 求复数的共轭复数
atan2(x,y) | 实数 | 反正切函数，求x/y的反正切值，所在象限由x和y的符号确定
fmod(x,y) | 实数 | 求x/y的余数

2.5 运算符 [返回页首]

Lu支持的运算符比较多，大家只使用自己熟悉的运算符即可。

运算符类型 | 运算符 | 名称 | Lu核心库支持的运算 | 说 明
双括号连接运算符 | := |  | 双括号连接 | 冒号前和等号后都必须是括号
单括号连接运算符 | ( )= |  | 单括号连接 | 等号后是一个表达式
[ ]= |  | 单括号连接
{ }= |  | 单括号连接
括号运算符 | ( ) | 小括号 | 括号运算 | 返回最后一个语句的值
[ ] | 中括号 | 括号运算
{ } | 大括号 | 括号运算
命名空间成员访问符 | :: | 双冒号 | 访问命名空间成员 | 访问命名空间成员
对象成员运算符 | . | 点 | 访问对象成员或传递函数参数 | 也称为函数参数运算符，或者变量函数调用运算符
后置单目运算符 | ++ | 后置自增 | 整数、实数 | 后置单目运算符（自增、自减、转置、点转置）
-- | 后置自减 | 整数、实数
' | 转置 | 未定义
.' | 点转置 | 未定义
前置单目运算符 | ! | 非 | 逻辑值、整数、实数 | 前置单目运算符（非、正、负、自增、自减、按位非） 对整数或实数求非时，返回逻辑值，且规定!0=true，!0.0=true，其他情况均返回false。
+ | 正 | 被忽略
- | 负 | 整数、实数、复数、三维向量
++ | 前置自增 | 整数、实数
-- | 前置自减 | 整数、实数
!! | 按位非 | 整数
乘方算术运算符 | ^ | 乘方 | 整数、实数、复数 | 算术运算符（乘方、点乘方）
.^ | 点乘方 | 未定义
乘除算术运算符 | * | 乘 | 整数、实数、复数、三维向量 | 算术运算符（乘、左除、右除、求模、点乘、点左除、点右除）
/ | 左除 | 整数、实数、复数
\ | 右除 | 未定义
% | 求模 | 整数
.* | 点乘 | 未定义
./ | 点左除 | 未定义
.\ | 点右除 | 未定义
加减算术运算符 | + | 加 | 整数、实数、复数、三维向量、字符串 | 算术运算符（加、减）
- | 减 | 整数、实数、复数、三维向量
移位运算符 | << | 左移位 | 整数 | 左移位、右移位
>> | 右移位 | 整数
关系运算符 | > | 大于 | 整数、实数 | 关系运算符（大于、大于等于、小于、小于等于、等于、不等于）
>= | 大于等于 | 整数、实数
< | 小于 | 整数、实数
<= | 小于等于 | 整数、实数
== | 等于 | 整数、实数
!= | 不等于 | 整数、实数
按位与 | && | 按位与 | 整数 | 按位与
按位异或 | ~~ | 按位异或 | 整数 | 按位异或
按位或 | || | 按位或 | 整数 | 按位或
逻辑与 | & | 逻辑与 | 逻辑值 | 逻辑与
逻辑异或 | ~ | 逻辑异或 | 逻辑值 | 逻辑异或
逻辑或 | | | 逻辑或 | 逻辑值 | 逻辑或
并 | $ | 并 | 整数、实数、复数 | 并。核心库并运算的结果为复数或三维向量。
赋值运算符 | = | 赋值 | 赋值 | 赋值运算符
对象赋值运算符 | .= | 对象赋值 | 对象赋值 | 变量函数调用运算符与赋值运算符的结合，一般用于对象赋值
语句分隔符 | , | 逗号 | 分隔语句 | 逗号、冒号、分号运算符
: | 冒号 | 分隔语句
; | 分号 | 分隔语句

2.6 函数及模块 [返回页首]

Lu使用等号定义一个函数，如下例：

> f(x,y) = x+y; //函数定义

> f[2,3]; //函数调用

> 加(数1,数2) = 数1+数2; //函数定义

> 加(2,3); //函数调用

函数中可以使用各种变量，如下例：

> f(x,y : a,b : c,d) = //x和y是自变量，第一个冒号后的变量是动态变量，第二个冒号后的变量是模块变量

> a=x+y, b=x-y, c=x*y, d=x/y,

> a+b+c+d;

> f[2.0,3.0];

自变量和动态变量只能被定义该变量的函数所访问；模块变量可被同一模块的所有表达式所访问，其他模块的表达式无法访问。自变量用于向表达式传递参数，因此自变量也称为形式参数。动态变量只在表达式执行时起作用，一旦表达式执行完毕，动态变量也随之失效。

在编译符#MODULE#和#END#之间的代码属于一个模块，如下例：

> #MODULE#

> (:: a) = a=5; //这个函数没有名字，这是允许的。该函数的作用是给模块变量a赋值

> f(x :: a) = x+a; //该函数是私有函数，只能被该模块的表达式所调用

> :::g(x) = x+f[x]; //该函数以编译符:::开头，是一个全局函数，全局函数名是唯一的，可被所有的表达式所调用

> #END#

> #MODULE#

> (:: a) = a=8; //这个函数没有名字，这是允许的。该函数的作用是给模块变量a赋值

> f(x :: a) = x+a; //该函数是私有函数，只能被该模块的表达式所调用

> :::h(x) = x+f[x]; //该函数以编译符:::开头，是一个全局函数，全局函数名是唯一的，可被所有的表达式所调用

> #END#

> //以下两个语句不属于以上两个模块

> g[2]; //调用全局函数g，结果为9

> h[2]; //调用全局函数g，结果为12

若源代码中没有编译符#MODULE#和#END#，则整个源代码属于同一个模块。

一般，Lu脚本中的变量须先声明后使用，使用编译符 mvar: 后，未声明的变量都看作模块变量，如下例：

> mvar:

> a=2, b=3; //模块变量a和b赋值

> a+b; //模块变量a和b相加

2.7 使用命名空间 [返回页首]

许多Lu扩展库中的函数是通过命名空间方式输出的。例如LuIMSL库中的函数使用命名空间“IMSL”输出，所有函数均具有类似“IMSL::ode”的格式，使用!!!using("IMSL");可简化LuIMSL中的函数访问。例如：

[例子] 设一阶微分方程组及初值为：
r'=2r-2rf, r(0)=1
f'=-f+rf, f(0)=3
计算t=1,2,...,10时的r、f的值。
程序如下：

> !!!using["IMSL","math"]; //使用命名空间"IMSL"和"math"。编译符“!!!”使函数using立即执行。
> f(t,r,f,dr,df)={dr=2*r-2*r*f, df=-f+r*f}; //函数定义
> ode[@f,ra1[0,1,2,3,4,5,6,7,8,9,10],ra1[1,3]].outa[];

如果不使用using函数，程序如下：

> f(t,r,f,dr,df)={dr=2*r-2*r*f, df=-f+r*f};
> IMSL::ode[@f,math::ra1[0,1,2,3,4,5,6,7,8,9,10],math::ra1[1,3]].math::outa[];

程序输出结果均为：

> 0. 1. 3.

> 1. 7.73453e-002 1.46445

> 2. 8.49774e-002 0.577954

> 3. 0.290891 0.249253

> 4. 1.4466 0.187219

> 5. 4.05146 1.43948

> 6. 0.175618 2.2586

> 7. 6.53112e-002 0.9088

> 8. 0.147227 0.366718

> 9. 0.650596 0.187575

> 10. 3.14433 0.348821

2.8 流程控制 [返回页首]

在Lu中，表达式的各个语句一般是顺序执行的。但是某些函数可以改变语句执行的顺序，称为流程控制函数。

（1）立即返回函数 return(x)

结束计算并立即返回表达式的值为x。

（2）判断函数 if(x,y1,y2,... ...,yn)

当逻辑语句x的值为真（或者对象x值非0）时，依次执行语句y1,y2,... ...,yn，否则，不执行语句y1,y2,... ...,yn。
该函数至少要有2个自变量参数，其中第一个参数为逻辑语句。
该函数的返回值无意义。

（3）自定义分段函数

which{
逻辑语句1 : 语句1,
逻辑语句2 : 语句2,
... ...,
逻辑语句n : 语句n,
缺省语句
};
Lu从前往后计算并检测逻辑语句的值，当检测到逻辑真（或者对象值非0）时，计算与此逻辑真对应的语句并返回该语句的值，如果没有检测到逻辑真，则计算缺省语句的值作为返回值，若此时没有缺省语句，则产生一个运行错误。
该函数至少要有2个自变量参数。
例如下式定义了一个分段函数：
(x)=which{x>0, 2*x-1,
x*x-1
};
如果舍弃该函数的返回值，则该函数可以作为一个选择计算函数使用。

（4）while循环函数

while循环是“当型”循环，其特点是：先判断条件是否成立，当条件成立时，则执行循环体，否则退出循环体，即“当条件成立时执行循环”。“当型”循环的循环体有可能一次也不执行。
while循环函数的格式如下：

while{x,
y1,y2,
...,
break(),
...,
continue(),
...,
yn
};
其中x为逻辑语句；y1,y2,...,break(),...,continue(), ...yn为循环体语句。当x的值为真（或者对象x值非0）时，依次执行循环体语句，直到x的值为假时退出循环。当执行到break()函数时，跳出while循环，执行while循环后面的语句部分；当执行到continue()函数时，返回到while循环的开始语句x处继续执行。
在循环体语句中，必须有能修改逻辑语句x的值的语句，使x的值为假，退出循环体，否则将产生无限循环。
该函数至少要有2个自变量参数，其中第一个参数为逻辑语句。
该函数的返回值无意义。
以下是一个while循环的例子：

(:i,k)=
{
i=0,k=0,
while{i<=1000000,k=k+i,i++}, //当i<=1000000时，计算k=k+i，然后i++；
k
};

（5）until循环函数

until循环是“直到型”循环，其特点是：先执行循环体，再判断条件是否成立，当条件成立时，退出循环体，否则继续执行循环体，即“执行循环直到条件成立”。“直到型”循环的循环体至少执行一次。
until循环函数的格式如下：

until{x1,x2,
...,
break(),
...,
continue(),
...,
y
};
until为先执行后判断的循环函数。即先执行循环体语句x1,x2,...,break(),...,continue(),...，然后计算逻辑语句y的值，直到y的值为真（或者对象y值非0）时退出循环。当执行到break()函数时，跳出until循环，执行until循环后面的语句部分；当执行到continue()函数时，返回到until循环的开始语句x1处继续执行。
在循环体语句中，必须有能修改逻辑语句y的值的语句，使y的值为真，退出循环体，否则将产生无限循环。
该函数至少要有2个自变量参数，其中最后一个参数为逻辑语句。
该函数的返回值无意义。
以下是一个until循环的例子：

(:i,k)=
{
i=0,k=0,
until{k=k+i,i++,i>1000000}, //计算k=k+i,i++，当i>1000000时退出；
k
};

注意：break()和continue()是两个无参函数，只能用在while和until两个循环函数中。

2.9 结果输出 [返回页首]

通常，本程序会计算并输出每一个表达式的结果。若要在一个表达式中输出多个结果，可使用o函数（o函数本身返回输出的字符个数），如下例：

> o[25+5,"\r\n",sin[2.5],"\r\n"]; //在双引号 " " 之间的内容表示一个字符串，而 "\r\n" 将输出一个换行符。

结果：

> 30

> 0.59847214410395644

> 25

注意：最后的数字25是o函数输出的字符个数。

若只希望用函数o输出结果，不希望看到每一个表达式的结果，需要使用函数SetTalk[false]关闭计算结果输出，如下例：

> SetTalk[false];

> o[25+5,"\r\n",sin[2.5],"\r\n"];

结果：

> 30

> 0.59847214410395644

使用函数SetTalk[true]可恢复计算结果输出。

2.10 代码重用 [返回页首]

将常用的计算式保存为文件，进行代码重用，以提高工作效率。

编写常量文件，使OpenLu自动加载，以简化计算。

编写公共的函数放到函数库中，以增加代码重用。

常用的计算编写成命令文件，添加到OpenLu的命令菜单。

以上本文都有相关的例子。

3 基本计算 [返回页首]

3.1 表达式计算 [返回页首]

这是最常用的计算，OpenLu为此提供了即时编译计算方式。如下例：

> f(x,y)=sin[x-cos(y)]; //函数定义

> 2+10/3;

> 2.5+f[1.2,0.8];

> sqrt[1-2i]; //复数表达式

> (2$3$5) * (5$3$2); //三维向量乘

结果（注意复数和三维向量在OpenLu中的输出格式）：

> 5

> 2.982313067962473

> {1.272019649514069$(-0.7861513777574233)}

> {(-9.)$21.$(-9.)}

3.2 求和与求积 [返回页首]

求和函数 sum(@F,y1min,y1max,y1dy;y2min,y2max,y2dy;... ...)：

F为求和函数句柄；y1min,y1max,y1dy为第一个自变量的初值、终值和参数增量[初值<终值，参数增量>0]，依次类推。

例子：

F(x,y)=sin[x]+0.8-y;
sum(@F,1.,20.,1.;-2.,10.,1.);

结果：

> -819.023115502543

上例x和y的增量均为1，更一般的情况是增量非1。仍以上式为例，但x增量为0.1，y的增量为0.05，代码如下：

F(x,y)=sin[x]+0.8-y;
sum(@F,1.,20.,0.1;2.,5.,0.05);

结果：

> -31323.60317910476

求积函数pro的用法同求和函数sum，但pro用于求积。

3.3 解方程 [返回页首]

方程（组）的求解，难易程度差别较大。在OpenLu中，普通的方程（组）可借助LuMath库中的拟牛顿法netn和对分法btFindRoot求解，难度大的方程（组）须借助优化库LuOpt中的iFind、Find和Opt函数求解。

（1）math::btFindRoot(f,a,b,h,k,eps)：对分法求非线性方程的实根

f：自定义一元函数句柄。函数自变量不能重新赋值。
a,b：求根区间的左端点和右端点（b>a）。
h：搜索求根时采用的步长（h>0）。
k: 可能的实根个数。可缺省，缺省值为10。
eps：控制精度（eps>0）。可缺省，缺省值为1e-6。

返回值：返回一个数组（存放搜索到的实根），或者返回nil。若返回数组的长度为k，则有可能在求根区间[a,b]内的实根未搜索完。

例子：

> f(x)=x^6-5*x^5+3*x^4+x^3-7*x^2+7*x-20; //函数定义
> math::btFindRoot[@f,-2.,5.,0.2].o[]; //函数o用于输出一个对象

结果：

> -1.40246 4.33376

（2）math::netn(f,x,eps,t,h,k)：求非线性方程组一组实根的拟牛顿法

f：自定义二元或2n(n>1)元函数句柄，由用户自编。

如果f是二元函数，则两个参数为等长的一维数组：

> f(x,y)= //二元函数，x[i]为自变量，y[i]为方程右端点函数值
> {
> y[0]=f1(x[0],x[1],...,x[n-1]),
> y[1]=f2(x[0],x[1],...,x[n-1]),
> ... ...
> y[n-1]=fn(x[0],x[1],...,x[n-1])
> };

或者：

> f(x1,x2,...,xn,y1,y2,...,yn)= //2n元函数，xi为自变量，yi为方程右端点函数值
> {
> y1=f1(x1,x2,...,xn),
> y2=f2(x1,x2,...,xn),
> ... ...
> yn=fn(x1,x2,...,xn)
> };

x：双精度实型一维数组，长度不小于n，存放一组初值，返回方程组的一组实根。
eps：控制精度（eps>0）。可缺省该参数，缺省值eps=1e-6。
t：控制h大小的变量，0<t<1。可缺省该参数，缺省值h=0.1。
h：增量初值，在本函数中将被破坏。可缺省该参数，缺省值h=0.1。
k：允许的最大迭代次数。可缺省该参数，缺省值k=100。

返回值：返回值为实际迭代次数。若返回值为-1表示代数方程奇异，若返回值为-2表示β=0，这两种情况可放宽精度要求、改变各个初值或改变各个方程顺序再试；若返回值等于0说明迭代了k次仍未满足精度要求，程序工作失败。

例子：解下例方程组

> x1*x1+x2*x2+x3*x3-1.0=0
> 2.0*x1*x1+x2*x2-4.0*x3=0
> 3.0*x1*x1-4.0*x2+x3*x3=0

代码：

> f(x1,x2,x3,y1,y2,y3)= //函数定义
> {
> y1=x1*x1+x2*x2+x3*x3-1.0,
> y2=2.0*x1*x1+x2*x2-4.0*x3,
> y3=3.0*x1*x1-4.0*x2+x3*x3
> };
> !!!using["math"]; //使用命名空间math
> main(:x,i)={
> //申请一维数组并赋初值的常规方法。函数new表示申请一个对象，real_s表示数组对象，data后的数据为初值1.0,1.0,1.0
> x=new{real_s,data : 1.0,1.0,1.0},
> i=netn[@f,x], //拟牛顿法解方程
> x.outa(), //用函数outa输出一个数组
> i //返回迭代次数
> };

或者：

> f(x,y)=
> {
> y[0]=x[0]*x[0]+x[1]*x[1]+x[2]*x[2]-1.0,
> y[1]=2.0*x[0]*x[0]+x[1]*x[1]-4.0*x[2],
> y[2]=3.0*x[0]*x[0]-4.0*x[1]+x[2]*x[2]
> };
> !!!using["math"];
> main(:x,i)={
> //申请一维数组并赋初值的简便方法。函数ra1(realarray1的缩写)表示申请一维数组，初值为1,1.0,1（ra1自动将整数转换为实数）
> i=netn[@f,x=ra1(1,1.0,1)],
> x.o(), //用函数o输出一个对象
> i
> };

结果：

> 0.785197 0.496611 0.369923

> 4

（3）luopt::iFind(f, luopt::optmax,m, luopt::optrange,min,max, luopt::opteps,eps, luopt::optpara,x1,x2,..., luopt::optthis,i)：求单变量方程的全部解

f：自定义n元函数句柄，不可缺省。格式如下：

> f(x1,x2,...,xn)=
> {
> ... ...
> };

默认求方程f(x1,x2,...,xn)=0第一个自变量的全部解，而其他自变量赋值为0.0。可以用参数optthis指定求解的自变量，也可以用参数optpara给出其他自变量的值。

luopt::optmax,m：区间分割数目（大于等于10），区间分割数目越多精度越高。可以缺省该参数，缺省值为200。
luopt::optrange,min,max：指定求解区间。若缺省该参数，则min为-1e50，max为1e50。
luopt::opteps,eps：控制精度要求，eps>0。可以缺省该参数，缺省值为1e-6。
luopt::optpara,x1,x2,...：给指定求解自变量之外的其他自变量赋值，参数x1,x2,...的个数比全部自变量个数少1。若缺省该参数，其他自变量缺省值均为0.0。
luopt::optthis,i：指定求解的自变量。0表示第一个自变量；1表示第二个自变量，以此类推。若缺省该参数，i为0。

返回值：解的个数。

例子1：求方程的全部解：f(x)=x^6-5*x^5+3*x^4+x^3-7*x^2+7*x-20;

> f(x)=x^6-5*x^5+3*x^4+x^3-7*x^2+7*x-20;
> luopt::iFind[@f];

结果（最后一个值为误差，下同）：

> -1.402463030422577 3.552713678800501e-015

> 4.333755446919994 -2.984279490192421e-013

> 2

例子2：求方程的全部解（x取-8～8，y取1）：f(x,y)=(x^2+y^2)^3-36*(x^2-y^2)^2;

> !!!using("luopt");
> f(x,y)=(x^2+y^2)^3-36*(x^2-y^2)^2;
> iFind[@f,optrange,-8.,8.,optpara,1.];

结果：

> -5.530393535267971 1. -3.637978807091713e-012

> -1.32936186218296 1. -7.105427357601002e-015

> -0.8047014256478491 1. -1.776356839400251e-015

> 0.8047014256478491 1. -1.776356839400251e-015

> 1.32936186218296 1. -7.105427357601002e-015

> 5.530393535267971 1. -3.637978807091713e-012

> 6

例子3：求方程的全部解（x取1，y取-8～8）：f(x,y)=(x^2+y^2)^3-36*(x^2-y^2)^2;

> !!!using("luopt");
> f(x,y)=(x^2+y^2)^3-36*(x^2-y^2)^2;
> iFind[@f, optrange,-8.,8., optthis,1, optpara,1.];

结果：

> 1. -5.530393535267971 -3.637978807091713e-012

> 1. -1.32936186218296 -7.105427357601002e-015

> 1. -0.8047014256478491 -1.776356839400251e-015

> 1. 0.8047014256478491 -1.776356839400251e-015

> 1. 1.32936186218296 -7.105427357601002e-015

> 1. 5.530393535267971 -3.637978807091713e-012

> 6

（4）luopt::Find(f, luopt::optmode,mode, luopt::optrange,x1min,x1max,x2min,x2max,...,xnmin,xnmax, luopt::opteps,eps)：求方程组的全部解

f：自定义2*n元函数句柄，不可缺省。格式如下：

> f(x1,x2,...,xn,y1,y2,...,yn)=
> {
> y1= ...,
> y2= ...,
> ... ...,
> yn= ...
> };

luopt::optmode,mode：工作模式，取0、1、2、3、... ...。通常，工作模式取值越大，搜到的解越多，但耗时越长。若缺省该参数，工作模式取0。
luopt::optrange,x1min,x1max,x2min,x2max,...,xnmin,xnmax：指定求解区间。若缺省该参数，则所有变量区间均为[-1e50～1e50]。
luopt::opteps,eps：控制精度要求，eps>0。可以缺省该参数，缺省值为1e-6。满足sqrt[(y1*y1+y2*y2+...+yn*yn)/n]<eps。

返回值：解的个数。

说明：该函数的解是不稳定的，需要多次运行该函数以获得需要的解。

例子1：解方程组：

> (x-y)^2-3*(x-y) = 10
> x^2+2*x*y+y^2 = 9

代码（最后一个值为误差，下同）：

> f(x,y,y1,y2)=
> {
> y1=(x-y)^2-3*(x-y)-10,
> y2=x^2+2*x*y+y^2-9
> };
> luopt::Find[@f];

结果：

> 4. -1. 0.

> 0.5 2.5 0.

> -2.5 -0.5 0.

> 1.000000000224727 -4.000000000225374 2.227885009675654e-009

> 4

例子2：解方程组：a取-10～10，t取-7～7

> -b*sin(a+6*t)+n-40.4945=0
> -b*sin(a+7*t)+n-40.5696=0
> -b*sin(a+8*t)+n-41.0443=0
> -b*sin(a+9*t)+n-41.4190=0

代码：

> !!!using["luopt"];
> f(a,b,n,t,y1,y2,y3,y4)=
> {
> y1=-b*sin(a+6*t)+n-40.4945,
> y2=-b*sin(a+7*t)+n-40.5696,
> y3=-b*sin(a+8*t)+n-41.0443,
> y4=-b*sin(a+9*t)+n-41.4190
> };
> Find[@f, optmode,5, optrange,-10.,10.,-1e50,1e50,-1e50,1e50,-7.,7.];

结果（没有验证过该方程组有多少组解，下面是其中一次求解结果）：

> 8.423278510740619 0.491530082706187 40.94928398718974 -1.077226214994066 5.024295867788081e-015

> 5.281685857151022 -0.4915300827061788 40.94928398718975 -1.077226214994089 1.123466709944544e-014

> 4.143092103608209 -0.4915300827069298 40.94928398718954 1.077226214995628 8.519922959291649e-013

> 1.001499450021447 0.4915300827000679 40.94928398718732 -5.205959092183973 4.316661155959305e-012

> -4.143092103780588 0.4915300827292421 40.94928398721459 -1.077226214971404 2.308770421222309e-011

> -5.281685858383328 0.4915300826310666 40.949283987277 1.077226215139597 1.209674914149958e-010

> -1.001499513894245 -0.4915300850351296 40.94928398852594 5.205959099724587 3.485087466848284e-009

> -2.140093572279421 -0.4915300631949757 40.94928396791384 1.077226272463665 1.373241653986354e-008

> -1.001499452411673 -0.491530028262163 40.94928398098966 -1.077226219100778 3.989970963218456e-008

> 9

（5）luopt::Opt(f, ... ...)：求无约束或约束条件下的n维极小值，可用于解方程（组）

有些方程（组）用常规方法求解比较困难，须借助于优化函数Opt求解。

很少有软件可求解以下方程组：

> a*exp(-b*7.85)+c*exp(-d*7.85)=28.9
> -a/b*exp(-b*7.85)-c/d*exp(-d*7.85)=500
> a/b^2*exp(-b*7.85)+c/d^2*exp(-d*7.85)=233
> a*exp(-b*1.85)+c*exp(-d*1.85)=20.9

代码：

> !!!using["luopt"];
> f(a,b,c,d:f1,f2,f3,f4)=
> f1=a*exp(-b*7.85)+c*exp(-d*7.85)-28.9,
> f2=-a/b*exp(-b*7.85)-c/d*exp(-d*7.85)-500,
> f3=a/b^2*exp(-b*7.85)+c/d^2*exp(-d*7.85)-233,
> f4=a*exp(-b*1.85)+c*exp(-d*1.85)-20.9,
> sqrt[(f1*f1+f2*f2+f3*f3+f4*f4)/4];
> Opt[@f, optwaysimdeep, optwayconfra];

多次运行，可得以下2组解（a,b,c,d，误差）：

> 19.08176873960328 -5.36612020972517e-002 -0.1719391618522963 -4.244947571876434e-003 1.70094863414172e-013
> -0.1719391618522608 -4.244947571876049e-003 19.08176873960331 -5.366120209725268e-002 7.53644380168212e-015

3.4 微积分 [返回页首]

（1）IMSL::QDAGS(F,A,B,ERRABS,ERRREL,&ERREST)：计算一个函数的积分（可能在端点存在奇异）

F：Lu一元函数句柄。该函数由用户定义。
A,B：积分下限及积分上限。
ERRABS：期望的绝对精度。ERRABS>=0。可缺省该参数，缺省值为0.0。
ERRREL：期望的相对精度。ERRREL>=0。可缺省该参数，缺省值为1e-6。
ERREST：返回计算的绝对误差。可缺省该参数。
返回值：积分值。

[例子] 求函数f(x)=ln(x)/sqrt(x)在0～1上的积分值

> f(x)=ln(x)/sqrt(x);
> IMSL::QDAGS[@f,0.,1.]; //得到积分值
> (:err)=IMSL::QDAGS[@f,0.,1.,0.,1e-6,&err],err; //得到积分值的绝对误差

结果：

> -4.000000000000085

> 1.354472090042691e-013

（2）IMSL::QDAG(F,A,B,IRULE,ERRABS,ERRREL,&ERREST)：基于Gauss-Kronrod法则使用自适应算法计算一个函数的积分

F：Lu一元函数句柄。该函数由用户定义。
A,B：积分下限及积分上限。
IRULE：积分法则。Gauss-Kronrod法则用于下面的点数（IRULE值：点数）：（1：7～15）、（2：11～21）、（3：15～31）、（4：20～41）、（5：25～51）、（6：30～61）。大多数函数推荐取IRULE=2；如果函数有一个奇异的峰值，取IRULE=1；如果函数是摆动的，取IRULE=6。可缺省该参数，缺省值为2。
ERRABS：期望的绝对精度。ERRABS>=0。可缺省该参数，缺省值为0.0。
ERRREL：期望的相对精度。ERRREL>=0。可缺省该参数，缺省值为1e-6。
ERREST：返回计算的绝对误差。可缺省该参数。
返回值：积分值。

[例子] 求函数f(x)=ln(x)/sqrt(x)在0～1上的积分值

> f(x)=ln(x)/sqrt(x);
> IMSL::QDAG[@f,0.,1.]; //得到积分值
> (:err)=IMSL::QDAG[@f,0.,1.,2,0.,1e-6,&err],err; //得到积分值的绝对误差

结果：

> -3.999999880644267

> 2.973612447385764e-006

（3）IMSL::QDAGP(F,A,B,PTS,ERRABS,ERRREL,&ERREST)：计算一个给定奇异点的函数的积分

F：Lu一元函数句柄。该函数由用户定义。
A,B：积分下限及积分上限。
PTS：数组，存放积分区间的间断点，至少要有一个间断点。通常这些间断点是被积函数出现奇异值的地方。
ERRABS：期望的绝对精度。ERRABS>=0。可缺省该参数，缺省值为0.0。
ERRREL：期望的相对精度。ERRREL>=0。可缺省该参数，缺省值为1e-6。
ERREST：返回计算的绝对误差。可缺省该参数。
返回值：积分值。

[例子] 求函数f(x)=x^3*ln{abs[(x^2-1)*(x^2-2)]}在0～3上的积分值

> f(x)=x^3*ln{abs[(x^2-1)*(x^2-2)]};
> IMSL::QDAG P[@f,0.,3.,math::ra1(1,sqrt(2.0))]; //函数math::ra1用于申请一维实数数组并赋初值

结果：

> 52.74074838347256

（4）IMSL::QDAGI(F,A,B,ERRABS,ERRREL,&ERREST)：计算一个函数在无穷区间或半无穷区间的积分

F：Lu一元函数句柄。该函数由用户定义。
A,B：积分下限及积分上限。设x是一个数，则可取的值为 A=-inf,B=x（-∞，x）；A=x,B=inf（x，+∞）；A=-inf,B=inf（-∞，+∞）。
ERRABS：期望的绝对精度。ERRABS>=0。可缺省该参数，缺省值为0.0。
ERRREL：期望的相对精度。ERRREL>=0。可缺省该参数，缺省值为1e-6。
ERREST：返回计算的绝对误差。可缺省该参数。
返回值：积分值。

[例子] 求函数x*exp[-x]在（0，+∞）上的积分值。

> f(x)=x*exp[-x];
> IMSL::QDAGI[@f,0.0,inf];

结果：

> 0.9999999999999998

（5）IMSL::TWODQ(F, A, B, G, H, IRULE, ERRABS, ERRREL, &ERREST)：计算二重积分

F：Lu二元被积函数句柄。该函数由用户定义。
A,B：积分下限与积分上限。
G,H：Lu一元函数句柄，由用户定义，用来计算内层积分的下限与上限。
IRULE：选择积分的法则。Gauss-Kronrod法则用于下面的点数（IRULE值：点数）：（1：7～15）、（2：11～21）、（3：15～31）、（4：20～41）、（5：25～51）、（6：30～61）。大多数函数推荐取IRULE=2；如果函数有一个奇异的峰值，取IRULE=1；如果函数是摆动的，取IRULE=6。可缺省该参数，缺省值为2。
ERRABS：期望的绝对精度。ERRABS>=0。可缺省该参数，缺省值为0.0。
ERRREL：期望的相对精度。ERRREL>=0。可缺省该参数，缺省值为1e-6。
ERREST：返回计算的绝对误差。可缺省该参数。
返回值：积分值。

[例子] 计算函数f(x,y)=y*cos(x+y*y)的近似积分值。外层区间取[0,1]，内层区间取[-2*x,5*x]。

> f(x,y)=y*cos(x+y*y);
> g(x)=-2*x;
> h(x)=5*x;
> IMSL::TWODQ[@f,0.,1.,@g,@h,6];

结果：

> -8.288981913740839e-002

（6）IMSL::QAND(F, math::ra1[A1, A2, ..., An, B1, B2, ..., Bn], MAXFCN, ERRABS, ERRREL, &ERREST)：计算函数在超矩形下的积分

F：Lu多元函数句柄，设有n个自变量。该函数由用户定义。
math::ra1[A1, A2, ..., An, B1, B2, ..., Bn]：数组，长度为n+n。A1, A2, ..., An是积分下限，有n个下限值。B1, B2, ..., Bn是积分上限，有n个上限值。
MAXFCN：可允许的函数估计的最大数目。必须MAXFCN<=256^n。可缺省该参数，缺省值为64^n。
ERRABS：期望的绝对精度。ERRABS>=0。可缺省该参数，缺省值为0.0。
ERRREL：期望的相对精度。ERRREL>=0。可缺省该参数，缺省值为1e-6。
ERREST：返回计算的绝对误差。可缺省该参数。
返回值：积分值。

[例子] 计算函数exp[-(x1^2+x2^2+x3^2)]在扩展的立方体（整个三维空间）上的积分的近似值。积分区间为[-2,-2,-2～2,2,2]。

> f(x1,x2,x3)=exp[-(x1^2+x2^2+x3^2)];
> IMSL::QAND[@f,math::ra1(-2,-2,-2,2,2,2)];

结果：

> 5.490551464090155

（7）IMSL::DERIV(FCN,KORDER,X,BGSTEP,TOL)：计算一元函数的一阶、二阶或三阶导数

FCN：Lu一元函数句柄，要计算该函数在X的导数。该函数由用户定义。
KORDER：导数的阶（1、2或3）。
X：被求导的点。
BGSTEP：用来计算步长的起始值，这个步长被用于计算导数。BGSTEP>0。可缺省该参数，缺省值为0.1。
TOL：允许的相对误差（0～1）。可缺省该参数，缺省值为1e-6。
返回值：函数的一阶、二阶或三阶导数。

[例子] 求函数f(x)=2*x^4+3*x在0.75处的三阶导数

> f(x)=2*x^4+3*x;
> IMSL::DERIV[@f,3,0.75];

结果：

> 36.00000000019881

3.5 微分方程求解 [返回页首]

IMSL::ode(FCN, math::ra1[t0, t1, ..., tk], math::ra1[Y1,Y2,...,Yn], TOL)：求解一次常微分方程[y'=f(t,y) ,y(t0)=y0]，Runge-Kutta方法

FCN：用户定义的函数，用于计算微分方程组中各方程右端函数值，由用户自编。该表达式有2*n+1个参数，第一个参数为自变量，随后n个参数为函数值，最后n个参数为右端函数值（即微分方程的值）。n为微分方程组中方程的个数，也是未知函数的个数。形式如下：

> f(t,y1,y2,y3,d1,d2,d3)=
> {
> d1=y2,
> d2=-y1,
> d3=-y3
> };

math::ra1[t0, t1, ..., tk]：数组，存放独立变量t。输入初始时间为t0，用户希望得到时间 t1, ..., tk 时的解。
math::ra1[Y1,Y2,...,Yn]：存放n个未知函数在起始点处的函数值Y(n)=Yn(t)。
TOL：允许误差。可缺省该参数，缺省值为1e-6。

返回值：(1+k)×(1+n)二维数组。存放(1+k)组结果（包含初始值），每一组结果即：t,Y1,Y2,...,Yn。

[例子] 设一阶微分方程组及初值为：
r'=2r-2rf, r(0)=1
f'=-f+rf, f(0)=3
计算t=1,2,...,10时的r、f的值。
程序如下：

> !!!using["IMSL","math"];
> f(t,r,f,dr,df)={dr=2*r-2*r*f, df=-f+r*f}; //函数定义
> ode[@f,ra1[0,1,2,3,4,5,6,7,8,9,10],ra1[1,3]].outa[];

结果：

> 0. 1. 3.

> 1. 7.73453e-002 1.46445

> 2. 8.49774e-002 0.577954

> 3. 0.290891 0.249253

> 4. 1.4466 0.187219

> 5. 4.05146 1.43948

> 6. 0.175618 2.2586

> 7. 6.53112e-002 0.9088

> 8. 0.147227 0.366718

> 9. 0.650596 0.187575

> 10. 3.14433 0.348821

3.6 优化拟合 [返回页首]

luopt::Opt(f, luopt::optrange,x1min,x1max,x2min,x2max,...,xnmin,xnmax, luopt::optwaysimdeep, luopt::optwayconfra, luopt::optnum,num)：求无约束或约束条件下的n维极小值

f：自定义n元函数句柄，用于计算目标函数f(x1,x2,...,xn)的值，不可缺省。该函数由用户自编，格式如下：

> f(x1,x2,...,xn)=
> {
> g(x1,x2,...,xn)
> };

luopt::optrange,x1min,x1max,x2min,x2max,...,xnmin,xnmax：指定搜索区间。若缺省该参数，则所有变量区间均为[-1e20～1e20]。
luopt::optwaysimdeep：使用单形调优法局部深度搜索。
luopt::optwayconfra：使用连分式局部搜索方法。
luopt::optnum,num：设置最多输出的极小值的个数。可以缺省该参数，默认输出1个极小值。

返回值：极小值个数。

说明1：该函数使用随机算法搜索全局最小值，故解是不稳定的，应多次搜索甚至变换参数搜索，以最小者为最优。

说明2：Opt须注册后才能使用其全部功能，请参考优化库LuOpt的说明。

例子1：计算下列目标函数的极小值点与极小值：J=100*(x1-x0*x0)2+(1-x0)2
程序如下：

> f(x0,x1)=100*(x1-x0*x0)^2+(1-x0)^2;
> fcopt::Opt[@f];

结果（最后一个数为误差，下同）：

> 1. 1. 0.

例子2：求下列隐函数z的最小值：
z=sin[(z*x-0.5)^2+2*x*y*y-z/10]*exp{-[(x-0.5-exp(-y+z))^2+y*y-z/5+3]}
其中x范围[-1,7]，y范围[-2,2]。

程序如下：

> !!!using("luopt");
> f(x,y,z)=z+1e10*{z-sin[(z*x-0.5)^2+2*x*y*y-z/10]*exp{-[(x-0.5-exp(-y+z))^2+y*y-z/5+3]}}^2; //构造目标函数，注意1e10
> Opt[@f, optwaysimdeep, optwayconfra, optrange,-1.,7., -2.,2., -1e10,1e10];

结果（需多次运行）：

> 2.898338314819993 -0.8573299220967106 -2.33540823984039e-002 -2.335408239796544e-002

例子3：拟合公式：z = p0*(1-exp(-p1*(x-p2)))+p3*x^p4+p5*x*y;

参数：p0 - p5
变量：x,y,z
数据(x,y,z)：

> 2 101 172
> 3 14 210
> 4 136 241
> 5 52 265
> 6 67 280
> 7 81 289
> 8 54 294
> 9 20 302
> 10 6 299
> 11 2 306

Lu代码：

> !!!using["luopt","math"];
> init(::Array,max)=
> {
> max=10,
> Array=new[real_s,max,3].SetArray{
> "2 101 172
> 3 14 210
> 4 136 241
> 5 52 265
> 6 67 280
> 7 81 289
> 8 54 294
> 9 20 302
> 10 6 299
> 11 2 306"
> }
> };
> f(p0, p1, p2, p3, p4, p5 :i,s,x,y,z:Array,max)=
> {
> s=0,i=0,(i<max).while{
> x=Array[i,0], y=Array[i,1], z=Array[i,2],
> s=s+[ p0*(1-exp(-p1*(x-p2)))+p3*x^p4+p5*x*y - z ]^2,
> i++
> },
> sqrt[s/max]
> };
> Opt[@f, optwayconfra];

结果（需多次求解）：

> 306.0849059154657 0.4607174830055115 0.9026291308250309 248.1563530146011 -2.274779410407842 -3.621982090081021e-003 1.506033828737254

3.7 矩阵运算 [返回页首]

矩阵运算需要使用FcMath扩展库，该库的函数通过命名空间“math”输出。

例子：

> !!!using["math"];
> main(:a,b,c)=
> a=matrix[5,1 : 1.,2.,3.,4.,5.], //生成6

×1矩阵并赋初值
b=matrix[1,6 : 1.,2.,3.,4.,5.,6.], //生成 1×5矩阵并赋初值
c=a*b, //矩阵乘
o[a,b,c,c(all:3),c(3:all),c(2,3:3,5)]; //输出5个矩阵，其中c(all:3),c(3:all),c(3,5:2,3)都是矩阵c的子矩阵，all表示取所有的行或列

结果：

> 1.

> 2.

> 3.

> 4.

> 5.

> 1. 2. 3. 4. 5. 6.

> 1. 2. 3. 4. 5. 6.

> 2. 4. 6. 8. 10. 12.

> 3. 6. 9. 12. 15. 18.

> 4. 8. 12. 16. 20. 24.

> 5. 10. 15. 20. 25. 30.

> 4.

> 8.

> 12.

> 16.

> 20.

> 4. 8. 12. 16. 20. 24.

> 12. 15. 18.

> 16. 20. 24.

3.8 函数图形 [返回页首]

LuWin窗口库由数据可视化库CChart提供支持，具有强大的绘图功能，该库的函数及常量通过命名空间“win”输出。 详细说明参考：LuWin使用说明。

LuWin中的Plot函数 不仅可以绘制函数图形，而且可以绘制动画，当然要完整掌握Plot的用法需要较多的Lu脚本知识，这里只给出Plot函数的基础用法说明。

（1）Plot函数的简单用法

> f(x)=sin[10*x]; //一元函数
> g(x)=x*sin[10*x]; //一元函数
> win::Plot[@f, @g]; //绘制函数f和g的图形

这种用法虽然简单，但需要通过菜单设置图形的属性，例如：X轴的范围、曲线的颜色等等。

以下的例子是通过脚本设置图形属性的。

（2）Ix选项

> !!!using("win"); //使用命名空间win
> f(x)=sin[10*x]; //一元函数
> g(x)=x*sin[10*x]; //一元函数
> Plot[Ix : -5.,5., @f, @g]; //绘制函数f和g的图形，Ix指出X轴绘图范围

（3）隐函数图形

> !!!using("win");
> f(x,y)=(x^2+y^2)^3-36*(x^2-y^2)^2; //二元函数确定了一个隐函数
> Plot[Ix : -8.,8., Igrid : true, //Igrid指出是否绘制网格
> @f, Arange,-8.,8., Adots,200]; //Arange指出Y的可能的变化范围 ，通常不能省略该参数；Adot指出绘图点数，绘图点数越多越准确

友情提示：隐函数绘制时，调整Arange的范围大小有助于获得更准确的图形。

（4）绘制含参变量的函数

> !!!using("win");
> f(u,x,y)= x=u*sin[u],y=u*cos[u]^2; //三元函数确定了一个含参变量的函数，第一个参数u是参变量，x和y的返回值确定了一个点
> Plot[Ix : -9.,9., @f, Arange,-9.,9.]; //Arange指出参变量u的变化范围

LuWin中还提供了功能更强大的ChartWnd函数 ，可以绘制的图像类型有：typeXY（普通XY图）、typeSplit（分裂视图）、typeShareX（共享X轴视图）、typeLayered（分层视图）、typePie（饼图）、typeStem（柱图）、typeContourLine（等高线图）、typeContourMap（云图）、type3DLine（3D曲线图）、type3DSurface（3D图面图），不再一一给出说明。

3.9 使用常量文件 [返回页首]

如果在工作或学习中经常用到一些常量，可将这些常量放到文件中，让OpenLu自动加载这些常量，提高工作效率。

常量用函数const进行定义。通常，只能将静态数据如整数、实数、复数、三维向量等定义为常量。

以下是一个常量文件，实际上是一个表达式，但只用到了const函数。

> //常量文件MyConst.txt

> const["my_num",1000], const["my_pi",3.1416], const["my_i",1-2i], //定义一些整数、实数、复数常量

> const["my::num",1000], const["my::pi",3.1416], const["my::i",1-2i], //在命名空间“my”中定义整数、实数、复数常量

> const["我的整数",1000], const["我的向量",1$5$8]; //可以使用汉字作为常量名

设常量文件MyConst.txt保存在文件夹“command”中，要想让OpenLu自动加载运行该文件，须进行如下操作：

（1）打开工作区文件，添加如下内容

//#COMMAND（必须为大写）：自定义命令，定义弹出式菜单“常量”。

#COMMAND (常量)

{

"MyConst*Command\MyConst.txt"

}

（2）在工作区文件中找到自动运行设置项 #AUTOEXE，添加 "MyConst" 自动运行项目。

//#AUTOEXE（必须为大写）：程序启动时将自动执行以下命令，这些命令必须在#COMMAND中定义。

#AUTOEXE

{

"加载运行错误描述"

"加载函数说明"

"即时编译计算"

"MyConst"

}

（3）保存工作区文件。

这样，当OpenLu重新启动时，将自动执行文件MyConst.txt的内容，自定义的常量就可以使用了。

3.10 自定义函数库 [返回页首]

将常用的函数放到函数库中，可进行代码重用，提高工作效率。

函数库中的函数，只有定义为全局函数，或者通过命名空间输出，才能被其他程序使用。以下是一个函数库文件：

> //函数库文件：面积体积公式.m

> //模块名：面积体积公式
> ////////////////////////////////////////////////////////////////////////////////
> //用全局函数输出函数。以:::开头的函数为全局函数，否则为私有函数。
> CircleArea(r)=3.1415926*r*r; //圆面积。该公式只能被本模块的表达式所访问。
> :::Circle_A(r)=3.1415926*r*r; //圆面积。
> :::Triangle_A(a,b,c:s)= {s=(a+b+c)/2, sqrt[s*(s-a)*(s-b)*(s-c)]}; //三角形面积。
> :::Cyclinder_V(r,h)=CircleArea(r)*h; //圆柱体体积。
> ////////////////////////////////////////////////////////////////////////////////
> //用命名空间输出函数
> #MODULE# //定义一个子模块
> !!!Module("Area"); //创建模块命名空间Area
> CircleArea(r)=3.1415926*r*r;
> 圆面积(r)=3.1415926*r*r;
> 三角形面积(a,b,c:s)= {s=(a+b+c)/2, sqrt[s*(s-a)*(s-b)*(s-c)]};
> 圆柱体体积(r,h)=CircleArea(r)*h;
> !!!OutFun("圆面积","三角形面积","圆柱体体积"); //输出模块命名空间中的函数
> #END# //子模块定义结束

设函数库文件“面积体积公式.m”保存在文件夹“module”中，要想在OpenLu中使用该文件，须打开工作区文件，添加如下内容 （缺省的工作区文件中已存在该内容）：

> //#MODULE（必须为大写）：设置模块。
> #MODULE
> {
> //定义模块“面积体积公式”，模块文件为“Module\面积体积公式.m”。
> "面积体积公式*Module\面积体积公式.m"
> }

保存工作区文件并执行菜单“设置->重载模块文件”。

以下代码中使用了模块“面积体积公式”：

#USE# 面积体积公式 ; //编译符#USE#指出要使用模块“面积体积公式”

Circle_A[5];

Triangle_A(3.,4.,5.);

Cyclinder_V(2.,3.);

Area::圆面积[5];

Area::三角形面积[3.,4.,5.];

Area::圆柱体体积[2.,3.];

3.11 创建命令菜单 [返回页首]

在“使用常量文件”中已经介绍了如何创建命令菜单，以及如何使OpenLu在启动时自动执行该命令，不再赘述。

4 软件组成与结构 [返回页首]

4.1 文件及文件夹 [返回页首]

OpenLu运行时至少需要MLu32.dll和lu32.dll两个动态库的支持。其他内容使OpenLu的功能更加完善。

文件 readme.htm：帮助文件。

文件夹 dll：存放Lu扩展动态库。 注意该文件夹中有一个文件“ImslErr.txt”，如果使用FcIMSL中的函数，要查看该文件中有没有错误输出。

文件夹 command：存放命令文件。

文件夹 err：存放Lu函数的错误提示文件。

文件夹 funhelp：存放Lu函数说明文件。

文件夹 ini：存放OpenLu工作区文件。

文件夹 module：存放模块文件，即自定义函数库文件。

文件夹 help：存放帮助文件。

文件夹 olu：存放用户源程序文件。

OpenLu在初次运行时，会自动加载文件夹“ini”中的默认工作区文件“OpenLu.ini”。通过该文件的配置，OpenLu自动加载了Lu扩展库文件、生成命令菜单并自动执行部分命令（Lu函数错误提示及函数说明）、加载模块文件等等。

4.2 开放式软件系统 [返回页首]

可随时将Lu扩展库添加到该系统；可根据需要自己编写函数库、命令菜单、常量文件等等。

5 更详细的帮助 [返回页首]

参考：OpenLu使用说明

访问：http://www.forcal.net/

6 问题及建议 [返回页首]

本软件旨在成为“工程计算助手”，若您有好的建议，请与我联系。

版权所有© Lu程序设计 2011-2013，保留所有权利
E-mail: forcal@sina.com QQ：630715621
最近更新: 2013年11月28日