FC2ブログ

初心者によるMATLABメモ

3次元形状やってんのになぜかMATLABを使わされることになった人のメモ。

 

検索エンジンから来た方は読みたい記事が表示されていない可能性があります。
その場合、左メニューのフォームでブログ内を検索すると見たい記事を見れると思います。
もしくは、カテゴリー名をクリックしていただくと各カテゴリーの記事のリストが見れます。

[雑記,愚痴] 初心表明

なんかひょんなことから強制的にMATLABで作業しなくてはならなくてはなったので,いろいろメモしていこうかなと。

しかし,コード書きづらくてしょうがない。
文法変だし。
あと,付属のエディタはありえん,重たすぎ。
使ってないけど。
スポンサーサイト



このエントリに付けられたタグ|

[基本] コロン演算子(:)

MATLAB始めて絶対いきなり詰まったこと。
というか普通の人なら,これ詰まるよ。
コロン演算子(:)
人のソース見るとこれが一杯出てくるけど,なんだこりゃ?

一応こことか見りゃなんとなくわかるが,もっと詳しく書いておいてくんないと無理っす。
要は等差級数の1次元配列(行)のショートカットなのか?と今は思い中。

a:b = [a,a+1,...,b]
a:c:b = [a,a+c,a+2c, ...,b]

というか
a:bがa:1:bのショートカット.


実行例で言うとこんな感じ。

基本形
1:5 = [1,2,3,4,5]

[実行例]
>> disp(1:5)
1 2 3 4 5


ステップ幅を2に。
1:2:5 = [1,3,5]

[実行例]
>> disp(1:2:5)
1 3 5


ステップ幅は整数でなくてもよい。
1:1.5:5 = [1,2.5,4]

[実行例]
>> disp(1:1.5:5)
1.0000 2.5000 4.0000

ここでわかるように上端に指定した値を超えた場合,上端の値は返らない。(ここなら上端5は結果得られる行列に含まれていない.)

あと,下限>上限だと空の行列が返る。
>> 2:1
ans =
Empty matrix: 1-by-0


あ、ちなみに縦(列)の等差級数はこんな感じでとりあえず作れる.
>> disp([1:4]');
1
2
3
4


というかまだ書こうと思ったことがあったりして長くなりそうなので「コロン演算子(:)part.2」に続く…
このエントリに付けられたタグ|MATLABコロン演算子

[雑記,愚痴] ドキュメント…残念ながら英語で頑張るしか…

あ、今までサイバネットの日本語ドキュメントで逃げてきたけど。
今更見たら、全然
公式サイトのドキュメントの方がアツイでやんの…

こんなに内容違うのか…
コロン演算子の説明も英語の方が全然わかりやすい…
colon (:) :: Functions (MATLAB Function Reference)

Optimization Toolboxの説明も…
諦めて英語読むしかないのか…
サイバネット頑張ってよ。
このエントリに付けられたタグ|MATLAB

[基本] 配列のインデックス内のコロン演算子(:)

公式サイトのドキュメントによるまとめ。
配列のインデックスに出現するコロン演算子(:)。

A(:,j) … Aのj列目.
A(i,:) … Aのi行目.
A(:,:) … 元の2次元配列と等価.行列ならA自体.
A(j:k) … A(j), A(j+1),...,A(k).1次元配列Aのj番目からk番目までスライス.
A(:,j:k) … A(:,j), A(:,j+1),...,A(:,k).j列目からk列目までスライス.
A(:,:,k) … 3次元配列のkページ目.
A(:) … A のすべての要素を1列に変換.

とりあえず例はそれぞれエントリ化する予定…
バラバラにした方があとでブログ内で検索したときにやりたいことがすぐ見つかるかな?と思うので。
このエントリに付けられたタグ|MATLABコロン演算子配列

[基本] 行列から列を取り出す

行列Aから列を取り出すコマンド.

A(:,i) … m×nの行列A(2次元配列A)のi列目が取り出せる.
A(:,i:j) … m×nの行列A(2次元配列A)のi列目からj列目までが取り出せる.
A(:,i:k:j) … m×nの行列A(2次元配列A)のi列目からk列おきにj列目までが取り出せる.


実行例はこんな感じ.
行列Aを定義.
>>A=[1:5;6:10;11:15;16:20]
A =
     1     2     3     4     5
     6     7     8     9    10
    11    12    13    14    15
    16    17    18    19    20

行列Aの2列目を取り出す.
>>A(:,2)
ans =

     2
     7
    12
    17

行列Aの2列目から4列目までを取り出す.
>>A(:,2:4)
ans =
     2     3     4
     7     8     9
    12    13    14
    17    18    19

行列Aの偶数列(2列おきに)を取り出す.
>>A(:,2:2:4)
ans =
     2     4
     7     9
    12    14
    17    19

このエントリに付けられたタグ|MATLABコロン演算子配列行列

[基本] 行列から行を取り出す

行列Aから行を取り出すコマンド.

A(i,:) … m×nの行列A(2次元配列A)のi行目が取り出せる.
A(i:j,:) … m×nの行列A(2次元配列A)のi行目からj行目までが取り出せる.
A(i:k:j,:) … m×nの行列A(2次元配列A)のi行目からk行おきにj行目までが取り出せる.


実行例はこんな感じ.
行列Aを定義.
>> A=[1:5;6:10;11:15;16:20]
A =
     1     2     3     4     5
     6     7     8     9    10
    11    12    13    14    15
    16    17    18    19    20

行列Aの2行目を取り出す.
>> A(2,:)
ans =
     6     7     8     9    10

行列Aの2行目から4行目までを取り出す.
>> A(2:4,:)
ans =
     6     7     8     9    10
    11    12    13    14    15
    16    17    18    19    20

行列Aの奇数行目(2行おきに)を取り出す.
>> A(1:2:3,:)
ans =
     6     7     8     9    10
    16    17    18    19    20

このエントリに付けられたタグ|MATLABコロン演算子配列行列

[Geometry] ベクトルの内積(ドット積)

なんかGeometryとかゆーカテゴリ作ったけど何も書いてなかったと思ったので今日は内積でも。
とはいえ厳密な定義とかよくわからんのでそっちはこれとかこれを見てください。

とりあえず,公式のドキュメントサイバネットのドキュメントによれば,下記.

関数dot()
C = dot(A,B) = ベクトルAとBのスカラ積.
C = dot(A,B,dim) = AとBの次元dimのスカラ積.

ただ,列ベクトルの集合に対してなら,
function Rdot(A,B) = sum(A.*B)
とかを定義した方が個人的にはよいかと思っている最中.(2006/10/19現在)

自分で定義した関数は遅くなりがちなので頑張ってdot(A,B)と書くところをsum(A.*B)と書いた方が速いです。
一文字しか違いませんし。(2006/11/03現在)

一応,行ベクトルの集合に対してなら,
function Rdot(A,B) = sum([a.*b]')'とか.
だけど,そもそもdot()が列ベクトルの集合にに対して定義されているのでベクトルを行で表すのはやめたほうがよい.

ちなみに,ただのベクトル同士なら下記の方が計算が速い.
行ベクトル同士ならa*b'
列ベクトル同士ならa'*b

ちなみに,sum(A.*B)は内積の別の表現法.実際,ここにも書いてある.

あとは下記ダラダラ実行例書いておきます.
まずは行ベクトルとしてA,Bを定義して計算してみる.
>> a=rand(1,3)
a =
    0.1389    0.2028    0.1987
>> b=rand(1,3)
b =
    0.6038    0.2722    0.1988

計算的には下記のどれでも一緒.
>> dot(a,b)
ans =
    0.1786
>> a*b'
ans =
    0.1786
>> sum(a.*b)
ans =
    0.1786

ただ,計算時間を見てみると…
>> tic;dot(a,b);toc
経過時間は0.000115秒です
>> tic;a*b';toc
経過時間は0.000033秒です
>> tic;sum(a.*b);toc
経過時間は0.000034秒です

標準関数のdotなんか遅い…

続いて,列ベクトルで計算してみる.どっちかというと列ベクトルであつかう方が自然かなぁと。
>> a=a';b=b'; ←転置です,一応
>> dot(a,b)
ans = 0.1786
>> a'*b
ans = 0.1786
>> sum(a.*b)
ans = 0.1786

もちろん計算結果は変わらない.

こちらもあいも変わらずdotは遅い.
a*b'とかa'*bが最速?
>> tic;dot(a,b);toc
経過時間は0.000115秒です
>> tic;a'*b;toc
経過時間は0.000032秒です
>> tic;sum(a.*b);toc
経過時間は0.000033秒です

上に「a*b'とかa'*bが最速?」とか書いたけど,やってみればわかるが,ならこいつらは,ベクトル群だと計算できないことに気づく.

列ベクトル群としてa,bを定義して計算してみる.
a,bをそれぞれ7つの3次元ベクトルの集合として定義.
>> a=rand(3,7)
a =
    0.8385    0.7027    0.6946    0.9568    0.1730    0.2523    0.1365
    0.5681    0.5466    0.6213    0.5226    0.9797    0.8757    0.0118
    0.3704    0.4449    0.7948    0.8801    0.2714    0.7373    0.8939
>> b=rand(3,7)
b =
    0.1991    0.2844    0.9883    0.5155    0.2259    0.5298    0.3798
    0.2987    0.4692    0.5828    0.3340    0.5798    0.6405    0.7833
    0.6614    0.0648    0.4235    0.4329    0.7604    0.2091    0.6808

そして実行結果と計算時間です。
ここでもやはりdotは遅いです…
>> dot(a,b)
ans =    0.5817    0.4851    1.3852    1.0488    0.8135    0.8488    0.6697
>> sum(a.*b)
ans =    0.5817    0.4851    1.3852    1.0488    0.8135    0.8488    0.6697

>> tic;dot(a,b);toc
経過時間は0.000109秒です
>> tic;sum(a.*b);toc
経過時間は0.000035秒です

あと,さっきも書いたように,もちろん下記はコケます.数学的に考えればわかるかと…
もちろん行ベクトルの集合にたいしてのa*b'も駄目です.
>> a'*b
ans =
    0.5817    0.5290    1.3167    0.7823    0.8005    0.8856    1.0157
    0.5975    0.4851    1.2015    0.7374    0.8140    0.8154    0.9980
    0.8496    0.5406    1.3852    0.9096    1.1215    0.9321    1.2916
    0.9288    0.5744    1.6230    1.0488    1.1884    1.0257    1.3720
    0.5067    0.5265    0.8569    0.5339    0.8135    0.7759    1.0180
    0.7995    0.5304    1.0720    0.7417    1.1254    0.8488    1.2838
    0.6220    0.1023    0.5203    0.4613    0.7174    0.2667    0.6697


続いて,行ベクトル群の場合.
しかし,dot()がそもそも列ベクトルに対して定義されているので無駄な表現になる.
これはsum()を用いた表現も同様で,ドキュメントにも『Aが行列の場合、sum(A)は Aの列をベクトルとして扱い、各列の和を行ベクトルとして出力します。』と書いてあるので転置しないといけないので冗長である.
基本的にベクトルは列で表す方がよい。
というか,個人的にそうじゃないと気持ち悪い.
>> a=a';b=b';
>> dot(a',b')'
ans =
    0.5817
    0.4851
    1.3852
    1.0488
    0.8135
    0.8488
    0.6697
>> sum([a.*b]')'
ans =
    0.5817
    0.4851
    1.3852
    1.0488
    0.8135
    0.8488
    0.6697
>> tic;dot(a',b')';toc
経過時間は0.000123秒です
>> tic;sum([a.*b]')';toc
経過時間は0.000046秒です

ここまででとりあえず数値のベクトルならsum(a.*b)がよい感じ.

ここでふと思ったのだが,この方法だと
数値じゃないと計算できないのか?もしや。
と思ったのでSymbolic Math Toolboxでシンボリック変数として計算してみた。
>> syms a b px py pz qx qy qz real;
>> a=[px;py;pz];
>> b=[qx;qy;qz];
>> dot(a,b)
ans =px*qx+py*qy+pz*qz
>> a'*b
ans =px*qx+py*qy+pz*qz
>> sum(a.*b)
ans =px*qx+py*qy+pz*qz
>> tic;dot(a,b);toc
経過時間は0.015119秒です
>> tic;a'*b;toc
経過時間は0.009412秒です
>> tic;sum(a.*b);toc
経過時間は0.009085秒です


結局,工学的な幾何学的計算ではなんか標準のdot関数は僕が使う範囲では無能な気が…
次元の処理も今のところいらないし(てか、数学よく知らないんだけど次元を考えた内積ってなに?数学的に).
複素数も使いませんし.
基本的にif分でのエラーチェックもいらないからなぁ.
万能ではあるんだろうけど.

結局見たら関数dotも結局実数値のベクトルの計算なら
dot(A,B) = sum(A.*B)
って書いてあったんだよね。だから個人的にはエラーチェックなどいらんから,そっち使うかなぁ。
このエントリに付けられたタグ|MATLABベクトル内積dot

[基本] 同じ行や列を持つ行列/各行(列)ごとに特定の値を四則演算する

このエントリの方法ではなく,こちらの方法の方がよいです。

同じ行や列を持つ行列/各行(列)ごとに特定の値を四則演算する
よく使うのでメモ.
基本的にはこれです。
A = ones(size(A'))*A = 1行ベクトルAをn行に増やす.
B = B*ones(size(B')) = 1行ベクトルBをn列に増やす.

で、実行例.
行ベクトルAを同じ行を持つn×n行列に.

>> A=[1:5]
A =
     1     2     3     4     5
>> ones(size(A'))*A
ans=
     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5

列ベクトルBを同じ列を持つn×n行列に.
>> B=[1:5]'
B =
     1
     2
     3
     4
     5
>> B*ones(size(B'))
ans=
     1     1     1     1     1
     2     2     2     2     2
     3     3     3     3     3
     4     4     4     4     4
     5     5     5     5     5

j個要素を持つ列ベクトルCを同じ列を持つn×jの行列に.
>> C=rand(1,5)
C =
    0.7266    0.4120    0.7446    0.2679    0.4399
>> ones([3,1])*C
ans=
    0.7266    0.4120    0.7446    0.2679    0.4399
    0.7266    0.4120    0.7446    0.2679    0.4399
    0.7266    0.4120    0.7446    0.2679    0.4399

Dの各列に同じ値の四則演算をする.(ここでは積)
>> D=[1:5;2:2:10;3:3:15]
D =
     1     2     3     4     5
     2     4     6     8    10
     3     6     9    12    15
>> E=[1:5]
E =
     1     2     3     4     5

そのまま要素ごとの積をするとエラーが出る。
>> D.*E
??? エラー: ==> times
行列の次元は同じである必要があります

で,こうする↓
>> E=ones(length(D(:,1)),1)*E
E =
     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5
>> D.*E
ans=
     1     4     9    16    25
     2     8    18    32    50
     3    12    27    48    75
>> 

このエントリに付けられたタグ|MATLAB行列ones

[興味本位] 無駄に3個以上の数字をコロン(:)で接続してみるとどうなるか?

通常コロン(:)で数字を繋ぐのは3つまで。
つまり…
1:5
1:2:5
まで。
じゃあ,「もっと繋ぐとどうなんのさ?1:2:3:4:5:6:7:8とか」と思ったので,やってみた。

結果はこんな感じ↓。
ぱっと見わかりづらいのでワンラインのコマンドの説明を書いておくと
[1] 1:NでN個の要素を持つ行を生成
[2] int2strで文字に変換
[3] strvcatで半角スペースで接続して文字列に。
[4] regexprepで連続した半角スペースをコロン(:)に変換。
[5] evalで実行
要するに
1:2:3:4: ... :98:99:100
みたいなコマンドを実行してみた。

>> % 数字の個数が5000個(偶数)
>> eval(regexprep(strvcat(int2str(1:5000)), 's+', ':'))
ans =
  Columns 1 through 8
           1           2           3           4           5           6           7           8
(略)
  Columns 4993 through 5000
        4993        4994        4995        4996        4997        4998        4999        5000

>> % 数字の個数が5001個(奇数)
>> eval(regexprep(strvcat(int2str(1:5001)), 's+', ':'))
ans =
           1        5001


どうも結論的にはこんな感じ。

適当にコロンで繋いだ数字を連続させてみると
a:b: ... :y:z

数字の数が偶数なら
a:b: ... :z = ... = a:z

数字の数が奇数なら
a:b: ... :y:z = ... =a:y:z

しかし,単純に左から計算していってたら偶数の方も同じ結果になるはずなんだけどなぁ。
MATLAB内部でどうなってるかは謎。
誰かに教えて欲しいもの。

参考:
strvcat (MATLAB Function Reference)
int2str (MATLAB Function Reference)
regexprep :: Functions (MATLAB Function Reference)
このエントリに付けられたタグ|MATLABコロン演算子

[基本] コマンドのヘルプを見る

作業してるときに「この関数の使い方どんなのだっけ?」とかなったとき,コマンドの使い方を調べるコマンド.
help (コマンド名)

詳しく知りたい人はヘルプ見るなり,オンラインで見たほうがよいけど。
ヘルプは重たくて嫌だし,WEBで調べるのも結構ダルいので意外と使ってます。

一応ドキュメントこれ↓
help (MATLAB Function Reference)

適当に関数sumのヘルプを見る。
>> help sum
    SUM 要素の和
 
  S = SUM(X) は、ベクトル X の要素の和を出力します。
  X がベクトルの場合、S は、各列の和からなる行ベクトルです。
  X がN次元配列の場合、SUM(X) は、最初の 1 でない次元で操作します。
  X が浮動小数点、つまり、倍精度または単精度の場合、そのクラス
…(略)
このエントリに付けられたタグ|MATLABコマンドヘルプhelp

[ファイル操作] データの保存(基本形)

MATLABである変数もしくは現在使用している変数をすべて保存する方法。
基本的にこれ↓

書き込み
save - 現在の変数をmatlab.matに全部保存.
save('filename') - 現在の変数をfilenameに全部保存.
save('filename', '変数1', '変数2', ...) - 現在の変数1,変数2をfilenameに保存.
save('filename', 'オプション', '変数1', '変数2', ...) - 現在の変数1,変数2をfilenameにオプションを指定して保存.
※filenameは省略するとmatlab.matとして保存される。
※変数は省略すると全部保存される。
※オプションが何もないときはオプション'-mat'で保存。

オプション
-append - 追加書き込みモード
-regexp - 正規表現を使用.
-struct - 構造体の各フィールドを個々の変数として保存.
-ascii - ファイルの拡張子に関わらずASCII書式で保存
-ascii -double - 16桁の数字でASCII保存。
-ascii -tabs - タブで区切でASCII保存。

-mat - matファイル形式で保存。
-v4 - MATLAB4用mat-ファイルで保存。
-v6 - MATLAB6用mat-ファイルで保存。

まずデータの保存の方から。
こんな感じで適当に行列と文字列と関数を作成。
>> clear all;
>> A=rand(3)
>> Astr=num2str(rand(3));
>> Afun = @() A;
A =
    0.4418    0.6756    0.4784
    0.3533    0.6992    0.5548
    0.1536    0.7275    0.1210

でとりあえず全部保存
>> save
matlab.matに保存しています

続いて,行列Aだけを保存。
ここで注意したいのが,変数ではなく変数名の文字列を渡さないといけないところ。
>> save('onlyA','A')
変数名の文字列ではなく変数を渡すとこうなります↓
>> save('onlyA',A)
??? エラー: ==> save
引数は文字列である必要があります

最後にありそうなTab区切りのアスキーデータ(テキストファイル)で保存してみる。
>> save('ascii.mat','-ascii','-tabs','A','Astr');

ちなみに変数に関数ハンドルみたいにテキストにできないものがあると全部保存しようとするとこうなるので注意。
>> save('ascii.mat','-ascii', '-tabs')
警告: Attempt to write an unsupported data type to an ASCII file.
    Variable 'Afun' not written to file.

save :: Functions (MATLAB Function Reference)

読み込みの方はこっち
このエントリに付けられたタグ|MATLAB保存matファイルファイル操作save

[ファイル操作] データの読み込み(基本形)

MATLABでsaveコマンドで保存したmatファイルからある変数もしくはすべての変数を読み込む方法。
基本的にはこれです↓
データの読み込み
load - matlab.matからにデータを全部読み込み.
load('filename') - filenameからデータを全部読み込み.
load('filename','変数1','変数2' ...) - filenameから変数1,変数2...を読み込み。
load('filename', 'オプション', '変数1', '変数2', ...) - 現在の変数1,変数2をfilenameにオプションを指定して保存.
※変数は省略すると全部読み込まれるされる。
※変数名,filenameにはワイルドカード(*)が使用可能。
※オプションが何もないときはmatファイルとしてバイナリとして読み込み。

オプション
-regexp - 正規表現を使用.
-ascii - ファイルの拡張子に関わらずASCII書式で読み込み.
-mat - matファイル形式で読み込み。

データの読み込み例。
基のデータはこの記事参照。
matlab.matからのデータを読み込こんで表示してみる。
>> load;
matlab.matからロードしています

>> disp(A);disp(Astr);disp(Afun);
    0.4418    0.6756    0.4784
    0.3533    0.6992    0.5548
    0.1536    0.7275    0.1210

0.45075      0.2731     0.23235
0.71588     0.25477     0.80487
0.89284      0.8656      0.9084
    @() A

続いて,行列Aだけを読み込み。
ここで注意したいのが,変数ではなく変数名の文字列を渡さないといけないところ。
disp()してみるとAstrは定義されていない.
>> load('matlab.mat','A');
>> disp(A);disp(Astr);disp(Afun);
    0.4418    0.6756    0.4784
    0.3533    0.6992    0.5548
    0.1536    0.7275    0.1210

??? 'Astr' は未定義の関数、または変数です

だいたいこんな感じです。

load :: Functions (MATLAB Function Reference)
このエントリに付けられたタグ|MATLAB読み込みmatファイルファイル操作load

[興味本位] n×m行列のある部分を取得する場合

MATLAB内でn×m行列のi行目だけが欲しいときやn×m行列のi行目のs列からe列までを取得するときは通常A(i,:),A(i,s:e)とか書くと思いますが,
例えばA(i,:)はA(i:n:n*m)として書けたり,A(i,s:e)はA(n*(s-1)+i:n:n*e)とか書けたりします。
素朴な疑問として,「どっちが早いわけ?」とか無駄に思って実行してみた。
特な意味はない。

あ,ちなみにiって変数やらeって変数を使ってるけどわかりづらくなるのでよい子は使わない方向で。

以下,テスト。
100×100000の行列の4行目だけを取り出し,Bに代入って作業を1000回繰り返してみた。
>> n=1e2;
>> m=1e5;
>> A=rand(n,m);
>> B=zeros(1,m);
>> i=4;

>> tic;for ind=1:1000 B=A(i,:);end;toc;
経過時間は5.109347秒です

>> tic;for ind=1:1000 B=A(i,1:m);end;toc;
経過時間は9.265582秒です

>> tic;for ind=1:1000 B=A(i:n:n*m);end;toc;
経過時間は6.173648秒です

とりあえず標準的なスタイルのA(i,:)が最速で安心しました。
しかも結構違うし。
でも、この結果を見て気づくことが…
A(i,1:m)はA(i:n:n*m)より遅いってことはn×m行列のi行目のs列からe列までを取得するならただの1次元の配列として扱った方が早いってこと?
なわけで続いて,同じ100×100000の行列の4行目の10列目から50000列目までを取り出し,Cに代入って作業を1000回繰り返してみた。
>> i=4;
>> s=10;
>> e=5e4;
>> C=zeros(1,e-s+1);
>> ;tic;for ind=1:1000 C=A(i,s:e);end;toc
経過時間は4.339726秒です

>> tic;for ind=1:1000 B=A(i,:);C=B(s:e);end;toc
経過時間は5.998034秒です

>> tic;for ind=1:1000 C=A(n*(s-1)+i:n:n*e);end;toc
経過時間は2.778152秒です

やっぱし…
標準的なスタイルのA(i,s:e)の方が遅い…
意外だが1行のある部分を引っ張るなら1次元配列で扱ったほうが早いのか…

ちなみにわかりずらいけど両表現は同じ行列だということを書いておく。
>> isequal(A(i,s:e),A(n*(s-1)+i:n:n*e))
ans =1

最後に複数行に渡るときの場合
同じ100×100000の行列の4行目から100行目の10列目から50000列目までを取り出し,Dに代入って作業を100回繰り返してみる。
一応処理が重いので100回に減らした。
>> i=4;
>> j=100;
>> s=10;
>> e=5e4;
>> D=zeros(j-i+1,e-s+1);
>> D2=zeros(j-i+1,e-s+1);
>> tic;for ind=1:100 D=A(i:j,s:e);end;toc;
経過時間は6.269663秒です
>> tic;for ind=1:100 D2=A(ones(j-i+1,1)*[n*(s-1)+i:n:n*e]+[0:j-i]'*ones(1,e-s+1));end;toc;
経過時間は55.2068秒です
>> isequal(D,D2)
ans =1

今度は圧倒的に標準的な表現の方が早い。
まぁ下の方はインデクスの生成法が相当無茶あるので比較にならないって話だけど。

結論的には一応少なくとも僕の環境では
n×m行列のi行目のs列からe列までを取得するならただの1次元の配列として扱った方が早い模様です。

ちなみにこれは行データがほしい場合だけの特殊なケースで、n×m行列のi列目のs行からe行までを取得するなら標準的なスタイルの方が速いです。
要はA(n*(i-1)+s:n*(i-1)+e)'よりA(s:e,i)の方が速いのであしからず。まぁ転置しないといけないから当たり前なんですけど。
このエントリに付けられたタグ|MATLAB行列インデックスコロン演算子

[数値解析] 積分

だいたい本とかを見ると,
一応積分は例えば下記の関数を0,1の範囲で定積分するならこんな感じで書いてあるかと思います。
ex001

>> func1 = @(x) x+x.^2;
>> quad(func1,0,1)
ans =
    0.8333
>> quadl(func1,0,1)
ans =
    0.8333

でも,思うんですが実際に使うときは大概その関数には他の引数もあるはず。
そんなときはquadl(関数ハンドル,下限,上限,[],[],第2引数,第3引数…)とすれば渡せます。
例えば下記の関数func2についてなら,こんな感じです。
ex002

>> func2 = @(x,a,b) a.*x+b.*x.^2;
>> quad(func2,0,1,[],[],1,2)
ans =
    1.1667
>> quadl(func2,0,1,[],[],1,2)
ans =
    1.1667

ただ,個人的によくわかりませんが関数がfunc3(a,b,x)みたく定義してある場合はどうしたらいいんですかね?
一応下記の感じで無理にやればできるんだけど,もちろん実行速度はガタ落ち。
>> func3 = @(a,b,x) a.*x+b.*x.^2;
>> quadl(@(x,a,b) func3(a,b,x),0,1,[],[],1,2)
ans =
    1.1667

>> tic;quadl(@(x,a,b) func3(a,b,x),0,1,[],[],1,2);toc
経過時間は0.002313秒です
>> tic;quadl(func2,0,1,[],[],1,2);toc
経過時間は0.000756秒です

まぁそんな風には関数定義するなってことなんですかね?
どうなんでしょう?誰か教えて。

で、空行列を渡してるパラメータについては下記URLを見てください。
誤差許容範囲とかが設定できます。
quad, quad8 (MATLAB Function Reference)
quadl (MATLAB Function Reference)
このエントリに付けられたタグ|MATLAB積分

[ファイル操作] CSV形式のデータの読み書き

ありがちなcsvファイル(カンマ区切り)の読み込みと書き出しです。
ただ,ここで紹介する関数csvwriteとcsvreadはその関数名から期待されるような動きはテンでしてくれませんのであしからず…
まず『,"1,2,2",』みたいな正しいフォーマットのcsvを読みこまないのはまだ許せますが,文字列も読み込みません.
数字だけ…
まぁそれでも利用価値はあるかなぁと思うので書いておきます.
まぁ面倒でない人は,,csvread()はdlmread(filename, ',', r, c)へのショートカットなのでdlmreadを使った方がよいです。
それに他の区切り文字の場合も気にせず使えますから。
とか言うと見も蓋もないですが、ここでは一応MATLAB様が用意してくださっているcsvwriteとcsvreadを使ってみます。
一応ただ使うだけならこっちの方が便利ではあるので。

基本的にはこれです↓
書き込み = csvwrite('filename',M)もしくはdlmwrite('filename',M,',')
読み込み = M = csvread('filename') もしくは dlmread('filename',',')
部分読み込み = M = csvread('filename',row,col,range)もしくはdlmread('filename',',',range)
※rangeは省略可。指定する場合[始点行,始点列,終点行,終点列]
※ここでのrow,col,rangeにおいてはなぜかMATLAB標準の1から始まるインデックスではなく1列目が0で表されるので注意!!

実際に下記のような乱数の5x5行列Aを保存して読み込んでみます。
>> A=rand(5)
A =
    0.9501    0.7621    0.6154    0.4057    0.0579
    0.2311    0.4565    0.7919    0.9355    0.3529
    0.6068    0.0185    0.9218    0.9169    0.8132
    0.4860    0.8214    0.7382    0.4103    0.0099
    0.8913    0.4447    0.1763    0.8936    0.1389

書き込みは,こんな感じです↓
一応,書き込みの方は文字列もいけます。
>> csvwrite('Amatrix.csv',A);
>> csvwrite('abcd.csv',['a','b';'c','d']);

次に読み込み。
多分こっちの方が利用する回数は多いかと思います。
まず,ただ行列Aを読み込んでの復元。
>> clear all;
>> A = csvread('Amatrix.csv')
A =
    0.9501    0.7621    0.6154    0.4057    0.0579
    0.2311    0.4565    0.7919    0.9355    0.3529
    0.6068    0.0185    0.9218    0.9169    0.8132
    0.4860    0.8214    0.7382    0.4103    0.0099
    0.8913    0.4447    0.1763    0.8937    0.1389

続いて,行列Aの一部分を読み込んでみます。
ここで注意したいのが通常MATLABでは配列,行列において1からインデックスが始まりますが,1列目,1行目が0で表されるところ。
なんでこんな仕様になっているのかはイマイチ謎ですが,
察するにcsvread()というかdlmread()の仕様が,
ファイルから1行読み込んだ後,
setdiff(sprintf(' bt'),デリミタ文字)として
1行をデリミタ文字でスプリットして配列化しているせいかなぁとか思います。
この場合だと1列しかデータがない場合0ですからね。
で,これに合わせて行の指定の方も0から始まってるということです。
個人的にはどうせなら引数はMATLABに添った形で1づつ引いてくれよと思いますが。

まぁ結局csvファイルの場合ならば何個カンマを読んだ後のデータからを読み込むか?という方法でrowとcolを指定することになってます。
下記の例の場合,行列Aの3行目以降2列目以降のみを読み込みます。
>> A2 = csvread('Amatrix.csv',2,1)
A2 =
    0.0185    0.9218    0.9169    0.8132
    0.8214    0.7382    0.4103    0.0099
    0.4447    0.1763    0.8937    0.1389

この作業は一度全部を読み込んでA(row+1:length(A(:,1)),col+1:length(A(1,:)))を取り出すのと同じです。
>> isequal(A2,A(3:length(A(:,1)),2:length(A(1,:))))
ans =
     1

続いて,範囲指定しての行列Aの部分の取り出し。
>> A3 = csvread('Amatrix.csv',2,0,[2,0,3,2])
A3 =
    0.6068    0.0185    0.9218
    0.4860    0.8214    0.7382

このとき,始点の位置を間違えてみたりすると切り取り線の外側の範囲にある要素は0として返ってきます。
>> A3 = csvread('Amatrix.csv',1,1,[2,0,3,2])
警告: R and C should match RANGE(1:2).  Use DLMREAD(FILE,DELIMITER,RANGE) instead.
> In dlmread at 110
  In csvread at 47

A3 =
         0         0         0         0
         0    0.0185    0.9218    0.9169
         0    0.8214    0.7382    0.4103

最後に時間を計ってみましたが,csvreadの部分取出しと全体読み出し後に部分を取り出すのはあまり時間的には差異はないようです。
というかここまで書いておいてなんですが,csvread()はdlmread(filename, ',', r, c,)への単なるショートカットなので使わないのが一番アツイような気がします。
まぁそこまで遅くならないのでどうでもいいかもですが,他の区切り文字の場合も使えるという意味ではdlmread()の方を覚えておくのがよいかなぁとか思います。
>> csvwrite('Bmatrix.csv',rand(1000,10));
>> tic;for ind=1:100 B = csvread('Bmatrix.csv',20,1);end;toc;
経過時間は2.918437秒です
>> tic;for ind=1:100 B2 = csvread('Bmatrix.csv');B2=B2(21:length(B2(:,1)),2:length(B2(1,:)));end;toc;
経過時間は2.866840秒です
>> tic;for ind=1:100 B3 = csvread('Bmatrix.csv');aa=size(B2);B2=B2(21:aa(1),2:aa(2));end;toc;
経過時間は2.867893秒です
>> tic;for ind=1:100 B4 = csvread('Bmatrix.csv');B4=B4(21:1000,2:10);end;toc;
経過時間は2.891784秒です
>> tic;for ind=1:100 B5 = dlmread('Bmatrix.csv',',',20,1);end;toc;
経過時間は2.810123秒です


csvwrite (MATLAB Function Reference)
csvread (MATLAB Function Reference)
dlmread (MATLAB Function Reference)
dlmwrite (MATLAB Function Reference)
このエントリに付けられたタグ|MATLABcsvファイル操作カンマ区切り