2012-06-07 20 views
32

norm'u denedim, ancak yanlış sonuç verdiğini düşünüyorum. (c(1, 2, 3) norm sqrt(1*1+2*2+3*3), ancak 6 döndürür ..R'deki bir vektörün Euclidean normu nasıl hesaplanır?

x1 <- 1:3 
norm(x1) 
# Error in norm(x1) : 'A' must be a numeric matrix 
norm(as.matrix(x1)) 
# [1] 6 
as.matrix(x1) 
#  [,1] 
# [1,] 1 
# [2,] 2 
# [3,] 3 
norm(as.matrix(x1)) 
# [1] 6 

kimse R bir vektör normunu hesaplamak için fonksiyon ne biliyor mu

+1

"norm" oldukça düşünmüyor ne norm içten bir SVD yapar Bunun nedeni muhtemelen bu. Sqrt (sum (x^2)) 'yi deneyin. R "ne bekliyorsun" diyor. “norm” ve “dist”, bir matrisin satırları arasında genelleştirilmiş mesafe hesaplamaları sağlamak için tasarlanmıştır. –

+0

Bu, bileşenlerin her birinin karekökünü kareye bölen bir vektör döndürür, böylece * 1 2 3 * yerine Euclidean Norm – runlevel0

cevap

36

Bu onlara kendini yazmaya önemsiz bir işlevdir:

norm_vec <- function(x) sqrt(sum(x^2)) 
Ayrıca olarak normunu bulabilirsiniz
+11

Hey, telif hakkını yukarıdaki yorumdan ihlal ettiniz! Senden sonra bir RIAA avukatı ekibi gönderiyorum. :-) –

+4

@CarlWitthoft Sadece gittim ve bazı telif hakları ödedim, umarım hepimiz kare oluruz. :) – joran

+5

Bu cevaba katılmıyorum. R'de hemen hemen her zaman mevcutsa yerleşik bir işlev kullanmak istersiniz. Son derece optimize edilmişlerdir. Bernd'in cevabı doğru cevaptır. Buna rastlarsanız, aşağı doğru ilerleyin ve bunu gerçekleştirmek için uygun R işlevini kullanın. – Dalupus

2

:

Result<-sum(abs(x)^2)^(1/2) 

YA Hatta Ayrıca olarak deneyebilirsiniz:

Result<-sqrt(t(x)%*%x) 

İkisi aynı cevabı

+4

İki basitleştirme: Eğer 'x' bileşenleri gerçek sayı ise, abs (x)^2'yi x^2 ile değiştirebilirsiniz. Benzer şekilde, '% *%' vektörleri gerektiği gibi aktarır, böylece t (x)% *% x' x% x% x' için basitleştirebilirsiniz. – jochen

11
norm(x, type = c("O", "I", "F", "M", "2")) 

varsayılan "O" olduğunu verecektir. "O", "o" veya "1" bir norm belirtir (maksimum mutlak sütun toplamı);

"F" veya "f" Frobenius normunu belirtir (x'in bir vektör olduğu gibi muamele edilen Euclidean normu); Sonuç Yani sqrt(1*1+2*2+3*3)

aynı

norm(as.matrix(x1),"o") 

sonuç 6'dır,

norm(as.matrix(x1),"f") 

norm(as.matrix(x1)) olarak, norm(as.matrix(x1),"f") cevaptır.

0

Matrisinizi cbind kullanarak sütun mengenesi olarak oluşturun, ardından norm işlevi bir argüman olarak Frobenius norm (Euclidean norm) ile iyi çalışır.

x1 < -cbind (1: 3)

normu (x1, "F")

[1] 3,741657

sqrt (1 x 1 + 2 * 2 + 3 * 3)

[1] 3,741657

35
norm(c(1,1), type="2")  # 1.414214 
norm(c(1, 1, 1), type="2") # 1.732051 
+1

Bu, R'nin dahili optimizasyonları kullanmasına izin veren doğru yanıttır. – Dalupus

+0

Bu, benim için jorah'ın cevabından daha fazla zaman alır. Zamanlamaları kontrol etmek için AbdealiJK'nin cevabına bakınız. – Vincent

2

I'mma benzer adlı vektör/cross product ile R'ın crossprod karıştırmayın eşdeğer Ar ifadesi

norm_vec(x) <- function(x){sqrt(crossprod(x))} 

olarak da orada bu dışarı atmak. Bu isimlendirme, özellikle fizik/mekanik geçmişi olanlarda confusion neden olduğu bilinmektedir.

+0

Kesinlikle, yazdığım kod söylediklerinizi yapacaktı ama ben sadece vektör norm hesaplamasını vurgulamaya çalışıyordum. Joran'ın adlandırma kuralını burada takip edeceğim. Iyi öneri. – jxramos

1

Verileriniz varsa.çerçeve veya bir data.table 'DT', ve her bir sıraya göre Euclidian normu (norm 2) hesaplamak isteyin, apply fonksiyonu kullanılabilir.

apply(X = DT, MARGIN = 1, FUN = norm, '2') 

Örnek:

>DT 

     accx  accy  accz 
1: 9.576807 -0.1629486 -0.2587167 
2: 9.576807 -0.1722938 -0.2681506 
3: 9.576807 -0.1634264 -0.2681506 
4: 9.576807 -0.1545590 -0.2681506 
5: 9.576807 -0.1621254 -0.2681506 
6: 9.576807 -0.1723825 -0.2682434 
7: 9.576807 -0.1723825 -0.2728810 
8: 9.576807 -0.1723825 -0.2775187 

> apply(X = DT, MARGIN = 1, FUN = norm, '2') 
[1] 9.581687 9.582109 9.581954 9.581807 9.581932 9.582114 9.582245 9.582378 
8

kimsenin yukarıda önerilen yöntemleri için sonuçlar profilleme çalıştı şaşırdım, bu yüzden yaptım. Bir liste oluşturmak için rastgele bir üniforma fonksiyonu kullanılır ve tekrarı (kriter zarfının tipi için basit bir arka) için bunu kullandım:

> uut <- lapply(1:100000, function(x) {runif(1000, min=-10^10, max=10^10)}) 
> norm_vec <- function(x) sqrt(sum(x^2)) 
> norm_vec2 <- function(x){sqrt(crossprod(x))} 
> 
> system.time(lapply(uut, norm_vec)) 
    user system elapsed 
    0.58 0.00 0.58 
> system.time(lapply(uut, norm_vec2)) 
    user system elapsed 
    0.35 0.00 0.34 
> system.time(lapply(uut, norm, type="2")) 
    user system elapsed 
    6.75 0.00 6.78 
> system.time(lapply(lapply(uut, as.matrix), norm)) 
    user system elapsed 
    2.70 0.00 2.73 

elle ardından Sqrt Güç alarak ve daha hızlı görünüyor olduğunu Gerçek değerler için en az norm numaralı yapı.

> norm 
function (x, type = c("O", "I", "F", "M", "2")) 
{ 
    if (identical("2", type)) { 
     svd(x, nu = 0L, nv = 0L)$d[1L] 
    } 
    else .Internal(La_dlange(x, type)) 
} 

ve SVD fonksiyonu dahili olarak bir matris içine vektör dönüştürür ve daha karmaşık şeyler yapar:

> svd 
function (x, nu = min(n, p), nv = min(n, p), LINPACK = FALSE) 
{ 
    x <- as.matrix(x) 
    ... 
+0

Bu sorunun "Bunu yapmak için R'yi nasıl alabilirim?" optimizasyon Aynı zamanda R'de kendi mesafe fonksiyonumu yaptım, sonra yerleşik fonksiyonun ne olduğunu ve neden sadece "norm (v)" denemediğini merak ettim haha. Ayrıca fonksiyonumun hızını da kontrol ettim. –

İlgili konular