1#ifndef TATAMI_MATH_HELPERS_H
2#define TATAMI_MATH_HELPERS_H
23template<
typename InputValue_ =
double>
29 static constexpr bool is_basic =
false;
31 bool is_sparse()
const {
40 template<
typename Index_,
typename OutputValue_>
41 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
42 for (Index_ i = 0; i < length; ++i) {
43 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
44 auto& val = output[i];
47 output[i] = std::abs(input[i]);
56 template<
typename Index_,
typename OutputValue_>
57 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
58 core(input, length, output);
61 template<
typename Index_,
typename OutputValue_>
62 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
63 core<Index_>(input, indices.size(), output);
66 template<
typename Index_,
typename OutputValue_>
67 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
68 core(input, number, output);
71 template<
typename OutputValue_,
typename Index_>
72 OutputValue_ fill(
bool, Index_)
const {
91template<
typename InputValue_ =
double>
97 static constexpr bool is_basic =
false;
99 bool is_sparse()
const {
107 template<
typename Index_,
typename OutputValue_>
108 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
109 for (Index_ i = 0; i < length; ++i) {
110 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
111 auto& val = output[i];
112 if (!std::isnan(val)) {
113 val = (
static_cast<InputValue_
>(0) < val) - (val <
static_cast<InputValue_
>(0));
117 if (!std::isnan(val)) {
118 output[i] = (
static_cast<InputValue_
>(0) < val) - (val <
static_cast<InputValue_
>(0));
119 }
else if constexpr(std::numeric_limits<OutputValue_>::has_quiet_NaN) {
120 output[i] = std::numeric_limits<OutputValue_>::quiet_NaN();
132 template<
typename Index_,
typename OutputValue_>
133 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
134 core(input, length, output);
137 template<
typename Index_,
typename OutputValue_>
138 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
139 core<Index_>(input, indices.size(), output);
142 template<
typename Index_,
typename OutputValue_>
143 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
144 core(input, number, output);
147 template<
typename OutputValue_,
typename Index_>
148 OutputValue_ fill(
bool, Index_)
const {
166template<
typename InputValue_ =
double,
typename Base_ = InputValue_>
183 static constexpr bool is_basic =
false;
185 bool is_sparse()
const {
195 template<
typename Index_,
typename OutputValue_>
196 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
197 for (Index_ i = 0; i < length; ++i) {
198 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
199 auto& val = output[i];
200 val = std::log(val) / my_base;
202 output[i] = std::log(input[i]) / my_base;
211 template<
typename Index_,
typename OutputValue_>
212 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
213 core(input, length, output);
216 template<
typename Index_,
typename OutputValue_>
217 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
218 core<Index_>(input, indices.size(), output);
221 template<
typename Index_,
typename OutputValue_>
222 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
223 core(input, number, output);
226 template<
typename OutputValue_,
typename Index_>
227 OutputValue_ fill(
bool, Index_)
const {
229 return std::log(
static_cast<OutputValue_
>(0));
245template<
typename InputValue_ =
double>
251 static constexpr bool is_basic =
false;
253 bool is_sparse()
const {
261 template<
typename Index_,
typename OutputValue_>
262 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
263 for (Index_ i = 0; i < length; ++i) {
264 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
265 auto& val = output[i];
266 val = std::sqrt(val);
268 output[i] = std::sqrt(input[i]);
277 template<
typename Index_,
typename OutputValue_>
278 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
279 core(input, length, output);
282 template<
typename Index_,
typename OutputValue_>
283 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
284 core(input, indices.size(), output);
287 template<
typename Index_,
typename OutputValue_>
288 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
289 core(input, number, output);
292 template<
typename OutputValue_,
typename Index_>
293 OutputValue_ fill(
bool, Index_)
const {
310template<
typename InputValue_ =
double>
316 static constexpr bool is_basic =
false;
318 bool is_sparse()
const {
326 template<
typename Index_,
typename OutputValue_>
327 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
328 for (Index_ i = 0; i < length; ++i) {
329 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
330 auto& val = output[i];
331 val = std::ceil(val);
333 output[i] = std::ceil(input[i]);
342 template<
typename Index_,
typename OutputValue_>
343 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
344 core(input, length, output);
347 template<
typename Index_,
typename OutputValue_>
348 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
349 core<Index_>(input, indices.size(), output);
352 template<
typename Index_,
typename OutputValue_>
353 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
354 core(input, number, output);
357 template<
typename OutputValue_,
typename Index_>
358 OutputValue_ fill(
bool, Index_)
const {
375template<
typename InputValue_ =
double>
381 static constexpr bool is_basic =
false;
383 bool is_sparse()
const {
391 template<
typename Index_,
typename OutputValue_>
392 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
393 for (Index_ i = 0; i < length; ++i) {
394 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
395 auto& val = output[i];
396 val = std::floor(val);
398 output[i] = std::floor(input[i]);
407 template<
typename Index_,
typename OutputValue_>
408 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
409 core(input, length, output);
412 template<
typename Index_,
typename OutputValue_>
413 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
414 core(input, indices.size(), output);
417 template<
typename Index_,
typename OutputValue_>
418 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
419 core(input, number, output);
422 template<
typename OutputValue_,
typename Index_>
423 OutputValue_ fill(
bool, Index_)
const {
440template<
typename InputValue_ =
double>
446 static constexpr bool is_basic =
false;
448 bool is_sparse()
const {
456 template<
typename Index_,
typename OutputValue_>
457 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
458 for (Index_ i = 0; i < length; ++i) {
459 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
460 auto& val = output[i];
461 val = std::trunc(val);
463 output[i] = std::trunc(input[i]);
472 template<
typename Index_,
typename OutputValue_>
473 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
474 core(input, length, output);
477 template<
typename Index_,
typename OutputValue_>
478 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
479 core(input, indices.size(), output);
482 template<
typename Index_,
typename OutputValue_>
483 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
484 core(input, number, output);
487 template<
typename OutputValue_,
typename Index_>
488 OutputValue_ fill(
bool, Index_)
const {
506template<
typename InputValue_ =
double,
typename Base_ = InputValue_>
523 static constexpr bool is_basic =
false;
525 bool is_sparse()
const {
533 template<
typename Index_,
typename OutputValue_>
534 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
535 for (Index_ i = 0; i < length; ++i) {
536 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
537 auto& val = output[i];
538 val = std::log1p(val) / my_base;
540 output[i] = std::log1p(input[i]) / my_base;
551 template<
typename Index_,
typename OutputValue_>
552 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
553 core(input, length, output);
556 template<
typename Index_,
typename OutputValue_>
557 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
558 core(input, indices.size(), output);
561 template<
typename Index_,
typename OutputValue_>
562 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
563 core(input, number, output);
566 template<
typename OutputValue_,
typename Index_>
567 OutputValue_ fill(
bool, Index_)
const {
584template<
typename InputValue_ =
double>
590 static constexpr bool is_basic =
false;
592 bool is_sparse()
const {
600 template<
typename Index_,
typename OutputValue_>
601 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
602 for (Index_ i = 0; i < length; ++i) {
603 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
604 auto& val = output[i];
605 val = std::round(val);
607 output[i] = std::round(input[i]);
616 template<
typename Index_,
typename OutputValue_>
617 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
618 core(input, length, output);
621 template<
typename Index_,
typename OutputValue_>
622 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
623 core(input, indices.size(), output);
626 template<
typename Index_,
typename OutputValue_>
627 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
628 core(input, number, output);
631 template<
typename OutputValue_,
typename Index_>
632 OutputValue_ fill(
bool, Index_)
const {
649template<
typename InputValue_ =
double>
655 static constexpr bool is_basic =
false;
657 bool is_sparse()
const {
665 template<
typename Index_,
typename OutputValue_>
666 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
667 for (Index_ i = 0; i < length; ++i) {
668 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
669 auto& val = output[i];
672 output[i] = std::exp(input[i]);
681 template<
typename Index_,
typename OutputValue_>
682 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
683 core(input, length, output);
686 template<
typename Index_,
typename OutputValue_>
687 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
688 core(input, indices.size(), output);
691 template<
typename Index_,
typename OutputValue_>
692 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
693 core(input, number, output);
696 template<
typename OutputValue_,
typename Index_>
697 OutputValue_ fill(
bool, Index_)
const {
714template<
typename InputValue_ =
double>
720 static constexpr bool is_basic =
false;
722 bool is_sparse()
const {
730 template<
typename Index_,
typename OutputValue_>
731 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
732 for (Index_ i = 0; i < length; ++i) {
733 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
734 auto& val = output[i];
735 val = std::expm1(val);
737 output[i] = std::expm1(input[i]);
746 template<
typename Index_,
typename OutputValue_>
747 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
748 core(input, length, output);
751 template<
typename Index_,
typename OutputValue_>
752 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
753 core(input, indices.size(), output);
756 template<
typename Index_,
typename OutputValue_>
757 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
758 core(input, number, output);
761 template<
typename OutputValue_,
typename Index_>
762 OutputValue_ fill(
bool, Index_)
const {
779template<
typename InputValue_ =
double>
785 static constexpr bool is_basic =
false;
787 bool is_sparse()
const {
795 template<
typename Index_,
typename OutputValue_>
796 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
797 for (Index_ i = 0; i < length; ++i) {
798 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
799 auto& val = output[i];
800 val = std::acos(val);
802 output[i] = std::acos(input[i]);
811 template<
typename Index_,
typename OutputValue_>
812 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
813 core(input, length, output);
816 template<
typename Index_,
typename OutputValue_>
817 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
818 core(input, indices.size(), output);
821 template<
typename Index_,
typename OutputValue_>
822 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
823 core(input, number, output);
826 template<
typename OutputValue_,
typename Index_>
827 OutputValue_ fill(
bool, Index_)
const {
845template<
typename InputValue_ =
double>
851 static constexpr bool is_basic =
false;
853 bool is_sparse()
const {
861 template<
typename Index_,
typename OutputValue_>
862 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
863 for (Index_ i = 0; i < length; ++i) {
864 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
865 auto& val = output[i];
866 val = std::acosh(val);
868 output[i] = std::acosh(input[i]);
877 template<
typename Index_,
typename OutputValue_>
878 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
879 core(input, length, output);
882 template<
typename Index_,
typename OutputValue_>
883 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
884 core(input, indices.size(), output);
887 template<
typename Index_,
typename OutputValue_>
888 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
889 core(input, number, output);
892 template<
typename OutputValue_,
typename Index_>
893 OutputValue_ fill(
bool, Index_)
const {
895 return std::acosh(
static_cast<InputValue_
>(0));
911template<
typename InputValue_ =
double>
917 static constexpr bool is_basic =
false;
919 bool is_sparse()
const {
927 template<
typename Index_,
typename OutputValue_>
928 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
929 for (Index_ i = 0; i < length; ++i) {
930 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
931 auto& val = output[i];
932 val = std::asin(val);
934 output[i] = std::asin(input[i]);
943 template<
typename Index_,
typename OutputValue_>
944 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
945 core(input, length, output);
948 template<
typename Index_,
typename OutputValue_>
949 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
950 core(input, indices.size(), output);
953 template<
typename Index_,
typename OutputValue_>
954 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
955 core(input, number, output);
958 template<
typename OutputValue_,
typename Index_>
959 OutputValue_ fill(
bool, Index_)
const {
976template<
typename InputValue_ =
double>
982 static constexpr bool is_basic =
false;
984 bool is_sparse()
const {
992 template<
typename Index_,
typename OutputValue_>
993 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
994 for (Index_ i = 0; i < length; ++i) {
995 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
996 auto& val = output[i];
997 val = std::asinh(val);
999 output[i] = std::asinh(input[i]);
1008 template<
typename Index_,
typename OutputValue_>
1009 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1010 core(input, length, output);
1013 template<
typename Index_,
typename OutputValue_>
1014 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1015 core(input, indices.size(), output);
1018 template<
typename Index_,
typename OutputValue_>
1019 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1020 core(input, number, output);
1023 template<
typename OutputValue_,
typename Index_>
1024 OutputValue_ fill(
bool, Index_)
const {
1041template<
typename InputValue_ =
double>
1047 static constexpr bool is_basic =
false;
1049 bool is_sparse()
const {
1057 template<
typename Index_,
typename OutputValue_>
1058 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
1059 for (Index_ i = 0; i < length; ++i) {
1060 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
1061 auto& val = output[i];
1062 val = std::atan(val);
1064 output[i] = std::atan(input[i]);
1073 template<
typename Index_,
typename OutputValue_>
1074 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1075 core(input, length, output);
1078 template<
typename Index_,
typename OutputValue_>
1079 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1080 core(input, indices.size(), output);
1083 template<
typename Index_,
typename OutputValue_>
1084 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1085 core(input, number, output);
1088 template<
typename OutputValue_,
typename Index_>
1089 OutputValue_ fill(
bool, Index_)
const {
1106template<
typename InputValue_ =
double>
1112 static constexpr bool is_basic =
false;
1114 bool is_sparse()
const {
1122 template<
typename Index_,
typename OutputValue_>
1123 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
1124 for (Index_ i = 0; i < length; ++i) {
1125 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
1126 auto& val = output[i];
1127 val = std::atanh(val);
1129 output[i] = std::atanh(input[i]);
1138 template<
typename Index_,
typename OutputValue_>
1139 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1140 core(input, length, output);
1143 template<
typename Index_,
typename OutputValue_>
1144 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1145 core(input, indices.size(), output);
1148 template<
typename Index_,
typename OutputValue_>
1149 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1150 core(input, number, output);
1153 template<
typename OutputValue_,
typename Index_>
1154 OutputValue_ fill(
bool, Index_)
const {
1171template<
typename InputValue_ =
double>
1177 static constexpr bool is_basic =
false;
1179 bool is_sparse()
const {
1187 template<
typename Index_,
typename OutputValue_>
1188 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
1189 for (Index_ i = 0; i < length; ++i) {
1190 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
1191 auto& val = output[i];
1192 val = std::cos(val);
1194 output[i] = std::cos(input[i]);
1203 template<
typename Index_,
typename OutputValue_>
1204 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1205 core(input, length, output);
1208 template<
typename Index_,
typename OutputValue_>
1209 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1210 core(input, indices.size(), output);
1213 template<
typename Index_,
typename OutputValue_>
1214 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1215 core(input, number, output);
1218 template<
typename OutputValue_,
typename Index_>
1219 OutputValue_ fill(
bool, Index_)
const {
1236template<
typename InputValue_ =
double>
1242 static constexpr bool is_basic =
false;
1244 bool is_sparse()
const {
1252 template<
typename Index_,
typename OutputValue_>
1253 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
1254 for (Index_ i = 0; i < length; ++i) {
1255 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
1256 auto& val = output[i];
1257 val = std::cosh(val);
1259 output[i] = std::cosh(input[i]);
1268 template<
typename Index_,
typename OutputValue_>
1269 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1270 core(input, length, output);
1273 template<
typename Index_,
typename OutputValue_>
1274 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1275 core(input, indices.size(), output);
1278 template<
typename Index_,
typename OutputValue_>
1279 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1280 core(input, number, output);
1283 template<
typename OutputValue_,
typename Index_>
1284 OutputValue_ fill(
bool, Index_)
const {
1301template<
typename InputValue_ =
double>
1307 static constexpr bool is_basic =
false;
1309 bool is_sparse()
const {
1317 template<
typename Index_,
typename OutputValue_>
1318 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
1319 for (Index_ i = 0; i < length; ++i) {
1320 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
1321 auto& val = output[i];
1322 val = std::sin(val);
1324 output[i] = std::sin(input[i]);
1333 template<
typename Index_,
typename OutputValue_>
1334 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1335 core(input, length, output);
1338 template<
typename Index_,
typename OutputValue_>
1339 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1340 core(input, indices.size(), output);
1343 template<
typename Index_,
typename OutputValue_>
1344 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1345 core(input, number, output);
1348 template<
typename OutputValue_,
typename Index_>
1349 OutputValue_ fill(
bool, Index_)
const {
1366template<
typename InputValue_ =
double>
1372 static constexpr bool is_basic =
false;
1374 bool is_sparse()
const {
1382 template<
typename Index_,
typename OutputValue_>
1383 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
1384 for (Index_ i = 0; i < length; ++i) {
1385 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
1386 auto& val = output[i];
1387 val = std::sinh(val);
1389 output[i] = std::sinh(input[i]);
1398 template<
typename Index_,
typename OutputValue_>
1399 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1400 core(input, length, output);
1403 template<
typename Index_,
typename OutputValue_>
1404 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1405 core(input, indices.size(), output);
1408 template<
typename Index_,
typename OutputValue_>
1409 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1410 core(input, number, output);
1413 template<
typename OutputValue_,
typename Index_>
1414 OutputValue_ fill(
bool, Index_)
const {
1431template<
typename InputValue_ =
double>
1437 static constexpr bool is_basic =
false;
1439 bool is_sparse()
const {
1447 template<
typename Index_,
typename OutputValue_>
1448 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
1449 for (Index_ i = 0; i < length; ++i) {
1450 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
1451 auto& val = output[i];
1452 val = std::tan(val);
1454 output[i] = std::tan(input[i]);
1463 template<
typename Index_,
typename OutputValue_>
1464 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1465 core(input, length, output);
1468 template<
typename Index_,
typename OutputValue_>
1469 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1470 core(input, indices.size(), output);
1473 template<
typename Index_,
typename OutputValue_>
1474 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1475 core(input, number, output);
1478 template<
typename OutputValue_,
typename Index_>
1479 OutputValue_ fill(
bool, Index_)
const {
1496template<
typename InputValue_ =
double>
1502 static constexpr bool is_basic =
false;
1504 bool is_sparse()
const {
1512 template<
typename Index_,
typename OutputValue_>
1513 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
1514 for (Index_ i = 0; i < length; ++i) {
1515 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
1516 auto& val = output[i];
1517 val = std::tanh(val);
1519 output[i] = std::tanh(input[i]);
1528 template<
typename Index_,
typename OutputValue_>
1529 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1530 core(input, length, output);
1533 template<
typename Index_,
typename OutputValue_>
1534 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1535 core(input, indices.size(), output);
1538 template<
typename Index_,
typename OutputValue_>
1539 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1540 core(input, number, output);
1543 template<
typename OutputValue_,
typename Index_>
1544 OutputValue_ fill(
bool, Index_)
const {
1561template<
typename InputValue_ =
double>
1567 static constexpr bool is_basic =
false;
1569 bool is_sparse()
const {
1577 template<
typename Index_,
typename OutputValue_>
1578 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
1579 for (Index_ i = 0; i < length; ++i) {
1580 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
1581 auto& val = output[i];
1582 val = std::tgamma(val);
1584 output[i] = std::tgamma(input[i]);
1593 template<
typename Index_,
typename OutputValue_>
1594 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1595 core(input, length, output);
1598 template<
typename Index_,
typename OutputValue_>
1599 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1600 core(input, indices.size(), output);
1603 template<
typename Index_,
typename OutputValue_>
1604 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1605 core(input, number, output);
1608 template<
typename OutputValue_,
typename Index_>
1609 OutputValue_ fill(
bool, Index_)
const {
1611 return std::tgamma(
static_cast<InputValue_
>(0));
1627template<
typename InputValue_ =
double>
1633 static constexpr bool is_basic =
false;
1635 bool is_sparse()
const {
1643 template<
typename Index_,
typename OutputValue_>
1644 void core(
const InputValue_* input, Index_ length, OutputValue_* output)
const {
1645 for (Index_ i = 0; i < length; ++i) {
1646 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
1647 auto& val = output[i];
1648 val = std::lgamma(val);
1650 output[i] = std::lgamma(input[i]);
1659 template<
typename Index_,
typename OutputValue_>
1660 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
1661 core(input, length, output);
1664 template<
typename Index_,
typename OutputValue_>
1665 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
1666 core(input, indices.size(), output);
1669 template<
typename Index_,
typename OutputValue_>
1670 void sparse(
bool, Index_, Index_ number,
const InputValue_* input,
const Index_*, OutputValue_* output)
const {
1671 core(input, number, output);
1674 template<
typename OutputValue_,
typename Index_>
1675 OutputValue_ fill(
bool, Index_)
const {
1677 return std::lgamma(
static_cast<InputValue_
>(0));
Take the absolute value of a matrix entry.
Definition math_helpers.hpp:24
Take the inverse cosine of a matrix entry.
Definition math_helpers.hpp:780
Take the inverse hyperbolic cosine of a matrix entry.
Definition math_helpers.hpp:846
Take the inverse sine of a matrix entry.
Definition math_helpers.hpp:912
Take the inverse hyperbolic sine of a matrix entry.
Definition math_helpers.hpp:977
Take the inverse tangent of a matrix entry.
Definition math_helpers.hpp:1042
Take the inverse hyperbolic tangent of a matrix entry.
Definition math_helpers.hpp:1107
Take the ceiling of a matrix entry.
Definition math_helpers.hpp:311
Take the cosine of a matrix entry.
Definition math_helpers.hpp:1172
Take the hyperbolic cosine of a matrix entry.
Definition math_helpers.hpp:1237
Use a matrix entry as an exponent.
Definition math_helpers.hpp:650
Use a matrix entry as an exponent minus 1.
Definition math_helpers.hpp:715
Take the floor of a matrix entry.
Definition math_helpers.hpp:376
Apply the gamma function to a matrix entry.
Definition math_helpers.hpp:1562
Apply the log-gamma function to a matrix entry.
Definition math_helpers.hpp:1628
Take the logarithm of a matrix entry plus 1.
Definition math_helpers.hpp:507
DelayedUnaryIsometricLog1p(Base_ base)
Definition math_helpers.hpp:517
DelayedUnaryIsometricLog1p()
Definition math_helpers.hpp:512
Take the logarithm of a matrix entry.
Definition math_helpers.hpp:167
DelayedUnaryIsometricLog()
Definition math_helpers.hpp:172
DelayedUnaryIsometricLog(Base_ base)
Definition math_helpers.hpp:177
Round a matrix entry to the nearest integer.
Definition math_helpers.hpp:585
Take the sign of a matrix entry.
Definition math_helpers.hpp:92
Take the sine of a matrix entry.
Definition math_helpers.hpp:1302
Take the hyperbolic sine of a matrix entry.
Definition math_helpers.hpp:1367
Take the square root of a matrix entry.
Definition math_helpers.hpp:246
Take the tangent of a matrix entry.
Definition math_helpers.hpp:1432
Take the hyperbolic tangent of a matrix entry.
Definition math_helpers.hpp:1497
Integer truncation of a matrix entry.
Definition math_helpers.hpp:441
Flexible representations for matrix data.
Definition Extractor.hpp:15