工程计算助手
?
歡迎訪問 Lu程序設計
工程計算助手
| 1 概述 | 3 基本計算 | 4 軟件組成與結構 |
| 2 基礎知識 | 3.1 表達式計算 | 4.1 文件及文件夾 |
| 2.1 啟動界面及工作模式 | 3.2 求和與求積 | 4.2 開放式軟件系統 |
| 2.2 代碼格式 | 3.3 解方程 | 5 更詳細的幫助 |
| 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 代碼重用 |
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::QDAGP[@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須注冊后才能使用其全部功能。如果沒有注冊,當優化參數多于2個時,Opt函數僅返回最小值,不能返回優化參數。目前免費注冊,用函數luopt::OptPassword獲取機器碼后,通過E-mail發送到forcal@sina.com獲取注冊碼,同時允許免費用戶的E-mail在網上發布。
??? 函數OptPassword的格式(返回值及參數pw1,pw1,... ...,pwn將返回多個機器碼):luopt::OptPassword(&pw1,&pw1,... ...,&pwn)
??? 函數OptPassword的用法1:luopt::OptPassword();
??? 函數OptPassword的用法2:(:pw)=luopt::OptPassword(&pw),pw;
??? 函數OptPassword的用法3:(:pw)=luopt::OptPassword(0,&pw),pw;
??? 獲取注冊碼后,打開OpenLu中的工作區文件,修改以下部分(注冊碼在冒號后):"dll\LuOpt32.dll:604508320"
??? 例子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 使用常量文件? [返回頁首]
??? 如果在工作或學習中經常用到一些常量,可將這些常量放到文件中,讓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.9 自定義函數庫? [返回頁首]
??? 將常用的函數放到函數庫中,可進行代碼重用,提高工作效率。
??? 函數庫中的函數,只有定義為全局函數,或者通過命名空間輸出,才能被其他程序使用。以下是一個函數庫文件:
//函數庫文件:面積體積公式.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.10 創建命令菜單? [返回頁首]
??? 在“使用常量文件”中已經介紹了如何創建命令菜單,以及如何使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-2012,保留所有權利
E-mail: forcal@sina.com? QQ:630715621
最近更新: 2011年12月31日
總結
- 上一篇: js 获取移动端设备类型及系统版本号
- 下一篇: drcom linux最新版,Ubunt