tinyopt
700
Tinyopt, a lightweight, header only optimization library
Toggle main menu visibility
Loading...
Searching...
No Matches
norms.h
1
// Copyright 2026 Julien Michot.
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include <tinyopt/math.h>
7
#include <tinyopt/traits.h>
8
#include <type_traits>
9
10
namespace
tinyopt::losses
{
11
16
18
template
<
typename
T>
19
auto
SquaredL2
(
const
T &x) {
20
constexpr
bool
IsMatrix = traits::is_matrix_or_array_v<T> || traits::is_sparse_matrix_v<T>;
21
if
constexpr
(traits::is_pair_v<T>) {
// pair
22
return
SquaredL2
(x.first, x.second);
23
}
else
if
constexpr
(IsMatrix) {
// scalar
24
return
x.squaredNorm();
25
}
else
{
// scalar
26
return
x * x;
27
}
28
}
29
31
template
<
typename
T,
typename
ExportJ>
32
auto
SquaredL2
(
const
T &x,
const
ExportJ &Jx_or_bool,
bool
add_scale =
true
) {
33
constexpr
bool
IsMatrix = traits::is_matrix_or_array_v<T> || traits::is_sparse_matrix_v<T>;
34
const
auto
l =
SquaredL2
(x);
35
if
constexpr
(std::is_null_pointer_v<ExportJ>) {
36
return
l;
37
}
else
if
constexpr
(IsMatrix) {
38
using
Scalar =
typename
traits::params_trait<T>::Scalar;
39
RowVector<Scalar, traits::params_trait<T>::Dims> J = x.transpose();
40
if
(add_scale) J *= Scalar(2.0);
41
if
constexpr
(traits::is_bool_v<ExportJ>)
42
return
std::make_pair(l, J);
43
else
44
return
std::make_pair(l, (J * Jx_or_bool).eval());
45
}
else
{
// scalar
46
return
std::make_pair(l, add_scale ? T(2.0) * x : x);
47
}
48
}
49
51
template
<
typename
T>
52
auto
L2
(
const
T &x) {
53
constexpr
bool
IsMatrix = traits::is_matrix_or_array_v<T> || traits::is_sparse_matrix_v<T>;
54
if
constexpr
(traits::is_pair_v<T>) {
// pair
55
return
L2
(x.first, x.second);
56
}
else
if
constexpr
(IsMatrix) {
// scalar
57
return
x.norm();
58
}
else
{
// scalar
59
using
std::abs;
60
return
abs(x);
// same as sqrt(x*x);
61
}
62
}
63
65
template
<
typename
T,
typename
ExportJ>
66
auto
L2
(
const
T &x,
const
ExportJ &Jx_or_bool) {
67
constexpr
bool
IsMatrix = traits::is_matrix_or_array_v<T> || traits::is_sparse_matrix_v<T>;
68
const
auto
l =
L2
(x);
69
if
constexpr
(std::is_null_pointer_v<ExportJ>) {
70
return
l;
71
}
else
if
constexpr
(IsMatrix) {
72
const
auto
J = l > FloatEpsilon() ? (x / l).eval() : x;
73
if
constexpr
(traits::is_bool_v<ExportJ>)
74
return
std::make_pair(l, J.transpose().eval());
75
else
76
return
std::make_pair(l, (J.transpose() * Jx_or_bool).eval());
77
}
else
{
// scalar
78
return
std::make_pair(l, 1);
79
}
80
}
81
83
template
<
typename
T>
84
auto
L1
(
const
T &x) {
85
constexpr
bool
IsMatrix = traits::is_matrix_or_array_v<T> || traits::is_sparse_matrix_v<T>;
86
if
constexpr
(traits::is_pair_v<T>) {
// pair
87
return
L1
(x.first, x.second);
88
}
else
if
constexpr
(IsMatrix) {
// scalar
89
return
x.template lpNorm<1>();
90
}
else
{
// scalar
91
using
std::abs;
92
return
abs(x);
93
}
94
}
95
97
template
<
typename
T,
typename
ExportJ>
98
auto
L1
(
const
T &x,
const
ExportJ &Jx_or_bool) {
99
constexpr
bool
IsMatrix = traits::is_matrix_or_array_v<T> || traits::is_sparse_matrix_v<T>;
100
const
auto
l =
L1
(x);
101
if
constexpr
(std::is_null_pointer_v<ExportJ>) {
102
return
l;
103
}
else
if
constexpr
(IsMatrix) {
104
using
Scalar =
typename
traits::params_trait<T>::Scalar;
105
constexpr
int
DimsJ = traits::params_trait<T>::Dims;
106
if
constexpr
(traits::is_bool_v<ExportJ>)
107
return
std::make_pair(l, RowVector<Scalar, DimsJ>(x.array().sign()));
108
else
109
return
std::make_pair(l, (x.array().sign() * Jx_or_bool).eval());
110
}
else
{
// scalar
111
return
std::make_pair(l, 1);
112
}
113
}
114
116
template
<
typename
T>
117
auto
Linf
(
const
T &x) {
118
constexpr
bool
IsMatrix = traits::is_matrix_or_array_v<T> || traits::is_sparse_matrix_v<T>;
119
if
constexpr
(traits::is_pair_v<T>) {
// pair
120
return
Linf
(x.first, x.second);
121
}
else
if
constexpr
(IsMatrix) {
122
return
x.template lpNorm<Infinity>();
123
}
else
{
// scalar
124
using
std::abs;
125
return
abs(x);
126
}
127
}
128
130
template
<
typename
T,
typename
ExportJ>
131
auto
Linf
(
const
T &x,
const
ExportJ &Jx_or_bool) {
132
constexpr
bool
IsMatrix = traits::is_matrix_or_array_v<T> || traits::is_sparse_matrix_v<T>;
133
if
constexpr
(std::is_null_pointer_v<ExportJ>) {
134
return
Linf
(x);
135
}
else
if
constexpr
(IsMatrix) {
136
using
Scalar =
typename
traits::params_trait<T>::Scalar;
137
constexpr
int
DimsJ = traits::params_trait<T>::Dims;
138
RowVector<Scalar, DimsJ> J(1, x.rows());
139
J.setZero();
140
int
max_idx;
141
const
auto
l = x.cwiseAbs().maxCoeff(&max_idx);
142
J[max_idx] = x[max_idx] >= 0 ? 1 : -1;
143
if
constexpr
(traits::is_bool_v<ExportJ>)
144
return
std::make_pair(l, J);
145
else
146
return
std::make_pair(l, (J * Jx_or_bool).eval());
147
}
else
{
// scalar
148
if
(x >= 0)
149
return
std::make_pair(x, T(1.0));
150
else
151
return
std::make_pair(-x, T(-1.0));
152
}
153
}
154
156
157
}
// namespace tinyopt::losses
tinyopt::losses
Definition
activations.h:8
tinyopt::losses::Linf
auto Linf(const T &x)
Return L infinity norm of a vector or scalar.
Definition
norms.h:117
tinyopt::losses::SquaredL2
auto SquaredL2(const T &x)
Return the squared L2 norm of a vector or scalar (a.k.a Sum of Squares).
Definition
norms.h:19
tinyopt::losses::L2
auto L2(const T &x)
Return L2 norm of a vector or scalar.
Definition
norms.h:52
tinyopt::losses::L1
auto L1(const T &x)
Return L1 norm of a vector or scalar.
Definition
norms.h:84
include
tinyopt
losses
norms.h
Generated by
1.18.0