10/24/2006

While 迴圈

While迴圈
利用while...end是可以不確定執行次數下停止,利用if...end則可協助判斷。以求多項式之x²-2x-5之根為例,先確定可能根的範圍,例如:b>x>a,則可利用分段法逐漸迫近解:


% find root of athe polynormial f(x)=x^3-2x-5
a=0;fa=-Inf;
b=3;fb=Inf;
while b-a>eps*b
x=(a+b)/2;
fx=x^3-2*x-5;%polynormial
if sign(fx)==sign(fa)
a=x;fa=fx;
else
b=x;fb=fx;
end
end
x
-------------------------------------

上述之解法中,先設定a與b之值及其對應之f值,由於後者之第一次較難掌握,故只要使用正負無窮大之值作為起點。進入後,即進行二分法,求得新x值即可確定得到f的對應值。當然在這裡設定負無窮大在a=0這邊,也有點冒險。執行的結果如下:

>> format long
>> ex01

x =

2.09455148154233

10/23/2006

如何轉換細胞陣列與結構陣列

細胞陣列與結構陣列之轉換

細胞陣列與結構陣列兩者間都是屬於資料結構之表示法,故其間之轉換也是一項重要的步驟,通常使用如下兩指令:


  • struct2cell:由結構陣列轉為細胞陣列。
    cell2struct:由細胞陣列轉為結構陣列。


  • 第一項可以直接由結構轉換細胞陣列,但會失去欄位之資訊。
    第二項由細胞陣列轉換為在後面多加兩項參數,其一為欄位名稱,其二為其維度。其指令型式為:


    c = struct2cell(s)
    s = cell2struct(c, fields, dim)


    舉例:

    >> clear book, book.category = 'novel'; ...
    book.name = '請用文明來說服我'; book.author = '龍應台'...
    ;book.price=500;
    >> book

    book =

    category: 'novel'
    name: '請用文明來說服我'
    author: '龍應台'
    price: 500

    >> cost=struct2cell(book) %由book結構轉為cost細胞陣列

    cost =

    'novel'
    '請用文明來說服我'
    '龍應台'
    [ 500]

    >> cost{3} %使用大括號

    ans =

    龍應台

    >> cost(2) %使用一般括號

    ans =

    '請用文明來說服我'

    >> cost{2} %使用大括號

    ans =

    請用文明來說服我


    最後之兩個指令雖然相同,但其意義不同,前者仍然是一個細胞之型式,後者為其內容。

    下面為由細胞轉回結構陣列之情形,必須在第二項加入欄位名稱,此名稱並不一定要與原先的一致:



    >> BOOK=cell2struct(cost,{'class' 'Book_name' 'Author' 'Price'})

    BOOK =

    class: 'novel'
    Book_name: '請用文明來說服我'
    Author: '龍應台'
    Price: 500

    >> BOOK.Book_name

    ans =

    請用文明來說服我



    最後一項顯然為其內容。若原來資料有多筆記錄,則必須加入dim之參數。

    排序的問題

    陣列的排序常按大小以升幂(asend)或降幂(descend)排列,其指令型式為sort()或sortrows()。這兩種指令之結果略有不同,茲以magic(6)所產生的矩陣為例:


    >> AA=magic(6)

    AA =

    35 1 6 26 19 24
    3 32 7 21 23 25
    31 9 2 22 27 20
    8 28 33 17 10 15
    30 5 34 12 14 16
    4 36 29 13 18 11

    >> sort(AA)%依行向方式排列

    ans =

    3 1 2 12 10 11
    4 5 6 13 14 15
    8 9 7 17 18 16
    30 28 29 21 19 20
    31 32 33 22 23 24
    35 36 34 26 27 25

    >> sort(AA,2)%依列向方式排列


    ans =

    1 6 19 24 26 35
    3 7 21 23 25 32
    2 9 20 22 27 31
    8 10 15 17 28 33
    5 12 14 16 30 34
    4 11 13 18 29 36

    >> sort(AA,2,'descend')%依列向且以降幂方式排列

    ans =

    35 26 24 19 6 1
    32 25 23 21 7 3
    31 27 22 20 9 2
    33 28 17 15 10 8
    34 30 16 14 12 5
    36 29 18 13 11 4

    %可以依
    >> D=[[2 2 3 3 4 4]' AA(:,[1:3])] %先造一個新矩陣

    D =

    2 35 1 6
    2 3 32 7
    3 31 9 2
    3 8 28 33
    4 30 5 34
    4 4 36 29

    >> sortrows(D,[1 2]) %依第一及第二行排列

    ans =

    2 3 32 7
    2 35 1 6
    3 8 28 33
    3 31 9 2
    4 4 36 29
    4 30 5 34

    最大值與最小值

    最大值與最小值分別使用max()與min()兩函數即可求得,兩者之參數型式均相同。但其結果均是以行向比較,不是列向。例如:


    >> a=magic(5)

    a =

    17 24 1 8 15
    23 5 7 14 16
    4 6 13 20 22
    10 12 19 21 3
    11 18 25 2 9

    >> max(a)

    ans =

    23 24 25 21 22



    若要使用列向表示,則必須在第三參數上標明,其第三參數即為ndim值,至於第二參數則為另一組比較的陣列,若僅求一個矩陣之列向最大或最小值,則第二參數以[ ]空矩陣取代即可,而令ndim=2,如:

    >> max(a,[],2)

    ans =

    24
    23
    22
    21
    25

    >> min(a)

    ans =

    4 5 1 2 3

    >> min(a,[],2)

    ans =

    1
    5
    4
    3
    2

    使用轉置指令亦可得到列向最小值,只是所得的為列向量,必須調整才能符合原先之需求:

    >> min(a')

    ans =

    1 5 4 3 2


    若是兩個相同大小之矩陣進行比較大小時,則可將第二矩陣置於第二參數位置,而ndim值同樣有效,只是其預設值為ndim=1:

    >> B=[1:10]';
    >> b=[10:-1:1]';
    >> max(B,b)

    ans =

    10
    9
    8
    7
    6
    6
    7
    8
    9
    10

    在左邊的輸出參數第一項為行向或列向之最大或最小值,其第二項輸出則為其在該行向或列向之所在位置:

    >> [m,I]=max(a)

    m =

    23 24 25 21 22


    I =

    2 1 5 4 3


    不過,若兩矩陣作比較,求取陣列中之最大或最小值時,輸出項中不能有第二參數,因為各參數之同列或同行進行比較,均為已知。

    10/22/2006

    一個向量的絕對值

    絕對值為一個向量之無符號正值,其指令為abs()。例如一向量m如下:


    >> m=[-5:5]
    m =
    -5 -4 -3 -2 -1 0 1 2 3 4 5

    >> abs(m)
    ans =
    5 4 3 2 1 0 1 2 3 4 5

    但是向量若為複數,則其絕對值為該複數之模數,或實量,例如:


    >> mm=[3+4i;4+9i;5-4i],x=abs(mm)
    mm =
    3 + 4i
    4 + 9i
    5 - 4i
    x =
    5
    9.8489
    6.4031

    所以,若以複數型式表示兩相垂直之座標量,則利用abs之絕對值功能可以求得其向量之絕對值。亦即若


    R= a + bi


    則|R|=(a*a+b*b)1/2,而|R|=abs(a+bi)

    若一個向量超過二項單元,則亦可使用下列計算求得其絕對值:

    >> aaa=[3 4 5 12];r=sqrt(aaa*aaa')
    r =
    13.928
    >> aaa=[3 4];r=sqrt(aaa*aaa')
    r =
    5

    向量之長度

    一個向量之長度及絕對值可以利用length()指令。此指令在於求得向量之長度或元素個數。例如:


    >> a=1:9
    a =
    1 2 3 4 5 6 7 8 9
    >> length(a)
    ans =
    9
    >> length(a')
    ans =
    9

    後者顯示:這個length指令不論向量為行向量或列向量,均取其最大數目之行數或列數。即使a為矩陣,其結果應與max(size(a))相同。

    >> aa=[0:9;0:9]
    aa =
    0 1 2 3 4 5 6 7 8 9
    0 1 2 3 4 5 6 7 8 9
    >> max(size(aa))
    ans =
    10
    >> length(aa)
    ans =
    10


    下面為向量aa之元素三次方和之指令。開始時先假設aa為數目未知之向量,故必須使用length函數指令來求得其數目,然後再予以三次方並相加:

    >> aa=[1 4 3 5];x=0;for i=1:length(aa),x=x+aa(i)^3,end
    x =
    1
    x =
    65
    x =
    92
    x =
    217

    如何延長指令行數

    如何延長指令長度

    下面是一個將魔術函數轉為行向量,再轉為2X8的矩陣B:


    >> A_magic_elements=magic(4);B=reshape(A_magic_elements(:),2,8)
    B =
    16 9 2 7 3 6 13 12
    5 4 11 14 10 15 8 1

    >> A_magic_elements=magic(4);B=reshape(A_magic_elements...
    (:),2,8)


    注意在上一行之最後項加上三連續點後,要按shift-enter才能接續整個指令之陳述,不能只按enter,否則會立即執行該不完整的指令,因而會得到錯誤指示。

    B =
    16 9 2 7 3 6 13 12
    5 4 11 14 10 15 8 1


    同一個指令亦可利用這種方式分成好幾行一齊執行:

    >> A_magic_elements=magic(4);...
    B=reshape(A_magic_elements...
    (:),2,8)
    B =
    16 9 2 7 3 6 13 12
    5 4 11 14 10 15 8 1