2015-06-04 22 views
12

Haskell'deki vektör kütüphanesi ile pratik yapmanın bir yolu olarak, daha önce C yazmış olduğum bir Nelder-Mead minimizasyon algoritmasını tekrar yazmaya çalışıyorum. bazı vektör işlemlerini deyimsel olarak tercüme etmekte sorun.Haskell'de İyonatik Vektör Cebiri

Örneğin, n + 1 (filtreleme uzaklıkta bir indeks) bir listesini üzerinden n vektörleri ağırlık merkezini bulan bir fonksiyonu, C

dikkate bu

static void get_centroid(double **s, int n, int iz, 
         double *C) 
{ 
    for (int i = 0; i < n+1; i++) { 
    if (i != iz) { 
     for (int j = 0; j < n; j++) 
     C[j] += s[i][j]; 
    } 
    } 
    for (int j = 0; j < n; j++) 
    C[j] /= n; 
} 
şekilde yazılabilir

Ben Haskell içine bu tercüme denedim ve oluyor vektör cebir özünü yakalamak değil gibi bu kod oldukça inelegant bulmak aşağıdaki

import Data.Vector 
import qualified Data.Vector as V 

type Node = Vector Double 

type Simplex = Vector Node 

centroid :: Simplex -> Int -> Node 
centroid s iz = V.map (/ (fromIntegral $ V.length s)) $ V.zipWith (-) v (s ! iz) 
    where v = V.foldl go V.empty s 
     where go a b = V.zipWith (+) a b 

ile sona erdi (ve olduğu Ayrıca S [iz]) ekleyip çıkardığımdan da daha verimsiz. Bir çözüm, bir çeşit vektör uzay tipini uygulamak veya daha spesifik bir lineer cebir kütüphanesi kullanmak olacaktır, ancak bu tür ortak operasyonlar olduğundan, daha akıcı 'düz' bir çözüm olup olmadığını merak ediyordum.

+5

Bu yarışmaya neden 'Data.Vector' kullanmak istiyorsunuz? Daha spesifik bir kütüphane neredeyse kesinlikle gidilecek yoldur. Ancak, bu vektörlerle denemek isterseniz 1. Hız için "kutusuz" sürümlere geçin ve 2. Bir satır/sütun atlamak için vektör dilimleme işlemlerine bakın. – dfeuer

cevap

4

dfeuer için + 1 ile başlarım; Daha spesifik bir kütüphane neredeyse kesinlikle hem daha temiz hem de daha verimli olacaktır.

centroid' :: Simplex -> Int -> Node 
centroid' s iz = let t = foldl1 (V.zipWith (+)) (V.drop iz s) 
        n = fromIntegral (V.length t - 1) 
       in V.map (/ n) t 

sürümüne Bir genel yorum: yaratmak çok kolay "salt ne arıyorsun senin centroid fonksiyonunun daha deyimsel uygulama ise

Ancak, ben bu bir mi "Haskell kodu. İlk satırınızda, ayrıştırılması zor olan çok şey var. where bloğunuz doğru yönde adım atıyor, ancak kavramsal bileşenleri kırmak için daha da ileri gideceğim. Ayrıca, Hoogle numaralı telefondan da

. drop numaralı bir fonksiyonun olduğunu bilmiyordum, ancak var olsaydım,ve Vector'un yeni bir Vector ürününe geçtiğini biliyordum. Hoogle, Vector'u dizine eklemez, ancak vektör için API, listeler için API'ya çok benzer. "[A] -> Int -> [a]" ve "Int -> [a] -> [a]" için arama yaptım ve drop'u buldum.

(Stackage endeksi Vector, böylece aramak yok "Int -> Vektör a -> Vektör, bir" orada çalışan)

+0

Teşekkürler! Bu aradığım cevap türü. Bence katlama ve harita, her vektör operasyonunun özünü yakalar ve bunun daha karmaşık algoritmalara nasıl dönüştüğünü hayal edebilirim. –