// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2021 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_MATH_NORM_H namespace ircd::math { template void norm(const vector_view &out, const vector_view &in, const simd::lane_type &eps, const vector_view &tmp); } /// Renormalization. /// /// TODO: Figure out how to use less double template inline void ircd::math::norm(const vector_view &__restrict__ out, const vector_view &__restrict__ in, const simd::lane_type &epsilon, const vector_view &tmp) { using singlep = simd::lane_type; using doublep = simd::lane_type; static_assert(simd::lanes() == simd::lanes()); assert(out.size() >= in.size()); assert(tmp.size() >= in.size()); const size_t num { in.size() }; const size_t elems { num * simd::lanes() }; const doublep mean ( //TODO: XXX math::mean(vector_view { reinterpret_cast(in.data()), elems }) ); for(uint i(0); i < num; ++i) { const auto wider { lane_cast(in[i]) }; tmp[i] = wider - mean; const auto res { pow(tmp[i], 2) }; out[i] = lane_cast(res); } const doublep s ( //TODO: XXX math::mean(vector_view { reinterpret_cast(out.data()), elems }) ); const doublep divisor ( sqrt(s + epsilon) ); for(uint i(0); i < num; ++i) { const auto res { tmp[i] / divisor }; out[i] = lane_cast(res); } }