指令稿檔案(Script Files)可以包含(幾乎)任何的 Octave 指令,執行指令稿時 Octave 會將其中的指令讀入後執行,就跟直接在命令列中輸入一樣,這樣可以讓使用者很方便的執行一連串的指令。
指令稿檔案與函數檔案不同,其第一行指令不可以為 function 關鍵字開頭。在指令稿檔案中可以定義多個函數,並且一次將這些函數載入(只有載入,沒有執行),由於第一行指令(不包含註解或空白行)的開頭不可以是 function,所以必須執行別的指令,若沒有需要執行其他的指令,可以加入一行沒有作用的指令,例如:
# Prevent Octave from thinking that this # is a function file: 1; # Define function one: function one () ...
若指令稿中第一個指令以 function 關鍵字開頭,Octave 會嘗試將其編譯後並執行之,並且產生一些警告訊息。
為了使 Octave 可以正確的載入指令稿檔案,可以將指令稿檔案命名為 .m 檔案,放置在載入路徑中,然後在 Octave 中輸入其主檔名,Octave 就會將其載入,其載入的規則與函數檔案相同。
Octave 在執行函數之前,並不會去檢查其中的指令是否有定義,例如 Octave 在編譯下面這個指令稿檔案時是不會出現問題的:
# not a function file: 1; function foo () do_something (); endfunction function do_something () do_something_else (); endfunction
這個指令稿檔案先定義 foo() 函數,而 foo() 函數中呼叫 do_something() 函數,雖然在定義 foo() 函數時 do_something() 函數還沒有被定義,但是因為 Octave 並沒有去執行 foo() 函數,所以此時 Octave 還不需要 do_something() 函數的定義,等到隨後 do_something() 函數定義之後,再執行 foo() 函數時,do_something() 函數已經有定義了,所以這樣寫是沒有問題的。
指令稿檔案除了命名為 .m 檔然後輸入其主檔名將其載入外,也可以使用 source() 函數載入指令稿檔案。
source (file)
source(file) 函數可以載入指令稿檔案 file,這與直接執行 .m 指令稿名稱相同,但此 file 的名稱沒有限制(可以是 .txt 或其他的檔案名稱)。
在撰寫程式時有時候會需要將函數以變數的形式傳遞,例如將一個函數指定為另一個函數的傳入參數,這時就可以利用下面介紹的方法。
函數握把(function handle)是一個指向函數的指標,其定義方式為
@function-name
例如:
f = @sin;
這樣會建立一個指向 sin() 函數的函數握把 f。
函數握把主要用於將一個函數傳遞給其他的函數(例如:quad() 與 fsolve() 函數)使用,例如:
f = @sin; quad (f, 0, pi)
輸出為
ans = 2
若要呼叫函數握把所指向的函數,可以使用 feval() 函數或是直接使用函數握把並加入參數,若沒有輸入參數,則還是要加上小括號 (),例如:
f = @sin; feval (f, pi/4)
輸出為
ans = 0.70711
f (pi/4)
輸出為
ans = 0.70711
functions (fcn_handle)
functions(fcn_handle) 函數會傳回一個包含函數握把 fcn_handle 相關訊息的資料結構(struct)。
func2str (fcn_handle)
func2str(fcn_handle) 函數會傳回一個字串,內容為函數握把 fcn_handle 所指向的函數名稱。
str2func (fcn_name)
str2func(fcn_name) 函數會將包含函數名稱的字串 fcn_name 轉為函數握把。
匿名函數(Anonymous Functions)就是沒有函數名稱的函數,其定義方式為:
@(argument-list) expression
在 expression 中所使用的變數若不在傳入參數 argument-list 中,則會由目前的變數環境中抓取。匿名函數主要用於定義一個不需要名稱的函數,例如定義一個函數並將此函數傳入 quad() 函數中:
f = @(x) x.^2; quad (f, 0, 10)
輸出為
ans = 333.33
將 sin() 函數以匿名函數包裝:
quad (@(x) sin (x), 0, pi)
輸出為
ans = 2
將 betainc() 函數包裝成 quad() 函數可以形式:
a = 1; b = 2; quad (@(x) betainc (x, a, b), 0, 0.4)
其中 betainc() 函數的參數 a 與 b 會從目前的變數環境中取得,輸出為
ans = 0.13867
行內函數(Inline Functions)是指使用 inline() 函數從一個包含程式主體(body)的字串所建立的函數,例如:
f = inline("x^2 + 2");
這樣會建立一個 f() 函數,其可接受一個輸入參數,例如 f(2)。
inline (str) inline (str, arg1, ...) inline (str, n)
inline() 函數會由包含程式主體的字串 str 建立行內函數,若只有指定一個 str 參數,則函數的參數會自動由 str 中取出,而參數的順序會依照英文字母的順序排序,而在擷取參數時 i 與 j 會被忽略,因為 i 與 j 也代表複數的虛部,使用起來容易造成混淆。所有加上小括號的名稱都會被視為函數。
參數 arg1, ... 可以指定參數的名稱。參數 n 為一個正整數,指定參數的個數為 n,若指定為 n 則所有的參數為 "x", "p1", ..., "pn"。
argnames (fun)
argnames(fun) 函數會傳回包含行內函數 fun 的所有參數名稱的字串巢狀陣列。例如:
f = inline("x^2 + 2"); argnames(f)
輸出為
ans =
{
[1,1] = x
}
formula (fun)
formula(fun) 函數會傳回行內函數 fun 的內容,例如:
f = inline("x^2 + 2"); formula(f)
輸出為
ans = x^2 + 2
char(fun) 與 formula(fun) 是相同的。vectorize (fun)
vectorize(fun) 函數會將行內函數 fun 轉為向量化的函數,即將 * 與 / 等運算子替換為 .* 與 ./ 等運算子。例如:
f = inline("x^2 + 2"); vectorize(f)
輸出為
ans = f(x) = x.^2 + 2
symvar (s)
symvar(s) 函數會從包含函數主體的字串 s 中擷取出所有的函數參數,並以巢狀陣列傳回,一般的常數會被忽略(例如:pi、 NaN、 Inf、 eps、 i 或 j),若沒有找到任何參數,則傳回空的巢狀陣列。例如:
symvar("x^2 + 2 + y")
輸出為
ans =
{
[1,1] = x
[2,1] = y
}