2016-06-01 7 views
1

まず、質問の不明瞭なタイトルについてお詫び申し上げます。理由は私が仕事場での数学的プロセスを特定できなかったからです。ここでPythonでの連続ベクトル減算または「減算畳み込み」?

は、一言で言えば状況です:

  1. 私は長さの異なる2つのベクトルf1とf2を、持っています。
  2. f1とf2の間の最小二乗距離を計算したいと思います。

ここでは、(4メガバイトのファイルから生成された)、しかし、私は進んでどのように大規模なベクトルF1に起因する

import numpy as np 

def distLstSq(f1,f2): 
    "Return the least square distance between f1 and f2 per unit element" 
    return np.sum(np.square(np.subtract(f1,f2)))/len(f1) 

f1 = np.arange(100) 
f2 = np.random.random_integers(1,100,5) 

nBuf = len(f2) 
dist = np.empty(len(f1)-nBuf) 
for i in range(len(f1)-nBuf): 
    temp = f1[i:i+nBuf] 
    dist[i] = distLstSq(temp,f2) 

ですが、私は、任意のよりエレガントなニシキヘビ解決策がなかったかどうかを疑問に思いました。少ないCPUリソースで短時間で実行できます。おそらく一種の「減算畳み込み」で、f2がf1の上をスライドする、要素ごとに、各ステップで減算操作を行います。

お寄せいただきありがとうございます!

ベルトラン

+1

の長さに依存しますか? – Divakar

+0

* "私は2つのベクトルf1とf2を持っています..." *しかし* "... aとbの間の距離" *。私は 'a'と' b'は 'f1'と' f2'と仮定しました。あれは正しいですか?また、実行可能なMVCE(http://stackoverflow.com/help/mcve)が役立ちます。 –

+0

フィードバックいただきありがとうございます、私はあなたの発言に従って投稿を更新しました。 –

答えて

2

まず、私はdistにおける用語の数がlen(f1)-nBufしかしlen(f1)-nBuf+1ではないことを指摘したいと思います。これは、短い方のベクトルが長い方のベクトルと完全に重なる方法です。ただ定数によってスケーリングされlen(f1)、除算を無視

、あなたはF2の各スライスのために次のことを計算している。

summation

だから私はあなたには、いくつかで操作の数を減らすことができると思います事前計算。また、クロスワードを見つけるのにnp.convolveを使うこともできます。

f1_squared = f1**2 
f2_squared_sum = np.sum(f2**2) 
nBuf = len(f2) 
cross_terms = -2*np.convolve(f1, f2[::-1], "valid") 
# reverse f2 to get what we want. 
# "valid" returns where vectors completely overlap 
squared_distance = [f2_squared_sum + np.sum(f1_squared[i:i+nBuf]) + cross_terms[i] 
        for i in xrange(len(cross_terms))] 
mean_squared_distance = np.array(squared_distance)/nBuf 

あなたのバージョン:

timeit.timeitに基づいて
nBuf = len(f2) 
dist = np.empty(len(f1)-nBuf+1) 
for i in xrange(len(f1)-nBuf+1): 
    temp = f1[i:i+nBuf] 
    dist[i] = distLstSq(temp,f2) 

、私のバージョンは、30から50パーセント高速です。

np.sum(f1_squared[i:i+nBuf])を繰り返して操作するので、パフォーマンスをさらに向上させることができます。合計を行うには、いくつかの分割と征服の方法があるはずです。

また、私はscipy.signal.fftconvolvenp.convolveよりも速いことができると思うが、これは、 `` poly`をdistLstSqPoly`and何短いベクトル(see here)

+0

フィードバックをいただきありがとうございます:私は(私は約70000とf2約300の長さの周りのf1)で作業しているスケールでは、違いはあなたのコードで私は10-20%速くなります。 –

+0

また、あなたのメソッドには1つの警告があると思います。オーバーフローを避けるために(私は16ビットの符号なし整数を使用していますが、関数を32ビットとしてキャストする必要があります。あなたのケースでは、演奏するキャストが増えています。私が扱っているスケール(それぞれ約70000とf2の長さは約300です)では、速度を50%下げます。つまり、メモリの消費量が少ない他の解決策がない場合は、私は推測します。 –

+0

符号なし整数を使用している場合は、どのように整数アンダーフローを処理しますか? (x^2 + y^2)> = 2xyなので、アンダーフローを避けることができます。または、両方のメソッドが32ビット符号付きintにキャストされていることを意味しますか? – bernie