MUQ  0.4.3
WorkPiece.h
Go to the documentation of this file.
1 #ifndef WORKPIECE_H_
2 #define WORKPIECE_H_
3 
4 #include<iostream>
5 #include<vector>
6 #include<map>
7 #include<string>
8 #include<sstream>
9 #include<cassert>
10 #include<memory>
11 #include<string>
12 
13 #include "boost/any.hpp"
14 #include "boost/optional.hpp"
15 
16 #include <Eigen/Dense>
17 
18 #include "MUQ/config.h"
19 
20 #include "MUQ/Modeling/WorkPiece.h"
21 
22 #if MUQ_HAS_SUNDIALS==1
23 // Sundials includes
24 #include <nvector/nvector_serial.h>
25 #include <sundials/sundials_dense.h> // definitions DlsMat DENSE_ELEM
26 #endif
27 
28 namespace muq {
29  namespace Modeling {
30 
31  // Forward declaration of WorkGraphPiece
32  class WorkGraphPiece;
33  class WorkGraph;
34 
36  template <typename T>
37  using ref_vector = std::vector<std::reference_wrapper<const T>>;
38 
40  class WorkPiece {
41 
42  // Make WorkGraphPiece a friend so it can access WorkPiece's outputs directly
43  friend class WorkGraphPiece;
44  friend class WorkGraph;
45 
46  protected:
47 
49  enum Fix {
54 
55  public:
56 
58  WorkPiece();
59 
61 
65  WorkPiece(int const num, WorkPiece::Fix const fix = WorkPiece::Fix::Inputs);
66 
68 
72  WorkPiece(int const numIns, int const numOuts);
73 
75 
80  WorkPiece(std::vector<std::string> const& types, WorkPiece::Fix const fix = WorkPiece::Fix::Inputs);
81 
83 
99  WorkPiece(std::map<unsigned int, std::string> const& types, WorkPiece::Fix const fix = WorkPiece::Fix::Inputs);
100 
102 
108  WorkPiece(std::map<unsigned int, std::string> const& types, int const num, WorkPiece::Fix const fixTypes = WorkPiece::Fix::Inputs, WorkPiece::Fix const fixNum = WorkPiece::Fix::Inputs);
109 
111 
115  WorkPiece(std::vector<std::string> const& types, int const num);
116 
118 
122  WorkPiece(int const num, std::vector<std::string> const& types);
123 
125 
130  WorkPiece(std::map<unsigned int, std::string> const& inTypes, int const numIns, int const numOuts);
131 
133 
138  WorkPiece(int const numIns, std::map<unsigned int, std::string> const& outTypes, int const numOuts);
139 
141 
145  WorkPiece(std::vector<std::string> const& inTypes, std::vector<std::string> const& outTypes);
146 
148 
152  WorkPiece(std::map<unsigned int, std::string> const& inTypes, std::vector<std::string> const& outTypes);
153 
155 
160  WorkPiece(std::map<unsigned int, std::string> const& inTypes, int const num, std::vector<std::string> const& outTypes);
161 
163 
167  WorkPiece(std::vector<std::string> const& inTypes, std::map<unsigned int, std::string> const& outTypes);
168 
170 
175  WorkPiece(std::vector<std::string> const& inTypes, std::map<unsigned int, std::string> const& outTypes, int const num);
176 
178 
182  WorkPiece(std::map<unsigned int, std::string> const& inTypes, std::map<unsigned int, std::string> const& outTypes);
183 
185 
190  WorkPiece(std::map<unsigned int, std::string> const& inTypes, int const numIn, std::map<unsigned int, std::string> const& outTypes);
191 
193 
198  WorkPiece(std::map<unsigned int, std::string> const& inTypes, std::map<unsigned int, std::string> const& outTypes, int const numOut);
199 
201 
207  WorkPiece(std::map<unsigned int, std::string> const& inTypes, int const numIn, std::map<unsigned int, std::string> const& outTypes, int const numOut);
208 
210  virtual ~WorkPiece() {}
211 
213 
220  std::vector<boost::any> const& Evaluate(std::vector<boost::any> const& ins);
221 
223 
230  std::vector<boost::any> const& Evaluate(ref_vector<boost::any> const& ins);
231 
233 
236  std::vector<boost::any> const& Evaluate();
237 
239 
244  template<typename... Args>
245  std::vector<boost::any> const& Evaluate(Args... args) {
246  // clear the outputs
247  Clear();
248 
249  // create the reference input vector
250  ref_vector<boost::any> inputs;
251  inputs.reserve(numInputs<0? 0 : numInputs);
252 
253  // begin calling the EvaluateRecursive with the first input
254  return EvaluateRecursive(inputs, args...);
255  }
256 
257  // /// Evaluate the Jacobian of this muq::Modeling::WorkPiece using references to the inputs
258  // /**
259  // This function takes a vector of inputs to the muq::Modeling::WorkPiece, which must match WorkPiece::numInputs and WorkPiece::inputTypes if they are specified. It then calls WorkPiece::JacobianImpl(), which computes the Jacobian. The Jacobian must be implemented by a child class, unless both the input and the output are Eigen::VectorXd's. In this case, we default to finite difference.
260  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
261  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
262  // @param[in] ins A vector of inputs
263  // \return The Jacobian of this muq::Modeling::WorkPiece
264  // */
265  // boost::any Jacobian(unsigned int const wrtIn, unsigned int const wrtOut, std::vector<boost::any> const& ins);
266  //
267  // /// Evaluate the Jacobian of this muq::Modeling::WorkPiece using references to the inputs
268  // /**
269  // This function takes the references to the inputs to the muq::Modeling::WorkPiece, which must match WorkPiece::numInputs and WorkPiece::inputTypes if they are specified. It then calls WorkPiece::JacobianImpl(), which computes the Jacobian. The Jacobian must be implemented by a child class, unless both the input and the output are Eigen::VectorXd's. In this case, we default to finite difference.
270  //
271  // References are used for efficiency in the muq::Modeling::WorkGraph.
272  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
273  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
274  // @param[in] ins A vector of references to the inputs
275  // \return The Jacobian of this muq::Modeling::WorkPiece
276  // */
277  // boost::any Jacobian(unsigned int const wrtIn, unsigned int const wrtOut, ref_vector<boost::any> const& ins);
278  //
279  // /// Evaluate the Jacobian of this muq::Modeling::WorkPiece using multiple arguments
280  // /**
281  // This function allows the user to compute the Jacobian of an output with respect to one of the inputs. If both the input and the output type is an Eigen::VectorXd and the user has not implemented the Jacobian, we default to finite difference.
282  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
283  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
284  // @param[in] args The inputs (may be more than one)
285  // \return The Jacobian of this muq::Modeling::WorkPiece
286  // */
287  // template<typename... Args>
288  // boost::any Jacobian(unsigned int const wrtIn, unsigned int const wrtOut, Args... args) {
289  // // make sure the input and output number are valid
290  // assert(numInputs<0 || wrtIn<numInputs);
291  // assert(numOutputs<0 || wrtOut<numOutputs);
292  //
293  // // clear the outputs and derivative information
294  // ClearDerivatives();
295  //
296  // // create the reference input vector
297  // ref_vector<boost::any> inputs;
298  // inputs.reserve(numInputs<0? 0 : numInputs);
299  //
300  // // begin calling the JacobianRecursive with the first input
301  // return JacobianRecursive(wrtIn, wrtOut, inputs, args...);
302  // }
303  //
304  // /// Compute the Jacobian using finite differences
305  // /**
306  // Assume the input and output type are Eigen::VectorXd.
307  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
308  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
309  // @param[in] args The inputs (may be more than one)
310  // @param[in] refTol Scaled value for the finite difference step size (defaults to 1e-4)
311  // @param[in] minTol Minimum value for the finite difference step size (defaults to 1e-6)
312  // */
313  // void JacobianByFD(unsigned int const wrtIn, unsigned int const wrtOut, ref_vector<boost::any> const& inputs, double const relTol = 1.0e-4, const double minTol = 1.0e-6);
314  //
315  // /// Evaluate the action of the Jacobian of this muq::Modeling::WorkPiece using references to the inputs
316  // /**
317  // This function takes a vector of inputs to the muq::Modeling::WorkPiece, which must match WorkPiece::numInputs and WorkPiece::inputTypes if they are specified. It then calls WorkPiece::JacobianActionImpl(), which computes the action of the Jacobian. The Jacobian must be implemented by a child class, unless the input and the output and the vector the Jacobian is action on are Eigen::VectorXd's. In this case, we call WorkPiece::Jacobian() and apply it to the vector.
318  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
319  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
320  // @param[in] vec We want to apply the Jacobian to this vector
321  // @param[in] ins A vector of inputs
322  // \return The Jacobian of this muq::Modeling::WorkPiece
323  // */
324  // boost::any JacobianAction(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, std::vector<boost::any> const& ins);
325  //
326  // /// Evaluate the action of the Jacobian of this muq::Modeling::WorkPiece using references to the inputs
327  // /**
328  // References are used for efficiency in the muq::Modeling::WorkGraph.
329  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
330  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
331  // @param[in] vec We want to apply the Jacobian to this vector
332  // @param[in] ins A vector of references to the inputs
333  // \return The Jacobian of this muq::Modeling::WorkPiece
334  // */
335  // boost::any JacobianAction(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, ref_vector<boost::any> const& ins);
336  //
337  // /// Evaluate the action of the Jacobian of this muq::Modeling::WorkPiece using multiple arguments
338  // /**
339  // This function allows the user to compute the action of the Jacobian of an output with respect to one of the inputs. If the vector given to this function, the input type and the output type is an Eigen::VectorXd and the user has not implemented the Jacobian action, we call muq::Modeling::Jacobian and apply it to the given vector
340  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
341  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
342  // @param[in] vec We want to apply the Jacobian to this vector
343  // @param[in] args The inputs (may be more than one)
344  // \return The action of the Jacobian of this muq::Modeling::WorkPiece on vec
345  // */
346  // template<typename... Args>
347  // boost::any JacobianAction(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, Args... args) {
348  // // make sure the input and output number are valid
349  // assert(numInputs<0 || wrtIn<numInputs);
350  // assert(numOutputs<0 || wrtOut<numOutputs);
351  //
352  // // clear the outputs and derivative information
353  // ClearDerivatives();
354  //
355  // // create the reference input vector
356  // ref_vector<boost::any> inputs;
357  // inputs.reserve(numInputs<0? 0 : numInputs);
358  //
359  // // begin calling the JacobianActionRecursive with the first input
360  // return JacobianActionRecursive(wrtIn, wrtOut, vec, inputs, args...);
361  // }
362  //
363  // /// Compute the action of the Jacobian using finite differences
364  // /**
365  // Assume the input and output type are Eigen::VectorXd.
366  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
367  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
368  // @param[in] vec We want to apply the Jacobian to this vector
369  // @param[in] args The inputs (may be more than one)
370  // */
371  // void JacobianActionByFD(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, ref_vector<boost::any> const& input);
372  //
373  // /// Evaluate the action of the Jacobian transpose of this muq::Modeling::WorkPiece using references to the inputs
374  // /**
375  // This function takes a vector of inputs to the muq::Modeling::WorkPiece, which must match WorkPiece::numInputs and WorkPiece::inputTypes if they are specified. It then calls WorkPiece::JacobianTransposeActionImpl(), which computes the action of the Jacobian transpose. The Jacobian must be implemented by a child class, unless the input and the output and the vector the Jacobian transpose is action on are Eigen::VectorXd's. In this case, we call WorkPiece::Jacobian() and apply it to the vector.
376  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
377  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
378  // @param[in] vec We want to apply the Jacobian to this vector
379  // @param[in] ins A vector of inputs
380  // \return The Jacobian of this muq::Modeling::WorkPiece
381  // */
382  // boost::any JacobianTransposeAction(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, std::vector<boost::any> const& ins);
383  //
384  // /// Evaluate the action of the Jacobian transpose of this muq::Modeling::WorkPiece using references to the inputs
385  // /**
386  // References are used for efficiency in the muq::Modeling::WorkGraph.
387  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
388  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
389  // @param[in] vec We want to apply the Jacobian to this vector
390  // @param[in] ins A vector of references to the inputs
391  // \return The Jacobian of this muq::Modeling::WorkPiece
392  // */
393  // boost::any JacobianTransposeAction(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, ref_vector<boost::any> const& ins);
394  //
395  // /// Evaluate the action of the Jacobian transpose of this muq::Modeling::WorkPiece using multiple arguments
396  // /**
397  // This function allows the user to compute the action of the Jacobian transpose of an output with respect to one of the inputs. If the vector given to this function, the input type and the output type is an Eigen::VectorXd and the user has not implemented the Jacobian transpose action, we call muq::Modeling::Jacobian and apply it to the given vector
398  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
399  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
400  // @param[in] vec We want to apply the Jacobian transpose to this vector
401  // @param[in] args The inputs (may be more than one)
402  // \return The action of the Jacobian transpose of this muq::Modeling::WorkPiece on vec
403  // */
404  // template<typename... Args>
405  // boost::any JacobianTransposeAction(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, Args... args) {
406  // // make sure the input and output number are valid
407  // assert(numInputs<0 || wrtIn<numInputs);
408  // assert(numOutputs<0 || wrtOut<numOutputs);
409  //
410  // // clear the outputs and derivative information
411  // ClearDerivatives();
412  //
413  // // create the reference input vector
414  // ref_vector<boost::any> inputs;
415  // inputs.reserve(numInputs<0? 0 : numInputs);
416  //
417  // // begin calling the JacobianTransposeActionRecursive with the first input
418  // return JacobianTransposeActionRecursive(wrtIn, wrtOut, vec, inputs, args...);
419  // }
420  //
421  // /// Compute the action of the Jacobian transpose using finite differences
422  // /**
423  // Assume the input and output type are Eigen::VectorXd.
424  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
425  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
426  // @param[in] vec We want to apply the Jacobian transpose to this vector
427  // @param[in] args The inputs (may be more than one)
428  // */
429  // void JacobianTransposeActionByFD(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, ref_vector<boost::any> const& inputs);
430 
432 
435  std::string const& Name();
436 
438  void SetName(std::string const& newName);
439 
441 
447  std::string InputType(unsigned int inputNum, bool const demangle = true) const;
448 
450  int InputSize(unsigned int inputNum) const;
451 
452  void SetInputSize(unsigned int inputNum, int newSize);
453 
455 
461  std::string OutputType(unsigned int outputNum, bool const demangle = true) const;
462 
464  std::map<unsigned int, std::string> OutputTypes() const;
465 
467  std::map<unsigned int, std::string> InputTypes() const;
468 
470 
473  unsigned int ID() const;
474 
483  virtual double GetRunTime(const std::string& method="Evaluate") const;
484 
492  virtual unsigned long int GetNumCalls(const std::string& method = "Evaluate") const;
493 
497  virtual void ResetCallTime();
498 
499 
502 
505 
507  static ref_vector<const boost::any> ToRefVector(std::vector<boost::any> const& anyVec);
508  static ref_vector<const Eigen::VectorXd> ToRefVector(std::vector<Eigen::VectorXd> const& anyVec);
509 
510  protected:
511 
513 
518  bool CheckInputType(unsigned int const inputNum, std::string const& type) const;
519 
521 
526  bool CheckOutputType(unsigned int const outputNum, std::string const& type) const;
527 
528 
530 
534  std::vector<std::string> Types(std::vector<boost::any> const& vec) const;
535 
537 
540  bool clearOutputs = true;
541 
543 
546  std::vector<boost::any> outputs = std::vector<boost::any>(0);
547 
549 
552  std::map<unsigned int, std::string> inputTypes;
553 
555 
558  std::map<unsigned int, std::string> outputTypes;
559 
560  std::map<unsigned int, int> inputSizes;
561 
563 
568  std::map<unsigned int, std::string> Types(std::vector<std::string> const& typesVec) const;
569 
570 
571  // The following variables keep track of how many times the Implemented functions, i.e. EvaluateImpl, GradientImpl,
572  // etc... are called.
573  unsigned long int numEvalCalls = 0;
574 
575  // these variables keep track of the total wall-clock time spent in each of the Implemented functions. They are in
576  // units of milliseconds
577  double evalTime = 0;
578 
580  const unsigned int id;
581 
583  std::string name;
584 
585 
586  virtual std::string CreateName() const;
587 
588  private:
589 
591 
596  virtual void EvaluateImpl(ref_vector<boost::any> const& inputs) = 0;
597 
599 
605  template<typename ith, typename... Args>
606  std::vector<boost::any> const& EvaluateRecursive(ref_vector<boost::any> &inputs, ith const& in, Args... args) {
607  const int inputNum = inputs.size();
608 
609  // we have not yet put all of the inputs into the map, the ith should be less than the total number
610  assert(numInputs<0 || inputNum+1<numInputs);
611 
612  // check the input type
613  assert(CheckInputType(inputNum, typeid(in).name()));
614 
615  // add the last input to the input vector
616  const boost::any in_any(in);
617  inputs.push_back(std::cref(in_any));
618 
619  // call with EvaluateRecursive with the remaining inputs
620  return EvaluateRecursive(inputs, args...);
621  }
622 
624 
629  template<typename last>
630  std::vector<boost::any> const& EvaluateRecursive(ref_vector<boost::any> &inputs, last const& in) {
631 
632  const int inputNum = inputs.size();
633 
634  // this is the last input, the last one should equal the total number of inputs
635  assert(numInputs<0 || inputNum+1==numInputs);
636 
637  // check the input type
638  assert(CheckInputType(inputNum, typeid(in).name()));
639 
640  // add the last input to the input vector
641  const boost::any in_any(in);
642  inputs.push_back(std::cref(in_any));
643 
644  return Evaluate(inputs);
645  }
646 
647  // /// User-implemented function that to compute the Jacobian
648  // /**
649  // If th user does not implement this function, the Jacobian cannot be computed. However, if both the input and the output type are Eigen::VectorXd, we default to finite difference.
650  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
651  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
652  // @param[in] inputs The vector of references to the inputs
653  // */
654  // virtual void JacobianImpl(unsigned int const wrtIn, unsigned int const wrtOut, ref_vector<boost::any> const& inputs);
655  //
656  // /// Creates WorkPiece::inputs when the WorkPiece::Jacobian is called with multiple arguments
657  // /**
658  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
659  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
660  // @param[in] inputs The growing vector of inputs
661  // @param[in] in The input corresponding to the \f$i^{th}\f$ input
662  // @param[in] args The remaining (greater than \f$i\f$) inputs
663  // \return The Jacobian of this muq::Modeling::WorkPiece
664  // */
665  // template<typename ith, typename... Args>
666  // boost::any JacobianRecursive(unsigned int const wrtIn, unsigned int const wrtOut, ref_vector<boost::any> &inputs, ith const& in, Args... args) {
667  // const int inputNum = inputs.size();
668  //
669  // // we have not yet put all of the inputs into the map, the ith should be less than the total number
670  // assert(numInputs<0 || inputNum+1<numInputs);
671  //
672  // // check the input type
673  // assert(CheckInputType(inputNum, typeid(in).name()));
674  //
675  // // add the last input to the input vector
676  // const boost::any in_any(in);
677  // inputs.push_back(std::cref(in_any));
678  //
679  // // call with JacobianRecursive with the remaining inputs
680  // return JacobianRecursive(wrtIn, wrtOut, inputs, args...);
681  // }
682  //
683  // /// Creates WorkPiece::inputs when the WorkPiece::Jacobian is called with multiple arguments
684  // /**
685  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
686  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
687  // @param[in] inputs The growing vector of inputs
688  // @param[in] in The input corresponding to the last input
689  // \return The Jacobian of this muq::Modeling::WorkPiece
690  // */
691  // template<typename last>
692  // boost::any JacobianRecursive(unsigned int const wrtIn, unsigned int const wrtOut, ref_vector<boost::any> &inputs, last const& in) {
693  // const int inputNum = inputs.size();
694  //
695  // // this is the last input, the last one should equal the total number of inputs
696  // assert(numInputs<0 || inputNum+1==numInputs);
697  //
698  // // check the input type
699  // assert(CheckInputType(inputNum, typeid(in).name()));
700  //
701  // // add the last input to the input vector
702  // const boost::any in_any(in);
703  // inputs.push_back(std::cref(in_any));
704  //
705  // return Jacobian(wrtIn, wrtOut, inputs);
706  // }
707  //
708  // /// User-implemented function that to compute the action of the Jacobian
709  // /**
710  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
711  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
712  // @param[in] vec We want to apply the Jacobian to this vector
713  // @param[in] inputs The vector of references to the inputs
714  // */
715  // virtual void JacobianActionImpl(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, ref_vector<boost::any> const& inputs);
716  //
717  // /// Creates WorkPiece::inputs when the WorkPiece::JacobianAction is called with multiple arguments
718  // /**
719  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
720  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
721  // @param[in] vec We want to apply the Jacobian to this vector
722  // @param[in] inputs The growing vector of inputs
723  // @param[in] in The input corresponding to the \f$i^{th}\f$ input
724  // @param[in] args The remaining (greater than \f$i\f$) inputs
725  // \return The action of the Jacobian of this muq::Modeling::WorkPiece on vec
726  // */
727  // template<typename ith, typename... Args>
728  // boost::any JacobianActionRecursive(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, ref_vector<boost::any>& inputs, ith const& in, Args... args) {
729  // const int inputNum = inputs.size();
730  //
731  // // we have not yet put all of the inputs into the map, the ith should be less than the total number
732  // assert(numInputs<0 || inputNum+1<numInputs);
733  //
734  // // check the input type
735  // assert(CheckInputType(inputNum, typeid(in).name()));
736  //
737  // // add the last input to the input vector
738  // const boost::any in_any(in);
739  // inputs.push_back(std::cref(in_any));
740  //
741  // // call with JacobianActionRecursive with the remaining inputs
742  // return JacobianActionRecursive(wrtIn, wrtOut, vec, inputs, args...);
743  // }
744  //
745  // /// Creates WorkPiece::inputs when the WorkPiece::JacobianAction is called with multiple arguments
746  // /**
747  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
748  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
749  // @param[in] vec We want to apply the Jacobian to this vector
750  // @param[in] inputs The growing vector of inputs
751  // @param[in] in The input corresponding to the last input
752  // \return The action of the Jacobian of this muq::Modeling::WorkPiece on vec
753  // */
754  // template<typename last>
755  // boost::any JacobianActionRecursive(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, ref_vector<boost::any>& inputs, last const& in) {
756  // const int inputNum = inputs.size();
757  //
758  // // this is the last input, the last one should equal the total number of inputs
759  // assert(numInputs<0 || inputNum+1==numInputs);
760  //
761  // // check the input type
762  // assert(CheckInputType(inputNum, typeid(in).name()));
763  //
764  // // add the last input to the input vector
765  // const boost::any in_any(in);
766  // inputs.push_back(std::cref(in_any));
767  //
768  // return JacobianAction(wrtIn, wrtOut, vec, inputs);
769  // }
770  //
771  // /// User-implemented function that to compute the action of the Jacobian transpose
772  // /**
773  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
774  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
775  // @param[in] vec We want to apply the Jacobian transpose to this vector
776  // @param[in] inputs The vector of references to the inputs
777  // */
778  // virtual void JacobianTransposeActionImpl(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, ref_vector<boost::any> const& inputs);
779  //
780  // /// Creates WorkPiece::inputs when the WorkPiece::JacobianTransposeAction is called with multiple arguments
781  // /**
782  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
783  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
784  // @param[in] vec We want to apply the Jacobian transpose on this vector
785  // @param[in] inputs The growing vector of inputs
786  // @param[in] in The input corresponding to the \f$i^{th}\f$ input
787  // @param[in] args The remaining (greater than \f$i\f$) inputs
788  // \return The action of the Jacobian of this muq::Modeling::WorkPiece on vec
789  // */
790  // template<typename ith, typename... Args>
791  // boost::any JacobianTransposeActionRecursive(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, ref_vector<boost::any>& inputs, ith const& in, Args... args) {
792  // const int inputNum = inputs.size();
793  //
794  // // we have not yet put all of the inputs into the map, the ith should be less than the total number
795  // assert(numInputs<0 || inputNum+1<numInputs);
796  //
797  // // check the input type
798  // assert(CheckInputType(inputNum, typeid(in).name()));
799  //
800  // // add the last input to the input vector
801  // const boost::any in_any(in);
802  // inputs.push_back(std::cref(in_any));
803  //
804  // // call with JacobianTransposeActionRecursive with the remaining inputs
805  // return JacobianTransposeActionRecursive(wrtIn, wrtOut, vec, inputs, args...);
806  // }
807  //
808  // /// Creates WorkPiece::inputs when the WorkPiece::JacobianTransposeAction is called with multiple arguments
809  // /**
810  // @param[in] wrtIn The input number we are taking the Jacobian with respect to
811  // @param[in] wrtOut The output number we are taking the Jacobian with respect to
812  // @param[in] vec We want to apply the Jacobian transpose to this vector
813  // @param[in] inputs The growing vector of inputs
814  // @param[in] in The input corresponding to the last input
815  // \return The action of the Jacobian of this muq::Modeling::WorkPiece on vec
816  // */
817  // template<typename last>
818  // boost::any JacobianTransposeActionRecursive(unsigned int const wrtIn, unsigned int const wrtOut, boost::any const& vec, ref_vector<boost::any>& inputs, last const& in) {
819  // const int inputNum = inputs.size();
820  //
821  // // this is the last input, the last one should equal the total number of inputs
822  // assert(numInputs<0 || inputNum+1==numInputs);
823  //
824  // // check the input type
825  // assert(CheckInputType(inputNum, typeid(in).name()));
826  //
827  // // add the last input to the input vector
828  // const boost::any in_any(in);
829  // inputs.push_back(std::cref(in_any));
830  //
831  // return JacobianTransposeAction(wrtIn, wrtOut, vec, inputs);
832  // }
833 
835  void Clear();
836 
838 
843  void DestroyAny(boost::any& obj) const;
844 
846 
849  virtual void DestroyAnyImpl(boost::any& obj) const;
850 
852  static unsigned int CreateID();
853 
855 
865  //const std::map<std::string, std::string> types;
866  }; // class WorkPiece
867  } // namespace Modeling
868 } // namespace muq
869 
870 #endif
A muq::Modeling::WorkPiece created from a muq::Modeling::WorkGraph.
A graph of connected muq::Modeling::WorkPiece's.
Definition: WorkGraph.h:20
Base class for MUQ's modelling envronment.
Definition: WorkPiece.h:40
void Clear()
Clear muq::Modeling::WorkPiece::outputs when muq::Modeling::Evaluate is called.
Definition: WorkPiece.cpp:730
std::vector< boost::any > const & EvaluateRecursive(ref_vector< boost::any > &inputs, ith const &in, Args... args)
Creates WorkPiece::inputs when the WorkPiece::Evaluate is called with multiple arguments.
Definition: WorkPiece.h:606
std::string const & Name()
Get the (unique) name of this work piece.
Definition: WorkPiece.cpp:538
std::map< unsigned int, std::string > outputTypes
The output types.
Definition: WorkPiece.h:558
std::map< unsigned int, int > inputSizes
Definition: WorkPiece.h:560
bool CheckOutputType(unsigned int const outputNum, std::string const &type) const
Check the output type.
Definition: WorkPiece.cpp:756
std::map< unsigned int, std::string > OutputTypes() const
Get the output types.
Definition: WorkPiece.cpp:655
bool CheckInputType(unsigned int const inputNum, std::string const &type) const
Check the input type.
Definition: WorkPiece.cpp:743
std::vector< boost::any > const & EvaluateRecursive(ref_vector< boost::any > &inputs, last const &in)
Creates WorkPiece::inputs when the WorkPiece::Evaluate is called with multiple arguments.
Definition: WorkPiece.h:630
const unsigned int id
A unique ID number assigned by the constructor.
Definition: WorkPiece.h:580
virtual unsigned long int GetNumCalls(const std::string &method="Evaluate") const
get the number of times one of the implemented methods has been called.
Definition: WorkPiece.cpp:598
std::map< unsigned int, std::string > inputTypes
The input types.
Definition: WorkPiece.h:552
WorkPiece()
Create a muq::Modeling::WorkPiece with no fixed number of inputs and outputs and variable input/outpu...
Definition: WorkPiece.cpp:10
std::string OutputType(unsigned int outputNum, bool const demangle=true) const
Get the output type (if we know it) for a specific output.
Definition: WorkPiece.cpp:630
virtual double GetRunTime(const std::string &method="Evaluate") const
Get the average run time for one of the implemented methods.
Definition: WorkPiece.cpp:580
virtual void EvaluateImpl(ref_vector< boost::any > const &inputs)=0
User-implemented function that determines the behavior of this muq::Modeling::WorkPiece.
unsigned long int numEvalCalls
Definition: WorkPiece.h:573
virtual void ResetCallTime()
Resets the number of call and times.
Definition: WorkPiece.cpp:592
std::vector< boost::any > const & Evaluate(Args... args)
Evalaute this muq::Modeling::WorkPiece using multiple arguments.
Definition: WorkPiece.h:245
std::map< unsigned int, std::string > InputTypes() const
Get the input types.
Definition: WorkPiece.cpp:659
std::vector< std::string > Types(std::vector< boost::any > const &vec) const
Get the types from a vector of boost::any's.
Definition: WorkPiece.cpp:201
static ref_vector< const boost::any > ToRefVector(std::vector< boost::any > const &anyVec)
Create vector of references from a vector of boost::any's.
Definition: WorkPiece.cpp:675
void SetName(std::string const &newName)
Set the name of this work piece.
Definition: WorkPiece.cpp:575
std::string InputType(unsigned int inputNum, bool const demangle=true) const
Get the input type (if we know it) for a specific input.
Definition: WorkPiece.cpp:609
unsigned int ID() const
Get the unique ID number.
Definition: WorkPiece.cpp:651
bool clearOutputs
Clear outputs every time Evaluate is called.
Definition: WorkPiece.h:540
void DestroyAny(boost::any &obj) const
Destroy a boost any.
Definition: WorkPiece.cpp:689
int numOutputs
The number of outputs.
Definition: WorkPiece.h:504
void SetInputSize(unsigned int inputNum, int newSize)
Definition: WorkPiece.cpp:780
Fix
Does the constructor fix the inputs or the outputs?
Definition: WorkPiece.h:49
@ Inputs
The constructor fixes the input number and possibly the types.
Definition: WorkPiece.h:51
@ Outputs
The constructor fixes the output number and possibly the types.
Definition: WorkPiece.h:53
virtual ~WorkPiece()
Default destructor.
Definition: WorkPiece.h:210
virtual std::string CreateName() const
Definition: WorkPiece.cpp:546
virtual void DestroyAnyImpl(boost::any &obj) const
Destroy a boost any.
Definition: WorkPiece.cpp:687
std::vector< boost::any > outputs
The outputs.
Definition: WorkPiece.h:546
std::vector< boost::any > const & Evaluate()
Evaluate this muq::Modeling::WorkPiece in the case that there are no inputs.
Definition: WorkPiece.cpp:222
static unsigned int CreateID()
Creates a unique ID number, must be called by the constructor.
Definition: WorkPiece.cpp:217
int InputSize(unsigned int inputNum) const
Get the length of a vector valued input with fixed size.
Definition: WorkPiece.cpp:770
std::string name
A unique name for this WorkPiece. Defaults to <ClassName>_<id>
Definition: WorkPiece.h:583
int numInputs
The number of inputs.
Definition: WorkPiece.h:501
std::vector< std::reference_wrapper< const T > > ref_vector
A vector of references to something ...
Definition: WorkPiece.h:37
std::string demangle(const char *name)
Definition: Demangler.cpp:6
const char * last
Definition: json.h:15399