| 76 | |
| 77 | template<typename T> |
| 78 | double LPQNorm(const Array<T> &A, double p, double q) { |
| 79 | using RT = normReductionResult<T>; |
| 80 | Array<RT> A_p_norm = createEmptyArray<RT>(dim4()); |
| 81 | |
| 82 | if (p == 1) { |
| 83 | A_p_norm = reduce<af_add_t, T, RT>(A, 0); |
| 84 | } else { |
| 85 | Array<T> P = createValueArray<T>(A.dims(), scalar<T>(p)); |
| 86 | Array<RT> invP = createValueArray<RT>(A.dims(), scalar<RT>(1.0 / p)); |
| 87 | |
| 88 | Array<T> A_p = arithOp<T, af_pow_t>(A, P, A.dims()); |
| 89 | Array<RT> A_p_sum = reduce<af_add_t, T, RT>(A_p, 0); |
| 90 | A_p_norm = arithOp<RT, af_pow_t>(A_p_sum, invP, invP.dims()); |
| 91 | } |
| 92 | |
| 93 | if (q == 1) { |
| 94 | return getScalar<RT>(reduce_all<af_add_t, RT, RT>(A_p_norm)); |
| 95 | } |
| 96 | |
| 97 | Array<RT> Q = createValueArray<RT>(A_p_norm.dims(), scalar<RT>(q)); |
| 98 | Array<RT> A_p_norm_q = arithOp<RT, af_pow_t>(A_p_norm, Q, Q.dims()); |
| 99 | |
| 100 | return std::pow(getScalar<RT>(reduce_all<af_add_t, RT, RT>(A_p_norm_q)), |
| 101 | (1.0 / q)); |
| 102 | } |
| 103 | |
| 104 | template<typename T> |
| 105 | double norm(const af_array a, const af_norm_type type, const double p, |