From facf580a9c7913090ed57537df57df5b64aea148 Mon Sep 17 00:00:00 2001 From: conrad Date: Sat, 8 Jun 2024 17:43:34 +1000 Subject: [PATCH] add tests for sparse stddev() --- tests2/fn_stddev.cpp | 551 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 551 insertions(+) create mode 100644 tests2/fn_stddev.cpp diff --git a/tests2/fn_stddev.cpp b/tests2/fn_stddev.cpp new file mode 100644 index 00000000..149d2b38 --- /dev/null +++ b/tests2/fn_stddev.cpp @@ -0,0 +1,551 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2011-2023 Ryan Curtin (http://www.ratml.org/) +// Copyright 2017-2023 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +#include + +#include "catch.hpp" + +using namespace arma; + +TEST_CASE("fn_stddev_empty_sparse_test", "[fn_stddev]") + { + SpMat m(100, 100); + + SpRow result = stddev(m); + + REQUIRE( result.n_cols == 100 ); + REQUIRE( result.n_rows == 1 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) result[i] == Approx(0.0).margin(0.001) ); + } + + result = stddev(m, 0, 0); + + REQUIRE( result.n_cols == 100 ); + REQUIRE( result.n_rows == 1 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) result[i] == Approx(0.0).margin(0.001) ); + } + + result = stddev(m, 1, 0); + + REQUIRE( result.n_cols == 100 ); + REQUIRE( result.n_rows == 1 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) result[i] == Approx(0.0).margin(0.001) ); + } + + result = stddev(m, 1); + + REQUIRE( result.n_cols == 100 ); + REQUIRE( result.n_rows == 1 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) result[i] == Approx(0.0).margin(0.001) ); + } + + SpCol colres = stddev(m, 1, 1); + + REQUIRE( colres.n_cols == 1 ); + REQUIRE( colres.n_rows == 100 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) colres[i] == Approx(0.0).margin(0.001) ); + } + + colres = stddev(m, 0, 1); + + REQUIRE( colres.n_cols == 1 ); + REQUIRE( colres.n_rows == 100 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) colres[i] == Approx(0.0).margin(0.001) ); + } + } + + + +TEST_CASE("fn_stddev_empty_cx_sparse_test", "[fn_stddev]") + { + SpMat > m(100, 100); + + SpRow result = stddev(m); + + REQUIRE( result.n_cols == 100 ); + REQUIRE( result.n_rows == 1 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) result[i] == Approx(0.0).margin(0.001) ); + } + + result = stddev(m, 0, 0); + + REQUIRE( result.n_cols == 100 ); + REQUIRE( result.n_rows == 1 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) result[i] == Approx(0.0).margin(0.001) ); + } + + result = stddev(m, 1, 0); + + REQUIRE( result.n_cols == 100 ); + REQUIRE( result.n_rows == 1 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) result[i] == Approx(0.0).margin(0.001) ); + } + + result = stddev(m, 1); + + REQUIRE( result.n_cols == 100 ); + REQUIRE( result.n_rows == 1 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) result[i] == Approx(0.0).margin(0.001) ); + } + + SpCol colres = stddev(m, 1, 1); + + REQUIRE( colres.n_cols == 1 ); + REQUIRE( colres.n_rows == 100 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) colres[i] == Approx(0.0).margin(0.001) ); + } + + colres = stddev(m, 0, 1); + + REQUIRE( colres.n_cols == 1 ); + REQUIRE( colres.n_rows == 100 ); + for (uword i = 0; i < 100; ++i) + { + REQUIRE( (double) colres[i] == Approx(0.0).margin(0.001) ); + } + } + + + +TEST_CASE("fn_stddev_sparse_test", "[fn_stddev]") + { + // Create a random matrix and do variance testing on it, with varying levels + // of nonzero (eventually this becomes a fully dense matrix). + for (int i = 0; i < 10; ++i) + { + SpMat x; + x.sprandu(50, 75, ((double) (i + 1)) / 10); + mat d(x); + + SpRow rr = stddev(x); + rowvec drr = stddev(d); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + rr = stddev(x, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + rr = stddev(x, 1, 0); + drr = stddev(d, 1, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + SpCol cr = stddev(x, 0, 1); + vec dcr = stddev(d, 0, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + cr = stddev(x, 1, 1); + dcr = stddev(d, 1, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + // Now on a subview. + rr = stddev(x.submat(11, 11, 30, 45), 0, 0); + drr = stddev(d.submat(11, 11, 30, 45), 0, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 35 ); + for (uword j = 0; j < 35; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + rr = stddev(x.submat(11, 11, 30, 45), 1, 0); + drr = stddev(d.submat(11, 11, 30, 45), 1, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 35 ); + for (uword j = 0; j < 35; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + cr = stddev(x.submat(11, 11, 30, 45), 0, 1); + dcr = stddev(d.submat(11, 11, 30, 45), 0, 1); + + REQUIRE( cr.n_rows == 20 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 20; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + cr = stddev(x.submat(11, 11, 30, 45), 1, 1); + dcr = stddev(d.submat(11, 11, 30, 45), 1, 1); + + REQUIRE( cr.n_rows == 20 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 20; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + // Now on an SpOp (spop_scalar_times) + rr = stddev(3.0 * x, 0, 0); + drr = stddev(3.0 * d, 0, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + rr = stddev(3.0 * x, 1, 0); + drr = stddev(3.0 * d, 1, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + cr = stddev(4.5 * x, 0, 1); + dcr = stddev(4.5 * d, 0, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + cr = stddev(4.5 * x, 1, 1); + dcr = stddev(4.5 * d, 1, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + // Now on an SpGlue! + SpMat y; + y.sprandu(50, 75, 0.3); + mat e(y); + + rr = stddev(x + y); + drr = stddev(d + e); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + rr = stddev(x + y, 1); + drr = stddev(d + e, 1); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + cr = stddev(x + y, 0, 1); + dcr = stddev(d + e, 0, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + cr = stddev(x + y, 1, 1); + dcr = stddev(d + e, 1, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + } + } + + + +TEST_CASE("fn_stddev_sparse_cx_test", "[fn_stddev]") + { + // Create a random matrix and do variance testing on it, with varying levels + // of nonzero (eventually this becomes a fully dense matrix). + for (int i = 0; i < 10; ++i) + { + SpMat > x; + x.sprandu(50, 75, ((double) (i + 1)) / 10); + cx_mat d(x); + + SpRow rr = stddev(x); + rowvec drr = stddev(d); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + rr = stddev(x, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + rr = stddev(x, 1, 0); + drr = stddev(d, 1, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + SpCol cr = stddev(x, 0, 1); + vec dcr = stddev(d, 0, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + cr = stddev(x, 1, 1); + dcr = stddev(d, 1, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + // Now on a subview. + rr = stddev(x.submat(11, 11, 30, 45), 0, 0); + drr = stddev(d.submat(11, 11, 30, 45), 0, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 35 ); + for (uword j = 0; j < 35; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + rr = stddev(x.submat(11, 11, 30, 45), 1, 0); + drr = stddev(d.submat(11, 11, 30, 45), 1, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 35 ); + for (uword j = 0; j < 35; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + cr = stddev(x.submat(11, 11, 30, 45), 0, 1); + dcr = stddev(d.submat(11, 11, 30, 45), 0, 1); + + REQUIRE( cr.n_rows == 20 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 20; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + cr = stddev(x.submat(11, 11, 30, 45), 1, 1); + dcr = stddev(d.submat(11, 11, 30, 45), 1, 1); + + REQUIRE( cr.n_rows == 20 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 20; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + // Now on an SpOp (spop_scalar_times) + rr = stddev(3.0 * x, 0, 0); + drr = stddev(3.0 * d, 0, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + rr = stddev(3.0 * x, 1, 0); + drr = stddev(3.0 * d, 1, 0); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + cr = stddev(4.5 * x, 0, 1); + dcr = stddev(4.5 * d, 0, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + cr = stddev(4.5 * x, 1, 1); + dcr = stddev(4.5 * d, 1, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + // Now on an SpGlue! + SpMat > y; + y.sprandu(50, 75, 0.3); + cx_mat e(y); + + rr = stddev(x + y); + drr = stddev(d + e); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + rr = stddev(x + y, 1); + drr = stddev(d + e, 1); + + REQUIRE( rr.n_rows == 1 ); + REQUIRE( rr.n_cols == 75 ); + for (uword j = 0; j < 75; ++j) + { + REQUIRE( drr[j] == Approx((double) rr[j]) ); + } + + cr = stddev(x + y, 0, 1); + dcr = stddev(d + e, 0, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + + cr = stddev(x + y, 1, 1); + dcr = stddev(d + e, 1, 1); + + REQUIRE( cr.n_rows == 50 ); + REQUIRE( cr.n_cols == 1 ); + for (uword j = 0; j < 50; ++j) + { + REQUIRE( dcr[j] == Approx((double) cr[j]) ); + } + } + } + + + +TEST_CASE("fn_stddev_sparse_alias_test", "[fn_stddev]") + { + sp_mat s; + s.sprandu(70, 70, 0.3); + mat d(s); + + s = stddev(s); + d = stddev(d); + + REQUIRE( d.n_rows == s.n_rows ); + REQUIRE( d.n_cols == s.n_cols ); + for (uword i = 0; i < d.n_elem; ++i) + { + REQUIRE(d[i] == Approx((double) s[i]) ); + } + + s.sprandu(70, 70, 0.3); + d = s; + + s = stddev(s, 1); + d = stddev(d, 1); + for (uword i = 0; i < d.n_elem; ++i) + { + REQUIRE( d[i] == Approx((double) s[i]) ); + } + }