| 60 | |
| 61 | template<typename T> |
| 62 | double vectorNorm(const Array<T> &A, double p) { |
| 63 | using RT = normReductionResult<T>; |
| 64 | if (p == 1) { return getScalar<RT>(reduce_all<af_add_t, T, RT>(A)); } |
| 65 | if (p == af::Inf) { |
| 66 | return getScalar<RT>(reduce_all<af_max_t, RT, RT>(cast<RT>(A))); |
| 67 | } else if (p == 2) { |
| 68 | Array<T> A_sq = arithOp<T, af_mul_t>(A, A, A.dims()); |
| 69 | return std::sqrt(getScalar<RT>(reduce_all<af_add_t, T, RT>(A_sq))); |
| 70 | } |
| 71 | |
| 72 | Array<T> P = createValueArray<T>(A.dims(), scalar<T>(p)); |
| 73 | Array<T> A_p = arithOp<T, af_pow_t>(A, P, A.dims()); |
| 74 | return std::pow(getScalar<RT>(reduce_all<af_add_t, T, RT>(A_p)), (1.0 / p)); |
| 75 | } |
| 76 | |
| 77 | template<typename T> |
| 78 | double LPQNorm(const Array<T> &A, double p, double q) { |