2013年6月27日木曜日

matlab: 一目で分かる多次元インデクス

matlab の配列参照に使うインデクスの基礎について.

まずはこれ.一目で分かる多次元インデクス!
a を [4 by 3 by 2] なる 3 次元配列とすると,

A three dimensional [4 by 3 by 2] array

その要素の番号は

Index / subscript correspondences of [4 by 3 by 2] array 'a'

となるのだ~! この表の意味は,例えば「a(2,3,2)とa(2,6)とa(22)は同じ要素を指す!」ということ.行列(2次元配列)の場合は,真ん中と右に注目してもらえばOK. さっきの例では a(2,6) と a(22) だね.

もうわかった?ともかく説明しよう.

3 次元配列 a の参照の仕方は
  1. a(i1, i2, i3)
  2. a(i1, i2)
  3. a(i1)
の3通り.s = size(a) とすると,s = [4,3,2] であって,式で書けば
通し番号 = (i3-1) * s(2) * s(1) + (i2-1) * s(1) + i1
となる.方式 2 では i3 = 1, 方式 3 では i3 = 1, i2 = 1 を補えばよい.例えば,
(3, 1, 2) の要素の通し番号 = (2-1) * 3 * 4 + (1-1) * 4 + 3 = 15
(3, 4) の要素の通し番号 = (1-1) * 3 * 4 + (4-1) * 4 + 3 = 15
(15) の要素の通し番号 = (1-1) * 3 * 4 + (1-1) * 4 + 15 = 15
となるわけだ.上の図と見比べてみると,方式 1, 2, 3 と通し番号との対応がわかるだろう.

多次元インデクス(サブスクリプト)と通し番号(リニアインデクス,リニアサブスクリプト)の相互変換は,sub2ind や ind2sub を使っても行える.

sub2ind は,多次元インデクスをリニアインデクスに変換する.
k = sub2ind( [4, 3, 2], 3, 1, 2 )
k = sub2ind( [4, 3, 2], 3, 4 )
k = sub2ind( [4, 3, 2], 15 )
はいずれも k = 15 を返す.

一方,ind2sub は,リニアインデクスを多次元インデクスに変換する.
>> i1 = ind2sub( [4, 3, 2], 15 )
i1 =
    15

>> [i1, i2] = ind2sub( [4, 3, 2], 15 )
i1 =
     3
i2 =
     4

>> [i1, i2, i3] = ind2sub( [4, 3, 2], 15 )
i1 =
     3
i2 =
     1
i3 =
     2
となる.

このプロセスは何次元配列にでも適用できる.つまり,N 次元配列を M 個の数字からなるサブスクリプトで参照するときは (ここでは M < N とするよ), 3 次元配列を 2 個や 1 個の数字からなるサブスクリプトで参照したときと同様,余りの次元は全て展開されて並べられたものとして考えると良い.

ちなみに,インデクスのやりとりをするには,セル配列を使うのも便利だ.
セル配列の使い方については当ブログの記事
も参照されたし.

[matlab 記事インデックスへ]

2013年6月10日月曜日

matlab: セル配列で困っている人へ

matlab に慣れてきた人でも,「セル配列」をすっきり理解しきれた気がしない,という人は多いかもしれない.そうした向きへセル配列の解説を試みる.

まとめ 兼 目次

  • セル配列とは「セル(=1×1のセル配列)」を並べた配列である.
  • 「セル」は,任意のデータを中括弧で囲むと出来る.B = {A} など.
    •  どんなタイプのものも中括弧 {} で囲むとセルになるということ.
  • セル配列の作り方は,根源的には 1) データを中括弧 {} で囲む(大括弧 [] 同様,複数のデータを一度に囲っても良い),2) cell 関数を使って空のセル配列を作る,3) struct2cell を使って構造体から変換する,の3通りで,この他に num2cell, mat2cell, cellstr という変換関数を使う方法もある.もちろん,個々のセルを配列として並べて大括弧 [] で囲んでも良い.
  • 小括弧 () を用いてアクセスすると,通常の配列と同様,部分配列を参照できる.
    • 取り出された部分配列もセル配列.
  • 中括弧 {} を用いてアクセスすると,セルの中身を取り出せる.
    • インデクス(=サブスクリプト)の解釈(参照される要素がどれになるか)は小括弧と同様.
    • 複数要素を参照すると,複数の文(式)を次々に実行(評価)したのと同じ結果になる.実行順序はリニアインデックス順.
  • 大事なのでもう一度.中括弧 {} アクセスは,複数文相当の表現!
  • セル配列に代入するには,次のいずれかの方法をとる.
    • 左辺を小括弧指定,右辺をサイズの適合するセル配列にする.例: a(1:3) = {'foo', 100, true};
    • 左辺を大括弧+中括弧指定,右辺を複数文相当の表現にする.例:[a{:}] = deal(100, 'strings', true);
  • 複数文相当の表現の使い道
    • 小括弧 () 受け:サブスクリプト,関数に入力引数を渡す
    • 中括弧 {} 受け:セル配列のサブスクリプト
    • 大括弧 [] 受け:連結,関数の出力引数を受け取る

注意


では,始めよう.


2013年6月3日月曜日

互換性: ボールペン替え芯実践編: ZEBRA JF-0.5 → uni-ball Signo RT UMN-105EW

替え芯互換性の実践レポート.ゼブラ ZEBRA JF-0.5芯 を 三菱 uni-ball Signo RT: UMN-105EW (本来の替え芯 UMR-85N) に入れてみた.

この組み合わせは互換リストに挙がっている.しかし,微妙に違う外形をしており,そのまま使うと芯出しノックのときにものすごく気合を入れて押し込まないといけない.芯のトータルの長さはほぼ同じだが,太い部分の長さが少しだけ違うからだ.
photo by bun6. 上: UMR-85N, 下:JF-0.5. 先端付近の形状の差.
そのままでも気合で何とかはなるが,JF-0.5の後部(太い方)の末尾を 1mm 程度削ったところ(丈夫なハサミならできる),ある程度スムーズになった.

※2013/08/05 追記:別の個体では削らなくても平気だった.勘違い?個体差?

ということで,結果:
  • ゼブラ ZEBRA JF-0.5芯 → 三菱 uni-ball Signo RT: UMN-105EW
    • そのまま入れても使えるが,ノックに気合がいる
      •  芯の後部太い方を 1mm ほどカットするとまあ普通に使える
    • 追記:そのまま入れてスムーズに使える場合もあるようだ
amazon で jf-0.5を検索umr-85nを検索すると,本数や色など結構いろいろバリエーションがある.

こんなちょっとしたことでも,分解したり組み立てたりするのは楽しいものですね.
UMR-85N を ZEBRA のボールペンに入れるとどうなるかも試してみたいところ.