2014-01-16 13 views
11

Juliaでは、1列とn行の配列を定義すると "n要素配列"のインスタンスが生成されるように見えますが、これはnx1とどのように違うのか分かりません配列:これは、のようないくつかの予期しない(私には)行動につながるジュリアのnx1配列とn要素配列の相違

julia> transpose(transpose(b)) 
3x1 Array{Int64,2}: 
1 
2 
3 

:私は二度n要素の配列の転置を取る場合紛らわしいこと

julia> a = [1 2 3] 
1x3 Array{Int64,2}: 
1 2 3 

julia> b = [1;2;3] 
3-element Array{Int64,1}: 
1 
2 
3 

は、戻り値の結果は、NX1の配列です。

julia> size(b) == size(transpose(transpose(b))) 
false 
件の

私の質問:

  1. NX1アレイとn要素の配列の違いは何ですか?
  2. 私が与えた二重転置の例のようなことをしないでnx1配列を作成するにはどうすればよいですか?

答えて

17

クイック回答:

  1. n X1たりN要素の配列であるのに対し、1X nアレイは、2次元マトリクス(単にこれだけ一つの行または列を持つように起こること)であります1次元列ベクトル。
  2. 私はn x1配列リテラルを作成する最も簡単な方法は、行ベクトルの転置を取っていると思う:[1 2 3]'。これとは逆に、vecを使用して、任意のn次元配列を1-dベクトルに平坦化することができます。

それは、なぜこの問題を考えるために、しかし、はるかに有益です。 Juliaのタイプシステムは、タイプに完全に基づいて設計されていますが、値ではありません。配列の次元数は型情報に含まれていますが、行数と列数は異なります。したがって、nx1行列とn要素ベクトルの違いは、それらが異なる型を持つことです...型推論エンジンは、行列には​​1つの列しかないことが分かりません。

ジュリアから最高のパフォーマンスを得るには、タイプの安定したという関数を書く必要があります(特にコア言語とライブラリの設計者)。つまり、関数は引数の型に基づいて純粋にどの型を返すかを推測できるはずです。これにより、コンパイラは、型の追跡を失うことなく、関数を介して変数を追跡することができます。その結果、特定の型に対して非常に高度に最適化されたコードを生成することができます。

ここで、もう一度転置について考えてみましょう。型安定した転置関数が必要な場合は、少なくとも2次元の配列を返す必要があります。ディメンションの1つが1であり、依然として良好なパフォーマンスを維持している場合は、何か面倒なことを行うことはできません。

メーリングリストとGitHubの両方の問題には、まだベクトル転置に関する議論がたくさんあります。開始するにはここをクリックしてください:Issue #2686: ones(3) != ones(3)''また、関連する問題についてのより深い議論のために:Issue #3262: embed tensor-like objects as higher-dimensional objects with trailing singleton dimensions。どちらも最終的には置き換えられ、Issue #4774: Taking vector transposes seriouslyに組み込まれました。ジュリア0.6ため


更新:ジュリアは今、ベクトルを取るには、非常に真剣に転置します!ベクトル転置では、1行の行列のように機能する特別なRowVector型が返されるようになりましたが、正確に1つの行があるという追加の知識があります。また、元のベクトルへの怠惰な "ビュー"です。問題の例では、これはsize(b) == size(transpose(transpose(b)))が真であるだけでなく、b'' === bであることを意味します。

Julia 0.6の次元を変更する変形操作を指定する方が少し簡単です。上の質問2(nx1配列の作成)に対する素敵な答えはreshape([1,2,3], :, 1)です。 :で指定されるディメンションは、ソース配列の長さに一致するように計算されます。