cos.hpp 12.2 KB
Newer Older
1
// Copyright 2021 Thomas A. R. Purcell
2
//
3
4
5
// 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
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
10
11
12
13
// 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.
14

15
/** @file feature_creation/node/operator_nodes/allowed_operator_nodes/cos.hpp
16
 *  @brief Defines a class for the cosine operator
17
 *
18
 *  @author Thomas A. R. Purcell (tpurcell90)
19
 *  @bug No known bugs.
20
21
 *
 *  This class represents the unary operator -> cos(A)
22
 */
23

Thomas Purcell's avatar
Thomas Purcell committed
24
25
26
#ifndef COS_NODE
#define COS_NODE

Thomas Purcell's avatar
Thomas Purcell committed
27
#include "feature_creation/node/operator_nodes/OperatorNode.hpp"
28
#include <fmt/core.h>
Thomas Purcell's avatar
Thomas Purcell committed
29

30
31
32
33
34
// DocString: cls_cos_node
/**
 * @brief Node for the cosine operator
 *
 */
35
class CosNode: public OperatorNode<1>
Thomas Purcell's avatar
Thomas Purcell committed
36
{
Thomas Purcell's avatar
Thomas Purcell committed
37
    friend class boost::serialization::access;
Thomas Purcell's avatar
Thomas Purcell committed
38

39
40
41
42
43
    /**
     * @brief Serialization function to send over MPI
     *
     * @param ar Archive representation of node
     */
Thomas Purcell's avatar
Thomas Purcell committed
44
45
46
47
48
    template <typename Archive>
    void serialize(Archive& ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<OperatorNode>(*this);
    }
Thomas Purcell's avatar
Thomas Purcell committed
49
public:
50
51
52
53
    /**
     * @brief Base Constructor
     * @details This is only used for serialization
     */
Thomas Purcell's avatar
Thomas Purcell committed
54
55
    CosNode();

56
    /**
Thomas Purcell's avatar
Thomas Purcell committed
57
     * @brief Constructor excluding bounds on the maximum absolute value of the Node
58
     *
59
60
     * @param feat (Node) shared_ptr of the feature to operate on (A)
     * @param feat_ind (int) Index of the new feature
61
     */
62
    CosNode(const node_ptr feat, const unsigned long int feat_ind);
Thomas Purcell's avatar
Thomas Purcell committed
63

64
    // DocString: cos_node_init
65
    /**
Thomas Purcell's avatar
Thomas Purcell committed
66
     * @brief Constructor including bounds on the maximum absolute value of the Node
67
     *
68
69
70
71
     * @param feat (Node) shared_ptr of the feature to operate on (A)
     * @param feat_ind (int) Index of the new feature
     * @param l_bound (double) Minimum absolute value allowed for the feature.
     * @param u_bound (double) Maximum absolute value allowed for the feature.
72
     */
73
    CosNode(const node_ptr feat, const unsigned long int feat_ind, const double l_bound, const double u_bound);
Thomas Purcell's avatar
Thomas Purcell committed
74

75
    /**
Thomas Purcell's avatar
Thomas Purcell committed
76
77
     * @brief Makes a hard copy node (All members of the Node are independent of the original one)
     * @return A shared_ptr to the copied node
78
79
80
     */
    virtual node_ptr hard_copy()const;

81
    // DocString: cos_node_unit
82
83
84
    /**
     * @brief Get the unit of the feature (combine the units of _feats)
     */
85
    inline Unit unit() const {return Unit();}
Thomas Purcell's avatar
Thomas Purcell committed
86

87
    // DocString: cos_node_expr
88
    /**
89
     * @brief A human readable equation representing the feature
90
     */
91
    inline std::string expr() const
92
93
    {
        return fmt::format(
Thomas Purcell's avatar
Thomas Purcell committed
94
            "cos({})",
95
96
97
            _feats[0]->expr()
        );
    }
98

99
100
    // DocString: cos_node_latex_expr
    /**
101
     * @brief Get the valid LaTeX expression that represents the feature
102
     */
103
    inline std::string get_latex_expr() const
104
    {
Thomas Purcell's avatar
Thomas Purcell committed
105
106
107
108
        return fmt::format(
            "\\left(\\cos{{ {} }}\\right)",
            _feats[0]->get_latex_expr()
        );
109
110
    }

111
    // DocString: cos_node_set_value
112
    /**
113
     * @brief Set the value of all training samples for the feature inside the central data storage array
114
     *
115
116
     * @param offset (int) Where the current node is in the binary expression tree relative to other nodes at the same depth
     * @param for_comp (bool) If true then the evaluation is used for comparing features
117
     */
118
    virtual void set_value(int offset=-1, const bool for_comp=false) const;
Thomas Purcell's avatar
Thomas Purcell committed
119

120
    // DocString: cos_node_set_test_value
121
    /**
122
     * @brief Set the value of all test samples for the feature inside the central data storage array
123
     *
124
125
     * @param offset (int) Where the current node is in the binary expression tree relative to other nodes at the same depth
     * @param for_comp (bool) If true then the evaluation is used for comparing features
126
     */
127
    virtual void set_test_value(int offset=-1, const bool for_comp=false) const;
128

129
    // DocString: cos_node_rung
Thomas Purcell's avatar
Thomas Purcell committed
130
    /**
Thomas Purcell's avatar
Thomas Purcell committed
131
     * @brief return the rung of the feature (Height of the binary expression tree - 1)
132
     *
Thomas Purcell's avatar
Thomas Purcell committed
133
     */
134
    inline int rung(const int cur_rung=0) const {return _feats[0]->rung(cur_rung + 1);}
Thomas Purcell's avatar
Thomas Purcell committed
135

Thomas Purcell's avatar
Thomas Purcell committed
136
137
138
    /**
     * @brief Returns the type of node this is
     */
139
    virtual inline NODE_TYPE type() const {return NODE_TYPE::COS;}
Thomas Purcell's avatar
Thomas Purcell committed
140

141
    /**
Thomas Purcell's avatar
Thomas Purcell committed
142
     * @brief Get the term used in the postfix expression for this Node
143
     */
144
    inline std::string get_postfix_term() const {return "cos";}
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
    // DocString: cos_node_matlab_expr
    /**
     * @brief Get the string that corresponds to the code needed to evaluate the node in matlab
     *
     * @return The matlab code for the feature
     */
    inline std::string matlab_fxn_expr() const
    {
        return fmt::format(
            "cos({})",
            _feats[0]->matlab_fxn_expr()
        );
    }

160
    /**
Thomas Purcell's avatar
Thomas Purcell committed
161
     * @brief update the dictionary used to check if an Add/Sub/AbsDiff node is valid
162
163
     *
     * @param add_sub_leaves the dictionary used to check if an Add/Sub node is valid
Thomas Purcell's avatar
Thomas Purcell committed
164
     * @param pl_mn 1 for addition and -1 for subtraction
165
166
     * @param expected_abs_tot The expected absolute sum of all values in add_sub_leaves
     */
167
    void update_add_sub_leaves(std::map<std::string, int>& add_sub_leaves, const int pl_mn, int& expected_abs_tot) const;
168
169

    /**
Thomas Purcell's avatar
Thomas Purcell committed
170
     * @brief update the dictionary used to check if an Mult/Div node is valid
171
     *
172
     * @param div_mult_leaves the dictionary used to check if an Mult/Div node is valid
Thomas Purcell's avatar
Thomas Purcell committed
173
     * @param fact amount to increment the element (a primary features) of the dictionary by
174
175
     * @param expected_abs_tot The expected absolute sum of all values in div_mult_leaves
     */
176
    void update_div_mult_leaves(std::map<std::string, double>& div_mult_leaves, const double fact, double& expected_abs_tot) const;
177

178
    #ifdef PARAMETERIZE
179
    /**
Thomas Purcell's avatar
Thomas Purcell committed
180
     * @brief The parameters used for including individual scale and bias terms to each operator in the Node
181
     */
182
    virtual std::vector<double> parameters() const {return {};}
183
184

    /**
Thomas Purcell's avatar
Thomas Purcell committed
185
186
     * @brief Optimize the scale and bias terms for each operation in the Node.
     * @details Use optimizer to find the scale and bias terms that minimizes the associated loss function
187
     *
Thomas Purcell's avatar
Thomas Purcell committed
188
     * @param optimizer The optimizer used to evaluate the loss function for each optimization and find the optimal parameters
189
190
191
192
193
     */
    virtual void get_parameters(std::shared_ptr<NLOptimizer> optimizer){return;}

    /**
     * @brief Set the non-linear parameters
194
195
196
     * @param params The new parameters for the feature
     * @param check_sz if True check the size of the params vector with the expected size
     */
197
    virtual void set_parameters(const std::vector<double> params, const bool check_sz=true){return;}
198

Thomas Purcell's avatar
Thomas Purcell committed
199
200
    /**
     * @brief Set the non-linear parameters
Thomas Purcell's avatar
Thomas Purcell committed
201
     * @param params The new scale and bias terms of this node
Thomas Purcell's avatar
Thomas Purcell committed
202
203
204
     */
    virtual void set_parameters(const double* params){return;}

205
    /**
206
     * @brief Set the value of all training samples for the feature inside the central data storage array
207
     *
Thomas Purcell's avatar
Thomas Purcell committed
208
     * @param params A pointer to the bias and scale terms for this Node and its children
209
210
     * @param offset (int) Where the current node is in the binary expression tree relative to other nodes at the same depth
     * @param for_comp (bool) If true then the evaluation is used for comparing features
Thomas Purcell's avatar
Thomas Purcell committed
211
     * @param depth (int) How far down a given Node is from the root OperatorNode
212
     */
213
    void set_value(const double* params, int offset=-1, const bool for_comp=false, const int depth=1) const;
214
215

    /**
216
     * @brief Set the value of all test samples for the feature inside the central data storage array
217
     *
Thomas Purcell's avatar
Thomas Purcell committed
218
     * @param params A pointer to the bias and scale terms for this Node and its children
219
220
     * @param offset (int) Where the current node is in the binary expression tree relative to other nodes at the same depth
     * @param for_comp (bool) If true then the evaluation is used for comparing features
Thomas Purcell's avatar
Thomas Purcell committed
221
     * @param depth (int) How far down a given Node is from the root OperatorNode
222
     */
223
    void set_test_value(const double* params, int offset=-1, const bool for_comp=false, const int depth=1) const;
224
225

    /**
226
     * @brief A human readable equation representing the feature
227
     *
Thomas Purcell's avatar
Thomas Purcell committed
228
229
     * @param params A pointer to the bias and scale terms for this Node and its children
     * @return A human readable equation representing the feature
230
     */
231
    inline std::string expr(const double* params, const int depth=1) const
232
233
    {
        return fmt::format(
234
            "(cos({:.6e}*{}{:+11.6e}))",
235
236
237
238
239
240
241
            params[0],
            (depth < nlopt_wrapper::MAX_PARAM_DEPTH ? _feats[0]->expr(params + 2, depth + 1) : _feats[0]->expr()),
            params[1]
        );
    }

    /**
242
     * @brief Get the valid LaTeX expression that represents the feature
243
     *
Thomas Purcell's avatar
Thomas Purcell committed
244
245
246
     * @param params A pointer to the bias and scale terms for this Node and its children
     * @param depth How far down a given Node is from the root OperatorNode
     * @return Get the valid LaTeX expression that represents the feature
247
     */
248
    inline std::string get_latex_expr(const double* params, const int depth=1) const
249
250
251
252
253
254
255
256
257
    {
        return fmt::format(
            "\\left(\\cos{{ \\left({:.3e}{}{:+8.3e} \\right)}}\\right)",
            params[0],
            (depth < nlopt_wrapper::MAX_PARAM_DEPTH ? _feats[0]->get_latex_expr(params + 2, depth + 1) : _feats[0]->get_latex_expr()),
            params[1]
        );
    }

258
259
260
    /**
     * @brief Get the string that corresponds to the code needed to evaluate the node in matlab
     *
Thomas Purcell's avatar
Thomas Purcell committed
261
262
     * @param params A pointer to the bias and scale terms for this Node and its children
     * @param depth How far down a given Node is from the root OperatorNode
263
264
265
266
267
     * @return The matlab code for the feature
     */
    inline std::string matlab_fxn_expr(const double* params, const int depth=1) const
    {
        return fmt::format(
268
            "cos({:.6e}.*{}{:+11.6e})",
269
270
271
272
273
274
            params[0],
            (depth < nlopt_wrapper::MAX_PARAM_DEPTH ? _feats[0]->matlab_fxn_expr(params + 2, depth + 1) : _feats[0]->matlab_fxn_expr()),
            params[1]
        );
    }

275
    /**
Thomas Purcell's avatar
Thomas Purcell committed
276
     * @brief Set the upper and lower bounds for the scale and bias term of this Node and its children
277
     *
Thomas Purcell's avatar
Thomas Purcell committed
278
279
280
     * @param lb A pointer to the location where the lower bounds for the scale and bias term of this Node is set
     * @param ub A pointer to the location where the upper bounds for the scale and bias term of this Node is set
     * @param depth How far down a given Node is from the root OperatorNode
281
     */
Thomas Purcell's avatar
Thomas Purcell committed
282
    void set_bounds(double* lb, double* ub, const int depth=1) const;
283

Thomas Purcell's avatar
Thomas Purcell committed
284
    /**
Thomas Purcell's avatar
Thomas Purcell committed
285
     * @brief Initialize the scale and bias terms for this Node and its children
Thomas Purcell's avatar
Thomas Purcell committed
286
     *
Thomas Purcell's avatar
Thomas Purcell committed
287
288
     * @param params A pointer to the bias and scale terms for this Node and its children
     * @param depth How far down a given Node is from the root OperatorNode
Thomas Purcell's avatar
Thomas Purcell committed
289
290
291
     */
    void initialize_params(double* params, const int depth = 1) const;

292
293
294
    /**
     * @brief Calculates the derivative of an operation with respect to the parameters for a given sample
     *
Thomas Purcell's avatar
Thomas Purcell committed
295
     * @param params A pointer to the bias and scale terms for this Node and its children
296
297
     * @param dfdp pointer to where the feature derivative pointers are located
     */
298
    inline void param_derivative(const double* params, double* dfdp) const
299
300
301
302
    {
        double* val_ptr = _feats[0]->value_ptr(params);
        std::transform(val_ptr, val_ptr + _n_samp, dfdp, [params](double vp){return -1.0 * std::sin(params[0] * vp + params[1]);});
    }
303
    #endif
Thomas Purcell's avatar
Thomas Purcell committed
304
};
305
306
307
308
309

/**
 * @brief Attempt to generate a new parameterized cosine node cos(A) and add it to feat_list
 *
 * @param feat_list list of features already generated
Thomas Purcell's avatar
Thomas Purcell committed
310
311
312
313
 * @param feat shared_ptr of the feature to operate on (A)
 * @param feat_ind Index of the new feature
 * @param l_bound Minimum absolute value allowed for the feature.
 * @param u_bound Maximum absolute value allowed for the feature.
314
 */
315
316
317
318
319
320
321
void generateCosNode(
    std::vector<node_ptr>& feat_list,
    const node_ptr feat,
    unsigned long int& feat_ind,
    const double l_bound,
    const double u_bound
);
Thomas Purcell's avatar
Thomas Purcell committed
322

Thomas Purcell's avatar
Thomas Purcell committed
323
#endif