Octave 中的數值資料包含純量(scalar)、向量(vector)與矩陣(matrix),其中的值可為實數或複數。

純量(Scalars)

最簡單的數值資料就是常數純量,其表示方法可以是整數、浮點數、分數或是科學記號, 例如:

105
1.05e+2
1050e-1

以上三個數值是一樣的。若要表示複數:

3 + 4i
3.0 + 4.0i
0.3e1 + 40e-1i

這三個複數也都表示同樣的數值,其中 i 代表複數的虛部,也就是 -1 的平方根。在 Octave 中要使用 i 來表示複數的虛部時,數字與 i 之間不能有空白,例如:

3 + 4 i

數字與 i 之間若有空白 Octave 就會產生錯誤。

代表複數虛部的 i 亦可以用 jIJ 來替代,這四個字母的功能相同。

Octave 在儲存常數純量時預設是使用雙精度浮點數(double precision)來儲存,若是複數則使用兩個雙精度浮點數儲存。

double (x)

double(x) 會將 x 轉換為雙精度浮點數後傳回,可用於純量或是矩陣。

complex (x)
complex (re, im)

complex(x) 會傳回實部為 x 虛部為 0 的複數。complex(re, im) 會傳回實部為 re 虛部為 im 的複數。使用 complex() 函數通常會比直接寫 a + bi 的形式方便,例如:

complex ([1, 2], [3, 4])

矩陣(Matrices)

定義矩陣

在 Octave 要定義一個矩陣很簡單,矩陣的大小 Octave 會自動依照使用者所輸入的資料來決定,每個列以分號(;)分隔,而一個列中的每個元素則是以逗號(,)分隔,例如:

a = [1, 2; 3, 4]

這樣會產生一個 22 的矩陣 a

在指定矩陣可以使用各種的表示方式,只要其組合起來的維度是正確的都可以被 Octave 接受,例如:

b = [a, a]

這會將兩個 a 合併起來變成一個 24 的矩陣。而若是組合起來的維度不正確,就會出現錯誤:

[a, 1]

Octave 會顯示其維度不符合:

error: number of rows must match (1 != 2) near line 5, column 5

所有在中括弧中的資料 Octave 都會視為矩陣,Octave 會自動判斷是否要將空白與換行轉換為元素與列的分隔符號,所以上面的矩陣 a 也可以寫成這樣:

a = [1 2
     3 4]

但有時候這種寫法會產生混淆,例如:

[1 - 1]

會被視為 11,所以會得到 0,而

[1 -1]

則會被視為 [1, -1]

在中括弧中呼叫函數時,也會發生類似的問題:

[sin (pi)]

會被視為 [sin, (pi)] 而產生錯誤,因為 sin() 函數必須要有一個傳入的參數,要避免產生錯誤必須把中間多餘的空白去除或是再加入一個小括弧:

[(sin (pi))]

用於矩陣轉置的單引號(')周圍的空白也要注意,例如:

a = [1, 2; 3, 4]
[a a']

若是單引號前多一個空白:

[a a ']

就會造成錯誤:

error: unterminated string constant
parse error:

  syntax error

>>> [a a ']
             ^

為了避免上述的問題,在表示矩陣時最好不要省略分號與逗號。

矩陣輸出格式

當使用者輸入的變數是矩陣時,Octave 會將矩陣的內容排版後輸出在螢幕上,以下的函數可以控制矩陣的輸出格式:

val = output_max_field_width ()
old_val = output_max_field_width (new_val)

查詢或設定數值在輸出時的最大字元寬度。

val = output_precision ()
old_val = output_precision (new_val)

查詢或設定數值在輸出時的最小有效位數。

output_max_field_width()output_precision() 函數配合可以設定各種輸出格式,使用者可以使用 format() 函數設定其組合,請參考輸入與輸出。

val = split_long_rows ()
old_val = split_long_rows (new_val)

若是矩陣太大無法一次顯示在螢幕上,Octave 預設會將矩陣的列(row)切開,每次顯示矩陣中一部分的列,split_long_rows() 函數可以查詢或設定矩陣在輸出時是否要將列(row)切開輸出,例如:

rand(2, 10)

輸出為

ans =

 Columns 1 through 7:

   0.085634   0.136640   0.455903   0.681633   0.687501   0.533536   0.461752
   0.708830   0.679109   0.119020   0.975902   0.110367   0.488791   0.518949

 Columns 8 through 10:

   0.196560   0.808889   0.576050
   0.670522   0.913750   0.866018

Octave 在輸出矩陣中非常大或非常小的數值時,會自動切換成科學記號來表示,這樣可以確保矩陣中每個元素都可以顯示較多的有效數字,若是想以固定的位數來表示矩陣中的數值,可以透過下面的函數更改設定,但更改此設定有可造成輸出的數值被誤判,因此不建議更改。

val = fixed_point_format ()
old_val = fixed_point_format (new_val)

查詢或設定是否將矩陣數值以固定位數輸出,若是設定以固定位數輸出,Octave 會以 scaled format 輸出矩陣:

fixed_point_format(1)
x=[100, 0.2; 0.3, 0.9]

輸出為

x =

  1.0e+02  *

  1.00000  0.00200
  0.00300  0.00900

輸出的第一個數值 1.0e+02 是一個係數,下方矩陣中每個數值乘上這係數就會得到原來的值,有時候這樣的輸出會產生過大的誤差:

fixed_point_format(0)
logspace(1, 7, 5)'
fixed_point_format(1)
logspace(1, 7, 5)'

因此在 fixed_point_format() 不是設定為 0 時,要注意輸出是否會產生錯誤。

空矩陣

在數學上矩陣的兩個維度有可能其中一個是 0 或是兩個都是 0 ,Octave 亦允許使用者使用一個維度或兩個維度都是 0 的矩陣,而空矩陣在輸出時預設會使用 [] 符號表示,這個可以使用下列函數設定:

val = print_empty_dimensions ()
old_val = print_empty_dimensions (new_val)

查詢或設定是否要將空矩陣的維度與 [] 符號一起輸出,例如:

zeros(3, 0)

會輸出

ans = [](3x0)

空矩陣也可以用來刪除矩陣的行或列,請參考運算。

範圍(Ranges)

範圍(Ranges)的表示法可以很方便的表示一個元素間距離相等的列向量(row vector),其表示方法是以冒號(:)分隔開始值、間距與結束值,例如要產生 13 的列向量,元素間的間距為 0.5,則:

1 : 0.5 : 3

產生的列向量等同於 [1, 1.5, 2, 2.5, 3]。間距亦可以是負的,這像會產生遞減的列向量:

3 : -0.5 : 1

若是將間距省略,則 Octave 會使用預設的間距 1 來產生列向量:

1 : 3

產生的列向量等同於 [1, 2, 3]

使用範圍表示法所得到的列向量有可能不包含範圍的結束值,例如:

1.2 : 0.3 : 2.6

若是要確保端點的值可以被納入,請使用 linspace() 函數。

除了在必要的情況,Octave 不會自動將範圍轉換成列向量,而會以範圍的形式儲存,因為列向量通常需要較多的記憶體來儲存,例如 1:10000 在 32 位元的系統就需要佔用 80,000 個位元組。當 Octave 中含有一些運算時,Octave 也會避免將範圍表示法轉換為列向量,例如:

a = 2*(1:1e7) - 1;
b = 1:2:2e7-1;

ab 所產生的列向量是一樣的,但 b 不需要建立一個長度是 10,000,000 的列向量。

範圍表示法無法接受間距為 0 的情況(也就是所有列向量的元素都相同),要產生這樣的列向量可以使用 ones() 函數,例如:

ones(1, 10)

若範圍表示法中包含運算式,Octave 在接受範圍表示法時會自動判斷此運算式是否為常數,若計算結果是常數,則會以此常數替代運算式。

單精度浮點數(Single Precision)

Octave 支援單精度浮點數運算,大部份的函數也都可以使用單精度浮點數的參數,並且以單精度浮點數傳回結果,單精度浮點數的建立可使用 single() 函數。

single (x)

single(x) 會將 x 轉換為單精度浮點數後傳回,可用於純量或是矩陣。例如:

sngl = single(rand(2, 2))
class(sngl)

有許多函數可以直接設定傳回值為單精度浮點數,例如:

ones (2, 2, "single")
zeros (2, 2, "single")
eye (2, 2,  "single")
NaN (2, 2, "single")
NA (2, 2, "single")
Inf (2, 2, "single")

整數(Integer)

Octave 支援整數的純量或矩陣,包含 8、16、32 與 64 位元的有號(signed)與無號(unsigned)整數,由於許多的運算需要使用浮點數,整數在遇到浮點運算時會自動轉換成浮點數,因此整數通常只用於儲存數值而不用來計算。

最常見的整數矩陣是將一般的浮點數矩陣轉換為整數矩陣,例如:

fmat = rand (2, 2)

輸出為

fmat =

   0.70290   0.92763
   0.80579   0.31735

int32() 函數將 fmat 轉換為 32 位元的整數矩陣:

int32(fmat)

輸出為

ans =

  1  1
  1  0

由結果看出浮點數會被轉換為最接近的整數。

isinteger (x)

isinteger(x) 可判斷 x 是否為整數。

isinteger(8) 會傳回 false,因為 Octave 所有的常數預設都是使用雙精度浮點數儲存。

int8 (x)

int8(x) 會將 x 轉換為 8 位元的有號整數後傳回。

uint8 (x)

uint8(x) 會將 x 轉換為 8 位元的無號整數後傳回。

int16 (x)

int16(x) 會將 x 轉換為 16 位元的有號整數後傳回。

uint16 (x)

uint16(x) 會將 x 轉換為 16 位元的無號整數後傳回。

int32 (x)

int32(x) 會將 x 轉換為 32 位元的有號整數後傳回。

uint32 (x)

uint32(x) 會將 x 轉換為 32 位元的無號整數後傳回。

int64 (x)

int64(x) 會將 x 轉換為 64 位元的有號整數後傳回。

uint64 (x)

uint64(x) 會將 x 轉換為 64 位元的無號整數後傳回。

intmax (type)

intmax(type) 會傳回 type 類型整數能夠儲存的最大數值,type 可以指定的類型有:"int8""uint8""int16""uint16""int32""uint32""int64""uint64"

intmin (type)

intmin(type) 會傳回 type 類型整數能夠儲存的最小數值,type 可以指定的類型有:"int8""uint8""int16""uint16""int32""uint32""int64""uint64"

intwarning (action)
intwarning (s)
s = intwarning (...)

控制整數在轉換與運算時的警告訊息設定,可用的參數有:

  • "query":查詢目前的警告訊息的設定,若沒有指定輸出參數,則會直接將輸出顯示在螢幕上,若是有指定輸出參數則會傳回 "identifier""state" 的資料結構。
  • "on":將警告訊息開啟,若是沒有指定輸出參數,則不會有傳回值,若有指定輸出參數則會傳回原本的設定。
  • "off":將警告訊息關閉,若是沒有指定輸出參數,則不會有傳回值,若有指定輸出參數則會傳回原本的設定。

例如查詢目前的設定:

intwarning("query")

關閉警告訊息,並將目前的設定儲存為 old_s

old_s = intwarning("off")

將設定還原:

intwarning(old_s)

整數運算(Integer Arithmetic)

Octave 支援一些基本的整數運算,例如:加(+)、減(-)、乘(.*)、除(./),這些運算可以用於相同類型的整數,也就是說兩個 32 位元的整數可以直接相加,但一個 16 位元與一個 32 位元的整數就無法直接相加。例如:

a = int16(10)
b = int32(10)
a + b

a 是一個 16 位元的整數而 b 是一個 32 位元的整數,若是直接相加就會出現錯誤:

error: binary operator `+' not implemented for `int16 scalar' by `int32 scalar' operations

在 Octave 中對於整數的算術運算會先將整數轉換為雙精度浮點數,經過運算之後在轉換回原來的整數類型,而雙精度浮點數只有 53 個位元可以用來表示整數,所以在 Octave 中無法進行 64 位元的整數運算。

在使用整數運算時,必須注意 underflow 與 overflow 的問題,這個問題會發生在使用的整數類型無法表示計算的結果,例如無號整數無法表示 10 - 20,而 Octave 會確保整數運算的結果是最接近真實值的整數,因此無號整數運算 10 - 20 的結果是 0

Octave 在進行整數除法的運算時,會將結果轉為最接近實際值的整數(使用 round),這與一般的程式語言不同(使用 floor),例如:

int32(5) ./ int32(8)

結果是 1

idivide (x, y, op)

使用不同的規則進行整數除法運算,Octave 預設的整數除法運算 a ./ b 會將結果轉為最接近實際值的整數(使用 round),而 idivide() 函數可以使用其他的規則來進行個別元素的整數除法運算,其中 op 參數可以指定要使用的整數除法規則:

  • "fix":將結果朝向 0 的方向轉為最接近的整數。
  • "round":將結果轉為最接近實際值的整數。
  • "floor":將結果朝向負無限大的方向轉為最接近的整數。
  • "ceil":將結果朝向正無限大的方向轉為最接近的整數。

若不指定 op 參數,預設會使用 "fix"。例如:

idivide (int8 ([-3, 3]), int8 (4), "fix")

輸出為

ans =

  0  0
idivide (int8 ([-3, 3]), int8 (4), "round")

輸出為

ans =

  -1   1
idivide (int8 ([-3, 3]), int8 (4), "ceil")

輸出為

ans =

  0  1
idivide (int8 ([-3, 3]), int8 (4), "floor")

輸出為

ans =

  -1   0

位元操作(Bit Manipulations)

Octave 提供了許多操控位元的函數,最基本的就是取得與設定數值中的指定位元:

bitset (a, n)
bitset (a, n, v)

bitset() 會設定 a 中第 n 個位元值為 v,參數 n 為大於 0 的整數;參數 v10,若是不指定則預設為 1。例如:

a = 10
dec2bin(a)
b = bitset(a, 1)
dec2bin(b)
X = bitget (a, n)

bitget(a, n) 傳回 a 中第 n 個位元值,例如:

bitget(4, 3)

參數 n 亦可以向量或範圍表示法指定:

bitget(4, 1:4)
bitget(4, 4:-1:1)
bitget(4, [1, 3])

在 Octave 中除了 bitcmp() 函數之外,所有的位元操作函數都可以接受純量或陣列,當一個以上的參數是陣列時,這些陣列必須要有相同的大小,而 Octave 會針對陣列中每個元素個別進行位元運算,若只有一個參數是陣列而其餘的參數是純量時,純量的參數會自動重複以配合陣列的元素進行運算,例如:

bitget(100, 8:-1:1)

第一個參數是純量,第二個參數是 18 陣列,因此 Octave 會將第一個參數重複 8 次,就像這樣:

bitget(100 * ones(1, 8), 8:-1:1)

這兩個寫法是一樣的。

Octave 的位元運算都是針對整數的位元作運算,即便傳入的數值是浮點數,Octave 也會自動轉為整數,例如:傳入浮點數 10 會被視為整數,因此其各個位元的值為 [1, 0, 1, 0],而不是表示浮點數的位元值。

在位元運算中常常會需要查詢可以被浮點數表示的最大的整數,尤其是在建立遮罩(mask)的時候,這時可以使用 bitmax() 函數:

bitmax ()

傳回可以被浮點數表示的最大整數,在 IEEE-754 的系統中是 2^53-1。這個函數可以看成是 intmax() 函數的浮點數版本。

Octave 也支援 andorxor 位元運算:

bitand (x, y)

bitand(x, y) 傳回 xy 的位元 AND 運算,xy 為大於或等於0 且小於或等於 bitmax 的無號整數。

bitor (x, y)

bitor(x, y) 傳回 xy 的位元 OR 運算,xy 為大於或等於0 且小於或等於 bitmax 的無號整數。

bitxor (x, y)

bitxor(x, y) 傳回 xy 的位元 XOR 運算,xy 為大於或等於0 且小於或等於 bitmax 的無號整數。

bitcmp (a, k)

bitcmp(a, k) 傳回 a 的位元 NOT 運算結果,也就是 a 的補數(complement),參數 k 是指定傳回運算結果的位元數,若不指定則預設是 log(bitmax) + 1,例如:

bitcmp(7, 4)
dec2bin(11)
dec2bin(bitcmp(11, 6))
bitshift (a, k)
bitshift (a, k, n)

bitshift(a, k, n) 傳回 a 位元 shift 的結果。參數 k 是指定 shift 的距離,正整數代表向左,負整數代表向右;參數 n 是指定傳回運算結果的位元數,若不指定則預設是 log(bitmax) + 1,例如:

bitshift (eye (3), 1)
bitshift (10, [-2, -1, 0, 1, 2])

經過位元 shift 運算超出左右兩邊邊界的位元將會遺失。

Octave 的位元 shift 運算會將負整數的負號保留,例如:

bitshift (-10, -1)
bitshift (int8 (-1), -1)

bitshift (int8 (-1), -1) 的運算結果是 -1,原因是在於 int8 類型的 -1 ,其二進位表示為 [1, 1, 1, 1, 1, 1, 1, 1],經過位元 shift 運算之後,還是維持一樣的值。

邏輯值(Logical Values)

Octave 內建支援邏輯值(truefalse)與相關的邏輯運算:AND(&)、OR(|)與 NOT(!)。

除了邏輯運算之外,Octave 亦允許在算術運算式中使用邏輯值,邏輯值在進行算術運算時會自動轉為雙精度浮點數,true 轉會 1false 轉換為0,因此

true * 22 - false / 6

結果是 22

邏輯值亦可以使用在矩陣的索引與巢狀陣列上,當矩陣使用一個邏輯像像當作索引時,會將矩陣中對應邏輯向量為 true 的元素取出,例如:

data = [1, 2; 3, 4]
idx = (data <= 2)
data(idx)

這會將 data 矩陣中小於或等於 2 的元素取出,另外一種比較精簡的寫法:

data(data <= 2)

邏輯值的建立可以從數值資料轉換而得到,或是直接使用 truefalse 函數。

logical (arg)

logical(arg) 會將 arg 轉換為邏輯值(0 轉換為 false,除了0 以外的值轉換為 true)。例如:

logical([-1, 0, 1])

[-1, 0, 1] != 0

所得到的結果是相同的。

true (x)
true (n, m)
true (n, m, k, ...)

傳回各種維度的邏輯值陣列,陣列中所有的元素都是 true,例如 33 的方陣:

true(3)

3 乘 2 的矩陣:

true(3, 2)

更高維度的陣列:

true(3, 4, 2)
false (x)
false (n, m)
false (n, m, k, ...)

傳回各種維度的邏輯值陣列,陣列中所有的元素都是 false,使用方法與 true() 函數相同。

數值類型轉換

在 Octave 中有許多運算子可以接受不同的變數類型,而 Octave 預設會將精確度較高的數值類型轉換為較低的數值類型再進行運算,這與一般程式語言中的習慣是不同的,例如:將一個 8 位元的整數與浮點數相加:

a = uint8(1) + 1

這裡的浮點數 1 會被轉型為 8 位元的整數,因此所得到的 a 是一個 8 位元的整數。而單精度浮點數與雙精度浮點數相加:

b = single(1) + 1

所得到的 b 則是單精度浮點數。

以下是各種類型的數值運算組合與所得到的結果類型:

混合運算結果
double OP singlesingle
double OP integerinteger
double OP chardouble
double OP logicaldouble
single OP integerinteger
single OP charsingle
single OP logicalsingle

這個規則亦可套用至函數的參數,例如:

min(single(1), 0)

這會傳回單精度浮點數的數值。

陣列中的值以索引的方式指定成其他類型的數值時,陣列中的數值類型不會改變,例如:

x = ones(2, 2)
x(1, 1) = single(2)

得到的 x 還是維持 22 的雙精度浮點數。

判斷數值類型

數值在運算時常常會因為遇到不同類型的數值而轉換,而在很多情況下不同的變數類型會產生不同的結果,例如內建的 abs() 函數,當輸入值是實數時,它會傳回數值的絕對值,而當輸入的值是複數時,它會傳回此複數的長度。以下是 abs() 函數的定義:

function a = abs (x)
    if (isreal (x))
        a = sign (x) .* x;
    elseif (iscomplex (x))
        a = sqrt (real(x).^2 + imag(x).^2);
    endif
endfunction

Octave 有許多函數可以查詢數值目前的類型:

isnumeric (x)

判斷 x 是否為數值物件。

isreal (x)

判斷 x 是否為實數。

isfloat (x)

判斷 x 是否為浮點數。

iscomplex (x)

判斷 x 是否為複數。

ismatrix (x)

判斷 x 是否為矩陣。

isvector (x)

判斷 x 是否為向量。

isscalar (x)

判斷 x 是否為純量。

issquare (x)

判斷 x 是否為方陣(square matrix),若為方陣則傳回 x 的維度,否則傳回0

issymmetric (x, tol)

判斷 x 是否為對稱矩陣(symmetric matrix),若為對稱矩陣則傳回 x 的維度,否則傳回0tol 參數用來設定容許的誤差值,判定 x 是否為對稱矩陣是依據

norm (x - x., inf) / norm (x, inf) < tol

來判定的,若省略 tol 參數,則會使用系統的精確度。

isdefinite (x, tol)

判斷 x 是否為正定對稱矩陣(symmetric positive definite),若為正定對稱矩陣則傳回 1,否則傳回 -1tol 參數用來設定容許的誤差值,若省略 tol 參數,則會使用 100 倍的系統精確度。

islogical (x)

判斷 x 是否為邏輯值。

isprime (x)

判斷 x 是否為質數。