NUMCXX  0.13.20181108
Numerical library for small projects and teaching purposes
10-numcxx-expressions.cxx
Go to the documentation of this file.
1 #include <iostream>
29 #include <numcxx/numcxx.hxx>
30 
31 int main()
32 {
33  const int n=3;
35  // Declare three arrays with double elements. Like in the case
36  // with std::vector, the contents of a class object is placed on
37  // the stack, but the large data array is put on the heap.
38 
43 
45  // We can assign constant values to an array.
46  // The expression template trick allows to do the same for B
47  // as the loop does for A.
48  for (int i=0;i<n;i++)
49  A(i)=3.0;
50  B=3.0;
51 
52  std::cout << "Assigning constant values to an array:" << std::endl;
53  // numcxx arrays can be printed via iostreams.
54  std::cout << "A:"<< std::endl << A << std::endl;
55  std::cout << "B:"<< std::endl << B << std::endl;
56 
58  for (int i=0;i<n;i++)
59  A(i)=i+5;
60  B=A;
61 
62  std::cout << "Copying data from one array to the other:" << std::endl;
63  std::cout << "A:"<< std::endl << A << std::endl;
64  std::cout << "B:"<< std::endl << B << std::endl;
65 
67  // On arrays of the same size, we can perform the operations
68  // allowed for elements of a vector space, i.e. addition, subraction and
69  // multiplication by scalars.
70  // The expression template trick allows to do the same for C
71  // as the loop does for D.
72  for (int i=0;i<n;i++)
73  C(i)=3*A(i)+B(i);
74  D=3*A+B;
75  std::cout << "Arithmetic expressions:" << std::endl;
76  std::cout << "C:"<< std::endl << C << std::endl;
77  std::cout << "D:"<< std::endl << C << std::endl;
78 
79 
81  // In array expressions, stay safe and avoid
82  // auto on the left hand side!
84 
85  // If you want to use auto, do it like this.
86  auto F=numcxx::arrayexpr(A+17*B);
87 
88  // The alternative
89  // auto F=A+17*B;
90  // won't work with << or later use of F on the left
91  // hand side of expressions because the type of F detected
92  // by auto is the expression template, not the vector.
93  // Here, it would be detected at compile time.
94 
95  std::cout << "Avoiding auto with expression templates:" << std::endl;
96  std::cout << "E:"<< std::endl << E << std::endl;
97  std::cout << "F:"<< std::endl << F << std::endl;
98 
100  // This is the real dangerous situation with auto,
101  // described in https://eigen.tuxfamily.org/dox/TopicPitfalls.html
102  auto G=numcxx::arrayexpr(19*A+10*B);
103 
104  // With
105  // auto G=19*A+10*B;
106  // G would be an instance of an intermediate type which contains
107  // A and B and the possibility to calculate the result of the rhs expression.
108  // Changing A would change also A in G and lead to a different result.
109  // This is not detected at compile time!
110  A(1)++;
111  E=G+E;
112  std::cout << "Pitfalls of auto:" << std::endl;
113  std::cout << "E:"<< std::endl << E << std::endl;
114 
115 }
TArray1< typename A::value_type > arrayexpr(const A &a)
Evaluate expression as array.
Definition: util.ixx:19
int main()
Main header of the library.
One dimensional array class.
Definition: tarray1.hxx:31
double B(double x)