Apple Accelerate Framework escala y normaliza un vector

¿Qué funciones puedo usar en Accelerate.framework para escalar un vector mediante un escalar y normalizar un vector? Encontré uno que creo que podría funcionar para escalar en la documentation, pero estoy confundido acerca de su funcionamiento.

 vDSP_vsma Vector scalar multiply and vector add; single precision. void vDSP_vsma ( const float *__vDSP_A, vDSP_Stride __vDSP_I, const float *__vDSP_B, const float *__vDSP_C, vDSP_Stride __vDSP_K, float *__vDSP_D, vDSP_Stride __vDSP_L, vDSP_Length __vDSP_N ); 

La forma más fácil de normalizar un vector en el lugar es algo así

 int n = 3; float v[3] = {1, 2, 3}; cblas_sscal(n, 1.0 / cblas_snrm2(n, v, 1), v, 1); 

Necesitarás

 #include <cblas.h> 

o

 #include <vblas.h> 

(o ambos). Tenga en count que varias de las funciones se encuentran en la sección "matriz" cuando operan con vectores.

Si desea utilizar las funciones de vDSP, consulte la sección División de Vector-Escalar . Hay varias cosas que puedes hacer:

  • vDSP_dotpr() , sqrt() y vDSP_vsdiv()
  • vDSP_dotpr() , vrsqrte_f32() y vDSP_vsmul() ( vrsqrte_f32() es un NEON GCC incorporado, sin embargo, por lo que debe comprobar que está comstackndo para armv7).
  • vDSP_rmsqv() , se multiplica por sqrt(n) y vDSP_vsdiv()

La razón por la que no existe una function de normalización vectorial es porque el "vector" en vDSP significa "muchas cosas a la vez" (hasta alnetworkingedor de 8192 ) y necesariamente el "vector" del álgebra lineal. Es bastante sin sentido normalizar un vector de elementos 1024 , y una function rápida para normalizar un vector de elementos 3 no es algo que haga que su aplicación sea significativamente más rápida, por lo que no hay una.

El uso previsto de vDSP es más como normalizar 1024 2 o 3 vectores de elementos. Puedo ver un puñado de maneras de hacer esto:

  • Use vDSP_vdist() para get un vector de longitudes, seguido de vDSP_vdiv() . Sin vDSP_vdist() debe utilizar vDSP_vdist() varias veces para vectores de longitud superior a 2.
  • Use vDSP_vsq() para cuadrar todas las inputs, vDSP_vadd() varias veces para agregarlas todas, el equivalente de vDSP_vsqrt() o vDSP_vrsqrt() y vDSP_vmul() o vDSP_vdiv() según corresponda. No debería ser demasiado difícil escribir el equivalente de vDSP_vsqrt() o vDSP_vrsqrt() .
  • Varias forms que pretenden su input son un vector complejo. No es probable que sea más rápido.

Por supuesto, si no tiene 1024 vectores para normalizar, no complique demasiado las cosas.

Notas:

  1. No utilizo "2-vector" y "3-vector" para evitar la confusión con el "cuatro-vector" de la relatividad.
  2. Una buena opción de n es una que casi llena tu caching de datos L1. No es dificil; Han estado relativamente fijas en 32K durante una década o más (pueden compartirse entre núcleos virtuales en una CPU hipertrípedo y algunos procesadores más antiguos / más baratos pueden tener 16K), por lo que lo máximo que debe hacer es alnetworkingedor de 8192 para tener lugar en el lugar operación en flotadores Es posible que desee restar un poco para el espacio de stack, y si está realizando varias operaciones secuenciales, probablemente desee mantener todo en caching; 1024 o 2048 parecen bastante sensatos y probablemente más obtendrán performances decrecientes. Si te importa, mide el performance …